The website at https://openadapt.ai was showing:
- ✓ 5.4k Total Downloads (All Packages) - CORRECT
- ✓ 1,470 GitHub Stars - CORRECT
- ✓ 10 Packages - CORRECT
- ❌ 0 Today (All Packages) - WRONG
- ❌ 0 This Week (All Packages) - WRONG
- ❌ 0 This Month (All Packages) - WRONG
After investigation, I discovered:
-
API is working correctly: The
/api/pypistatsendpoint was returning valid data:{ "data": { "last_day": 244, "last_week": 254, "last_month": 575 } } -
Previous fix existed: There was already a fix in commit
9cab6c5that addressed a similar issue (ensuring the API returns all time periods, not just month). -
Actual problem: The component in
PyPIDownloadChart.jswas usingPromise.all()to fetch three pieces of data concurrently:- Recent download stats
- GitHub repository stats
- Package version history
The issue with
Promise.all()is that if ANY promise rejects, the ENTIRE operation fails and none of the state gets set. This meant if GitHub's API was rate-limited or the version history was slow, the download stats wouldn't display either.
Changed from Promise.all() to Promise.allSettled() in /Users/abrichr/oa/src/openadapt-web/components/PyPIDownloadChart.js.
Before (fragile):
const [recent, github, versions] = await Promise.all([
getRecentDownloadStats(),
getGitHubStats(),
getPackageVersionHistory('openadapt'),
]);
setRecentStats(recent);
setGithubStats(github);
setVersionHistory(versions);After (robust):
const results = await Promise.allSettled([
getRecentDownloadStats(),
getGitHubStats(),
getPackageVersionHistory('openadapt'),
]);
// Handle each result individually
if (results[0].status === 'fulfilled' && results[0].value) {
console.log('Recent stats loaded:', results[0].value);
setRecentStats(results[0].value);
} else {
console.error('Failed to load recent stats:', results[0].reason);
}
if (results[1].status === 'fulfilled' && results[1].value) {
setGithubStats(results[1].value);
} else {
console.error('Failed to load GitHub stats:', results[1].reason);
}
if (results[2].status === 'fulfilled' && results[2].value) {
setVersionHistory(results[2].value);
} else {
console.error('Failed to load version history:', results[2].reason);
}- Graceful degradation: Each API call is independent
- Better reliability: Stats will display even if other APIs fail
- Improved debugging: Individual error logging for each API
- Better UX: Users see the data that successfully loads
/Users/abrichr/oa/src/openadapt-web/components/PyPIDownloadChart.js
-
Verified API endpoint is working:
curl "https://openadapt.ai/api/pypistats?package=openadapt&endpoint=recent" # Returns: {"data":{"last_day":244,"last_month":575,"last_week":254},...}
-
Tested multiple packages - all returning valid data
-
Expected behavior after deployment:
- Today: ~200-300 downloads
- This Week: ~250-400 downloads
- This Month: ~500-1000 downloads
Created PR #123: #123
Branch: fix/stats-showing-zeros
- The PR will trigger a Vercel/Netlify preview deployment
- Verify the stats display correctly in the preview
- Merge the PR to deploy to production
- Users may need to hard refresh (Cmd+Shift+R / Ctrl+Shift+R) to clear cached JS
- Builds on PR #108 which fixed the API to return all time periods
- Complements the existing error handling in
pypistatsHistory.js