diff --git a/.doctrees/deployment.doctree b/.doctrees/deployment.doctree
index d2ffd26..6675cb5 100644
Binary files a/.doctrees/deployment.doctree and b/.doctrees/deployment.doctree differ
diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle
index 942eed0..53efde2 100644
Binary files a/.doctrees/environment.pickle and b/.doctrees/environment.pickle differ
diff --git a/.doctrees/quickstart.doctree b/.doctrees/quickstart.doctree
index 1c77766..1e297e3 100644
Binary files a/.doctrees/quickstart.doctree and b/.doctrees/quickstart.doctree differ
diff --git a/.doctrees/testing.doctree b/.doctrees/testing.doctree
index 1c91d71..e8ca6e2 100644
Binary files a/.doctrees/testing.doctree and b/.doctrees/testing.doctree differ
diff --git a/.doctrees/tour.doctree b/.doctrees/tour.doctree
index a1ee73a..05defef 100644
Binary files a/.doctrees/tour.doctree and b/.doctrees/tour.doctree differ
diff --git a/_sources/deployment.rst.txt b/_sources/deployment.rst.txt
index f30b59c..7644ceb 100644
--- a/_sources/deployment.rst.txt
+++ b/_sources/deployment.rst.txt
@@ -1,34 +1,32 @@
Deployment
==========
-Responder applications are standard ASGI apps. You can deploy them anywhere
-you'd deploy a Python web service.
+Responder applications are standard `ASGI
Responder applications are standard ASGI apps. You can deploy them anywhere -you’d deploy a Python web service.
+Responder applications are standard ASGI +apps. ASGI (Asynchronous Server Gateway Interface) is the modern successor +to WSGI — it supports async, WebSockets, and HTTP/2. This means you can +deploy a Responder app anywhere that runs Python, using any ASGI server.
The simplest way to run your application:
-# api.py
-import responder
-
-api = responder.API()
-
-@api.route("/")
-def hello(req, resp):
- resp.text = "hello, world!"
-
-if __name__ == "__main__":
+During development, api.run() is all you need:
+if __name__ == "__main__":
api.run()
-This starts a production uvicorn server on 127.0.0.1:5042.
+This starts a uvicorn server on
+127.0.0.1:5042. Uvicorn is a lightning-fast ASGI server built on
+uvloop — it handles thousands of
+concurrent connections efficiently and protects against slowloris attacks,
+making a reverse proxy like nginx optional for many deployments.
Docker¶
-A minimal Dockerfile for deploying a Responder application:
+Docker is the most common way to package and deploy web applications.
+Here’s a minimal Dockerfile:
FROM python:3.13-slim
WORKDIR /app
COPY . .
@@ -79,40 +77,57 @@ you’d deploy a Python web service.
$ docker run -p 8000:80 myapi
+The python:3.13-slim image is about 150MB — small enough for fast
+deploys but includes everything you need. For even smaller images, you
+can use python:3.13-alpine, though some packages may need extra
+build dependencies.
Cloud Platforms¶
-Responder automatically honors the PORT environment variable, which is
-set by most cloud platforms. When PORT is set, Responder binds to
-0.0.0.0 on that port automatically.
-This works out of the box with:
+Responder automatically honors the PORT environment variable. When
+PORT is set, the server binds to 0.0.0.0 on that port — this is
+the convention that virtually every cloud platform uses.
+This means zero configuration on:
-Fly.io
-Railway
-Render
-Google Cloud Run
-Azure Container Apps
-AWS App Runner
+Fly.io — fly launch and you’re done
+Railway — push your code, Railway sets PORT
+Render — set start command to python api.py
+Google Cloud Run — containerize and deploy
+Azure Container Apps — same pattern
+AWS App Runner — and here too
-Just deploy your code and set the start command to python api.py.
+The pattern is always the same: deploy your code, set the start command
+to python api.py, and the platform handles the rest.
Uvicorn Directly¶
-For more control over the production server, you can bypass api.run()
-and use uvicorn directly:
+For production deployments where you want more control, bypass
+api.run() and use uvicorn directly:
$ uvicorn api:api --host 0.0.0.0 --port 8000 --workers 4
-This gives you access to all of uvicorn’s options: worker count, SSL
-certificates, access logging, and more. See the
-uvicorn documentation for details.
+The --workers flag spawns multiple processes, each handling requests
+independently. A good starting point is 2-4 workers per CPU core.
+Uvicorn supports many options — SSL certificates, access logging, graceful
+shutdown timeouts, and more. See the
+uvicorn documentation for details.
Reverse Proxy¶
-In production, you may want to place Responder behind a reverse proxy like
-nginx or Caddy for SSL termination, load balancing, or serving static assets.
+For high-traffic production deployments, you may want a reverse proxy like
+nginx or Caddy in
+front of your application for:
+
+SSL/TLS termination — let the proxy handle HTTPS certificates
+Load balancing — distribute traffic across multiple app instances
+Static asset serving — offload static files to the proxy
+Rate limiting — at the infrastructure level
+
Responder’s TrustedHostMiddleware and HTTPSRedirectMiddleware work
-correctly behind proxies that set standard forwarding headers.
+correctly behind proxies that set standard forwarding headers
+(X-Forwarded-For, X-Forwarded-Proto).
+That said, uvicorn is production-ready on its own. Many applications run
+uvicorn directly without a reverse proxy and do just fine.
diff --git a/index.html b/index.html
index a031b3a..9e76c92 100644
--- a/index.html
+++ b/index.html
@@ -138,9 +138,12 @@ with — you’re in the right place.
This guide will walk you through the basics of building a web service with -Responder. By the end, you’ll know how to declare routes, handle requests, -send responses, render templates, and process background tasks.
+Responder. By the end, you’ll understand how HTTP requests and responses +work, how to define routes, read data from clients, send data back, render +HTML templates, and process work in the background.The first thing you need to do is declare a web service. This is the central -object that holds all your routes, middleware, and configuration:
+Every web application starts with a single object — the application
+instance. In Responder, this is the API class. It holds your routes,
+middleware, templates, and configuration. Think of it as the central
+nervous system of your web service:
import responder
api = responder.API()
That’s it. One import, one line. You now have a fully functional ASGI +application with gzip compression, static file serving, session support, +and a production-ready server — all wired up and ready to go.
Next, add a route. Here, we’ll make the root URL say “hello, world!”:
+A web service isn’t very useful until it can respond to requests. In HTTP,
+a route maps a URL path to a function that handles it. When a client
+(like a browser or curl) sends a request to that path, your function
+runs and produces a response.
Here’s the simplest possible route:
@api.route("/")
def hello_world(req, resp):
resp.text = "hello, world!"
Every view receives a req (request) and resp (response) object. You
-don’t need to return anything — just mutate the response directly.
Two things to notice:
+Every view function receives two arguments: req (the incoming
+request) and resp (the outgoing response).
You don’t return anything. Instead, you mutate the response object +directly. This is a deliberate design choice — it keeps the API +consistent whether you’re setting text, JSON, headers, cookies, or +status codes.
Start your web service with api.run():
Start your web service with a single call:
api.run()
This spins up a production-grade uvicorn server on port 5042, ready for
-incoming HTTP requests.
This spins up a production-grade uvicorn
+server on port 5042, ready for incoming HTTP requests. Open
+http://localhost:5042 in your browser and you’ll see your hello world
+response.
You can customize the port with api.run(port=8000). The PORT
environment variable is also honored automatically — when set, Responder
-binds to 0.0.0.0 on that port, which is what cloud platforms like
-Fly.io, Railway, and Google Cloud Run expect.
0.0.0.0 on that port, which is what cloud platforms expect.
Note
Both sync and async views are supported. The async keyword is always
-optional — use it when you need to await something.
await something, like reading a
+request body or querying a database.
If you want dynamic URLs, use Python’s familiar f-string syntax to declare -variables in your routes:
+Static URLs like /about are useful, but most applications need dynamic
+routes — URLs that contain variable data, like a user ID or a product slug.
In Responder, you declare route parameters using Python’s f-string syntax:
@api.route("/hello/{who}")
def hello_to(req, resp, *, who):
resp.text = f"hello, {who}!"
A GET request to /hello/world will respond with hello, world!.
Route parameters are passed as keyword-only arguments (after the *).
A GET request to /hello/world will respond with hello, world!.
+A request to /hello/guido will respond with hello, guido!.
Route parameters are passed as keyword-only arguments (after the *
+in the function signature). This is a Python feature that makes the
+interface explicit — you always know which arguments come from the URL.
You can constrain route parameters to specific types. The parameter will be -automatically converted before it reaches your view:
+By default, route parameters are strings. But often you want them as +integers, UUIDs, or other types. Responder can convert them automatically +using type annotations in the route pattern:
@api.route("/add/{a:int}/{b:int}")
async def add(req, resp, *, a, b):
resp.text = f"{a} + {b} = {a + b}"
Here, a and b will arrive as Python int objects, not strings.
+If someone requests /add/3/hello, they’ll get a 404 — the route won’t
+match because hello isn’t a valid integer.
Supported types:
str — matches any string without slashes (default)
int — matches digits, converts to int
float — matches decimal numbers, converts to float
str — matches any string without slashes (this is the default)
int — matches digits and converts to int
float — matches decimal numbers and converts to float
uuid — matches UUID strings like 550e8400-e29b-41d4-a716-446655440000
path — matches any string including slashes, useful for file paths
path — matches any string including slashes, useful for file paths
+like /files/{filepath:path}
Responder gives you several ways to send data back to the client. Just set -the appropriate property on the response object.
-Text and HTML:
+When an HTTP server receives a request, it must send back a response. Every
+HTTP response has three parts: a status code (like 200 OK or 404 Not
+Found), headers (metadata like Content-Type), and a body (the actual
+data).
Responder lets you set all three by mutating the response object.
+Text and HTML — the simplest response types. resp.text sets the
+Content-Type to text/plain, while resp.html sets it to
+text/html:
resp.text = "plain text response"
resp.html = "<h1>HTML response</h1>"
JSON — the most common pattern for APIs. Set resp.media to any
-JSON-serializable Python object:
JSON — the lingua franca of web APIs. Set resp.media to any
+JSON-serializable Python object — a dict, a list, whatever — and Responder
+will serialize it to JSON and set the right headers:
@api.route("/hello/{who}/json")
def hello_json(req, resp, *, who):
resp.media = {"hello": who}
If the client sends an Accept: application/x-yaml header, the same data
-will be returned as YAML instead. Content negotiation is automatic.
Files — serve a file from disk with automatic content-type detection:
+will be returned as YAML instead. This is called content negotiation — +the server and client agree on a format. It happens automatically. +Files — serve a file from disk. Responder uses Python’s mimetypes
+module to figure out the Content-Type from the file extension:
resp.file("reports/annual.pdf")
Raw bytes:
+Raw bytes — for binary data like images or protocol buffers:
resp.content = b"\x89PNG\r\n..."
Status codes and headers:
+Status codes — HTTP status codes tell the client what happened. 200
+means success, 201 means something was created, 404 means not found,
+500 means the server broke. Set it directly:
resp.status_code = 201
-resp.headers["X-Custom"] = "value"
Redirects:
+Headers — HTTP headers carry metadata. Common ones include
+Content-Type, Cache-Control, Authorization, and custom
+application headers:
resp.headers["X-Custom"] = "value"
+Redirects — tell the client to go somewhere else:
api.redirect(resp, location="/new-url")
This sends a 301 Moved Permanently response by default. The client’s
+browser will automatically follow the redirect.
The request object gives you access to everything the client sent.
-Method and URL:
+The other half of HTTP is the request — the data the client sends to your +server. This includes the HTTP method (GET, POST, PUT, DELETE), the URL, +headers, query parameters, cookies, and optionally a body.
+Responder wraps all of this in the req object.
Method and URL — every HTTP request has a method (what the client wants +to do) and a URL (what resource it’s about):
req.method # "get", "post", etc. (lowercase)
req.full_url # "http://example.com/path?q=1"
req.url # parsed URL object
Headers — case-insensitive, just like you’d expect:
+Headers — HTTP headers carry metadata from the client, like what +content types it accepts, authentication tokens, and more. Responder’s +headers dict is case-insensitive, because the HTTP spec says header names +are case-insensitive:
req.headers["Content-Type"]
req.headers["content-type"] # same thing
Query parameters:
+Query parameters — the part of the URL after the ?. These are
+commonly used for search, filtering, and pagination:
# GET /search?q=python&page=2
req.params["q"] # "python"
req.params["page"] # "2"
Path parameters — also available on the request object:
+Note that query parameters are always strings. If you need an integer,
+you’ll need to convert it yourself: int(req.params["page"]).
Path parameters — the dynamic parts of the URL that matched your route +pattern. These are also available on the request object, which is useful +in before-request hooks where they aren’t passed as function arguments:
req.path_params["user_id"] # same as the keyword argument
Request body — for POST/PUT/PATCH requests, you need to await the
-body content:
# JSON body
+Request body — for POST, PUT, and PATCH requests, the client sends
+data in the body. Since reading the body is an I/O operation, you need to
+await it:
+# JSON body (the most common format for APIs)
data = await req.media()
-# Form data
+# Form data (from HTML forms)
data = await req.media("form")
-# File uploads
+# File uploads (multipart)
files = await req.media("files")
# Raw bytes
@@ -193,40 +251,56 @@ body content:
Other useful properties:
-req.is_json # True if content type is JSON
-req.cookies # dict of cookies
-req.session # session data (dict)
-req.client # (host, port) tuple
-req.is_secure # True if HTTPS
+req.is_json # True if the content type is JSON
+req.cookies # dict of cookies sent by the client
+req.session # session data (a signed, server-side dict)
+req.client # (host, port) tuple — the client's IP address
+req.is_secure # True if the request came over HTTPS
Rendering Templates¶
-Responder includes built-in Jinja2
-support. Templates are loaded from the templates/ directory by default.
-The simplest way is to use api.template():
+While APIs typically return JSON, many web applications need to render
+HTML pages. Responder includes built-in support for
+Jinja2, one of the most popular
+templating engines in the Python ecosystem.
+Templates let you write HTML with placeholders that get filled in with
+dynamic data. This keeps your presentation logic (HTML) separate from
+your application logic (Python) — a pattern called
+separation of concerns.
+The simplest way to render a template is api.template(). Templates
+are loaded from the templates/ directory by default:
@api.route("/hello/{name}/html")
def hello_html(req, resp, *, name):
resp.html = api.template("hello.html", name=name)
-You can also use the Templates class directly for more control:
+The template file templates/hello.html might look like:
+<h1>Hello, {{ name }}!</h1>
+
+
+The {{ name }} part is a Jinja2 expression — it gets replaced with
+the value you passed in.
+You can also use the Templates class directly for more control over
+the template directory and configuration:
from responder.templates import Templates
-templates = Templates(directory="templates")
+templates = Templates(directory="my_templates")
@api.route("/page")
def page(req, resp):
resp.html = templates.render("page.html", title="Hello")
-Async rendering is supported too:
+For applications that need non-blocking template rendering (rare, but
+useful under extreme load), async rendering is supported:
templates = Templates(directory="templates", enable_async=True)
resp.html = await templates.render_async("page.html", title="Hello")
-You can render template strings without a file:
+And for quick one-off templates, you can render a string directly without
+a file:
resp.html = api.template_string("Hello, {{ name }}!", name="world")
@@ -234,7 +308,12 @@ support. Templates are loaded from the
Background Tasks¶
Sometimes you want to accept a request, respond immediately, and do the
-actual processing later. Responder makes this easy with background tasks:
+actual processing later. This is a common pattern for operations that take
+a long time — sending emails, processing images, updating caches, or
+calling slow external APIs.
+Responder makes this easy with background tasks. Decorate any function
+with @api.background.task and it will run in a thread pool, separate
+from the request/response cycle:
@api.route("/incoming")
async def receive_incoming(req, resp):
data = await req.media()
@@ -247,12 +326,21 @@ actual processing later. Responder makes this easy with background tasks:
process_data(data)
- # Respond immediately — processing continues in the background
+ # This response is sent immediately, while process_data
+ # continues running in the background.
resp.media = {"status": "accepted"}
-The @api.background.task decorator wraps any function to run in a thread
-pool. The client gets an immediate response while the work continues.
+The client gets an instant response — the heavy lifting happens after.
+This is the same pattern used by task queues like Celery, but much simpler
+for lightweight use cases where you don’t need a full message broker.
+
+Note
+Background tasks run in threads, not processes. They share memory with
+your application, which makes them fast to start but means CPU-intensive
+work will block the event loop. For heavy computation, consider a proper
+task queue.
+
diff --git a/searchindex.js b/searchindex.js
index d529729..b92d5d5 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-Search.setIndex({"alltitles":{"API Documentation":[[0,null]],"Added":[[2,"added"],[2,"id1"],[2,"id7"],[2,"id8"],[2,"id11"],[2,"id14"],[2,"id19"],[2,"id26"],[2,"id32"],[2,"id33"],[2,"id34"],[2,"id35"],[2,"id36"],[2,"id39"],[2,"id40"],[2,"id42"],[2,"id45"],[2,"id48"],[2,"id49"],[2,"id50"],[2,"id54"]],"After-Request Hooks":[[9,"after-request-hooks"]],"Background Tasks":[[6,"background-tasks"]],"Backlog":[[1,null]],"Before-Request Hooks":[[9,"before-request-hooks"]],"Build JavaScript Application":[[3,"build-javascript-application"]],"CORS":[[9,"cors"]],"Changed":[[2,"changed"],[2,"id6"],[2,"id9"],[2,"id12"],[2,"id15"],[2,"id18"],[2,"id23"],[2,"id24"],[2,"id25"],[2,"id27"],[2,"id28"],[2,"id30"],[2,"id31"],[2,"id37"],[2,"id41"],[2,"id46"],[2,"id47"],[2,"id53"]],"Changelog":[[2,null]],"Class-Based Views":[[9,"class-based-views"]],"Cloud Platforms":[[4,"cloud-platforms"]],"Cookie-Based Sessions":[[9,"cookie-based-sessions"]],"Cookies":[[9,"cookies"]],"Create a Web Service":[[6,"create-a-web-service"]],"Custom Error Handling":[[9,"custom-error-handling"]],"Deployment":[[4,null]],"Deprecated":[[2,"deprecated"]],"Development Sandbox":[[7,null]],"Docker":[[4,"docker"]],"Feature Tour":[[9,null]],"Fixed":[[2,"fixed"],[2,"id2"],[2,"id3"],[2,"id4"],[2,"id5"],[2,"id10"],[2,"id13"],[2,"id16"],[2,"id17"],[2,"id20"],[2,"id21"],[2,"id22"],[2,"id29"],[2,"id38"],[2,"id43"],[2,"id44"],[2,"id51"],[2,"id52"]],"Future Ideas":[[1,"future-ideas"]],"Getting Started":[[8,"getting-started"]],"GraphQL":[[9,"graphql"]],"HSTS":[[9,"hsts"]],"Hello World":[[6,"hello-world"]],"Installation":[[5,"installation"]],"Launch Local File":[[3,"launch-local-file"]],"Launch Module Entrypoint":[[3,"launch-module-entrypoint"]],"Launch Remote File":[[3,"launch-remote-file"]],"Launch with Non-Standard Instance Name":[[3,"launch-with-non-standard-instance-name"]],"Lifespan Events":[[9,"lifespan-events"]],"MessagePack":[[9,"messagepack"]],"Method Filtering":[[9,"method-filtering"]],"Mounting Other Apps":[[9,"mounting-other-apps"]],"OpenAPI Documentation":[[9,"openapi-documentation"]],"Operations":[[7,"operations"]],"Project":[[5,null]],"Quick Start":[[6,null]],"Rate Limiting":[[9,"rate-limiting"]],"Reading Requests":[[6,"reading-requests"]],"Removed":[[2,"removed"]],"Rendering Templates":[[6,"rendering-templates"]],"Request ID":[[9,"request-id"]],"Requests & Responses":[[0,"requests-responses"]],"Responder":[[5,null]],"Responder CLI":[[3,null]],"Reverse Proxy":[[4,"reverse-proxy"]],"Route Groups":[[9,"route-groups"]],"Route Parameters":[[6,"route-parameters"]],"Run the Server":[[6,"run-the-server"]],"Running Locally":[[4,"running-locally"]],"Sending Responses":[[6,"sending-responses"]],"Server-Sent Events (SSE)":[[9,"server-sent-events-sse"]],"Serving Files":[[9,"serving-files"]],"Setup":[[7,"setup"]],"Static Files":[[9,"static-files"]],"Streaming Files":[[9,"streaming-files"]],"Testing":[[8,null]],"Testing Before and After Hooks":[[8,"testing-before-and-after-hooks"]],"Testing Error Handling":[[8,"testing-error-handling"]],"Testing File Uploads":[[8,"testing-file-uploads"]],"Testing Headers and Cookies":[[8,"testing-headers-and-cookies"]],"Testing JSON APIs":[[8,"testing-json-apis"]],"Testing Lifespan Events":[[8,"testing-lifespan-events"]],"Testing Request Validation":[[8,"testing-request-validation"]],"Testing WebSockets":[[8,"testing-websockets"]],"The Idea":[[5,"the-idea"]],"Tips":[[8,"tips"]],"Trusted Hosts":[[9,"trusted-hosts"]],"Type Convertors":[[6,"type-convertors"]],"Unreleased":[[2,"unreleased"]],"User Guide":[[5,null]],"Using Fixtures":[[8,"using-fixtures"]],"Utility Functions":[[0,"utility-functions"]],"Uvicorn Directly":[[4,"uvicorn-directly"]],"Web Service (API) Class":[[0,"module-responder"]],"WebSocket Support":[[9,"websocket-support"]],"What You Get":[[5,"what-you-get"]],"v0.0.1 - 2018-10-12":[[2,"v0-0-1-2018-10-12"]],"v0.0.10 - 2018-10-17":[[2,"v0-0-10-2018-10-17"]],"v0.0.2 - 2018-10-13":[[2,"v0-0-2-2018-10-13"]],"v0.0.3 - 2018-10-13":[[2,"v0-0-3-2018-10-13"]],"v0.0.4 - 2018-10-15":[[2,"v0-0-4-2018-10-15"]],"v0.0.5 - 2018-10-15":[[2,"v0-0-5-2018-10-15"]],"v0.0.6 - 2018-10-16":[[2,"v0-0-6-2018-10-16"]],"v0.0.7 - 2018-10-16":[[2,"v0-0-7-2018-10-16"]],"v0.0.8 - 2018-10-17":[[2,"v0-0-8-2018-10-17"]],"v0.0.9 - 2018-10-17":[[2,"v0-0-9-2018-10-17"]],"v0.1.0 - 2018-10-17":[[2,"v0-1-0-2018-10-17"]],"v0.1.1 - 2018-10-17":[[2,"v0-1-1-2018-10-17"]],"v0.1.2 - 2018-10-18":[[2,"v0-1-2-2018-10-18"]],"v0.1.3 - 2018-10-18":[[2,"v0-1-3-2018-10-18"]],"v0.1.4 - 2018-10-19":[[2,"v0-1-4-2018-10-19"]],"v0.1.5 - 2018-10-20":[[2,"v0-1-5-2018-10-20"]],"v0.1.6 - 2018-10-20":[[2,"v0-1-6-2018-10-20"]],"v0.2.0 - 2018-10-22":[[2,"v0-2-0-2018-10-22"]],"v0.2.1 - 2018-10-23":[[2,"v0-2-1-2018-10-23"]],"v0.2.2 - 2018-10-23":[[2,"v0-2-2-2018-10-23"]],"v0.2.3 - 2018-10-24":[[2,"v0-2-3-2018-10-24"]],"v0.3.0 - 2018-10-24":[[2,"v0-3-0-2018-10-24"]],"v0.3.1 - 2018-10-24":[[2,"v0-3-1-2018-10-24"]],"v0.3.2 - 2018-10-25":[[2,"v0-3-2-2018-10-25"]],"v0.3.3 - 2018-10-25":[[2,"v0-3-3-2018-10-25"]],"v1.0.0 - 2018-10-26":[[2,"v1-0-0-2018-10-26"]],"v1.0.1 - 2018-10-26":[[2,"v1-0-1-2018-10-26"]],"v1.0.2 - 2018-10-27":[[2,"v1-0-2-2018-10-27"]],"v1.0.3 - 2018-10-27":[[2,"v1-0-3-2018-10-27"]],"v1.0.4 - 2018-10-27":[[2,"v1-0-4-2018-10-27"]],"v1.0.5- 2018-10-27":[[2,"v1-0-5-2018-10-27"]],"v1.1.0 - 2018-10-27":[[2,"v1-1-0-2018-10-27"]],"v1.1.1 - 2018-10-29":[[2,"v1-1-1-2018-10-29"]],"v1.1.2 - 2018-11-11":[[2,"v1-1-2-2018-11-11"]],"v1.1.3 - 2019-01-12":[[2,"v1-1-3-2019-01-12"]],"v1.2.0 - 2018-12-29":[[2,"v1-2-0-2018-12-29"]],"v1.3.0 - 2019-02-22":[[2,"v1-3-0-2019-02-22"]],"v1.3.1 - 2019-04-28":[[2,"v1-3-1-2019-04-28"]],"v1.3.2 - 2019-08-15":[[2,"v1-3-2-2019-08-15"]],"v2.0.0 - 2019-09-19":[[2,"v2-0-0-2019-09-19"]],"v2.0.1 - 2019-09-20":[[2,"v2-0-1-2019-09-20"]],"v2.0.2 - 2019-09-20":[[2,"v2-0-2-2019-09-20"]],"v2.0.3 - 2019-09-20":[[2,"v2-0-3-2019-09-20"]],"v2.0.4 - 2019-11-19":[[2,"v2-0-4-2019-11-19"]],"v2.0.5 - 2019-12-15":[[2,"v2-0-5-2019-12-15"]],"v3.0.0 - 2026-03-22":[[2,"v3-0-0-2026-03-22"]]},"docnames":["api","backlog","changes","cli","deployment","index","quickstart","sandbox","testing","tour"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1},"filenames":["api.rst","backlog.md","changes.md","cli.rst","deployment.rst","index.rst","quickstart.rst","sandbox.md","testing.rst","tour.rst"],"indexentries":{"accepts() (responder.request method)":[[0,"responder.Request.accepts",false]],"add_event_handler() (responder.api method)":[[0,"responder.API.add_event_handler",false]],"add_route() (responder.api method)":[[0,"responder.API.add_route",false]],"after_request() (responder.api method)":[[0,"responder.API.after_request",false]],"api (class in responder)":[[0,"responder.API",false]],"apparent_encoding (responder.request property)":[[0,"responder.Request.apparent_encoding",false]],"client (responder.request property)":[[0,"responder.Request.client",false]],"content (responder.request property)":[[0,"responder.Request.content",false]],"content (responder.response attribute)":[[0,"responder.Response.content",false]],"cookies (responder.request property)":[[0,"responder.Request.cookies",false]],"cookies (responder.response attribute)":[[0,"responder.Response.cookies",false]],"encoding (responder.request property)":[[0,"responder.Request.encoding",false]],"exception_handler() (responder.api method)":[[0,"responder.API.exception_handler",false]],"file() (responder.response method)":[[0,"responder.Response.file",false]],"formats (responder.response attribute)":[[0,"responder.Response.formats",false]],"full_url (responder.request property)":[[0,"responder.Request.full_url",false]],"graphql() (responder.api method)":[[0,"responder.API.graphql",false]],"group() (responder.api method)":[[0,"responder.API.group",false]],"headers (responder.request property)":[[0,"responder.Request.headers",false]],"headers (responder.response attribute)":[[0,"responder.Response.headers",false]],"is_100() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_100",false]],"is_200() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_200",false]],"is_300() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_300",false]],"is_400() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_400",false]],"is_500() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_500",false]],"is_json (responder.request property)":[[0,"responder.Request.is_json",false]],"media (responder.response attribute)":[[0,"responder.Response.media",false]],"media() (responder.request method)":[[0,"responder.Request.media",false]],"method (responder.request property)":[[0,"responder.Request.method",false]],"module":[[0,"module-responder",false]],"mount() (responder.api method)":[[0,"responder.API.mount",false]],"on_event() (responder.api method)":[[0,"responder.API.on_event",false]],"params (responder.request property)":[[0,"responder.Request.params",false]],"path_matches_route() (responder.api method)":[[0,"responder.API.path_matches_route",false]],"path_params (responder.request property)":[[0,"responder.Request.path_params",false]],"redirect() (responder.api method)":[[0,"responder.API.redirect",false]],"request (class in responder)":[[0,"responder.Request",false]],"requests (responder.api property)":[[0,"responder.API.requests",false]],"responder":[[0,"module-responder",false]],"response (class in responder)":[[0,"responder.Response",false]],"route() (responder.api method)":[[0,"responder.API.route",false]],"schema() (responder.api method)":[[0,"responder.API.schema",false]],"serve() (responder.api method)":[[0,"responder.API.serve",false]],"session (responder.request property)":[[0,"responder.Request.session",false]],"session (responder.response attribute)":[[0,"responder.Response.session",false]],"session() (responder.api method)":[[0,"responder.API.session",false]],"sse() (responder.response method)":[[0,"responder.Response.sse",false]],"state (responder.request property)":[[0,"responder.Request.state",false]],"status_code (responder.response attribute)":[[0,"responder.Response.status_code",false]],"stream_file() (responder.response method)":[[0,"responder.Response.stream_file",false]],"template() (responder.api method)":[[0,"responder.API.template",false]],"template_string() (responder.api method)":[[0,"responder.API.template_string",false]],"text (responder.request property)":[[0,"responder.Request.text",false]],"url (responder.request property)":[[0,"responder.Request.url",false]],"url_for() (responder.api method)":[[0,"responder.API.url_for",false]]},"objects":{"":[[0,0,0,"-","responder"]],"responder":[[0,1,1,"","API"],[0,1,1,"","Request"],[0,1,1,"","Response"]],"responder.API":[[0,2,1,"","add_event_handler"],[0,2,1,"","add_route"],[0,2,1,"","after_request"],[0,2,1,"","exception_handler"],[0,2,1,"","graphql"],[0,2,1,"","group"],[0,2,1,"","mount"],[0,2,1,"","on_event"],[0,2,1,"","path_matches_route"],[0,2,1,"","redirect"],[0,3,1,"","requests"],[0,2,1,"","route"],[0,2,1,"","schema"],[0,2,1,"","serve"],[0,2,1,"","session"],[0,2,1,"","template"],[0,2,1,"","template_string"],[0,2,1,"","url_for"]],"responder.API.status_codes":[[0,4,1,"","is_100"],[0,4,1,"","is_200"],[0,4,1,"","is_300"],[0,4,1,"","is_400"],[0,4,1,"","is_500"]],"responder.Request":[[0,2,1,"","accepts"],[0,3,1,"","apparent_encoding"],[0,3,1,"","client"],[0,3,1,"","content"],[0,3,1,"","cookies"],[0,3,1,"","encoding"],[0,3,1,"","full_url"],[0,3,1,"","headers"],[0,3,1,"","is_json"],[0,2,1,"","media"],[0,3,1,"","method"],[0,3,1,"","params"],[0,3,1,"","path_params"],[0,3,1,"","session"],[0,3,1,"","state"],[0,3,1,"","text"],[0,3,1,"","url"]],"responder.Response":[[0,5,1,"","content"],[0,5,1,"","cookies"],[0,2,1,"","file"],[0,5,1,"","formats"],[0,5,1,"","headers"],[0,5,1,"","media"],[0,5,1,"","session"],[0,2,1,"","sse"],[0,5,1,"","status_code"],[0,2,1,"","stream_file"]]},"objnames":{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","property","Python property"],"4":["py","function","Python function"],"5":["py","attribute","Python attribute"]},"objtypes":{"0":"py:module","1":"py:class","2":"py:method","3":"py:property","4":"py:function","5":"py:attribute"},"terms":{"":[0,2,3,4,5,6,8,9],"0":[3,4,6,9],"1":[0,3,4,6,9],"10":[0,6,9],"100":9,"127":[3,4],"13":[3,4],"16":3,"2":[6,8,9],"200":[3,8,9],"201":[6,8],"2024":3,"25":3,"26":3,"3":[4,5,8,9],"301":0,"308":2,"3600":9,"4":4,"40":2,"400":[0,8,9],"401":9,"41d4":6,"422":8,"429":9,"446655440000":6,"500":[2,8,9],"5042":[3,4,6],"55":3,"550e8400":6,"60":9,"600":[0,9],"8":[0,3],"80":4,"8000":[4,6],"8192":0,"9":[5,8],"99":8,"A":[0,3,4,5,6,9],"But":8,"By":[3,6,8,9],"For":[3,4,8,9],"If":[0,3,5,6,8,9],"In":[3,4,9],"It":[3,5,8,9],"No":[8,9],"One":[5,8],"That":[5,8],"The":[0,2,3,4,6,8,9],"There":[8,9],"To":3,"Will":0,"With":0,"__main__":[4,5,8],"__name__":[4,5,8,9],"_route_for":2,"a2wsgi":2,"a716":6,"abc123":[8,9],"abf":3,"abil":2,"abl":0,"about":8,"abov":[3,5],"accept":[0,2,3,6,8,9],"access":[3,4,6,9],"acm":3,"acquir":[3,7],"activ":7,"actual":[0,6,9],"ad":[1,9],"adapt":3,"add":[0,1,2,6,9],"add_directori":9,"add_event_handl":0,"add_head":9,"add_request_id":0,"add_rout":[0,9],"add_tim":8,"add_vers":8,"addit":[0,9],"address":[0,3],"adher":2,"after":[0,5,6],"after_request":[0,1,8,9],"ag":9,"against":[0,9],"ai":9,"alias":2,"alic":9,"all":[0,2,3,4,6,7,8,9],"alloc":8,"allow":9,"allow_credenti":[0,9],"allow_head":[0,9],"allow_method":[0,9],"allow_origin":[0,9],"allow_origin_regex":0,"allowed_host":[0,9],"alreadi":[0,8,9],"also":[0,2,3,6,8,9],"altern":0,"alwai":[5,6,9],"an":[0,3,6,9],"ani":[0,5,6,8,9],"annot":[5,9],"annual":[6,9],"anyon":5,"anyth":6,"anywher":4,"api":[2,3,4,5,6,9],"apispec":[2,9],"app":[0,2,3,4,5,8],"appar":0,"apparent_encod":0,"appear":5,"append":3,"applic":[0,2,4,5,6,8,9],"approach":9,"appropri":[6,9],"approx":3,"ar":[2,3,4,5,6,8,9],"arg":0,"argument":[0,2,6],"around":[0,5],"arrow":3,"asgi":[0,2,4,5,9],"ask":5,"assert":8,"asset":[3,4,9],"assum":3,"async":[0,1,2,5,6,8,9],"asynccontextmanag":9,"asynchron":2,"attack":9,"attr":3,"attribut":[0,3],"auth":5,"auth_check":9,"authent":9,"author":[3,7,9],"auto":9,"auto_escap":0,"autobuild":7,"automat":[0,4,5,6,8,9],"avail":[3,6],"avoid":8,"aw":[3,4],"await":[0,6,8,9],"az":3,"azur":[3,4],"b":[6,8],"back":[0,5,6],"background":[2,5],"backlog":5,"bad":[8,9],"balanc":4,"base":[0,2,3,5],"base_url":0,"basemodel":[0,8,9],"basic":[3,6],"batteri":5,"battl":5,"becom":0,"been":3,"befor":[5,6],"before_request":[0,1,2,8,9],"beforehand":3,"behind":4,"being":0,"best":5,"better":5,"bidirect":9,"bin":7,"binari":9,"bind":[0,4,6],"blob":3,"block":8,"bodi":[0,6,8,9],"boilerpl":5,"both":[5,6,9],"box":4,"break":8,"bring":5,"broke":8,"browser":[3,7,9],"bucket":[3,9],"bufix":2,"bug":[2,8],"bugfix":2,"build":[2,4,5,6,7],"built":[2,5,6,8,9],"bump":2,"bypass":4,"byte":[0,5,6],"cach":[8,9],"caddi":4,"call":[8,9],"callabl":0,"can":[0,3,4,5,6,8,9],"capac":3,"case":[0,5,6],"cat":9,"cd":7,"ceas":2,"central":6,"certain":0,"certif":4,"chanc":3,"chang":3,"changelog":5,"chardet":0,"check":[7,8],"check_exist":[0,9],"choos":[3,9],"chunk":0,"chunk_siz":0,"ci":2,"circuit":[1,5,9],"class":[2,5,6,8],"clean":[5,9],"cleanup":9,"cli":[2,5],"click":5,"client":[0,5,6,8,9],"clone":7,"close":[8,9],"close_database_connection_pool":0,"cloud":[3,5,6],"cmd":4,"code":[0,2,4,6,7,8,9],"com":[3,6,7,9],"command":[3,4],"common":[3,6,9],"commun":9,"compat":3,"complement":1,"complex":9,"compon":9,"compress":5,"concept":2,"concern":9,"conclud":3,"condit":8,"configur":[2,6,8],"conflict":2,"confus":8,"connect":[0,8,9],"consid":1,"constrain":6,"contact":0,"contain":[0,4],"content":[0,2,3,5,6,8,9],"content_typ":[0,8,9],"context":[5,8,9],"contextlib":9,"continu":6,"contract":8,"contribut":9,"control":[4,6,9],"convert":[2,6],"convertor":5,"cooki":[0,2,5,6],"copi":[4,9],"cor":[0,2,5,8],"core":2,"coroutin":0,"correctli":4,"correspond":3,"cors_param":[0,9],"count":[2,4],"creat":[0,5,7,8,9],"create_item":[0,9],"create_pet":9,"cross":9,"css":9,"csv":9,"curl":3,"current":3,"custom":[0,5,6,8],"d":[4,6,8],"dask":3,"data":[0,2,6,8,9],"databas":[8,9],"dataset":9,"date":3,"debug":[0,2,9],"decim":6,"declar":[2,6],"decod":[2,9],"decor":[0,6,9],"deep":5,"def":[0,4,5,6,8,9],"default":[0,1,2,3,6,8,9],"default_valu":[0,9],"defin":[3,9],"definit":0,"denpend":2,"depend":[2,8],"deploi":[4,5],"deploy":5,"descript":[0,9],"design":3,"detail":[4,9],"detect":[0,5,6,9],"dev":2,"dict":[0,5,6,9],"dictionari":[0,9],"differ":[3,8,9],"digit":6,"direct":[2,9],"directli":[5,6,8,9],"directori":[0,3,6,9],"disabl":8,"disk":[0,6,9],"dispatch":[2,9],"distribut":3,"django":5,"dna":5,"do":[3,6],"doc":[7,8,9],"docker":5,"dockerfil":4,"docs_rout":[0,9],"docstr":9,"document":[2,4,5,7],"doesn":[0,9],"domain":9,"don":[3,6,8],"down":9,"download":9,"dramat":2,"drop":2,"dropbox":3,"dump":2,"dure":8,"dynam":6,"e":0,"e29b":6,"each":[0,8,9],"easi":6,"echo":3,"ecosystem":5,"edit":[3,7],"effect":8,"effici":9,"either":[0,3],"element":[0,9],"els":9,"enabl":[2,9],"enable_async":6,"enable_hst":[0,9],"encod":[0,3],"end":6,"endpoint":[0,2,8,9],"enter":8,"entir":[0,9],"entri":3,"entrypoint":5,"enumer":3,"env":4,"environ":[0,4,6],"eol":2,"error":[0,5],"escap":0,"etc":[6,8,9],"even":3,"event":[0,2,5],"event_typ":0,"everi":[0,5,6,8,9],"everyth":[6,9],"exactli":8,"exampl":[3,6,9],"exc":[0,8,9],"exceed":9,"except":[0,2,5,8,9],"exception_cl":0,"exception_handl":[0,8,9],"exist":[0,2,3,5],"exit":8,"expect":[3,6],"expir":9,"explicit":9,"explicitli":9,"explor":[1,5,9],"expos":4,"expose_head":0,"express":5,"ext":[2,9],"extens":2,"extra":[2,3],"extra_asset":9,"extract":0,"f":[0,5,6,8,9],"fail":8,"failur":8,"falcon":5,"fall":0,"fals":[0,8,9],"familiar":[5,6],"fast":[5,8],"fastapi":5,"favourit":3,"featur":[0,5],"feed":9,"feel":5,"few":3,"fido":9,"field":[0,8,9],"figur":[5,9],"file":[0,2,5,6],"filenam":[0,8],"filesystem":[2,3],"filter":5,"fire":8,"first":[6,9],"fit":5,"fix":7,"fixtur":5,"flag":9,"flask":[5,9],"flask_app":9,"float":[0,6,8],"fly":[4,6],"forc":9,"form":[0,3,6],"format":[0,2,7,9],"forward":[4,5,9],"found":2,"framework":[5,9],"fresh":8,"from":[0,2,3,4,5,6,8,9],"frontend":9,"fsspec":3,"full":[0,2,3,9],"full_url":[0,6,9],"fun":5,"func":0,"function":[5,6],"fuse":3,"g":[0,3],"gc":3,"gener":[0,5,8,9],"get":[0,6,9],"get_us":[0,9],"git":[3,7],"github":[3,7],"give":[3,4,6,8,9],"given":[0,8],"gmt":3,"goe":9,"good":5,"googl":[3,4,6],"grade":6,"gradual":9,"graphen":[0,2,5,9],"graphiql":[2,5,9],"graphql":[0,2,5],"great":[5,9],"greet":[5,9],"greet_world":5,"greetingresourc":9,"group":[0,5],"guard":[5,9],"guid":6,"gzip":5,"h1":6,"ha":[8,9],"hadoop":3,"hand":[0,3],"handl":[5,6],"handle_value_error":[0,9],"handler":[0,3,5,8,9],"happen":5,"hard":8,"have":[0,2,3,8],"hdf":3,"head":3,"header":[0,4,5,6,9],"heavi":6,"hello":[0,3,4,5,8,9],"hello_html":6,"hello_json":6,"hello_to":6,"hello_world":6,"helloworld":3,"help":0,"here":[6,9],"hold":[5,6],"home":5,"honor":[4,6],"hook":[1,5],"host":[0,2,3,4,5,6],"hostnam":9,"how":6,"hst":5,"html":[0,2,5,6,9],"http":[0,2,3,5,6,7,8,9],"httpie":3,"httponli":9,"httpsredirectmiddlewar":4,"httpx":[2,8],"i":[0,2,3,4,5,6,8,9],"id":[0,5],"imag":9,"immedi":[5,6,9],"immut":2,"implement":[3,8],"import":[0,2,3,4,5,6,8,9],"importlib":3,"improv":2,"includ":[3,5,6,7,8,9],"incom":[0,6],"index":[0,9],"info":[0,2,9],"inform":0,"infrastructur":5,"inherit":[3,9],"initi":[0,8],"inlin":9,"input":8,"insensit":[0,5,6],"instal":[0,3,4,7,9],"instanc":[0,5,8],"instead":[3,6,8,9],"int":[0,6,9],"integ":0,"integr":9,"intent":5,"interact":[2,9],"intern":[8,9],"internet":3,"invalid":8,"invoc":3,"invok":3,"io":[4,6],"is_100":0,"is_200":0,"is_300":0,"is_400":0,"is_500":0,"is_class_bas":2,"is_json":[0,6],"is_secur":6,"isn":9,"issu":2,"item":[0,8,9],"itemin":0,"itemout":0,"its":[0,2,3],"javascript":[5,9],"jinja2":[0,6],"joi":5,"jpeg":9,"jpg":9,"json":[0,3,5,6,9],"just":[4,6,8,9],"keep":[2,8,9],"kei":[0,8,9],"kennethreitz":[3,7],"keyword":[0,6],"kind":3,"know":6,"known":0,"kwarg":0,"larg":[5,9],"larger":8,"later":[6,8],"launch":5,"layout":3,"lazili":0,"lead":8,"learn":5,"length":3,"less":9,"librari":8,"licens":0,"lifespan":[0,2,5],"like":[3,4,5,6,8,9],"limit":[1,5],"line":3,"link":9,"list":[0,3,8,9],"list_item":9,"list_pet":9,"list_us":[0,9],"live":9,"ll":[5,6,9],"load":[0,2,3,4,6,9],"local":5,"locat":[0,3,6],"log":[4,9],"log_level":2,"log_respons":9,"logic":[5,9],"login":9,"look":5,"lower":0,"lowercas":6,"mai":4,"main":3,"make":[6,8,9],"manag":[5,8,9],"mani":9,"manual":0,"map":2,"mark":2,"marshmallow":[0,2,9],"match":[0,6,9],"max_ag":[0,9],"mean":9,"media":[0,2,5,6,8,9],"memori":[0,9],"messag":[0,9],"messagepack":5,"method":[0,5,6,8],"middelwar":0,"middlewar":[1,2,6,9],"migrat":[2,9],"mime":0,"mimetyp":9,"min":9,"minim":[3,4],"minimum":2,"minor":2,"miss":[8,9],"mix":9,"ml":9,"mode":[0,7],"model":[0,8,9],"modern":9,"modul":[2,5,9],"more":[3,4,5,6,9],"most":[4,6,8],"mount":[0,2,5],"move":2,"msgpack":9,"much":9,"multipart":2,"multipl":[2,3,9],"must":[0,9],"mutabl":5,"mutat":[0,5,6],"myapi":4,"n":6,"name":[0,5,6,8,9],"namespac":2,"natur":8,"need":[3,5,6,8,9],"negoti":[0,5,6,8,9],"network":8,"never":9,"new":[0,6,8,9],"next":[3,6],"nginx":4,"non":5,"none":[0,2],"notabl":2,"notasecret":0,"note":9,"now":[2,9],"npm":3,"number":6,"object":[0,2,3,5,6,9],"objecttyp":[0,9],"obviou":8,"oci":3,"oct":3,"often":9,"ok":[3,8],"on_delet":9,"on_ev":[0,8,9],"on_get":[5,9],"on_post":[5,9],"on_put":9,"on_request":[5,9],"on_startup":8,"onc":9,"one":[0,3,5],"onli":6,"open":[2,7],"open_database_connection_pool":0,"openapi":[0,2,5],"openapi_rout":0,"openapi_them":0,"option":[0,2,3,4,5,6],"order":3,"organ":[8,9],"origin":9,"other":[0,2,3,5,6],"otherwis":[0,9],"out":[4,5,9],"over":[0,4,5,9],"overal":2,"overhead":8,"overrid":[0,9],"p":4,"packag":[2,3],"page":[2,6,9],"painless":8,"param":[0,2,5,6],"paramet":[0,5,8,9],"parameter":0,"pars":[0,2,6,8],"pass":[0,5,6,8,9],"passion":5,"password":3,"patch":6,"path":[0,2,3,5,6,8,9],"path_matches_rout":0,"path_param":[0,6],"pattern":[5,6,9],"pdf":[6,8,9],"per":[8,9],"period":9,"person":5,"pet":[0,9],"petin":9,"petout":9,"petschema":[0,9],"photo":9,"pin":2,"pip":[3,4,5,7],"place":[4,5,9],"plain":[3,6,9],"platform":[2,5,6],"pleas":3,"pleasant":5,"plugin":[2,9],"point":3,"polici":9,"pool":[5,6],"port":[0,3,4,6,8],"portion":0,"post":[0,6,8,9],"potenti":2,"power":[5,8],"prefer":9,"prefix":[0,9],"price":[0,8],"primari":0,"print":9,"process":[5,6,8],"process_data":6,"product":[4,5,6,8,9],"profil":9,"program":3,"programmat":9,"progress":9,"project":[2,3,7],"propag":8,"properli":8,"properti":[0,6,8],"protect":9,"protocol":[3,8],"prototyp":[2,5],"provid":0,"proxi":5,"push":5,"put":6,"py":[2,3,4,8],"pydant":[0,8,9],"pyproject":2,"pytest":[5,7,8],"python":[0,2,3,4,5,6,9],"q":6,"queri":[0,5,6,9],"quick":5,"r":[6,8],"race":8,"railwai":[4,6],"rais":[2,8,9],"raise_server_except":8,"random":0,"rang":[0,9],"rapidoc":[0,9],"rate":[1,5],"ratelimit":9,"rather":8,"raw":[3,5,6,9],"re":[0,5,8,9],"reach":6,"react":2,"read":[0,2,5,9],"readi":[5,6],"real":9,"realli":8,"receiv":[0,6,8,9],"receive_byt":9,"receive_incom":6,"receive_json":9,"receive_text":[8,9],"recommend":9,"redirect":[0,2,6,9],"redoc":[0,9],"reduc":2,"ref":[3,9],"refactor":[2,8],"refer":[3,8],"reflect":3,"regist":[0,8,9],"regular":3,"reject":8,"relat":9,"relationship":9,"releas":7,"reliabl":8,"remain":9,"remot":5,"renam":8,"render":[0,1,4,5,9],"render_async":6,"replac":2,"report":[6,8,9],"repres":0,"represent":0,"req":[0,4,5,6,8,9],"request":[2,3,5],"request_id":[0,9],"request_model":[0,8,9],"requestbodi":9,"requir":[2,8,9],"research":5,"resolv":[2,9],"resolve_hello":[0,9],"resourc":9,"resp":[0,2,4,5,6,8,9],"respond":[0,2,4,6,7,8,9],"respons":[3,5,8,9],"response_model":[0,9],"rest":5,"restrict":9,"result":9,"resum":2,"resume_incomplet":2,"retri":[0,9],"return":[0,2,5,6,8,9],"revers":5,"rfc3986":2,"right":[5,9],"root":6,"rout":[0,2,4,5,8],"router":2,"ruff":7,"run":[0,2,3,5,7,8,9],"runner":4,"runtim":9,"s3":3,"safe":2,"sai":6,"same":[5,6,9],"sandbox":5,"sat":3,"scale":5,"schema":[0,2,5,9],"scope":[0,9],"scratch":5,"search":[0,2,6],"second":3,"secret":9,"secret_kei":[0,9],"section":[3,9],"secur":9,"see":[3,4,8],"select":[0,2,3],"self":[0,9],"semant":2,"send":[0,2,5,8,9],"send_byt":9,"send_json":9,"send_text":[8,9],"sent":[0,5,6],"separ":8,"sequenti":2,"serial":9,"serializ":6,"serv":[0,2,4,5,6,8],"server":[0,2,3,4,5,8],"servestat":2,"servic":[3,4,5,8],"session":[0,2,5,6,8],"session_id":9,"set":[0,2,4,5,6,7,8,9],"set_cooki":[2,9],"set_text":0,"setup":[2,8],"sever":6,"sftp":3,"share":[0,5,8,9],"short":[1,5,9],"should":5,"shouldn":0,"show":2,"shut":9,"shutdown":[0,5,8,9],"shutdwown":2,"side":9,"sign":[5,9],"simpl":[8,9],"simplecooki":0,"simpler":[5,9],"simplest":[4,6],"simul":6,"sinc":8,"singl":[2,3,5,9],"size":0,"skip":9,"slash":6,"sleep":[6,8],"slim":4,"small":[5,8,9],"smb":3,"so":[3,8,9],"someth":[5,6,8],"sometim":6,"sourc":[0,7],"spec":9,"specif":[0,3,6,8,9],"specifi":3,"sphinx":7,"spin":6,"sse":[0,5],"ssh":3,"ssl":4,"stabil":2,"standalon":9,"standard":[4,5],"starlett":[0,2,5,8],"start":[4,5,9],"startup":[0,2,5,8,9],"state":[0,2,8,9],"statement":5,"static":[0,2,4,5],"static_app":9,"static_dir":[0,9],"static_rout":[0,2,9],"statu":[0,2,6,8],"status_cod":[0,5,6,8,9],"stdlib":2,"stop":9,"storag":3,"store":[0,3,9],"str":[0,6,8,9],"straightforward":9,"stranger":[0,9],"stream":[0,2,5],"stream_fil":[0,9],"strict":9,"string":[0,5,6,9],"structur":9,"style":9,"subcommand":3,"subrout":[5,9],"subtl":2,"suit":8,"suppli":2,"support":[0,1,2,3,5,6],"surpris":3,"suspect":5,"swagger":[5,9],"swagger_ui":[0,9],"switch":2,"symbol":3,"sync":[2,5,6],"syntax":[5,6],"synthet":3,"system":3,"t":[0,3,4,6,8,9],"take":5,"tamper":9,"target":[2,3],"task":[2,5],"tear":9,"templat":[0,1,2,5],"template_str":[0,6],"templates_dir":0,"termin":4,"terms_of_servic":0,"test":[0,2,5,7,9],"test_500":[2,8],"test_api":8,"test_create_item":8,"test_custom_error":8,"test_head":8,"test_hello":8,"test_hook":8,"test_json":8,"test_upload":8,"test_valid":8,"test_websocket":8,"test_with_lifespan":8,"testclient":[0,2,8],"text":[0,3,4,5,6,8,9],"than":[3,8],"thei":9,"them":[4,5,8,9],"theme":[0,9],"thi":[0,2,3,4,6,8,9],"thing":[6,8],"those":3,"thread":[5,6],"threadpoolexecutor":2,"three":9,"through":[6,9],"time":[0,3,5,6,8,9],"time_start":0,"tip":5,"titl":[0,6,9],"togeth":[5,9],"token":9,"toml":2,"too":[6,8,9],"tool":7,"toolbelt":2,"tour":5,"trace":9,"traceback":2,"tradit":9,"traffic":9,"transfer":3,"transport":9,"treat":[0,9],"trigger":8,"true":[0,6,8,9],"trust":5,"trustedhostmiddlewar":4,"tupl":[0,6,8],"type":[0,2,3,5,9],"typic":3,"typo":2,"ui":[2,5,9],"unauthor":9,"unhandl":9,"unicod":0,"uniqu":9,"unknown":0,"unmaintain":2,"unmatch":9,"unpin":2,"up":[0,2,6,7,9],"updat":[2,9],"upgrad":[2,7],"upload":[2,5,6],"url":[0,2,3,5,6,8,9],"url_for":[0,8],"urllib":2,"us":[0,2,3,4,5,6,9],"usag":[0,2],"user":[0,3,9],"user_id":[6,9],"usernam":9,"usual":[5,8],"utf":[0,3],"util":5,"uuid":[0,6,9],"uuid4":0,"uv":[3,5,7],"uvicorn":[0,2,3,5,6],"v1":[0,9],"valid":[3,5,9],"valu":[0,5,6,8,9],"valueerror":[0,8,9],"variabl":[0,4,6],"ve":[5,8],"venv":7,"veri":0,"verifi":8,"version":[0,2,3,8,9],"via":[2,9],"view":[0,2,5,6,8],"virtualenv":7,"visit":9,"w":[8,9],"wa":[0,2],"wai":[4,6,9],"walk":[6,9],"want":[0,4,5,6,8,9],"watch":7,"we":6,"web":[3,4,5],"webdav":3,"websocket":[0,1,2,5],"websocket_connect":8,"well":5,"went":5,"wget":3,"what":[6,8],"when":[2,3,4,5,6,8,9],"where":[3,9],"whether":0,"which":[2,3,4,6,8,9],"whichev":5,"while":[6,9],"whitenois":2,"who":[5,6],"widget":8,"wildcard":9,"window":2,"within":[2,3],"without":[0,6,8,9],"won":8,"work":[3,4,5,6,9],"workdir":4,"worker":4,"workgroup":3,"world":[0,3,4,5,8,9],"worri":8,"would":[3,8],"wrap":[6,8,9],"write":9,"ws_auth":9,"wsgi":[0,2,5,9],"x":[0,6,8,9],"x89png":6,"xml":0,"yaml":[0,2,5,6,8,9],"yield":[0,9],"yml":[0,9],"you":[0,3,4,6,8,9],"your":[3,4,6,8,9]},"titles":["API Documentation","Backlog","Changelog","Responder CLI","Deployment","Responder","Quick Start","Development Sandbox","Testing","Feature Tour"],"titleterms":{"0":2,"01":2,"02":2,"03":2,"04":2,"08":2,"09":2,"1":2,"10":2,"11":2,"12":2,"13":2,"15":2,"16":2,"17":2,"18":2,"19":2,"2":2,"20":2,"2018":2,"2019":2,"2026":2,"22":2,"23":2,"24":2,"25":2,"26":2,"27":2,"28":2,"29":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":2,"9":2,"The":5,"ad":2,"after":[8,9],"api":[0,8],"app":9,"applic":3,"background":6,"backlog":1,"base":9,"befor":[8,9],"build":3,"chang":2,"changelog":2,"class":[0,9],"cli":3,"cloud":4,"convertor":6,"cooki":[8,9],"cor":9,"creat":6,"custom":9,"deploy":4,"deprec":2,"develop":7,"directli":4,"docker":4,"document":[0,9],"entrypoint":3,"error":[8,9],"event":[8,9],"featur":9,"file":[3,8,9],"filter":9,"fix":2,"fixtur":8,"function":0,"futur":1,"get":[5,8],"graphql":9,"group":9,"guid":5,"handl":[8,9],"header":8,"hello":6,"hook":[8,9],"host":9,"hst":9,"id":9,"idea":[1,5],"instal":5,"instanc":3,"javascript":3,"json":8,"launch":3,"lifespan":[8,9],"limit":9,"local":[3,4],"messagepack":9,"method":9,"modul":3,"mount":9,"name":3,"non":3,"openapi":9,"oper":7,"other":9,"paramet":6,"platform":4,"project":5,"proxi":4,"quick":6,"rate":9,"read":6,"remot":3,"remov":2,"render":6,"request":[0,6,8,9],"respond":[3,5],"respons":[0,6],"revers":4,"rout":[6,9],"run":[4,6],"sandbox":7,"send":6,"sent":9,"serv":9,"server":[6,9],"servic":[0,6],"session":9,"setup":7,"sse":9,"standard":3,"start":[6,8],"static":9,"stream":9,"support":9,"task":6,"templat":6,"test":8,"tip":8,"tour":9,"trust":9,"type":6,"unreleas":2,"upload":8,"us":8,"user":5,"util":0,"uvicorn":4,"v0":2,"v1":2,"v2":2,"v3":2,"valid":8,"view":9,"web":[0,6],"websocket":[8,9],"what":5,"world":6,"you":5}})
\ No newline at end of file
+Search.setIndex({"alltitles":{"API Documentation":[[0,null]],"Added":[[2,"added"],[2,"id1"],[2,"id7"],[2,"id8"],[2,"id11"],[2,"id14"],[2,"id19"],[2,"id26"],[2,"id32"],[2,"id33"],[2,"id34"],[2,"id35"],[2,"id36"],[2,"id39"],[2,"id40"],[2,"id42"],[2,"id45"],[2,"id48"],[2,"id49"],[2,"id50"],[2,"id54"]],"After-Request Hooks":[[9,"after-request-hooks"]],"Background Tasks":[[6,"background-tasks"]],"Backlog":[[1,null]],"Before-Request Hooks":[[9,"before-request-hooks"]],"Build JavaScript Application":[[3,"build-javascript-application"]],"CORS":[[9,"cors"]],"Changed":[[2,"changed"],[2,"id6"],[2,"id9"],[2,"id12"],[2,"id15"],[2,"id18"],[2,"id23"],[2,"id24"],[2,"id25"],[2,"id27"],[2,"id28"],[2,"id30"],[2,"id31"],[2,"id37"],[2,"id41"],[2,"id46"],[2,"id47"],[2,"id53"]],"Changelog":[[2,null]],"Class-Based Views":[[9,"class-based-views"]],"Cloud Platforms":[[4,"cloud-platforms"]],"Cookie-Based Sessions":[[9,"cookie-based-sessions"]],"Cookies":[[9,"cookies"]],"Create a Web Service":[[6,"create-a-web-service"]],"Custom Error Handling":[[9,"custom-error-handling"]],"Deployment":[[4,null]],"Deprecated":[[2,"deprecated"]],"Development Sandbox":[[7,null]],"Docker":[[4,"docker"]],"Feature Tour":[[9,null]],"Fixed":[[2,"fixed"],[2,"id2"],[2,"id3"],[2,"id4"],[2,"id5"],[2,"id10"],[2,"id13"],[2,"id16"],[2,"id17"],[2,"id20"],[2,"id21"],[2,"id22"],[2,"id29"],[2,"id38"],[2,"id43"],[2,"id44"],[2,"id51"],[2,"id52"]],"Future Ideas":[[1,"future-ideas"]],"Getting Started":[[8,"getting-started"]],"GraphQL":[[9,"graphql"]],"HSTS":[[9,"hsts"]],"Hello World":[[6,"hello-world"]],"Installation":[[5,"installation"]],"Launch Local File":[[3,"launch-local-file"]],"Launch Module Entrypoint":[[3,"launch-module-entrypoint"]],"Launch Remote File":[[3,"launch-remote-file"]],"Launch with Non-Standard Instance Name":[[3,"launch-with-non-standard-instance-name"]],"Lifespan Events":[[9,"lifespan-events"]],"MessagePack":[[9,"messagepack"]],"Method Filtering":[[9,"method-filtering"]],"Mounting Other Apps":[[9,"mounting-other-apps"]],"OpenAPI Documentation":[[9,"openapi-documentation"]],"Operations":[[7,"operations"]],"Project":[[5,null]],"Quick Start":[[6,null]],"Rate Limiting":[[9,"rate-limiting"]],"Reading Requests":[[6,"reading-requests"]],"Removed":[[2,"removed"]],"Rendering Templates":[[6,"rendering-templates"]],"Request ID":[[9,"request-id"]],"Requests & Responses":[[0,"requests-responses"]],"Responder":[[5,null]],"Responder CLI":[[3,null]],"Reverse Proxy":[[4,"reverse-proxy"]],"Route Groups":[[9,"route-groups"]],"Route Parameters":[[6,"route-parameters"]],"Run the Server":[[6,"run-the-server"]],"Running Locally":[[4,"running-locally"]],"Sending Responses":[[6,"sending-responses"]],"Server-Sent Events (SSE)":[[9,"server-sent-events-sse"]],"Serving Files":[[9,"serving-files"]],"Setup":[[7,"setup"]],"Static Files":[[9,"static-files"]],"Testing":[[8,null]],"Testing Before and After Hooks":[[8,"testing-before-and-after-hooks"]],"Testing Error Handling":[[8,"testing-error-handling"]],"Testing File Uploads":[[8,"testing-file-uploads"]],"Testing Headers and Cookies":[[8,"testing-headers-and-cookies"]],"Testing JSON APIs":[[8,"testing-json-apis"]],"Testing Lifespan Events":[[8,"testing-lifespan-events"]],"Testing Request Validation":[[8,"testing-request-validation"]],"Testing WebSockets":[[8,"testing-websockets"]],"The Idea":[[5,"the-idea"]],"Tips":[[8,"tips"]],"Trusted Hosts":[[9,"trusted-hosts"]],"Type Convertors":[[6,"type-convertors"]],"Unreleased":[[2,"unreleased"]],"User Guide":[[5,null]],"Using Fixtures":[[8,"using-fixtures"]],"Utility Functions":[[0,"utility-functions"]],"Uvicorn Directly":[[4,"uvicorn-directly"]],"Web Service (API) Class":[[0,"module-responder"]],"WebSocket Support":[[9,"websocket-support"]],"What You Get":[[5,"what-you-get"]],"v0.0.1 - 2018-10-12":[[2,"v0-0-1-2018-10-12"]],"v0.0.10 - 2018-10-17":[[2,"v0-0-10-2018-10-17"]],"v0.0.2 - 2018-10-13":[[2,"v0-0-2-2018-10-13"]],"v0.0.3 - 2018-10-13":[[2,"v0-0-3-2018-10-13"]],"v0.0.4 - 2018-10-15":[[2,"v0-0-4-2018-10-15"]],"v0.0.5 - 2018-10-15":[[2,"v0-0-5-2018-10-15"]],"v0.0.6 - 2018-10-16":[[2,"v0-0-6-2018-10-16"]],"v0.0.7 - 2018-10-16":[[2,"v0-0-7-2018-10-16"]],"v0.0.8 - 2018-10-17":[[2,"v0-0-8-2018-10-17"]],"v0.0.9 - 2018-10-17":[[2,"v0-0-9-2018-10-17"]],"v0.1.0 - 2018-10-17":[[2,"v0-1-0-2018-10-17"]],"v0.1.1 - 2018-10-17":[[2,"v0-1-1-2018-10-17"]],"v0.1.2 - 2018-10-18":[[2,"v0-1-2-2018-10-18"]],"v0.1.3 - 2018-10-18":[[2,"v0-1-3-2018-10-18"]],"v0.1.4 - 2018-10-19":[[2,"v0-1-4-2018-10-19"]],"v0.1.5 - 2018-10-20":[[2,"v0-1-5-2018-10-20"]],"v0.1.6 - 2018-10-20":[[2,"v0-1-6-2018-10-20"]],"v0.2.0 - 2018-10-22":[[2,"v0-2-0-2018-10-22"]],"v0.2.1 - 2018-10-23":[[2,"v0-2-1-2018-10-23"]],"v0.2.2 - 2018-10-23":[[2,"v0-2-2-2018-10-23"]],"v0.2.3 - 2018-10-24":[[2,"v0-2-3-2018-10-24"]],"v0.3.0 - 2018-10-24":[[2,"v0-3-0-2018-10-24"]],"v0.3.1 - 2018-10-24":[[2,"v0-3-1-2018-10-24"]],"v0.3.2 - 2018-10-25":[[2,"v0-3-2-2018-10-25"]],"v0.3.3 - 2018-10-25":[[2,"v0-3-3-2018-10-25"]],"v1.0.0 - 2018-10-26":[[2,"v1-0-0-2018-10-26"]],"v1.0.1 - 2018-10-26":[[2,"v1-0-1-2018-10-26"]],"v1.0.2 - 2018-10-27":[[2,"v1-0-2-2018-10-27"]],"v1.0.3 - 2018-10-27":[[2,"v1-0-3-2018-10-27"]],"v1.0.4 - 2018-10-27":[[2,"v1-0-4-2018-10-27"]],"v1.0.5- 2018-10-27":[[2,"v1-0-5-2018-10-27"]],"v1.1.0 - 2018-10-27":[[2,"v1-1-0-2018-10-27"]],"v1.1.1 - 2018-10-29":[[2,"v1-1-1-2018-10-29"]],"v1.1.2 - 2018-11-11":[[2,"v1-1-2-2018-11-11"]],"v1.1.3 - 2019-01-12":[[2,"v1-1-3-2019-01-12"]],"v1.2.0 - 2018-12-29":[[2,"v1-2-0-2018-12-29"]],"v1.3.0 - 2019-02-22":[[2,"v1-3-0-2019-02-22"]],"v1.3.1 - 2019-04-28":[[2,"v1-3-1-2019-04-28"]],"v1.3.2 - 2019-08-15":[[2,"v1-3-2-2019-08-15"]],"v2.0.0 - 2019-09-19":[[2,"v2-0-0-2019-09-19"]],"v2.0.1 - 2019-09-20":[[2,"v2-0-1-2019-09-20"]],"v2.0.2 - 2019-09-20":[[2,"v2-0-2-2019-09-20"]],"v2.0.3 - 2019-09-20":[[2,"v2-0-3-2019-09-20"]],"v2.0.4 - 2019-11-19":[[2,"v2-0-4-2019-11-19"]],"v2.0.5 - 2019-12-15":[[2,"v2-0-5-2019-12-15"]],"v3.0.0 - 2026-03-22":[[2,"v3-0-0-2026-03-22"]]},"docnames":["api","backlog","changes","cli","deployment","index","quickstart","sandbox","testing","tour"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1},"filenames":["api.rst","backlog.md","changes.md","cli.rst","deployment.rst","index.rst","quickstart.rst","sandbox.md","testing.rst","tour.rst"],"indexentries":{"accepts() (responder.request method)":[[0,"responder.Request.accepts",false]],"add_event_handler() (responder.api method)":[[0,"responder.API.add_event_handler",false]],"add_route() (responder.api method)":[[0,"responder.API.add_route",false]],"after_request() (responder.api method)":[[0,"responder.API.after_request",false]],"api (class in responder)":[[0,"responder.API",false]],"apparent_encoding (responder.request property)":[[0,"responder.Request.apparent_encoding",false]],"client (responder.request property)":[[0,"responder.Request.client",false]],"content (responder.request property)":[[0,"responder.Request.content",false]],"content (responder.response attribute)":[[0,"responder.Response.content",false]],"cookies (responder.request property)":[[0,"responder.Request.cookies",false]],"cookies (responder.response attribute)":[[0,"responder.Response.cookies",false]],"encoding (responder.request property)":[[0,"responder.Request.encoding",false]],"exception_handler() (responder.api method)":[[0,"responder.API.exception_handler",false]],"file() (responder.response method)":[[0,"responder.Response.file",false]],"formats (responder.response attribute)":[[0,"responder.Response.formats",false]],"full_url (responder.request property)":[[0,"responder.Request.full_url",false]],"graphql() (responder.api method)":[[0,"responder.API.graphql",false]],"group() (responder.api method)":[[0,"responder.API.group",false]],"headers (responder.request property)":[[0,"responder.Request.headers",false]],"headers (responder.response attribute)":[[0,"responder.Response.headers",false]],"is_100() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_100",false]],"is_200() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_200",false]],"is_300() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_300",false]],"is_400() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_400",false]],"is_500() (in module responder.api.status_codes)":[[0,"responder.API.status_codes.is_500",false]],"is_json (responder.request property)":[[0,"responder.Request.is_json",false]],"media (responder.response attribute)":[[0,"responder.Response.media",false]],"media() (responder.request method)":[[0,"responder.Request.media",false]],"method (responder.request property)":[[0,"responder.Request.method",false]],"module":[[0,"module-responder",false]],"mount() (responder.api method)":[[0,"responder.API.mount",false]],"on_event() (responder.api method)":[[0,"responder.API.on_event",false]],"params (responder.request property)":[[0,"responder.Request.params",false]],"path_matches_route() (responder.api method)":[[0,"responder.API.path_matches_route",false]],"path_params (responder.request property)":[[0,"responder.Request.path_params",false]],"redirect() (responder.api method)":[[0,"responder.API.redirect",false]],"request (class in responder)":[[0,"responder.Request",false]],"requests (responder.api property)":[[0,"responder.API.requests",false]],"responder":[[0,"module-responder",false]],"response (class in responder)":[[0,"responder.Response",false]],"route() (responder.api method)":[[0,"responder.API.route",false]],"schema() (responder.api method)":[[0,"responder.API.schema",false]],"serve() (responder.api method)":[[0,"responder.API.serve",false]],"session (responder.request property)":[[0,"responder.Request.session",false]],"session (responder.response attribute)":[[0,"responder.Response.session",false]],"session() (responder.api method)":[[0,"responder.API.session",false]],"sse() (responder.response method)":[[0,"responder.Response.sse",false]],"state (responder.request property)":[[0,"responder.Request.state",false]],"status_code (responder.response attribute)":[[0,"responder.Response.status_code",false]],"stream_file() (responder.response method)":[[0,"responder.Response.stream_file",false]],"template() (responder.api method)":[[0,"responder.API.template",false]],"template_string() (responder.api method)":[[0,"responder.API.template_string",false]],"text (responder.request property)":[[0,"responder.Request.text",false]],"url (responder.request property)":[[0,"responder.Request.url",false]],"url_for() (responder.api method)":[[0,"responder.API.url_for",false]]},"objects":{"":[[0,0,0,"-","responder"]],"responder":[[0,1,1,"","API"],[0,1,1,"","Request"],[0,1,1,"","Response"]],"responder.API":[[0,2,1,"","add_event_handler"],[0,2,1,"","add_route"],[0,2,1,"","after_request"],[0,2,1,"","exception_handler"],[0,2,1,"","graphql"],[0,2,1,"","group"],[0,2,1,"","mount"],[0,2,1,"","on_event"],[0,2,1,"","path_matches_route"],[0,2,1,"","redirect"],[0,3,1,"","requests"],[0,2,1,"","route"],[0,2,1,"","schema"],[0,2,1,"","serve"],[0,2,1,"","session"],[0,2,1,"","template"],[0,2,1,"","template_string"],[0,2,1,"","url_for"]],"responder.API.status_codes":[[0,4,1,"","is_100"],[0,4,1,"","is_200"],[0,4,1,"","is_300"],[0,4,1,"","is_400"],[0,4,1,"","is_500"]],"responder.Request":[[0,2,1,"","accepts"],[0,3,1,"","apparent_encoding"],[0,3,1,"","client"],[0,3,1,"","content"],[0,3,1,"","cookies"],[0,3,1,"","encoding"],[0,3,1,"","full_url"],[0,3,1,"","headers"],[0,3,1,"","is_json"],[0,2,1,"","media"],[0,3,1,"","method"],[0,3,1,"","params"],[0,3,1,"","path_params"],[0,3,1,"","session"],[0,3,1,"","state"],[0,3,1,"","text"],[0,3,1,"","url"]],"responder.Response":[[0,5,1,"","content"],[0,5,1,"","cookies"],[0,2,1,"","file"],[0,5,1,"","formats"],[0,5,1,"","headers"],[0,5,1,"","media"],[0,5,1,"","session"],[0,2,1,"","sse"],[0,5,1,"","status_code"],[0,2,1,"","stream_file"]]},"objnames":{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","property","Python property"],"4":["py","function","Python function"],"5":["py","attribute","Python attribute"]},"objtypes":{"0":"py:module","1":"py:class","2":"py:method","3":"py:property","4":"py:function","5":"py:attribute"},"terms":{"":[0,2,3,4,5,6,8,9],"0":[3,4,6,9],"1":[0,3,4,6,9],"10":[0,6,9],"100":9,"127":[3,4],"13":[3,4],"150mb":4,"16":3,"2":[4,6,8,9],"200":[3,6,8,9],"201":[6,8],"2024":3,"25":3,"26":3,"3":[4,5,6,8,9],"301":[0,6],"308":2,"3600":9,"4":4,"40":2,"400":[0,8,9],"401":9,"404":6,"41d4":6,"422":[8,9],"429":9,"446655440000":6,"500":[2,6,8,9],"5000":9,"5042":[3,4,6],"55":3,"550e8400":6,"60":9,"600":[0,9],"8":[0,3],"80":4,"8000":[4,6],"8192":0,"9":[5,8],"99":8,"A":[0,3,4,5,6,9],"And":6,"As":9,"But":[6,8,9],"By":[3,6,8,9],"For":[3,4,6,8,9],"If":[0,3,5,6,8,9],"In":[3,6,9],"It":[3,5,6,8,9],"No":[8,9],"Not":6,"On":9,"One":[5,6,8],"That":[4,5,6,8],"The":[0,2,3,4,6,8,9],"There":[8,9],"These":6,"To":3,"Will":0,"With":0,"__main__":[4,5,8],"__name__":[4,5,8,9],"_route_for":2,"a2wsgi":2,"a716":6,"abc123":[8,9],"abf":3,"abil":2,"abl":0,"about":[4,6,8],"abov":[3,5],"accept":[0,2,3,6,8,9],"access":[3,4,9],"acm":3,"acquir":[3,7],"across":[4,9],"activ":7,"actual":[0,6,9],"ad":[1,9],"adapt":[3,9],"add":[0,1,2,6],"add_event_handl":0,"add_head":9,"add_request_id":0,"add_rout":[0,9],"add_tim":[8,9],"add_vers":8,"addit":0,"address":[0,3,6,9],"adher":2,"affect":9,"after":[0,5,6],"after_request":[0,1,8,9],"ag":9,"against":[0,4,9],"agre":6,"ai":9,"alias":2,"alic":9,"all":[0,2,3,4,6,7,8,9],"alloc":8,"allow":9,"allow_credenti":[0,9],"allow_head":[0,9],"allow_method":[0,9],"allow_origin":[0,9],"allow_origin_regex":0,"allowed_host":[0,9],"alongsid":9,"alpin":4,"alreadi":[0,8,9],"also":[0,2,3,6,8,9],"altern":[0,9],"alwai":[4,5,6,9],"an":[0,3,6,9],"angular":9,"ani":[0,4,5,6,8,9],"annot":[5,6,9],"annual":[6,9],"answer":9,"anyon":5,"anyth":6,"anywher":[4,9],"api":[2,3,4,5,6,9],"apispec":2,"app":[0,2,3,4,5,8],"appar":0,"apparent_encod":0,"appear":[5,9],"append":3,"applic":[0,2,4,5,6,8,9],"approach":9,"appropri":9,"approx":3,"ar":[2,3,4,5,6,8,9],"architectur":9,"aren":6,"arg":0,"argument":[0,2,6],"around":[0,5],"arriv":6,"arrow":3,"asgi":[0,2,4,5,6,9],"ask":[5,9],"assert":8,"asset":[3,4,9],"assum":3,"async":[0,1,2,4,5,6,8,9],"asynccontextmanag":9,"asynchron":[2,4],"attach":9,"attack":[4,9],"attr":3,"attribut":[0,3],"auth":[5,9],"auth_check":9,"authent":[6,9],"author":[3,6,7,9],"auto":9,"auto_escap":0,"autobuild":7,"automat":[0,4,5,6,8,9],"avail":[3,6],"avoid":[8,9],"aw":[3,4],"await":[0,6,8,9],"az":3,"azur":[3,4],"b":[6,8],"back":[0,5,6,9],"background":[2,5],"backlog":5,"bad":[8,9],"balanc":4,"bandwidth":9,"bar":9,"base":[0,2,3,5],"base_url":0,"basemodel":[0,8,9],"basic":[3,6],"batteri":5,"battl":5,"becaus":6,"becom":0,"been":3,"befor":[5,6],"before_request":[0,1,2,8,9],"beforehand":3,"behind":[4,9],"being":0,"best":5,"better":5,"bidirect":9,"bin":7,"binari":[6,9],"bind":[0,4,6],"blob":3,"block":[6,8,9],"bodi":[0,6,8,9],"boilerpl":5,"both":[5,6,9],"break":8,"bring":5,"broke":[6,8],"broker":6,"browser":[3,6,7,9],"bucket":[3,9],"buffer":6,"bufix":2,"bug":[2,8],"bugfix":2,"build":[2,4,5,6,7],"built":[2,4,5,6,8,9],"bump":2,"bypass":4,"byte":[0,5,6],"cach":[6,8,9],"caddi":4,"call":[6,8,9],"callabl":0,"came":6,"can":[0,3,4,5,6,8,9],"capac":3,"carri":6,"case":[0,5,6],"cat":9,"catch":9,"cd":7,"ceas":2,"celeri":6,"central":6,"certain":0,"certif":4,"chanc":3,"chang":3,"changelog":5,"channel":9,"chardet":0,"chat":9,"check":[7,8,9],"check_exist":[0,9],"choic":[6,9],"choos":[3,9],"chunk":[0,9],"chunk_siz":0,"ci":2,"circuit":[1,5,9],"class":[2,5,6,8],"clean":[5,9],"cleaner":9,"cleanup":9,"cli":[2,5],"click":5,"client":[0,5,6,8,9],"clone":7,"close":[8,9],"close_database_connection_pool":0,"cloud":[3,5,6],"cmd":4,"code":[0,2,4,6,7,8,9],"collabor":9,"com":[3,6,7,9],"come":[6,9],"command":[3,4],"common":[3,4,6,9],"commonli":6,"commun":9,"compact":9,"compat":3,"complement":[1,9],"complet":9,"compress":[5,6],"comput":6,"concept":[2,9],"concern":6,"conclud":3,"concurr":4,"condit":[8,9],"configur":[2,4,6,8,9],"conflict":2,"confus":8,"connect":[0,4,8,9],"consid":[1,6],"consist":[6,9],"consol":9,"const":9,"consum":9,"contact":0,"contain":[0,4,6],"container":4,"content":[0,2,3,5,6,8,9],"content_typ":[0,8,9],"context":[5,8,9],"contextlib":9,"continu":6,"contract":8,"control":[4,6,9],"convent":4,"convert":[2,6],"convertor":5,"cooki":[0,2,5,6],"copi":4,"cor":[0,2,5,8],"core":[2,4],"coroutin":0,"correctli":4,"correspond":3,"cors_param":[0,9],"count":2,"cpu":[4,6],"creat":[0,5,7,8,9],"create_item":[0,9],"create_pet":9,"cross":9,"css":9,"csv":9,"curl":[3,6],"current":3,"custom":[0,5,6,8],"cycl":6,"d":8,"dashboard":9,"dask":3,"data":[0,2,6,8,9],"databas":[6,8,9],"date":3,"debug":[0,2,9],"decim":6,"declar":[2,6],"decod":[2,9],"decor":[0,6,9],"deep":5,"def":[0,5,6,8,9],"default":[0,1,2,3,6,8,9],"default_valu":[0,9],"defend":9,"defin":[3,6,9],"definit":0,"delet":[6,9],"deliber":6,"denpend":2,"depend":[2,4,8],"deploi":[4,5],"deploy":5,"depth":9,"describ":9,"descript":[0,9],"design":[3,6,9],"detail":[4,9],"detect":[0,5,9],"dev":2,"develop":[4,9],"devic":9,"dict":[0,5,6,9],"dictionari":0,"differ":[3,8,9],"digit":6,"direct":[2,9],"directli":[5,6,8],"directori":[0,3,6,9],"disabl":8,"disk":[0,6,9],"dispatch":[2,9],"distribut":[3,4,9],"django":[5,9],"dna":5,"do":[3,4,6,9],"doc":[7,8,9],"docker":5,"dockerfil":4,"docs_rout":[0,9],"docstr":9,"document":[2,4,5,7],"doesn":[0,9],"domain":9,"don":[3,6,8,9],"done":4,"down":9,"download":9,"dramat":2,"drop":2,"dropbox":3,"dump":2,"duplex":9,"duplic":9,"dure":[4,8],"dynam":6,"e":0,"e29b":6,"each":[0,4,8,9],"easi":6,"echo":3,"ecosystem":[5,6],"edit":[3,7],"editor":9,"effect":8,"effici":4,"either":[0,3],"element":[0,9],"els":[6,9],"email":6,"emb":9,"enabl":[2,9],"enable_async":6,"enable_hst":[0,9],"encod":[0,3],"end":6,"endpoint":[0,2,8,9],"enforc":9,"engin":6,"enough":4,"ensur":9,"enter":8,"entir":[0,9],"entri":3,"entrypoint":5,"enumer":3,"env":4,"environ":[0,4,6],"eol":2,"error":[0,5],"escap":0,"essenti":9,"etc":[6,8,9],"even":[3,4,9],"event":[0,2,5,6],"event_typ":0,"eventsourc":9,"everi":[0,4,5,6,8,9],"everyth":[4,9],"exactli":[8,9],"exampl":[3,6,9],"exc":[0,8,9],"exceed":9,"except":[0,2,5,8,9],"exception_cl":0,"exception_handl":[0,8,9],"exist":[0,2,3,5],"exit":[8,9],"expect":[3,6],"expir":9,"explain":9,"explicit":[6,9],"explicitli":9,"explor":[1,5,9],"export":9,"expos":4,"expose_head":0,"express":[5,6],"ext":[2,9],"extens":[2,6],"extern":6,"extra":[2,3,4,9],"extract":0,"extrem":6,"f":[0,5,6,8,9],"fail":[8,9],"failur":8,"falcon":[5,9],"fall":0,"fals":[0,8,9],"familiar":5,"fast":[4,5,6,8],"fastapi":5,"faster":9,"favourit":3,"featur":[0,5,6],"feed":9,"feel":5,"few":3,"fido":9,"field":[0,8,9],"figur":[5,6],"file":[0,2,4,5,6],"filenam":[0,8],"filepath":6,"filesystem":[2,3],"fill":6,"filter":[5,6],"find":9,"fine":[4,9],"fire":8,"first":9,"fit":5,"fix":7,"fixtur":5,"flag":[4,9],"flask":[5,9],"flask_app":9,"float":[0,6,8],"fly":4,"follow":6,"font":9,"forg":9,"form":[0,3,6],"format":[0,2,6,7,9],"formerli":9,"forward":[4,5,9],"found":[2,6],"foundat":9,"framework":[5,9],"franca":6,"fresh":8,"from":[0,2,3,4,5,6,8,9],"front":4,"frontend":9,"fsspec":3,"full":[0,2,3,6,9],"full_url":[0,6,9],"fulli":6,"fun":5,"func":0,"function":[5,6,9],"fuse":3,"g":[0,3],"game":9,"gatewai":4,"gc":3,"gener":[0,5,8,9],"get":[0,6,9],"get_us":[0,9],"git":[3,7],"github":[3,7],"give":[3,8,9],"given":[0,8],"gmt":3,"go":6,"goe":9,"good":[4,5,9],"googl":[3,4],"grace":4,"grade":6,"gradual":9,"graphen":[0,2,5,9],"graphiql":[2,5,9],"graphql":[0,2,5],"great":[5,9],"greet":[5,9],"greet_world":5,"greetingresourc":9,"group":[0,5],"grow":9,"guard":5,"guid":6,"guido":6,"gzip":[5,6],"h1":6,"ha":[6,8],"hadoop":3,"half":6,"halv":9,"hand":[0,3],"handl":[4,5,6],"handle_value_error":[0,9],"handler":[0,3,5,8,9],"happen":[5,6],"hard":8,"have":[0,2,3,6,8],"hdf":3,"head":3,"header":[0,4,5,6,9],"heavi":6,"hello":[0,3,5,8,9],"hello_html":6,"hello_json":6,"hello_to":6,"hello_world":6,"helloworld":3,"help":0,"here":[4,6,9],"high":[4,9],"hold":[5,6],"home":5,"honor":[4,6],"hood":9,"hook":[1,5,6],"host":[0,2,3,4,5,6],"hostnam":9,"hour":9,"how":[6,9],"hst":5,"html":[0,2,5,6,9],"http":[0,2,3,4,5,6,7,8,9],"httpie":3,"httponli":9,"httpsredirectmiddlewar":4,"httpx":[2,8],"i":[0,2,3,4,5,6,8,9],"id":[0,5,6],"identifi":9,"imag":[4,6,9],"immedi":[5,6,9],"immut":2,"implement":[3,8],"import":[0,2,3,5,6,8,9],"importlib":3,"improv":2,"includ":[3,4,5,6,7,8,9],"incom":[0,6],"incredibli":9,"independ":4,"index":[0,9],"individu":9,"industri":9,"info":[0,2,9],"inform":0,"infrastructur":[4,5],"inherit":[3,9],"initi":[0,8],"inject":9,"input":[8,9],"insensit":[0,5,6],"instal":[0,3,4,7,9],"instanc":[0,4,5,6,8],"instant":6,"instead":[3,6,8,9],"int":[0,6,9],"integ":[0,6],"intens":6,"intent":5,"intention":9,"interact":[2,9],"interfac":[4,6],"intern":[8,9],"internet":3,"invalid":[8,9],"invoc":3,"invok":3,"io":4,"iot":9,"ip":[6,9],"is_100":0,"is_200":0,"is_300":0,"is_400":0,"is_500":0,"is_class_bas":2,"is_json":[0,6],"is_secur":6,"isn":[6,9],"issu":2,"item":[0,8,9],"itemin":0,"itemout":0,"its":[0,2,3,4],"j":9,"javascript":[5,9],"jinja2":[0,6],"joi":5,"jpeg":9,"jpg":9,"json":[0,3,5,6,9],"just":[4,8,9],"keep":[2,6,8,9],"kei":[0,8,9],"kennethreitz":[3,7],"keyword":[0,6],"kind":3,"know":6,"known":0,"kwarg":0,"languag":9,"larg":[5,9],"larger":8,"later":[6,8],"launch":[4,5],"layout":3,"lazili":0,"lead":8,"learn":[5,9],"length":3,"less":9,"let":[4,6,9],"level":4,"librari":[8,9],"licens":0,"lifespan":[0,2,5],"lift":6,"lightn":4,"lightweight":6,"like":[3,4,5,6,8,9],"limit":[1,4,5],"line":[3,6],"lingua":6,"list":[0,3,6,8,9],"list_item":9,"list_pet":9,"list_us":[0,9],"list_users_v2":9,"live":9,"ll":[5,6,9],"load":[0,2,3,4,6,9],"local":5,"localhost":6,"locat":[0,3,6],"log":[4,9],"log_level":2,"log_respons":9,"logic":[5,6,9],"login":9,"long":6,"look":[5,6],"loop":6,"lower":0,"lowercas":6,"machin":9,"mai":4,"main":3,"make":[4,6,8,9],"malici":9,"manag":[5,8,9],"mani":[4,6,9],"manual":0,"map":[2,6,9],"mark":[2,9],"marshmallow":[0,2,9],"match":[0,6,9],"matter":9,"max_ag":[0,9],"mean":[4,6],"mechan":9,"media":[0,2,5,6,8,9],"memori":[0,6,9],"messag":[0,6,9],"messagepack":5,"metadata":6,"method":[0,5,6,8],"microservic":9,"middelwar":0,"middlewar":[1,2,6,9],"might":6,"migrat":[2,9],"mime":0,"mimetyp":[6,9],"min":9,"minim":[3,4],"minimum":2,"minor":2,"miss":[8,9],"mix":9,"ml":9,"mode":[0,7],"model":[0,8,9],"modern":[4,9],"modifi":9,"modul":[2,5,6,9],"more":[3,4,5,6,9],"most":[4,6,8,9],"mount":[0,2,5],"move":[2,6,9],"msgpack":9,"much":[6,9],"multipart":[2,6],"multipl":[2,3,4,9],"multiplay":9,"must":[0,6,9],"mutabl":5,"mutat":[0,5,6],"my_templ":6,"myapi":4,"n":6,"name":[0,5,6,8,9],"namespac":2,"natur":8,"need":[3,4,5,6,8,9],"negoti":[0,5,6,8,9],"nervou":6,"network":8,"never":9,"new":[0,6,8,9],"next":3,"nginx":4,"non":[5,6],"none":[0,2],"normal":9,"notabl":2,"notasecret":0,"note":[6,9],"notic":6,"notif":9,"now":[2,6,9],"npm":3,"number":6,"o":6,"object":[0,2,3,5,6,9],"objecttyp":[0,9],"obviou":8,"oci":3,"oct":3,"off":6,"offload":4,"often":[6,9],"ok":[3,6,8],"on_delet":9,"on_ev":[0,8,9],"on_get":[5,9],"on_post":[5,9],"on_put":9,"on_request":[5,9],"on_startup":8,"onc":9,"one":[0,3,5,6,9],"ones":[6,9],"onli":[6,9],"onmessag":9,"open":[2,6,7],"open_database_connection_pool":0,"openapi":[0,2,5],"openapi_rout":0,"openapi_them":0,"oper":[6,9],"opt":9,"option":[0,2,3,4,5,6],"order":3,"organ":[8,9],"origin":9,"other":[0,2,3,5,6],"otherwis":[0,9],"out":[5,6],"outgo":6,"over":[0,5,6,9],"overal":2,"overhead":8,"overrid":[0,9],"overwhelm":9,"own":[4,9],"p":4,"pace":9,"packag":[2,3,4],"page":[2,6,9],"pagin":6,"painless":8,"param":[0,2,5,6],"paramet":[0,5,8,9],"parameter":0,"pars":[0,2,6,8,9],"part":[6,9],"pass":[0,5,6,8],"passion":5,"password":3,"patch":[6,9],"path":[0,2,3,5,6,8,9],"path_matches_rout":0,"path_param":[0,6],"pattern":[4,5,6,9],"pdf":[6,8,9],"per":[4,8,9],"perfect":9,"period":9,"perman":6,"permit":9,"persist":9,"person":5,"pet":[0,9],"petin":9,"petout":9,"petschema":[0,9],"photo":9,"piec":9,"pin":2,"pip":[3,4,5,7],"place":[5,9],"placehold":6,"plain":[3,6,9],"platform":[2,5,6],"pleas":3,"pleasant":5,"plugin":2,"point":[3,4],"polici":9,"pool":[5,6,9],"popular":[6,9],"port":[0,3,4,6,8],"portion":0,"possibl":6,"post":[0,6,8,9],"potenti":2,"power":[5,8,9],"practic":9,"prefer":9,"prefix":[0,9],"present":6,"prevent":9,"price":[0,8],"primari":0,"print":9,"privat":9,"process":[4,5,6,8,9],"process_data":6,"produc":6,"product":[4,5,6,8,9],"profil":9,"program":3,"programmat":9,"progress":9,"project":[2,3,7],"propag":8,"proper":6,"properli":8,"properti":[0,6,8],"protect":4,"proto":4,"protocol":[3,6,8,9],"prototyp":[2,5],"provid":0,"proxi":5,"public":9,"push":[4,5,9],"put":[6,9],"py":[2,3,4,8],"pydant":[0,8,9],"pyproject":2,"pytest":[5,7,8],"python":[0,2,3,4,5,6,9],"q":6,"queri":[0,5,6,9],"queue":6,"quick":5,"r":[6,8],"race":8,"railwai":4,"rais":[2,8,9],"raise_server_except":8,"random":0,"rang":[0,9],"rapidoc":[0,9],"rare":6,"rate":[1,4,5],"ratelimit":9,"rather":8,"raw":[3,5,6,9],"re":[0,4,5,6,8,9],"react":[2,9],"read":[0,2,5,9],"readabl":9,"readi":[4,5,6],"real":9,"realli":[8,9],"receiv":[0,6,8,9],"receive_byt":9,"receive_incom":6,"receive_json":9,"receive_text":[8,9],"recommend":9,"reconnect":9,"redirect":[0,2,6],"redoc":[0,9],"reduc":2,"ref":3,"refactor":[2,8],"refer":[3,8],"reflect":3,"refus":9,"regist":[0,8,9],"regular":3,"reject":[8,9],"relat":9,"releas":7,"reliabl":8,"remain":9,"remot":5,"remov":9,"renam":8,"render":[0,1,4,5,9],"render_async":6,"replac":[2,6,9],"report":[6,8,9],"repres":0,"represent":0,"req":[0,5,6,8,9],"request":[2,3,4,5],"request_id":[0,9],"request_model":[0,8,9],"requir":[2,8,9],"research":5,"resolv":[2,9],"resolve_hello":[0,9],"resourc":[6,9],"resp":[0,2,5,6,8,9],"respond":[0,2,4,6,7,8,9],"respons":[3,5,8,9],"response_model":[0,9],"rest":[4,5,9],"restrict":9,"result":9,"resum":2,"resume_incomplet":2,"retri":[0,9],"retriev":9,"return":[0,2,5,6,8,9],"revers":5,"rfc3986":2,"right":[5,6,9],"rout":[0,2,5,8],"router":2,"ruff":7,"run":[0,2,3,5,7,8,9],"runner":4,"s3":3,"safe":2,"sai":6,"said":4,"same":[4,5,6,9],"sandbox":5,"sat":3,"scale":5,"schema":[0,2,5,9],"scope":[0,9],"scratch":5,"search":[0,2,6,9],"second":3,"secret":9,"secret_kei":[0,9],"section":[3,9],"secur":9,"see":[3,4,6,8,9],"select":[0,2,3],"self":[0,9],"semant":2,"send":[0,2,5,8,9],"send_byt":9,"send_json":9,"send_text":[8,9],"sent":[0,5,6],"separ":[6,8],"sequenti":2,"serial":[6,9],"serializ":6,"serv":[0,2,4,5,6,8],"server":[0,2,3,4,5,8],"servestat":2,"servic":[3,5,8,9],"session":[0,2,5,6,8],"session_id":9,"set":[0,2,4,5,6,7,8,9],"set_cooki":[2,9],"set_text":0,"setup":[2,8],"sever":9,"sftp":3,"share":[0,5,6,8,9],"short":[1,5,9],"should":5,"shouldn":0,"show":[2,9],"shut":9,"shutdown":[0,4,5,8,9],"shutdwown":2,"side":[6,9],"sign":[5,6,9],"signatur":[6,9],"simpl":[8,9],"simplecooki":0,"simpler":[5,6,9],"simplest":6,"simul":6,"sinc":[6,8],"singl":[2,3,5,6,9],"size":0,"skip":9,"slash":6,"sleep":[6,8],"slim":4,"slow":6,"slowlori":4,"slug":6,"small":[4,5,8,9],"smaller":4,"smb":3,"so":[3,8,9],"solv":9,"some":[4,9],"someon":[6,9],"someth":[5,6,8,9],"sometim":[6,9],"somewher":6,"sourc":[0,7,9],"spawn":4,"spec":[6,9],"special":9,"specif":[0,3,8,9],"specifi":3,"sphinx":7,"spin":6,"sse":[0,5],"ssh":3,"ssl":4,"stabil":2,"standard":[4,5,9],"starlett":[0,2,5,8],"start":[4,5,9],"startup":[0,2,5,8,9],"state":[0,2,8,9],"statement":5,"static":[0,2,4,5,6],"static_dir":[0,9],"static_rout":[0,2,9],"statu":[0,2,6,8,9],"status_cod":[0,5,6,8,9],"stdlib":2,"still":9,"stop":9,"storag":3,"store":[0,3,9],"str":[0,6,8,9],"straightforward":9,"stranger":[0,9],"stream":[0,2,9],"stream_fil":[0,9],"strict":9,"string":[0,5,6,9],"strip":9,"structur":9,"style":9,"stylesheet":9,"subcommand":3,"subrout":[5,9],"subsequ":9,"subtl":2,"success":6,"successor":4,"suit":8,"suppli":2,"support":[0,1,2,3,4,5,6],"surpris":3,"suspect":5,"swagger":[5,9],"swagger_ui":[0,9],"switch":2,"symbol":3,"sync":[2,5,6],"syntax":[5,6],"synthet":3,"system":[3,6,9],"t":[0,3,4,6,8,9],"take":[5,6],"tamper":9,"target":[2,3],"task":[2,5],"tear":9,"tell":[6,9],"templat":[0,1,2,5],"template_str":[0,6],"templates_dir":0,"termin":4,"terms_of_servic":0,"test":[0,2,5,7],"test_500":[2,8],"test_api":8,"test_create_item":8,"test_custom_error":8,"test_head":8,"test_hello":8,"test_hook":8,"test_json":8,"test_upload":8,"test_valid":8,"test_websocket":8,"test_with_lifespan":8,"testclient":[0,2,8],"text":[0,3,5,6,8,9],"than":[3,8,9],"thei":[6,9],"them":[5,6,8,9],"theme":[0,9],"themselv":9,"thi":[0,2,3,4,6,8,9],"thing":[6,8],"think":6,"those":3,"though":4,"thousand":4,"thread":[5,6],"threadpoolexecutor":2,"three":[6,9],"through":[6,9],"throughput":9,"time":[0,3,5,6,8,9],"time_start":0,"timeout":4,"tip":5,"titl":[0,6,9],"tl":4,"togeth":[5,9],"token":[6,9],"toml":2,"too":[4,8,9],"tool":7,"toolbelt":2,"total":9,"tour":5,"trace":9,"traceback":[2,9],"tradit":9,"traffic":4,"transfer":3,"transport":9,"treat":[0,9],"trick":9,"trigger":8,"true":[0,6,8,9],"trust":5,"trustedhostmiddlewar":4,"tupl":[0,6,8],"two":[6,9],"type":[0,2,3,5,9],"typic":[3,6,9],"typo":[2,9],"ui":[2,5,9],"unauthor":9,"under":[6,9],"understand":6,"unicod":0,"uniqu":9,"unknown":0,"unless":9,"unlik":9,"unmaintain":2,"unmatch":9,"unpin":2,"unrecogn":9,"until":6,"up":[0,2,6,7,9],"updat":[2,6,9],"upgrad":[2,7,9],"upload":[2,5,6],"url":[0,2,3,5,6,8,9],"url_for":[0,8],"urllib":2,"us":[0,2,3,4,5,6,9],"usag":[0,2],"user":[0,3,6,9],"user_id":[6,9],"usernam":9,"usual":[5,8],"utf":[0,3],"util":5,"uuid":[0,6,9],"uuid4":0,"uv":[3,5,7],"uvicorn":[0,2,3,5,6],"uvloop":4,"v1":[0,9],"v2":9,"valid":[3,5,6,9],"valu":[0,5,6,8,9],"valueerror":[0,8,9],"variabl":[0,4,6],"ve":[5,8],"venv":7,"verb":9,"veri":[0,6],"verifi":8,"version":[0,2,3,8,9],"via":[2,9],"view":[0,2,5,6,8],"virtual":4,"virtualenv":7,"visit":9,"vue":9,"w":[8,9],"wa":[0,2,6],"wai":[4,6,9],"walk":[6,9],"want":[0,4,5,6,8,9],"watch":7,"web":[3,4,5,9],"webdav":3,"websit":9,"websocket":[0,1,2,4,5],"websocket_connect":8,"well":5,"went":5,"wget":3,"what":[6,8,9],"whatev":6,"when":[2,3,4,5,6,8,9],"where":[3,4,6,9],"whether":[0,6],"which":[2,3,6,8,9],"whichev":5,"while":[6,9],"whitenois":2,"who":[5,6],"widget":8,"wildcard":9,"window":2,"wire":6,"within":[2,3],"without":[0,4,6,8,9],"won":[6,8,9],"work":[3,4,5,6,9],"workdir":4,"worker":4,"workgroup":3,"world":[0,3,5,8,9],"worri":8,"would":[3,8],"wrap":[6,8,9],"write":[6,9],"wrong":9,"wsgi":[0,2,4,5,9],"x":[0,4,6,8,9],"x89png":6,"xml":0,"xss":9,"yaml":[0,2,5,6,8,9],"yield":[0,9],"yml":[0,9],"you":[0,3,4,6,8,9],"your":[3,4,6,8,9],"yourself":6,"zero":4},"titles":["API Documentation","Backlog","Changelog","Responder CLI","Deployment","Responder","Quick Start","Development Sandbox","Testing","Feature Tour"],"titleterms":{"0":2,"01":2,"02":2,"03":2,"04":2,"08":2,"09":2,"1":2,"10":2,"11":2,"12":2,"13":2,"15":2,"16":2,"17":2,"18":2,"19":2,"2":2,"20":2,"2018":2,"2019":2,"2026":2,"22":2,"23":2,"24":2,"25":2,"26":2,"27":2,"28":2,"29":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":2,"9":2,"The":5,"ad":2,"after":[8,9],"api":[0,8],"app":9,"applic":3,"background":6,"backlog":1,"base":9,"befor":[8,9],"build":3,"chang":2,"changelog":2,"class":[0,9],"cli":3,"cloud":4,"convertor":6,"cooki":[8,9],"cor":9,"creat":6,"custom":9,"deploy":4,"deprec":2,"develop":7,"directli":4,"docker":4,"document":[0,9],"entrypoint":3,"error":[8,9],"event":[8,9],"featur":9,"file":[3,8,9],"filter":9,"fix":2,"fixtur":8,"function":0,"futur":1,"get":[5,8],"graphql":9,"group":9,"guid":5,"handl":[8,9],"header":8,"hello":6,"hook":[8,9],"host":9,"hst":9,"id":9,"idea":[1,5],"instal":5,"instanc":3,"javascript":3,"json":8,"launch":3,"lifespan":[8,9],"limit":9,"local":[3,4],"messagepack":9,"method":9,"modul":3,"mount":9,"name":3,"non":3,"openapi":9,"oper":7,"other":9,"paramet":6,"platform":4,"project":5,"proxi":4,"quick":6,"rate":9,"read":6,"remot":3,"remov":2,"render":6,"request":[0,6,8,9],"respond":[3,5],"respons":[0,6],"revers":4,"rout":[6,9],"run":[4,6],"sandbox":7,"send":6,"sent":9,"serv":9,"server":[6,9],"servic":[0,6],"session":9,"setup":7,"sse":9,"standard":3,"start":[6,8],"static":9,"support":9,"task":6,"templat":6,"test":8,"tip":8,"tour":9,"trust":9,"type":6,"unreleas":2,"upload":8,"us":8,"user":5,"util":0,"uvicorn":4,"v0":2,"v1":2,"v2":2,"v3":2,"valid":8,"view":9,"web":[0,6],"websocket":[8,9],"what":5,"world":6,"you":5}})
\ No newline at end of file
diff --git a/testing.html b/testing.html
index f146d38..af5c29c 100644
--- a/testing.html
+++ b/testing.html
@@ -303,7 +303,7 @@ network overhead. Avoid API() configuration (like cors=True), create a new instance
in the test rather than sharing the fixture.
-
Use ``api.url_for()`` instead of hard-coded paths. It’s a small
+
Use api.url_for() instead of hard-coded paths. It’s a small
thing, but it makes refactoring painless.
Test the contract, not the implementation. Assert on status codes,
response bodies, and headers — not on internal state.
diff --git a/tour.html b/tour.html
index 920ae01..37d5e51 100644
--- a/tour.html
+++ b/tour.html
@@ -42,12 +42,24 @@
Feature Tour¶
-This section walks through Responder’s features in detail. Each section
-includes working code examples you can copy into your application.
+This section walks through Responder’s features in depth. Each section
+explains the concept, shows working code, and explains the design choices
+behind it. If you’re new to web development, this is a good place to learn
+how modern web frameworks work under the hood.
Method Filtering¶
-By default, a route matches all HTTP methods. If you want to restrict a
-route to specific methods, pass the methods parameter:
+HTTP defines several methods (also called verbs) that describe what a
+client wants to do with a resource. The most common are:
+
+GET — retrieve data
+POST — create something new
+PUT — replace something entirely
+PATCH — update part of something
+DELETE — remove something
+
+By default, a Responder route matches all methods. This is fine for simple
+endpoints, but REST APIs typically map different methods to different
+operations. Use the methods parameter to restrict a route:
@api.route("/items", methods=["GET"])
def list_items(req, resp):
resp.media = {"items": []}
@@ -58,13 +70,19 @@ route to specific methods, pass the <
resp.media = {"created": data}
-Note the check_existing=False — this allows you to register multiple
-handlers for the same path with different methods.
+Note the check_existing=False — Responder normally prevents you from
+registering two routes with the same path (to catch typos). When you
+intentionally want multiple handlers for the same path with different
+methods, you need to opt in.
Class-Based Views¶
-For more complex resources, you can use class-based views. Responder will
-dispatch to the appropriate method handler based on the HTTP method:
+Function-based views are great for simple endpoints, but sometimes you want
+to group related HTTP methods together into a single resource. This is
+where class-based views come in — a pattern popularized by
+Falcon.
+Responder dispatches to the appropriate method handler based on the HTTP
+method:
@api.route("/{greeting}")
class GreetingResource:
def on_get(self, req, resp, *, greeting):
@@ -81,13 +99,17 @@ dispatch to the appropriate method handler based on the HTTP method:
The on_request method is called for all HTTP methods, much like
middleware scoped to a single route. Method-specific handlers (on_get,
on_post, on_put, on_delete, etc.) are called after.
-No inheritance required — just define a class with the right method names.
+No inheritance required — just define a class with the right method names.
+This is simpler than Django’s View classes and more Pythonic than
+framework-specific base classes.
Lifespan Events¶
-Modern applications often need to set up resources on startup (database
-connections, caches, ML models) and tear them down on shutdown. Responder
-supports the lifespan context manager pattern:
+Real applications need to set up resources when they start (database
+connection pools, ML models, caches) and tear them down when they stop.
+This is called the application lifespan.
+The modern approach is the context manager pattern, where startup and
+shutdown are two halves of the same block:
from contextlib import asynccontextmanager
@asynccontextmanager
@@ -101,7 +123,10 @@ supports the lifespan context manager pattern:
api = responder.API(lifespan=lifespan)
-You can also use the traditional event decorator style:
+Everything before yield runs at startup. Everything after runs at
+shutdown. If startup fails, the server won’t start. If shutdown raises,
+it’s logged but the server still exits.
+The traditional event decorator style also works:
@api.on_event("startup")
async def startup():
print("starting up")
@@ -111,52 +136,65 @@ supports the lifespan context manager pattern:
print("shutting down")
-The context manager approach is preferred for new code — it makes the
-startup/shutdown relationship explicit and keeps related code together.
+The context manager is preferred for new code — it keeps related startup
+and shutdown logic together and makes resource cleanup more explicit.
Serving Files¶
-Serve files from disk with automatic content-type detection. Responder
-uses Python’s mimetypes module to figure out the right Content-Type
-header for you:
+Web applications often need to serve files — downloads, reports, images.
+Responder makes this simple with resp.file(), which reads a file from
+disk and sets the Content-Type header automatically using Python’s
+mimetypes module:
@api.route("/download")
def download(req, resp):
resp.file("reports/annual.pdf")
-You can override the content type if needed:
+You can override the content type if the automatic detection isn’t right:
@api.route("/image")
def image(req, resp):
resp.file("photos/cat.jpg", content_type="image/jpeg")
+For large files, use resp.stream_file() to avoid loading the entire
+file into memory. This streams the file in chunks:
+@api.route("/export")
+def export(req, resp):
+ resp.stream_file("data/export.csv")
+
+
Custom Error Handling¶
-By default, unhandled exceptions result in a 500 Internal Server Error.
-You can register custom handlers for specific exception types to return
-structured error responses:
+In production, you don’t want your users to see raw Python tracebacks.
+Responder lets you register custom handlers for specific exception types,
+so you can return clean, structured error responses:
@api.exception_handler(ValueError)
async def handle_value_error(req, resp, exc):
resp.status_code = 400
resp.media = {"error": str(exc)}
-Now, any route that raises a ValueError will return a clean 400 response
-with a JSON error message instead of a generic 500 page.
+Now, any route that raises a ValueError will return a clean JSON
+response with a 400 status code instead of a generic 500 error page.
+This is a common pattern in API development — you define your own exception
+classes for different error conditions, register handlers for each, and
+your API always returns consistent, machine-readable error responses.
Before-Request Hooks¶
-Run code before every request. This is useful for logging, adding common
-headers, or setting up per-request state:
+Sometimes you need to run the same code before every request —
+authentication checks, request logging, adding common headers, or setting
+up per-request state. Before-request hooks let you do this without
+duplicating code in every route:
@api.route(before_request=True)
def add_headers(req, resp):
- resp.headers["X-API-Version"] = "3.1"
+ resp.headers["X-API-Version"] = "3.2"
-Short-circuiting: If your hook sets resp.status_code, the route
-handler will be skipped entirely and the response will be sent immediately.
-This is the pattern for authentication guards:
+Short-circuiting is the really powerful part. If your hook sets
+resp.status_code, the route handler is skipped entirely and the
+response is sent immediately. This is the pattern for authentication:
@api.route(before_request=True)
def auth_check(req, resp):
if "Authorization" not in req.headers:
@@ -165,17 +203,32 @@ This is the pattern for authentication guards:
If the Authorization header is missing, the client gets a 401 response
-and the actual route handler never runs.
-WebSocket hooks work the same way:
-@api.before_request(websocket=True)
-async def ws_auth(ws):
- await ws.accept()
+and the actual route handler never runs. This is cleaner than adding
+auth checks to every individual route.
+
+
+After-Request Hooks¶
+The complement to before-request hooks. After-request hooks run after the
+route handler completes but before the response is sent. They’re useful
+for logging, adding response headers, or any post-processing:
+@api.after_request()
+def log_response(req, resp):
+ print(f"{req.method} {req.full_url} -> {resp.status_code}")
+
+@api.after_request()
+async def add_timing(req, resp):
+ resp.headers["X-Served-By"] = "responder"
WebSocket Support¶
-Responder supports WebSockets for real-time, bidirectional communication:
+HTTP is a request-response protocol — the client asks, the server answers.
+But some applications need real-time, bidirectional communication: chat
+apps, live dashboards, multiplayer games, collaborative editors.
+WebSockets solve this by
+upgrading an HTTP connection into a persistent, full-duplex channel where
+both sides can send messages at any time:
@api.route("/ws", websocket=True)
async def websocket(ws):
await ws.accept()
@@ -187,13 +240,49 @@ and the actual route handler never runs.
You can send and receive in multiple formats:
-send_text / receive_text — plain text
-send_json / receive_json — JSON objects
+send_text / receive_text — plain text strings
+send_json / receive_json — JSON objects (auto-serialized)
send_bytes / receive_bytes — raw binary data
+WebSocket routes are marked with websocket=True in the route decorator.
+They receive a ws object instead of req and resp.
+
+
+Server-Sent Events (SSE)¶
+SSE is a simpler alternative to WebSockets for one-way real-time
+communication — the server pushes events to the client, but the client
+can’t send messages back. This is perfect for live feeds, progress bars,
+notification streams, and AI response streaming.
+Unlike WebSockets, SSE works over plain HTTP, is automatically reconnected
+by the browser, and doesn’t require any special client-side libraries:
+@api.route("/events")
+async def events(req, resp):
+ @resp.sse
+ async def stream():
+ for i in range(10):
+ yield {"data": f"message {i}"}
+
+
+On the client side, you consume SSE events with JavaScript’s built-in
+EventSource API:
+const source = new EventSource("/events");
+source.onmessage = (event) => {
+ console.log(event.data);
+};
+
+
+Each yielded value can be a string (treated as data) or a dict with the
+standard SSE fields:
+yield {"event": "update", "data": "hello", "id": "1", "retry": "5000"}
+yield "simple string message"
+
+
GraphQL¶
+GraphQL is a query language for APIs that lets
+clients request exactly the data they need — no more, no less. Instead of
+multiple REST endpoints, you define a schema and let clients query it.
Responder includes built-in GraphQL support via
Graphene. Set up a full GraphQL endpoint
with a single method call:
@@ -208,16 +297,20 @@ with a single method call:
api.graphql("/graphql", schema=graphene.Schema(query=Query))
-Visiting /graphql in a browser renders the GraphiQL interactive IDE,
-where you can explore your schema and test queries. Programmatic clients
-can POST JSON queries to the same endpoint.
+Visiting /graphql in a browser renders the
+GraphiQL interactive IDE, where
+you can explore your schema, write queries, and see results in real-time.
+Programmatic clients can POST JSON queries to the same endpoint.
You can access the Responder request and response objects in your resolvers
through info.context["request"] and info.context["response"].
OpenAPI Documentation¶
-Responder can generate an OpenAPI schema and serve interactive API
-documentation automatically:
+OpenAPI (formerly Swagger) is the industry
+standard for describing REST APIs. An OpenAPI specification lets you
+auto-generate interactive documentation, client libraries, and validation
+logic.
+Responder generates OpenAPI specs from your code:
api = responder.API(
title="Pet Store",
version="1.0",
@@ -232,9 +325,11 @@ documentation automatically:
Interactive Swagger UI documentation at /docs
There are three ways to document your endpoints.
-Pydantic models — the recommended approach for new APIs. Use
-request_model and response_model to annotate your routes, and
-Responder will generate the schema automatically:
+Pydantic models — the recommended approach. Use request_model and
+response_model to annotate your routes, and Responder generates the
+schema automatically. When request_model is set, request bodies are
+also validated automatically — invalid inputs get a 422 response with
+detailed error messages:
from pydantic import BaseModel
class PetIn(BaseModel):
@@ -253,18 +348,10 @@ Responder will generate the schema automatically:
resp.media = {"id": 1, **data}
-This generates a full OpenAPI path with requestBody and responses
-schemas, all linked by $ref to your Pydantic models in
-components/schemas.
-You can also register standalone schemas with the @api.schema decorator:
-@api.schema("Pet")
-class Pet(BaseModel):
- name: str
- age: int = 0
-
-
-YAML docstrings — inline your OpenAPI spec directly in the docstring.
-This gives you full control over every detail:
+When response_model is set, the response is serialized through the
+model — extra fields are stripped and types are enforced.
+YAML docstrings — for full control, embed OpenAPI YAML in the
+docstring:
@api.route("/pets")
def list_pets(req, resp):
"""A list of pets.
@@ -278,8 +365,7 @@ This gives you full control over every detail:
resp.media = [{"name": "Fido"}]
-Marshmallow schemas — if you’re already using marshmallow for
-validation, Responder integrates with it via the apispec plugin:
+Marshmallow schemas — if you’re already using marshmallow:
from marshmallow import Schema, fields
@api.schema("Pet")
@@ -287,16 +373,39 @@ validation, Responder integrates with it via the apispec plugin:
name = fields.Str()
-All three approaches can be mixed in the same API. Pydantic models,
-marshmallow schemas, and YAML docstrings all contribute to the same
-generated OpenAPI specification.
-You can choose from multiple documentation themes:
-swagger_ui (default), redoc, rapidoc, or elements.
+All three approaches can be mixed in the same API. You can choose from
+multiple documentation themes: swagger_ui (default), redoc,
+rapidoc, or elements.
+
+
+Route Groups¶
+As your application grows, you’ll want to organize routes logically.
+Route groups let you share a URL prefix across related endpoints — a
+common pattern for API versioning:
+v1 = api.group("/v1")
+
+@v1.route("/users")
+def list_users(req, resp):
+ resp.media = []
+
+@v1.route("/users/{user_id:int}")
+def get_user(req, resp, *, user_id):
+ resp.media = {"id": user_id}
+
+v2 = api.group("/v2")
+
+@v2.route("/users")
+def list_users_v2(req, resp):
+ resp.media = {"users": [], "total": 0}
+
+
+This keeps your code organized without affecting the routing logic.
Mounting Other Apps¶
-Responder can mount any WSGI or ASGI application at a subroute. This means
-you can gradually migrate from Flask, or run multiple frameworks side by side:
+Responder can mount any WSGI or ASGI application at a subroute. This is
+incredibly useful for gradual migrations — you can run Flask and Responder
+side by side, moving routes over one at a time:
from flask import Flask
flask_app = Flask(__name__)
@@ -310,10 +419,14 @@ you can gradually migrate from Flask, or run multiple frameworks side by side:
Requests to /flask/ will be handled by Flask. Everything else goes
through Responder. Both WSGI and ASGI apps are supported — Responder
-wraps WSGI apps automatically.
+wraps WSGI apps in an ASGI adapter automatically.