The shared contract surface for the lens analyser family — manifest builder + FastAPI/CLI scaffolding every member exposes.
Project description
lens-contract
The shared contract surface for the lens analyser family.
Every Python member exposes the same manifest, the same GET /health + GET /manifest
routes, and the same serve / manifest CLI subcommands. This package is that
common surface, so a contract change is one release here instead of an edit in every
analyser.
It is infrastructure, not an analyser (role: library): it does not appear in
the family table and is not auto-routable.
What it provides
| Helper | Replaces the per-repo… |
|---|---|
make_manifest(...) |
_version() try/except + MANIFEST dict in manifest.py |
add_contract_routes(app, MANIFEST) |
hand-written GET /health + GET /manifest |
make_app(MANIFEST, analyse) |
the whole api.py for the path-only common case |
upload_tempfile(content, filename) |
the POST /analyse upload→tempfile→cleanup dance |
run_contract_subcommands(...) |
the serve (+--reload) + manifest dispatch in cli.py |
add_cors(app, env_prefix=…) |
per-repo CORS (one impl; env-driven; never * by default) |
add_rate_limit(app, env_prefix=…) |
per-repo slowapi setup (opt-in; needs lens-contract[ratelimit]) |
Making any member Electron/browser-ready
add_cors lets any member front a browser or Electron app via env vars, no code change:
{PREFIX}_MODE=desktop→ allowlocalhost/127.0.0.1/file://origins (Electron)- otherwise → allow
{PREFIX}_ALLOWED_ORIGINS(comma-separated; defaults to the common dev ports)
add_rate_limit is opt-in via {PREFIX}_RATE_LIMIT_ENABLED=true (limit from {PREFIX}_RATE_LIMIT, e.g. 60/minute).
What it deliberately does not provide
Per the family principle share the contract, not forced abstraction: the
analyse() business logic, the human-readable CLI output (rich), and the rich
analyse-CLI flags stay in each repo. rich is not even a dependency here.
Usage
# manifest.py
from lens_contract import make_manifest
MANIFEST = make_manifest(
name="name-analyser", accepts=["..."], produces="NameAnalysis",
extensions=[".ext"], auto_routable=True,
)
# api.py — common case
from lens_contract import make_app
from name_analyser import NameAnalyser
app = make_app(MANIFEST, lambda path: NameAnalyser().analyse(path))
# cli.py
from lens_contract import run_contract_subcommands
def main():
if run_contract_subcommands(MANIFEST, app_path="name_analyser.api:app",
default_port=8010, env_prefix="NAME_ANALYSER"):
return
... # bespoke analyse argparse + human output
Members needing extra /analyse form fields (e.g. --llm) build their own app with
add_contract_routes + upload_tempfile — see conversation-analyser as the
reference adopter.
Develop
uv venv && uv pip install -e '.[dev]'
uv run pytest
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 lens_contract-0.2.0.tar.gz.
File metadata
- Download URL: lens_contract-0.2.0.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7006ac527a1ab3033fa0d077dd5273d623ec38359eb13f0350d8c3574a7de7b
|
|
| MD5 |
65d4cc739d9bf243baa5654ebf7833f2
|
|
| BLAKE2b-256 |
69537b49ad47f9cc44fc00177bed15a2abbd91063734467cfd04359fe5c84116
|
File details
Details for the file lens_contract-0.2.0-py3-none-any.whl.
File metadata
- Download URL: lens_contract-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
509cb16f594cf905ac32f8ae09a6b46287b3a27b82d466b69993d827833ffcaa
|
|
| MD5 |
0e38d16d3128726f33b98dbec73540bc
|
|
| BLAKE2b-256 |
c7e3b5af8d9862fbc97c4e6710a0e260a7d9315e80fbca1422f5c1d2b4368906
|