{"id":51481638,"url":"https://github.com/random-walks/rrxiv-python","last_synced_at":"2026-07-07T02:01:51.579Z","repository":{"id":359174312,"uuid":"1228995967","full_name":"random-walks/rrxiv-python","owner":"random-walks","description":"Reference Python implementation of the rrxiv protocol — parser, client SDK, FastAPI reference server, conformance tests, and CLI.","archived":false,"fork":false,"pushed_at":"2026-05-30T19:34:14.000Z","size":1712,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T20:20:35.389Z","etag":null,"topics":["fastapi","open-science","preprint","python","reference-implementation","rrxiv"],"latest_commit_sha":null,"homepage":"https://api.rrxiv.com/api/v0/docs","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/random-walks.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T15:37:59.000Z","updated_at":"2026-05-30T19:34:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/random-walks/rrxiv-python","commit_stats":null,"previous_names":["random-walks/rrxiv-python"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/random-walks/rrxiv-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/random-walks%2Frrxiv-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/random-walks%2Frrxiv-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/random-walks%2Frrxiv-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/random-walks%2Frrxiv-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/random-walks","download_url":"https://codeload.github.com/random-walks/rrxiv-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/random-walks%2Frrxiv-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35211553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastapi","open-science","preprint","python","reference-implementation","rrxiv"],"created_at":"2026-07-07T02:01:46.616Z","updated_at":"2026-07-07T02:01:51.154Z","avatar_url":"https://github.com/random-walks.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rrxiv-python\n\nReference Python implementation of the [rrxiv protocol](https://github.com/random-walks/rrxiv) — parser, client SDK, FastAPI reference server, conformance test suite, and CLI.\n\n**Status: v0.1 — running in production at [api.rrxiv.com](https://api.rrxiv.com/api/v0/docs).** Not yet on PyPI; install from the git ref.\n\n## Installation\n\n```bash\n# Library + parser only\npip install \"rrxiv @ git+https://github.com/random-walks/rrxiv-python.git@main\"\n\n# Library + server (FastAPI, uvicorn, ed25519 signatures, sentry, etc.)\npip install \"rrxiv[server] @ git+https://github.com/random-walks/rrxiv-python.git@main\"\n```\n\nOr with [uv](https://docs.astral.sh/uv/):\n\n```bash\nuv add \"rrxiv[server] @ git+https://github.com/random-walks/rrxiv-python.git@main\"\n```\n\n## Quick tour\n\n### Parse a paper\n\n```bash\nrrxiv parse paper/main.tex --output paper.cir.json\nrrxiv validate paper.cir.json\n```\n\nProduces a [Canonical Intermediate Representation](https://github.com/random-walks/rrxiv/blob/main/schema/cir.schema.json) — paper metadata + claims + annotations + claim-graph edges, validated against the JSON Schema in `random-walks/rrxiv`.\n\n### Run a local instance\n\n```bash\n# Memory store (lost on exit) — fastest path to play with the API\nrrxiv serve --dev-mode\n\n# Persistent SQLite store with a seed corpus\nrrxiv serve \\\n  --store sqlite:////tmp/rrxiv.db \\\n  --seed-dir ./seed \\\n  --port 8765\n```\n\n`http://127.0.0.1:8765/api/v0/docs` then shows the full OpenAPI; `/api/v0/papers` lists the seeded corpus.\n\n### Bulk-load a corpus\n\n```bash\n# First boot: seed a fresh DB from a directory of *.cir.json + *.pdf\n# + *.source.tar.gz triples\nrrxiv seed-store --from ./seed --store sqlite:////data/rrxiv.db\n\n# When claim ids change between releases, --reset wipes the corpus tables\n# before re-seeding so no orphan rows linger\nrrxiv seed-store --from ./seed --store sqlite:////data/rrxiv.db --reset\n```\n\n`seed-store` also stamps `paper.source.uri` / `paper.source.rendered_pdf_uri` with the canonical `/api/v0/papers/{id}/{source,pdf}` endpoints so the web client can resolve them.\n\n## Package layout\n\n- `rrxiv.models` — Pydantic v2 models generated from the JSON Schemas (`Paper`, `Claim`, `Annotation`, `Citation`, `CIR`, plus enums).\n- `rrxiv.parser` — `.tex` → CIR. Recognises the [`rrxiv.cls`](https://github.com/random-walks/rrxiv/blob/main/template/rrxiv.cls) `\\claim` / `\\evidence` / `\\dependson` markup.\n- `rrxiv.client` — async + sync HTTP client + retry policy + signature middleware.\n- `rrxiv.server` — FastAPI app factory + 8 routers (auth, papers, claims, annotations, snapshots, search, submissions, sources). Pluggable `Store` (memory / sqlite / future Postgres).\n- `rrxiv.testing` — `live_server` pytest fixture for running the server against real HTTP.\n- `rrxiv.cli` — Typer CLI:\n  - **Authoring**: `parse`, `validate`, `submit`, `snapshot`, `doctor`.\n  - **Auth**: `login` (ORCID / agent / anonymous flows, keychain persistence).\n  - **Ops**: `serve`, `seed-store`.\n  - **Read**: `version`, `papers {list,get,versions}`, `claims {list,get,top}`, `search` — added in Sprint 19 so the CLI is a first-class read client, not write-only.\n  - **Annotations**: `annotation {validate,post,list,retract,replicate,comment,post-batch}` — `post-batch` hits `POST /annotations/bulk` (up to 100 per request, single rate-limit unit).\n- `tests/` — 400+ unit tests + the live cross-conformance test (`test_server_cross.py`) that runs the protocol-level test suite against the in-process server.\n\n## Development\n\n```bash\nuv sync --all-extras\nuv run pytest               # 400+ passed, ~4 skipped\nuv run ruff check .\nuv run mypy src/\n```\n\n## Reference server in production\n\nThe Fly.io deployment that powers `api.rrxiv.com` lives in a separate private repo, [`rrxiv-instance`](https://github.com/random-walks/rrxiv-instance) — it pins a specific `rrxiv-python` commit, layers on the production Dockerfile + Fly config, and bakes the canonical 9-paper seed corpus into the image. The split is intentional: `rrxiv-python` stays a library anyone can fork to spin up their own instance; the canonical instance's operational concerns (CORS allowlist, ORCID redirect URIs, Sentry DSNs) belong to the overlay.\n\nIf you want to run your own rrxiv instance, fork that repo's structure — don't depend on its config.\n\n## Schema sync\n\nSchemas live canonically in [random-walks/rrxiv](https://github.com/random-walks/rrxiv). We vendor them under `src/rrxiv/_schemas/` and regenerate Pydantic models from them.\n\nWhen the canonical schemas change (a new field, a tightened enum, a new schema file), run:\n\n```bash\n./scripts/sync_schemas.sh                 # default: ../rrxiv/schema   (workspace pattern)\n./scripts/sync_schemas.sh /path/to/schema # explicit path\n\n./scripts/regen_models.sh                 # regenerate src/rrxiv/models/_generated/\n```\n\n`sync_schemas.sh` writes `src/rrxiv/_schemas_manifest.txt` with the source path, git SHA, branch, and timestamp so you always know which version of the protocol the vendored schemas correspond to.\n\n`regen_models.sh` uses [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) (a dev dep, declared in `pyproject.toml`) to emit one Pydantic v2 module per schema into `src/rrxiv/models/_generated/`. The hand-written `src/rrxiv/models/__init__.py` re-exports the public surface so `from rrxiv.models import Paper, Claim, CIR, ...` keeps working when the generator output rearranges itself.\n\nThe cross-test in [`tests/test_models.py`](tests/test_models.py) loads every fixture from `../rrxiv/tests/schemas/fixtures/` and checks that pydantic agrees with ajv on each. If the two diverge (a fixture passes ajv but fails pydantic, or vice versa), CI fails — that catches both codegen bugs and silent schema drift.\n\n## License\n\nMIT (code) — see `LICENSE`. The protocol spec + schemas in `random-walks/rrxiv` are CC-BY-4.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandom-walks%2Frrxiv-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frandom-walks%2Frrxiv-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandom-walks%2Frrxiv-python/lists"}