mirror of
https://github.com/modelscope/FunASR.git
synced 2026-10-12 02:19:18 +00:00
docs: add growth metrics tracker
Add a lightweight script and cadence for tracking GitHub and PyPI growth metrics toward 20k stars.
This commit is contained in:
@@ -74,6 +74,17 @@ For each launch, prepare:
|
||||
- Add third-party integrations and community projects to README when they are maintained and runnable.
|
||||
- Keep citations and paper links visible for researchers.
|
||||
|
||||
## Tracking cadence
|
||||
|
||||
Use the lightweight metrics script before and after major README, homepage, release, or demo updates:
|
||||
|
||||
```bash
|
||||
python scripts/collect_growth_metrics.py
|
||||
python scripts/collect_growth_metrics.py --format json
|
||||
```
|
||||
|
||||
The script captures GitHub stars, forks, watchers, open issues, latest push time, and the current PyPI version using public APIs. Set `GITHUB_TOKEN` when running it from CI or a shared network to avoid public GitHub API rate limits. Paste the Markdown output into launch notes, weekly community updates, or release retrospectives so the 20k-star effort stays measurable.
|
||||
|
||||
## 30-day execution checklist
|
||||
|
||||
### Week 1: Repository conversion
|
||||
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Collect lightweight growth metrics for the FunASR repository.
|
||||
|
||||
The script uses only Python's standard library and public APIs by default.
|
||||
Set GITHUB_TOKEN to raise GitHub API rate limits in CI or release workflows.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import datetime as dt
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
DEFAULT_REPO = "modelscope/FunASR"
|
||||
DEFAULT_PACKAGE = "funasr"
|
||||
|
||||
|
||||
def fetch_json(url: str, headers: Optional[Dict[str, str]] = None) -> Any:
|
||||
request = urllib.request.Request(url, headers=headers or {})
|
||||
try:
|
||||
with urllib.request.urlopen(request, timeout=30) as response:
|
||||
return json.loads(response.read().decode("utf-8"))
|
||||
except urllib.error.HTTPError as exc:
|
||||
body = exc.read().decode("utf-8", errors="replace")
|
||||
raise RuntimeError(f"GET {url} failed with HTTP {exc.code}: {body}") from exc
|
||||
except urllib.error.URLError as exc:
|
||||
raise RuntimeError(f"GET {url} failed: {exc.reason}") from exc
|
||||
|
||||
|
||||
def github_headers() -> Dict[str, str]:
|
||||
headers = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
"User-Agent": "funasr-growth-metrics",
|
||||
}
|
||||
token = os.environ.get("GITHUB_TOKEN")
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
return headers
|
||||
|
||||
|
||||
def collect_metrics(repo: str, package: str) -> Dict[str, Any]:
|
||||
owner_repo = repo.strip("/")
|
||||
github = fetch_json(f"https://api.github.com/repos/{owner_repo}", github_headers())
|
||||
pypi = fetch_json(f"https://pypi.org/pypi/{package}/json", {"User-Agent": "funasr-growth-metrics"})
|
||||
latest_release = github.get("pushed_at")
|
||||
metrics = {
|
||||
"collected_at_utc": dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat(),
|
||||
"github": {
|
||||
"repo": owner_repo,
|
||||
"stars": github.get("stargazers_count"),
|
||||
"forks": github.get("forks_count"),
|
||||
"watchers": github.get("subscribers_count"),
|
||||
"open_issues": github.get("open_issues_count"),
|
||||
"default_branch": github.get("default_branch"),
|
||||
"pushed_at": latest_release,
|
||||
"html_url": github.get("html_url"),
|
||||
},
|
||||
"pypi": {
|
||||
"package": package,
|
||||
"version": pypi.get("info", {}).get("version"),
|
||||
"summary": pypi.get("info", {}).get("summary"),
|
||||
"project_url": pypi.get("info", {}).get("project_url"),
|
||||
},
|
||||
}
|
||||
return metrics
|
||||
|
||||
|
||||
def format_markdown(metrics: Dict[str, Any], star_goal: int) -> str:
|
||||
github = metrics["github"]
|
||||
pypi = metrics["pypi"]
|
||||
stars = github.get("stars") or 0
|
||||
remaining = max(star_goal - stars, 0)
|
||||
lines = [
|
||||
f"# FunASR Growth Snapshot ({metrics['collected_at_utc']})",
|
||||
"",
|
||||
f"- GitHub stars: **{stars:,}** / {star_goal:,} ({remaining:,} remaining)",
|
||||
f"- GitHub forks: **{github.get('forks'):,}**" if github.get("forks") is not None else "- GitHub forks: n/a",
|
||||
f"- GitHub watchers: **{github.get('watchers'):,}**" if github.get("watchers") is not None else "- GitHub watchers: n/a",
|
||||
f"- Open issues: **{github.get('open_issues'):,}**" if github.get("open_issues") is not None else "- Open issues: n/a",
|
||||
f"- PyPI package: **{pypi.get('package')} {pypi.get('version')}**",
|
||||
f"- Last GitHub push: `{github.get('pushed_at')}`",
|
||||
"",
|
||||
"## Links",
|
||||
"",
|
||||
f"- Repository: {github.get('html_url')}",
|
||||
f"- PyPI: {pypi.get('project_url')}",
|
||||
"- GitHub Pages: https://modelscope.github.io/FunASR/",
|
||||
"- Trendshift: https://trendshift.io/repositories/10479",
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Collect FunASR growth metrics.")
|
||||
parser.add_argument("--repo", default=DEFAULT_REPO, help="GitHub repository, e.g. modelscope/FunASR")
|
||||
parser.add_argument("--pypi-package", default=DEFAULT_PACKAGE, help="PyPI package name")
|
||||
parser.add_argument("--star-goal", type=int, default=20000, help="Target GitHub star count")
|
||||
parser.add_argument("--format", choices=["markdown", "json"], default="markdown", help="Output format")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
args = parse_args()
|
||||
try:
|
||||
metrics = collect_metrics(args.repo, args.pypi_package)
|
||||
except RuntimeError as exc:
|
||||
print(exc, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if args.format == "json":
|
||||
print(json.dumps(metrics, ensure_ascii=False, indent=2))
|
||||
else:
|
||||
print(format_markdown(metrics, args.star_goal), end="")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user