mirror of
https://github.com/kennethreitz/responder.git
synced 2026-10-24 05:59:12 +00:00
281 lines
20 KiB
HTML
281 lines
20 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="./">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<title>Migrating to Responder 5.0 — responder 9.2.0 documentation</title>
|
||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
|
||
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
|
||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=eb4102c5" />
|
||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
|
||
<link rel="stylesheet" type="text/css" href="_static/sphinx-design.min.css?v=95c83b7e" />
|
||
<link rel="stylesheet" type="text/css" href="_static/design-elements.e5416f61bae5d36adc6d722a2b6f8cff.css?v=452a8e97" />
|
||
<script src="_static/documentation_options.js?v=e8b940be"></script>
|
||
<script src="_static/doctools.js?v=fd6eb6e6"></script>
|
||
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
|
||
<script src="_static/clipboard.min.js?v=a7894cd8"></script>
|
||
<script src="_static/copybutton.js?v=fd10adb8"></script>
|
||
<script>
|
||
</script>
|
||
<script src="_static/design-tabs.js?v=f930bc37"></script>
|
||
<script src="_static/design-elements.bbdccc18c4abea9397628f9fea3d48c2.js?v=03c7770e"></script>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="next" title="Development Sandbox" href="sandbox.html" />
|
||
<link rel="prev" title="Migrating to Responder 6.0" href="migration-v6.html" />
|
||
|
||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||
|
||
|
||
|
||
|
||
|
||
</head><body>
|
||
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
|
||
|
||
<div class="body" role="main">
|
||
|
||
<section id="migrating-to-responder-5-0">
|
||
<h1>Migrating to Responder 5.0<a class="headerlink" href="#migrating-to-responder-5-0" title="Link to this heading">¶</a></h1>
|
||
<p>Responder 5 layers fully type-driven request/response I/O, composable dependency
|
||
injection, plan-driven OpenAPI, secure-by-default sessions, and a deferred
|
||
middleware stack onto the unchanged <code class="docutils literal notranslate"><span class="pre">(req,</span> <span class="pre">resp)</span></code> core. The new typed features
|
||
are <strong>additive sugar</strong> — your existing handlers keep working — but v5 makes a
|
||
handful of deliberate breaking changes, listed here with the one-line fix.</p>
|
||
<section id="sessions">
|
||
<h2>Sessions<a class="headerlink" href="#sessions" title="Link to this heading">¶</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Change</p></th>
|
||
<th class="head"><p>What to do</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">secret_key</span></code> no longer defaults to the public <code class="docutils literal notranslate"><span class="pre">"NOTASECRET"</span></code>; <code class="docutils literal notranslate"><span class="pre">API()</span></code> mints a random per-process key</p></td>
|
||
<td><p>Set <code class="docutils literal notranslate"><span class="pre">API(secret_key=…)</span></code> or the <code class="docutils literal notranslate"><span class="pre">RESPONDER_SECRET_KEY</span></code> env var for stable, multi-worker sessions (a startup warning fires until you do).</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">API(secret_key="NOTASECRET")</span></code> raises <code class="docutils literal notranslate"><span class="pre">SessionConfigError</span></code></p></td>
|
||
<td><p>Generate a real key: <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-c</span> <span class="pre">"import</span> <span class="pre">secrets;</span> <span class="pre">print(secrets.token_urlsafe(32))"</span></code>.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>Session cookies are <code class="docutils literal notranslate"><span class="pre">Secure</span></code> by default in production</p></td>
|
||
<td><p>No action behind a TLS proxy; pass <code class="docutils literal notranslate"><span class="pre">session_https_only=False</span></code> only if you genuinely serve plain HTTP (e.g. local dev, tests).</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">req.session</span></code> / <code class="docutils literal notranslate"><span class="pre">resp.session</span></code> raise <code class="docutils literal notranslate"><span class="pre">RuntimeError</span></code> when <code class="docutils literal notranslate"><span class="pre">sessions=False</span></code></p></td>
|
||
<td><p>Re-enable sessions, or stop reading the session under the explicit opt-out.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">sessions=True</span></code> with no key raises</p></td>
|
||
<td><p>Provide a key, or use <code class="docutils literal notranslate"><span class="pre">sessions="auto"</span></code> (the default) to auto-generate an ephemeral one.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Server-side sessions now slide their TTL via <code class="docutils literal notranslate"><span class="pre">touch</span></code>/<code class="docutils literal notranslate"><span class="pre">atouch</span></code> on read-only
|
||
requests (no behavior change for you; implement <code class="docutils literal notranslate"><span class="pre">touch</span></code> on a custom backend for
|
||
the cheaper path).</p>
|
||
</section>
|
||
<section id="req-method-is-uppercase">
|
||
<h2><code class="docutils literal notranslate"><span class="pre">req.method</span></code> is uppercase<a class="headerlink" href="#req-method-is-uppercase" title="Link to this heading">¶</a></h2>
|
||
<p><code class="docutils literal notranslate"><span class="pre">req.method</span></code> now returns <code class="docutils literal notranslate"><span class="pre">"GET"</span></code>, not <code class="docutils literal notranslate"><span class="pre">"get"</span></code> (matching Flask/FastAPI/Starlette).
|
||
For one deprecation cycle it compares case-insensitively, so <code class="docutils literal notranslate"><span class="pre">req.method</span> <span class="pre">==</span> <span class="pre">"get"</span></code>
|
||
keeps working <strong>with a <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></strong>. Uppercase your literals.</p>
|
||
<p>Hash-based membership is the one thing the shim can’t save: <code class="docutils literal notranslate"><span class="pre">req.method</span> <span class="pre">in</span> <span class="pre">{"get"}</span></code>
|
||
and <code class="docutils literal notranslate"><span class="pre">{"get":</span> <span class="pre">…}[req.method]</span></code> miss silently — use <code class="docutils literal notranslate"><span class="pre">==</span></code>, a tuple/list, or
|
||
uppercase keys.</p>
|
||
</section>
|
||
<section id="middleware-errors">
|
||
<h2>Middleware & errors<a class="headerlink" href="#middleware-errors" title="Link to this heading">¶</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Change</p></th>
|
||
<th class="head"><p>What to do</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">API.app</span></code> is a lazily-built read-only property, not a writable attribute</p></td>
|
||
<td><p>Mutate via <code class="docutils literal notranslate"><span class="pre">api.add_middleware(Cls,</span> <span class="pre">**opts)</span></code> (now valid post-construction), or wrap the API object: <code class="docutils literal notranslate"><span class="pre">asgi</span> <span class="pre">=</span> <span class="pre">MyMiddleware(api)</span></code>.</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>User middleware now sits inside <code class="docutils literal notranslate"><span class="pre">ServerErrorMiddleware</span></code></p></td>
|
||
<td><p>Its exceptions are now caught and rendered as <code class="docutils literal notranslate"><span class="pre">500</span></code>s. To wrap <em>everything</em>, wrap the API object instead of <code class="docutils literal notranslate"><span class="pre">add_middleware</span></code>.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>Session writes are not persisted on an unhandled <code class="docutils literal notranslate"><span class="pre">500</span></code></p></td>
|
||
<td><p>Persist explicitly before raising if you need it.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><code class="docutils literal notranslate"><span class="pre">X-Request-ID</span></code> now appears on error/<code class="docutils literal notranslate"><span class="pre">500</span></code> responses too, and
|
||
<code class="docutils literal notranslate"><span class="pre">api.add_exception_handler(exc_or_status,</span> <span class="pre">handler)</span></code> is now a first-class method.</p>
|
||
</section>
|
||
<section id="typed-handler-i-o">
|
||
<h2>Typed handler I/O<a class="headerlink" href="#typed-handler-i-o" title="Link to this heading">¶</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Change</p></th>
|
||
<th class="head"><p>What to do</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>A Pydantic return annotation (<code class="docutils literal notranslate"><span class="pre">-></span> <span class="pre">Model</span></code>) is now honored as <code class="docutils literal notranslate"><span class="pre">response_model</span></code></p></td>
|
||
<td><p>Make the returned dict conform, or pass <code class="docutils literal notranslate"><span class="pre">@api.route(...,</span> <span class="pre">response_model=False)</span></code> <em>(if you don’t want validation)</em>.</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>A body-model parameter beats a same-named dependency</p></td>
|
||
<td><p>Rename the dependency, or give the parameter a default.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">Query</span></code>/<code class="docutils literal notranslate"><span class="pre">Header</span></code>/<code class="docutils literal notranslate"><span class="pre">Cookie</span></code>/<code class="docutils literal notranslate"><span class="pre">Path</span></code> are reserved top-level names</p></td>
|
||
<td><p>Only affects <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">responder</span> <span class="pre">import</span> <span class="pre">*</span></code>; explicit imports are unaffected.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>New: <code class="docutils literal notranslate"><span class="pre">def</span> <span class="pre">search(req,</span> <span class="pre">resp,</span> <span class="pre">*,</span> <span class="pre">q:</span> <span class="pre">str</span> <span class="pre">=</span> <span class="pre">Query(...),</span> <span class="pre">token:</span> <span class="pre">str</span> <span class="pre">=</span> <span class="pre">Header(None))</span></code>
|
||
injects validated query params, headers, cookies, and path params.</p>
|
||
</section>
|
||
<section id="dependency-injection">
|
||
<h2>Dependency injection<a class="headerlink" href="#dependency-injection" title="Link to this heading">¶</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Change</p></th>
|
||
<th class="head"><p>What to do</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>A provider receives the request only via a <code class="docutils literal notranslate"><span class="pre">req</span></code>/<code class="docutils literal notranslate"><span class="pre">request</span></code> parameter or a <code class="docutils literal notranslate"><span class="pre">Request</span></code>/<code class="docutils literal notranslate"><span class="pre">WebSocket</span></code> annotation</p></td>
|
||
<td><p>Rename a nonstandard request parameter to <code class="docutils literal notranslate"><span class="pre">req</span></code>, or annotate it <code class="docutils literal notranslate"><span class="pre">Request</span></code>. A sole-unnamed-param provider still works for one cycle (with a <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code>).</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">req</span></code>/<code class="docutils literal notranslate"><span class="pre">request</span></code>/<code class="docutils literal notranslate"><span class="pre">resp</span></code>/<code class="docutils literal notranslate"><span class="pre">response</span></code>/<code class="docutils literal notranslate"><span class="pre">ws</span></code>/<code class="docutils literal notranslate"><span class="pre">websocket</span></code> are reserved dependency names</p></td>
|
||
<td><p>Rename any dependency registered under these.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>Misconfigured graphs raise <code class="docutils literal notranslate"><span class="pre">DependencyError</span></code> subclasses</p></td>
|
||
<td><p>Cycles, unknown params, and scope violations now surface as <code class="docutils literal notranslate"><span class="pre">DependencyCycleError</span></code> / <code class="docutils literal notranslate"><span class="pre">DependencyResolutionError</span></code> / <code class="docutils literal notranslate"><span class="pre">DependencyScopeError</span></code>.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>New: a provider can depend on other providers (recursive, memoized,
|
||
reverse-topological teardown, cycle detection).</p>
|
||
</section>
|
||
<section id="openapi">
|
||
<h2>OpenAPI<a class="headerlink" href="#openapi" title="Link to this heading">¶</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Change</p></th>
|
||
<th class="head"><p>What to do</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>Routes without a docstring/model now appear in the schema</p></td>
|
||
<td><p>Pass <code class="docutils literal notranslate"><span class="pre">@api.route(...,</span> <span class="pre">include_in_schema=False)</span></code> to hide a route (schema/docs/static/metrics are auto-excluded).</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>Docstring YAML is deep-merged onto a generated base</p></td>
|
||
<td><p>Fully-specified docstrings are unaffected; the generated parameters/request/response are added underneath.</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>The spec is now generated from each route’s methods, models, and
|
||
<code class="docutils literal notranslate"><span class="pre">Query</span></code>/<code class="docutils literal notranslate"><span class="pre">Header</span></code>/<code class="docutils literal notranslate"><span class="pre">Cookie</span></code> markers, with an automatic <code class="docutils literal notranslate"><span class="pre">422</span></code> for validating routes.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
||
<div class="sphinxsidebarwrapper"><p class="logo">
|
||
<a href="index.html">
|
||
<img class="logo" src="_static/responder.png" />
|
||
</a>
|
||
</p>
|
||
<p>
|
||
<strong>Responder</strong> — a familiar HTTP service framework for Python.
|
||
<br />
|
||
<small>v9.2.0</small>
|
||
</p>
|
||
<h3>Useful Links</h3>
|
||
<ul>
|
||
<li><a href="https://github.com/kennethreitz/responder">Responder @ GitHub</a></li>
|
||
<li><a href="https://pypi.org/project/responder/">Responder @ PyPI</a></li>
|
||
<li><a href="https://github.com/kennethreitz/responder/issues">Issue Tracker</a></li>
|
||
</ul><h3>Navigation</h3>
|
||
<p class="caption" role="heading"><span class="caption-text">User Guide</span></p>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="quickstart.html">Quick Start</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tour.html">Feature Tour</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="examples.html">Examples</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="routers.html">Composing Apps with Routers</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="guide-config.html">Configuration</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="clientgen.html">Generated Clients</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="deployment.html">Deployment</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="testing.html">Testing</a></li>
|
||
</ul>
|
||
<p class="caption" role="heading"><span class="caption-text">Tutorials</span></p>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-rest.html">Building a REST API</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-sqlalchemy.html">Using SQLAlchemy</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-auth.html">Authentication</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-websockets.html">WebSocket Tutorial</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-middleware.html">Writing Middleware</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="tutorial-flask.html">Migrating from Flask</a></li>
|
||
</ul>
|
||
<p class="caption" role="heading"><span class="caption-text">Reference</span></p>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="api.html">API Reference</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command Line Interface</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="runtime-contracts.html">Runtime Contracts</a></li>
|
||
</ul>
|
||
<p class="caption" role="heading"><span class="caption-text">Project</span></p>
|
||
<ul class="current">
|
||
<li class="toctree-l1"><a class="reference internal" href="changes.html">Changelog</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="migration-v9.html">Migrating to v9</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="migration-v8.html">Migrating to v8</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="migration-v7.html">Migrating to v7</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="migration-v6.html">Migrating to v6</a></li>
|
||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Migrating to v5</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="sandbox.html">Sandbox</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="backlog.html">Backlog</a></li>
|
||
</ul>
|
||
|
||
<div class="relations">
|
||
<h3>Related Topics</h3>
|
||
<ul>
|
||
<li><a href="index.html">Documentation overview</a><ul>
|
||
<li>Previous: <a href="migration-v6.html" title="previous chapter">Migrating to Responder 6.0</a></li>
|
||
<li>Next: <a href="sandbox.html" title="next chapter">Development Sandbox</a></li>
|
||
</ul></li>
|
||
</ul>
|
||
</div>
|
||
<search id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</search>
|
||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="footer">
|
||
©2018-2026, Kenneth Reitz.
|
||
|
||
|
|
||
<a href="_sources/migration-v5.md.txt"
|
||
rel="nofollow">Page source</a>
|
||
</div>
|
||
|
||
|
||
<a href="https://github.com/kennethreitz/responder" class="github">
|
||
<img src="_static/forkme_right_darkblue.png" alt="Fork me on GitHub" class="github"/>
|
||
</a>
|
||
|
||
|
||
|
||
</body>
|
||
</html> |