Lightning-paywalled FastAPI service — niche: Ready-to-submit PR generator for awesome-lists
Project description
milo-awesome-list-pr-generator
Paste your repo URL → get a ready-to-submit PR that adds your project to the right awesome-list.
Correct H2 section. Correct alphabetical position. Correct format. Lightning-paywalled at 200 sats for the auto-open step. Diff + body are free.
Why this exists
Every project that wants discovery via sindresorhus/awesome and its 700+ descendants hits the same wall:
- Find the right H2 section in a 2000-line README
- Insert at the correct alphabetical position
- Match the list's idiosyncratic format (link style, bullet char, separator, description length cap)
- Open the PR with a body the maintainer can merge in < 30s
Manual = 20-40 min. Often rejected for format issues. This automates steps 1-4.
Endpoint catalog
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/ |
free | Service info + endpoint catalog + pricing |
POST |
/generate |
free, 10/60s/IP | PR diff + body + runnable gh pr create command |
POST |
/submit |
200 sats Lightning | Opens the PR if X-Github-Token provided; otherwise returns the prepared command |
GET |
/pro |
$9 Lightning | Legacy paywall demo (worked example) |
POST /generate example
curl -X POST http://127.0.0.1:8101/generate \
-H 'content-type: application/json' \
-d '{
"awesome_repo": "bcongdon/awesome-lightning-network",
"project": {
"name": "my-cool-tool",
"url": "https://github.com/me/my-cool-tool",
"description": "LND channel rebalancing advisor with routing analytics.",
"language": "Python",
"license": "MIT",
"tags": ["lnd", "rebalance", "tools"]
}
}'
Response (truncated):
{
"ok": true,
"tier": "free",
"pr": {
"awesome_repo": "bcongdon/awesome-lightning-network",
"suggested_section": "Tools",
"section_match_score": 0.18,
"entry_line": "- [my-cool-tool](https://github.com/me/my-cool-tool) - LND channel rebalancing advisor with routing analytics.",
"diff": "--- a/README.md\n+++ b/README.md\n...",
"pr_title": "Add my-cool-tool to Tools",
"pr_body": "...",
"gh_pr_create_command": "# 1. Fork + clone ...\n# 2. Apply the diff ...\ncat <<'BODY' | gh pr create ..."
}
}
POST /submit flow
- First call returns 402 with a BOLT-11 invoice for 200 sats.
- Pay it in any LN wallet (Phoenix, Alby, Wallet of Satoshi, Zeus).
- Second call with
?payment_hash=<hash-from-402>:- With
X-Github-Token: ghp_...header → we rungh pr createon your behalf (token never stored, never logged, never echoed). - Without → response includes the fully-prepared command for you to run locally.
- With
curl -X POST "http://127.0.0.1:8101/submit?payment_hash=$PH" \
-H 'content-type: application/json' \
-H "X-Github-Token: $GH_TOKEN" \
-d '{ "awesome_repo": "...", "project": {...} }'
Pricing
/generate— free, 10 req / 60s per IP. Rate-limit response includes the/submitupgrade path./submit— 200 sats per PR. Either auto-open or fully-prepared command./pro— $9 legacy paywall demo (worked example of what/submitproduces).
Why so cheap on /submit? Per market-truth doctrine: ship + measure. 200 sats keeps friction low while the niche proves itself.
Quick start
pip install -e .
python -m milo_awesome_list_pr_generator.server --port 8101
Or via uvicorn:
uvicorn milo_awesome_list_pr_generator.server:app --port 8101
Lightning provider setup (30s)
export MILO_LIGHTNING_INVOICE_KEY=<your-LNBits-invoice-key>
export MILO_LIGHTNING_BASE_URL=https://legend.lnbits.com # or your self-host
Defaults to LNBits. To swap providers, see _milo_paywall_kit/.
Architecture
domain.py— pure-python; no HTTP outbound exceptfetch_awesome_list(injectable opener for tests)server.py— FastAPI; routes wired tomilo_paywall_kitfor L402-style 402 mediationtests/— 40 tests total: 24 domain + 10 endpoint + 6 baseline scaffold
Security
X-Github-Token, when supplied to/submit, is held only in the request-handler frame.- We never log it, never persist it, never echo it in responses (test enforces this).
- Auto-submit is disabled by default. Production deployment must opt in via
MILO_AWESOME_LIST_PR_GENERATOR_ALLOW_AUTO_SUBMIT=1AND inject a realrun_gh_pr_createvia DI. - Per CLAUDE.md: this is a content generator, not a publisher. We don't auto-push to non-Milo repos without explicit caller auth + opt-in.
README badge embed
Add to your project's README to show it was awesome-list-submitted with this tool:
[](https://github.com/miloantaeus/milo-awesome-list-pr-generator)
30-day kill criterion
Per market-truth doctrine: < 50 GitHub stars + 0 paid submissions in 60 days → deprecate.
Tracked metrics:
- GitHub stars on this repo
- Count of settled 200-sat invoices for
/submit - Count of
/generatecalls (proxy for free-tier interest)
If we hit the bar, Milo expands. If we don't, Milo kills it. No supervisor approval required for the kill — that's the doctrine.
Tests
pip install -e ".[test]"
pytest -q
# ====== 40 passed in 0.17s ======
Honest probability assessment
Build brief claimed:
- First
/generatecall within 30d: 30% - First paid
/submitwithin 60d: 10%
My take (see commit msg of launch post): I think first /generate is closer to 45% (distribution is straightforward — HN Show, Stacker.News, the awesome-list's own PR thread) but first paid /submit is closer to 6% because most awesome-list submitters are technical enough to copy-paste a gh pr create command, and Lightning payment friction (even at 200 sats) is non-trivial. The brief's numbers err on the conservative side for free + the optimistic side for paid.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file milo_awesome_list_pr_generator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: milo_awesome_list_pr_generator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
501223f23a6defd148beec7f2b02b510ef974dd8081e2db51feb18372b196e25
|
|
| MD5 |
133445d24958b2681ab45f240bfc1dca
|
|
| BLAKE2b-256 |
91867ee6edbb665c2b3ffff3a0c67ce9b3381255489d3d6c0171458b6eb54981
|