Files
responder/docs/source/cli.rst
T
kennethreitz 428181a096 Add JWT/OAuth2 auth, Problem exception, function middleware, and a broad feature sweep for 8.1.0
Flagship: JWTAuth (HS256/RS256/ES256, exp/aud/iss, JWKS with off-loop
fetch, scope claims -> requires()) and OAuth2Auth flow descriptions that
light up Swagger UI's Authorize button, behind a new responder[jwt] extra.

Also additive: responder.Problem (raisable RFC 9457) + RFC 9457 abort();
@api.middleware function-style HTTP middleware; Pydantic bodies and
Query/Header/Cookie/Path markers on class-based and WebSocket handlers;
Form-model binding; write-side preconditions (If-Match/If-Unmodified-Since
-> 412); q-ranked content negotiation; get_list for repeated headers;
status_code= route option; OpenAPI document caching; rate-limiter key=/
fail-open/X-RateLimit-Reset; configurable metrics buckets + in-flight
gauge; RFC 8288 pagination Link headers; Redis session serializer;
unified request-ID policy; CLI --host/--port/--server/--reload; optional
orjson encode backend; AsyncTestClient + SSE test helpers; fakeredis
backend coverage. Five DeprecationWarnings start the 9.0 clock.

Every feature was implemented test-first, then the combined diff went
through a 64-agent adversarial review that caught 19 issues including two
criticals (an auth scope-claim regression that flipped authorization
decisions, and a sync-middleware threadpool deadlock) -- all fixed with
regression tests before release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:08:42 -04:00

184 lines
5.8 KiB
ReStructuredText

Command Line Interface
======================
Responder installs a ``responder`` command that lets you launch
applications from the terminal. You can point it at a Python module,
a local file, or even a URL — and it will find your ``API`` instance
and start serving.
Launching from a Module
-----------------------
The most common way to run a Responder application in production. Use
Python's standard dotted module path::
$ responder run acme.app
This imports ``acme.app`` and looks for an attribute called ``api``
(a ``responder.API`` instance). It's the same import system Python
uses everywhere — your ``PYTHONPATH`` and virtual environment are
respected.
Launching from a File
---------------------
During development, you often have a single file you want to run::
$ responder run helloworld.py
This loads the file directly and starts the server. Quick and easy for
prototyping and single-file applications.
You can test it with a simple HTTP request::
$ curl http://127.0.0.1:5042/hello
hello, world!
Launching from a URL
--------------------
Responder can fetch and run a Python file from any URL — great for
demos, sharing examples, and running code from GitHub. Remote targets
require the ``cli`` extra::
$ uv pip install 'responder[cli]'
::
$ responder run https://github.com/kennethreitz/responder/raw/refs/heads/main/examples/helloworld.py
This also works with ``github://`` URLs and any filesystem protocol
supported by `fsspec <https://filesystem-spec.readthedocs.io/>`_::
$ responder run github://kennethreitz:responder@/examples/helloworld.py
Cloud storage is supported too — Azure Blob Storage, Google Cloud
Storage, S3, HDFS, SFTP, and more. Install ``fsspec[full]`` for all
protocols::
$ uv pip install 'fsspec[full]'
Custom Instance Names
---------------------
By default, Responder looks for an attribute called ``api``. If your
application uses a different name, specify it with a colon::
$ responder run acme.app:service
$ responder run myapp.py:application
For URLs, use a fragment::
$ responder run https://example.com/app.py#service
Run Options
-----------
A few flags tune how ``run`` behaves::
$ responder run --host 0.0.0.0 --port 8000 acme.app
- ``--host=<addr>`` — the network address to bind to. Defaults to
``127.0.0.1`` (or ``0.0.0.0`` when the ``PORT`` environment variable
is set).
- ``--port=<n>`` — the port to bind to. Defaults to ``5042``, or the
``PORT`` environment variable when set.
- ``--server=<name>`` — the server backend: ``uvicorn`` (the default)
or ``granian`` (requires the ``server`` extra).
- ``--reload`` — restart the server automatically when source files
change. Development only. Reload mode hands your app to uvicorn's
reloader, which must re-import it, so it requires a module target
such as ``acme.app:api`` (file paths and URLs won't work) and the
default uvicorn backend.
- ``--debug`` — turn on debug mode with verbose, debug-level logging.
- ``--limit-max-requests=<n>`` — serve at most ``n`` requests, then exit.
Handy for smoke tests and short-lived runs.
During development, the two usually go together::
$ responder run --reload --port 8000 acme.app:api
To check the version or list every command, run::
$ responder --version
$ responder --help
Running bare ``responder`` with no subcommand prints the usage summary
and exits with a non-zero status.
Environment Variables
---------------------
Responder reads two environment variables on its own — convenient when
you launch through the CLI and would rather not touch application code:
- ``PORT`` — when set, the server binds to ``0.0.0.0`` on this port.
This is how cloud platforms like Fly.io, Railway, and Heroku inject
the listen port.
- ``RESPONDER_SECRET_KEY`` — the signing key for cookie sessions.
Set ``RESPONDER_SECRET_KEY`` for any real deployment. If it's unset (and
sessions are left at their ``"auto"`` default), Responder mints a random
key per process and logs a warning. That's fine for a quick demo, but
every worker ends up with a different key, so signed session cookies stop
validating across workers and restarts — and users get logged out.
Generate a stable key with the canonical one-liner::
$ python -c "import secrets; print(secrets.token_urlsafe(32))"
then export it and run::
$ export RESPONDER_SECRET_KEY="<paste-the-generated-key>"
$ responder run acme.app
No code change is needed. To read a differently-named variable instead,
pass it explicitly when you construct the app::
import os
api = responder.API(secret_key=os.environ["MY_APP_SECRET"])
.. note::
The old public default ``secret_key="NOTASECRET"`` is now rejected
and raises ``SessionConfigError``. See :doc:`deployment` for the
full production checklist and :doc:`guide-config` for the rest of
the session settings.
Building Frontend Assets
-------------------------
If your project includes a JavaScript frontend with a ``package.json``,
the ``build`` subcommand runs ``npm run build``::
$ responder build
$ responder build /path/to/frontend
Generating a Client
-------------------
The ``client`` subcommand generates an API client from your app's OpenAPI
schema, using the same import target as ``run``. By default it prints a
Python client to stdout::
$ responder client acme.app:api > clients/service.py
Use ``--lang`` for another ecosystem (``python``, ``javascript``,
``typescript``, ``ruby``, or ``php``), ``--class-name`` to name the class, and
``--output`` / ``-o`` to write a file instead of stdout::
$ responder client --lang typescript --class-name ServiceClient \
-o clients/service.ts acme.app:api
The generated clients are dependency-free and typed where your OpenAPI schema
has models. See :doc:`clientgen` for the full feature set and the
``api.generate_client(...)`` equivalent.