Skip to content

Instantly share code, notes, and snippets.

@jefftriplett
Last active February 24, 2025 00:23
Show Gist options
  • Save jefftriplett/56ad443c21fee742d062d0a840aeeecd to your computer and use it in GitHub Desktop.
Save jefftriplett/56ad443c21fee742d062d0a840aeeecd to your computer and use it in GitHub Desktop.
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx",
# "rich",
# "typer",
# ]
# ///
"""
$ uv run django-top-100.py
"""
import httpx
import json
import typer
from pathlib import Path
from rich import box
from rich.console import Console
from rich.table import Table
def fetch_and_cache(
*,
url: str,
cache_file: str,
timeout: float = 10.0,
):
filename = Path(cache_file)
if filename.exists():
return filename.read_text()
response = httpx.get(url, timeout=timeout)
response.raise_for_status()
contents = response.text
Path(cache_file).write_text(contents)
return contents
def main(limit: int = 100):
content = fetch_and_cache(
url="https://hugovk.github.io/top-pypi-packages/top-pypi-packages-30-days.json",
cache_file="top-pypi-packages-30-days.json",
)
django_count = 0
django_index = 0
projects = json.loads(content)
table = Table(title=f"Django Packages Stats: Top {limit}", box=box.MARKDOWN)
table.add_column("Rank", justify="right")
table.add_column("Project", justify="left")
table.add_column("Downloads", justify="right")
table.add_column("Percent", justify="right")
for project in projects["rows"]:
name = project["project"]
download_count = project["download_count"]
# Process only packages with 'django' in their name
if any(sub in name for sub in ("django", "dj-", "wagtail", "whitenoise")):
if django_index <= limit:
if name == "django":
# For the Django project itself, no percent is calculated.
django_count = download_count
# Avoid division by zero if django_count hasn't been set
percent = download_count / django_count if django_count else 0
percent_str = "{:.2%}".format(percent)
package_str = (
f"[link=https://pypistats.org/packages/{name}]{name}[/link]"
)
# If the percentage exceeds the threshold, color the row yellow.
if percent >= 0.10:
table.add_row(
f"{django_index}" if django_index > 0 else "",
f"[yellow]{package_str}[/yellow]",
f"{download_count:,}",
percent_str,
)
else:
table.add_row(
f"{django_index}",
package_str,
f"{download_count:,}",
percent_str,
)
django_index += 1
console = Console()
console.print(table)
if __name__ == "__main__":
typer.run(main)
                Django Packages Stats: Top 100                    
Rank Project Downloads Percent
django 17,949,648 100.00%
1 djangorestframework 9,685,917 53.96%
2 django-cors-headers 7,212,016 40.18%
3 django-filter 5,702,845 31.77%
4 pytest-django 4,689,978 26.13%
5 django-extensions 4,541,391 25.30%
6 django-storages 4,413,800 24.59%
7 opentelemetry-instrumentation-django 4,067,028 22.66%
8 django-redis 3,596,319 20.04%
9 whitenoise 3,572,324 19.90%
10 djangorestframework-simplejwt 3,264,098 18.18%
11 django-debug-toolbar 3,226,431 17.97%
12 django-environ 2,876,392 16.02%
13 django-timezone-field 2,731,400 15.22%
14 django-celery-beat 2,091,794 11.65%
15 django-stubs 2,074,887 11.56%
16 django-stubs-ext 1,975,876 11.01%
17 dj-database-url 1,968,801 10.97%
18 django-appconf 1,663,766 9.27%
19 django-model-utils 1,661,065 9.25%
20 django-simple-history 1,547,464 8.62%
21 django-celery-results 1,530,058 8.52%
22 django-phonenumber-field 1,488,930 8.30%
23 django-crispy-forms 1,367,501 7.62%
24 django-js-asset 1,313,102 7.32%
25 social-auth-app-django 1,296,425 7.22%
26 django-ipware 1,284,614 7.16%
27 django-import-export 1,232,043 6.86%
28 pylint-django 1,213,550 6.76%
29 django-otp 1,145,051 6.38%
30 django-allauth 1,088,116 6.06%
31 djangorestframework-stubs 1,070,579 5.96%
32 django-countries 1,052,276 5.86%
33 django-silk 903,916 5.04%
34 django-oauth-toolkit 884,323 4.93%
35 django-prometheus 848,224 4.73%
36 django-csp 837,779 4.67%
37 django-health-check 816,264 4.55%
38 django-anymail 795,880 4.43%
39 django-picklefield 788,669 4.39%
40 django-modeltranslation 769,761 4.29%
41 django-taggit 761,561 4.24%
42 django-waffle 750,135 4.18%
43 django-formtools 731,548 4.08%
44 django-compressor 690,160 3.84%
45 djangorestframework-api-key 685,593 3.82%
46 django-polymorphic 680,241 3.79%
47 django-mptt 679,074 3.78%
48 django-ses 652,685 3.64%
49 django-ninja 588,096 3.28%
50 django-widget-tweaks 575,884 3.21%
51 django-axes 569,009 3.17%
52 django-admin-rangefilter 558,752 3.11%
53 django-object-actions 544,490 3.03%
54 django-structlog 544,331 3.03%
55 django-ratelimit 541,367 3.02%
56 django-reversion 520,884 2.90%
57 graphene-django 517,845 2.88%
58 django-migration-linter 511,567 2.85%
59 django-ckeditor 482,136 2.69%
60 django-webpack-loader 466,677 2.60%
61 djangorestframework-csv 457,048 2.55%
62 django-treebeard 452,960 2.52%
63 django-coverage-plugin 440,525 2.45%
64 django-localflavor 429,512 2.39%
65 django-two-factor-auth 426,482 2.38%
66 django-tables2 425,364 2.37%
67 djangorestframework-jwt 421,918 2.35%
68 fcm-django 420,370 2.34%
69 django-colorfield 411,887 2.29%
70 django-auth-ldap 410,123 2.28%
71 django-auditlog 396,036 2.21%
72 djangorestframework-dataclasses 389,742 2.17%
73 django-mysql 369,808 2.06%
74 django-constance 365,592 2.04%
75 django-types 355,389 1.98%
76 django-fsm 354,633 1.98%
77 django-json-widget 338,487 1.89%
78 django-guardian 336,730 1.88%
79 django-nested-admin 336,278 1.87%
80 django-tinymce 332,858 1.85%
81 django-hijack 326,913 1.82%
82 django-rest-swagger 320,323 1.78%
83 mozilla-django-oidc 318,450 1.77%
84 django-user-agents 318,068 1.77%
85 djangoql 315,207 1.76%
86 django-select2 310,614 1.73%
87 django-cleanup 308,862 1.72%
88 django-linear-migrations 305,734 1.70%
89 djangorestframework-camel-case 303,717 1.69%
90 django-rq 303,217 1.69%
91 djangorestframework-xml 301,997 1.68%
92 django-htmx 298,341 1.66%
93 django-money 297,291 1.66%
94 dj-rest-auth 294,622 1.64%
95 django-multiselectfield 287,872 1.60%
96 django-rest-knox 287,428 1.60%
97 django-deprecate-fields 282,386 1.57%
98 django-log-request-id 282,134 1.57%
99 django-autocomplete-light 279,022 1.55%
100 django-jazzmin 276,371 1.54%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment