feat(standards): codify codegen, ship generic Tier-B infra, add get_app_template + prompts; fix docs:// regressions

P0: fix doc:// -> docs:// across standards src/server/registry and regenerate stale mongo-ops bundle. P1: build recipe + spec-first routing now document the openapi-first codegen fast path (models/routes with --inject-request/--package). P4: CRUD template documents the model-vs-document id rule (BaseDocument owns id). P5: authless guidance (omit security keys). P6: template gains generic infra (http_cache, keyed SSE bus, KV port+in-memory+Redis), interfaces/openapi.py + .dockerignore + generic build test registered as components, and a get_app_template tool; genericity matrix marks LLM pool + human-in-loop as reference-app patterns. P7: intake/build/start_app/trial prompts. P8: template ships tests/integration/test_openapi_app_builds.py. Rebuilt standards + openapi-first bundles and re-collected.
This commit is contained in:
2026-10-13 03:26:51 +05:30
parent ef951a1913
commit fced40af59
109 changed files with 4082 additions and 5885 deletions

View File

@@ -761,7 +761,7 @@ that enforces OpenAPI as the single source of truth for a FastAPI service.</p>
Python handler function.
- Handlers are plain Python callables (no FastAPI decorators).
- FastAPI route registration is derived exclusively from the spec.
- FastAPI's autogenerated OpenAPI schema is fully overridden.
- FastAPI&#39;s autogenerated OpenAPI schema is fully overridden.
</code></pre></div></td></tr></table></div>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
@@ -924,7 +924,7 @@ handlers).</p>
- All routes are derived from the provided OpenAPI specification,
and each ``operationId`` is mapped to a Python function in the
supplied routes module.
- Auth dependencies are auto-injected from the spec's
- Auth dependencies are auto-injected from the spec&#39;s
``securitySchemes`` and per-operation ``security`` fields.
</code></pre></div></td></tr></table></div>
<p><strong>Guarantees:</strong></p>
@@ -955,9 +955,9 @@ handlers).</p>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="kn">import</span><span class="w"> </span><span class="nn">app.routes</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">routes</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="n">app</span> <span class="o">=</span> <span class="n">OpenAPIFirstApp</span><span class="p">(</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">"app/openapi.json"</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">&quot;app/openapi.json&quot;</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">routes_module</span><span class="o">=</span><span class="n">routes</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">"Example Service"</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;Example Service&quot;</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
</details>

View File

@@ -937,16 +937,16 @@ missing/duplicate, or required parameters are missing.</p>
<span class="normal"><a href="#__codelineno-0-15">15</a></span>
<span class="normal"><a href="#__codelineno-0-16">16</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first</span><span class="w"> </span><span class="kn">import</span> <span class="n">loader</span><span class="p">,</span> <span class="n">client</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_openapi</span><span class="p">(</span><span class="s2">"openapi.yaml"</span><span class="p">)</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_openapi</span><span class="p">(</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">)</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="n">api</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">OpenAPIClient</span><span class="p">(</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">spec</span><span class="o">=</span><span class="n">spec</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://localhost:8000"</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">base_url</span><span class="o">=</span><span class="s2">&quot;http://localhost:8000&quot;</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="c1"># Call operationId: getUser</span>
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="n">response</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">getUser</span><span class="p">(</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">path_params</span><span class="o">=</span><span class="p">{</span><span class="s2">"user_id"</span><span class="p">:</span> <span class="mi">123</span><span class="p">}</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">path_params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">123</span><span class="p">}</span>
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="p">)</span>
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14"></a>
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">)</span>

View File

@@ -762,21 +762,25 @@ definitions.</p>
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span>
<span class="normal"><a href="#__codelineno-0-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">spec_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">output_dir</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">*</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">use_models</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"models"</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;models&quot;</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">inject_request</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">package</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Generate route handler stubs from an OpenAPI specification.</p>
<p>Creates one <code>&lt;resource&gt;.py</code> file per resource in <em>output_dir</em>.
Resources are derived from the first path segment (e.g. <code>/pets</code>
and <code>/pets/{id}</code> both group under <code>pets</code>).</p>
<p>Creates one route module per resource in <em>output_dir</em>. Resources are
derived from the first path segment (e.g. <code>/pets</code> and <code>/pets/{id}</code>
both group under <code>pets</code>) and sanitized to valid module identifiers.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -849,6 +853,36 @@ for request-body schemas referenced via <code>$ref</code>.</p>
<code>&#39;models&#39;</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>inject_request</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, prepend <code>request: Request</code> to every handler so the
stub can later resolve services from <code>request.app.state</code>.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>package</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, emit <code>&lt;resource&gt;/routes.py</code> packages (each with an
<code>__init__.py</code>) instead of flat <code>&lt;resource&gt;.py</code> modules.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>

View File

@@ -641,19 +641,39 @@ must define an <code>operationId</code>, which becomes the handler function name
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Design constraints:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span>
<span class="normal">7</span></pre></div></td><td class="code"><div><pre><span></span><code>- ``operationId`` is required on every operation (matching
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span></pre></div></td><td class="code"><div><pre><span></span><code>- ``operationId`` is required on every operation (matching
``binder.bind_routes``).
- Handlers are stubs raising ``NotImplementedError``.
- Sub-resources (e.g. ``/pets/{id}/photo``) are grouped with their
parent resource (``pets``).
- Parameter types and defaults are inferred from the spec.
- ``response: Response`` is injected for non-200 success codes.
- Resource names are sanitized to valid Python module identifiers,
so a path such as ``/fetch-requests`` yields ``fetch_requests.py``.
- Passing ``inject_request=True`` prepends ``request: Request`` to
every handler (the composition-root / DI convention).
- ``multipart/form-data`` and
``application/x-www-form-urlencoded`` request bodies expand to one
parameter per schema property (``UploadFile`` / ``File`` / ``Form``)
instead of an opaque ``payload: dict``.
- Passing ``package=True`` writes ``&lt;resource&gt;/routes.py`` (with
``__init__.py`` sidecars) instead of a flat ``&lt;resource&gt;.py``.
</code></pre></div></td></tr></table></div>
</details>
@@ -682,21 +702,25 @@ must define an <code>operationId</code>, which becomes the handler function name
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span>
<span class="normal"><a href="#__codelineno-0-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">spec_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">output_dir</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">*</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">use_models</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"models"</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;models&quot;</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">inject_request</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">package</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Generate route handler stubs from an OpenAPI specification.</p>
<p>Creates one <code>&lt;resource&gt;.py</code> file per resource in <em>output_dir</em>.
Resources are derived from the first path segment (e.g. <code>/pets</code>
and <code>/pets/{id}</code> both group under <code>pets</code>).</p>
<p>Creates one route module per resource in <em>output_dir</em>. Resources are
derived from the first path segment (e.g. <code>/pets</code> and <code>/pets/{id}</code>
both group under <code>pets</code>) and sanitized to valid module identifiers.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -769,6 +793,36 @@ for request-body schemas referenced via <code>$ref</code>.</p>
<code>&#39;models&#39;</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>inject_request</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, prepend <code>request: Request</code> to every handler so the
stub can later resolve services from <code>request.app.state</code>.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>package</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, emit <code>&lt;resource&gt;/routes.py</code> packages (each with an
<code>__init__.py</code>) instead of flat <code>&lt;resource&gt;.py</code> modules.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>

View File

@@ -795,10 +795,10 @@ handlers explicitly via <code>operationId</code>.</p>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2"></a><span class="kn">import</span><span class="w"> </span><span class="nn">my_service.routes</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">routes</span>
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3"></a>
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4"></a><span class="n">api</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">OpenAPIFirstApp</span><span class="p">(</span>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">"openapi.yaml"</span><span class="p">,</span>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">,</span>
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6"></a> <span class="n">routes_module</span><span class="o">=</span><span class="n">routes</span><span class="p">,</span>
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">"My Service"</span><span class="p">,</span>
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8"></a> <span class="n">version</span><span class="o">=</span><span class="s2">"1.0.0"</span><span class="p">,</span>
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;My Service&quot;</span><span class="p">,</span>
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8"></a> <span class="n">version</span><span class="o">=</span><span class="s2">&quot;1.0.0&quot;</span><span class="p">,</span>
</span><span id="__span-2-9"><a id="__codelineno-2-9" name="__codelineno-2-9"></a><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
<p>OperationId-driven HTTP client:</p>
@@ -811,7 +811,7 @@ handlers explicitly via <code>operationId</code>.</p>
<span class="normal"><a href="#__codelineno-3-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first.loader</span><span class="w"> </span><span class="kn">import</span> <span class="n">load_openapi</span>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first.client</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAPIClient</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3"></a>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">load_openapi</span><span class="p">(</span><span class="s2">"openapi.yaml"</span><span class="p">)</span>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">load_openapi</span><span class="p">(</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">)</span>
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5"></a><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAPIClient</span><span class="p">(</span><span class="n">spec</span><span class="p">)</span>
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6"></a>
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7"></a><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get_health</span><span class="p">()</span>
@@ -866,7 +866,9 @@ handlers explicitly via <code>operationId</code>.</p>
</div>
</div>
</div><ul>
<li><a href="openapi_first/">Openapi First</a></li>
</ul>

View File

@@ -658,7 +658,7 @@ that enforces OpenAPI as the single source of truth for a FastAPI service.</p>
Python handler function.
- Handlers are plain Python callables (no FastAPI decorators).
- FastAPI route registration is derived exclusively from the spec.
- FastAPI's autogenerated OpenAPI schema is fully overridden.
- FastAPI&#39;s autogenerated OpenAPI schema is fully overridden.
</code></pre></div></td></tr></table></div>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
@@ -821,7 +821,7 @@ handlers).</p>
- All routes are derived from the provided OpenAPI specification,
and each ``operationId`` is mapped to a Python function in the
supplied routes module.
- Auth dependencies are auto-injected from the spec's
- Auth dependencies are auto-injected from the spec&#39;s
``securitySchemes`` and per-operation ``security`` fields.
</code></pre></div></td></tr></table></div>
<p><strong>Guarantees:</strong></p>
@@ -852,9 +852,9 @@ handlers).</p>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="kn">import</span><span class="w"> </span><span class="nn">app.routes</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">routes</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="n">app</span> <span class="o">=</span> <span class="n">OpenAPIFirstApp</span><span class="p">(</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">"app/openapi.json"</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">&quot;app/openapi.json&quot;</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">routes_module</span><span class="o">=</span><span class="n">routes</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">"Example Service"</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;Example Service&quot;</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
</details>

View File

@@ -836,16 +836,16 @@ missing/duplicate, or required parameters are missing.</p>
<span class="normal"><a href="#__codelineno-0-15">15</a></span>
<span class="normal"><a href="#__codelineno-0-16">16</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first</span><span class="w"> </span><span class="kn">import</span> <span class="n">loader</span><span class="p">,</span> <span class="n">client</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_openapi</span><span class="p">(</span><span class="s2">"openapi.yaml"</span><span class="p">)</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_openapi</span><span class="p">(</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">)</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="n">api</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">OpenAPIClient</span><span class="p">(</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">spec</span><span class="o">=</span><span class="n">spec</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">base_url</span><span class="o">=</span><span class="s2">"http://localhost:8000"</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">base_url</span><span class="o">=</span><span class="s2">&quot;http://localhost:8000&quot;</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="c1"># Call operationId: getUser</span>
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="n">response</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">getUser</span><span class="p">(</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">path_params</span><span class="o">=</span><span class="p">{</span><span class="s2">"user_id"</span><span class="p">:</span> <span class="mi">123</span><span class="p">}</span>
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">path_params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">123</span><span class="p">}</span>
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="p">)</span>
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14"></a>
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">)</span>

View File

@@ -762,21 +762,25 @@ definitions.</p>
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span>
<span class="normal"><a href="#__codelineno-0-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">spec_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">output_dir</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">*</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">use_models</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"models"</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;models&quot;</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">inject_request</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">package</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Generate route handler stubs from an OpenAPI specification.</p>
<p>Creates one <code>&lt;resource&gt;.py</code> file per resource in <em>output_dir</em>.
Resources are derived from the first path segment (e.g. <code>/pets</code>
and <code>/pets/{id}</code> both group under <code>pets</code>).</p>
<p>Creates one route module per resource in <em>output_dir</em>. Resources are
derived from the first path segment (e.g. <code>/pets</code> and <code>/pets/{id}</code>
both group under <code>pets</code>) and sanitized to valid module identifiers.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -849,6 +853,36 @@ for request-body schemas referenced via <code>$ref</code>.</p>
<code>&#39;models&#39;</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>inject_request</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, prepend <code>request: Request</code> to every handler so the
stub can later resolve services from <code>request.app.state</code>.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>package</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, emit <code>&lt;resource&gt;/routes.py</code> packages (each with an
<code>__init__.py</code>) instead of flat <code>&lt;resource&gt;.py</code> modules.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>

View File

@@ -641,19 +641,39 @@ must define an <code>operationId</code>, which becomes the handler function name
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Design constraints:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span>
<span class="normal">7</span></pre></div></td><td class="code"><div><pre><span></span><code>- ``operationId`` is required on every operation (matching
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span></pre></div></td><td class="code"><div><pre><span></span><code>- ``operationId`` is required on every operation (matching
``binder.bind_routes``).
- Handlers are stubs raising ``NotImplementedError``.
- Sub-resources (e.g. ``/pets/{id}/photo``) are grouped with their
parent resource (``pets``).
- Parameter types and defaults are inferred from the spec.
- ``response: Response`` is injected for non-200 success codes.
- Resource names are sanitized to valid Python module identifiers,
so a path such as ``/fetch-requests`` yields ``fetch_requests.py``.
- Passing ``inject_request=True`` prepends ``request: Request`` to
every handler (the composition-root / DI convention).
- ``multipart/form-data`` and
``application/x-www-form-urlencoded`` request bodies expand to one
parameter per schema property (``UploadFile`` / ``File`` / ``Form``)
instead of an opaque ``payload: dict``.
- Passing ``package=True`` writes ``&lt;resource&gt;/routes.py`` (with
``__init__.py`` sidecars) instead of a flat ``&lt;resource&gt;.py``.
</code></pre></div></td></tr></table></div>
</details>
@@ -682,21 +702,25 @@ must define an <code>operationId</code>, which becomes the handler function name
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span>
<span class="normal"><a href="#__codelineno-0-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generate_routes</span><span class="p">(</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">spec_path</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">output_dir</span><span class="p">:</span> <span class="n">Path</span><span class="p">,</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">*</span><span class="p">,</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">use_models</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"models"</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">models_module</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;models&quot;</span><span class="p">,</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">inject_request</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">package</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Path</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Generate route handler stubs from an OpenAPI specification.</p>
<p>Creates one <code>&lt;resource&gt;.py</code> file per resource in <em>output_dir</em>.
Resources are derived from the first path segment (e.g. <code>/pets</code>
and <code>/pets/{id}</code> both group under <code>pets</code>).</p>
<p>Creates one route module per resource in <em>output_dir</em>. Resources are
derived from the first path segment (e.g. <code>/pets</code> and <code>/pets/{id}</code>
both group under <code>pets</code>) and sanitized to valid module identifiers.</p>
<p><span class="doc-section-title">Parameters:</span></p>
@@ -769,6 +793,36 @@ for request-body schemas referenced via <code>$ref</code>.</p>
<code>&#39;models&#39;</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>inject_request</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, prepend <code>request: Request</code> to every handler so the
stub can later resolve services from <code>request.app.state</code>.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td><code>package</code></td>
<td>
<code>bool</code>
</td>
<td>
<div class="doc-md-description">
<p>If <code>True</code>, emit <code>&lt;resource&gt;/routes.py</code> packages (each with an
<code>__init__.py</code>) instead of flat <code>&lt;resource&gt;.py</code> modules.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>

View File

@@ -682,10 +682,10 @@ handlers explicitly via <code>operationId</code>.</p>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2"></a><span class="kn">import</span><span class="w"> </span><span class="nn">my_service.routes</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">routes</span>
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3"></a>
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4"></a><span class="n">api</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">OpenAPIFirstApp</span><span class="p">(</span>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">"openapi.yaml"</span><span class="p">,</span>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5"></a> <span class="n">openapi_path</span><span class="o">=</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">,</span>
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6"></a> <span class="n">routes_module</span><span class="o">=</span><span class="n">routes</span><span class="p">,</span>
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">"My Service"</span><span class="p">,</span>
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8"></a> <span class="n">version</span><span class="o">=</span><span class="s2">"1.0.0"</span><span class="p">,</span>
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7"></a> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;My Service&quot;</span><span class="p">,</span>
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8"></a> <span class="n">version</span><span class="o">=</span><span class="s2">&quot;1.0.0&quot;</span><span class="p">,</span>
</span><span id="__span-2-9"><a id="__codelineno-2-9" name="__codelineno-2-9"></a><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
<p>OperationId-driven HTTP client:</p>
@@ -698,7 +698,7 @@ handlers explicitly via <code>operationId</code>.</p>
<span class="normal"><a href="#__codelineno-3-7">7</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first.loader</span><span class="w"> </span><span class="kn">import</span> <span class="n">load_openapi</span>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2"></a><span class="kn">from</span><span class="w"> </span><span class="nn">openapi_first.client</span><span class="w"> </span><span class="kn">import</span> <span class="n">OpenAPIClient</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3"></a>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">load_openapi</span><span class="p">(</span><span class="s2">"openapi.yaml"</span><span class="p">)</span>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="n">spec</span> <span class="o">=</span> <span class="n">load_openapi</span><span class="p">(</span><span class="s2">&quot;openapi.yaml&quot;</span><span class="p">)</span>
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5"></a><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAPIClient</span><span class="p">(</span><span class="n">spec</span><span class="p">)</span>
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6"></a>
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7"></a><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get_health</span><span class="p">()</span>

View File

@@ -688,7 +688,7 @@ construct a strict, operationId-driven HTTP client.</p>
<span class="normal">29</span></pre></div></td><td class="code"><div><pre><span></span><code>from openapi_first.loader import load_openapi
from openapi_first.client import OpenAPIClient
spec = load_openapi("openapi.yaml")
spec = load_openapi(&quot;openapi.yaml&quot;)
client = OpenAPIClient(spec)
# List items
@@ -696,23 +696,23 @@ response = client.list_items()
# Get item by ID
response = client.get_item(
path_params={"item_id": 1}
path_params={&quot;item_id&quot;: 1}
)
# Create item
response = client.create_item(
body={"name": "Orange", "price": 0.8}
body={&quot;name&quot;: &quot;Orange&quot;, &quot;price&quot;: 0.8}
)
# Update item
response = client.update_item(
path_params={"item_id": 1},
body={"name": "Green Apple", "price": 0.6},
path_params={&quot;item_id&quot;: 1},
body={&quot;name&quot;: &quot;Green Apple&quot;, &quot;price&quot;: 0.6},
)
# Delete item
response = client.delete_item(
path_params={"item_id": 1}
path_params={&quot;item_id&quot;: 1}
)
</code></pre></div></td></tr></table></div>
<p>Client guarantees:

View File

@@ -659,13 +659,13 @@ construct a strict, operationId-driven HTTP client.</p>
<span class="normal">10</span></pre></div></td><td class="code"><div><pre><span></span><code>from openapi_first.loader import load_openapi
from openapi_first.client import OpenAPIClient
spec = load_openapi("openapi.yaml")
spec = load_openapi(&quot;openapi.yaml&quot;)
client = OpenAPIClient(spec)
response = client.get_health()
assert response.status_code == 200
assert response.json() == {"status": "ok"}
assert response.json() == {&quot;status&quot;: &quot;ok&quot;}
</code></pre></div></td></tr></table></div>
<p>Client guarantees:
- One callable per OpenAPI <code>operationId</code>

View File

@@ -691,7 +691,7 @@ construct a strict, operationId-driven HTTP client.</p>
<span class="normal">29</span></pre></div></td><td class="code"><div><pre><span></span><code>from openapi_first.loader import load_openapi
from openapi_first.client import OpenAPIClient
spec = load_openapi("openapi.yaml")
spec = load_openapi(&quot;openapi.yaml&quot;)
client = OpenAPIClient(spec)
# List items
@@ -699,23 +699,23 @@ response = client.list_items()
# Get item by ID
response = client.get_item(
path_params={"item_id": 1}
path_params={&quot;item_id&quot;: 1}
)
# Create item
response = client.create_item(
body={"name": "Orange", "price": 0.8}
body={&quot;name&quot;: &quot;Orange&quot;, &quot;price&quot;: 0.8}
)
# Update item
response = client.update_item(
path_params={"item_id": 1},
body={"name": "Green Apple", "price": 0.6},
path_params={&quot;item_id&quot;: 1},
body={&quot;name&quot;: &quot;Green Apple&quot;, &quot;price&quot;: 0.6},
)
# Delete item
response = client.delete_item(
path_params={"item_id": 1}
path_params={&quot;item_id&quot;: 1}
)
</code></pre></div></td></tr></table></div>
<p>Client guarantees:

View File

@@ -699,21 +699,21 @@ library API surface.</p>
<span class="normal">19</span></pre></div></td><td class="code"><div><pre><span></span><code>from openapi_first.loader import load_openapi
from openapi_first.client import OpenAPIClient
spec = load_openapi("openapi.yaml")
spec = load_openapi(&quot;openapi.yaml&quot;)
client = OpenAPIClient(spec)
# List pets with pagination
response = client.list_pets(query_params={"limit": 10, "offset": 0})
response = client.list_pets(query_params={&quot;limit&quot;: 10, &quot;offset&quot;: 0})
# Create a pet with FK references
response = client.create_pet(
body={"name": "Fido", "species": "dog", "parents": [1, 2]}
body={&quot;name&quot;: &quot;Fido&quot;, &quot;species&quot;: &quot;dog&quot;, &quot;parents&quot;: [1, 2]}
)
# Upload a pet photo
response = client.upload_pet_photo(
path_params={"id": 1},
body={"file": open("photo.jpg", "rb")},
path_params={&quot;id&quot;: 1},
body={&quot;file&quot;: open(&quot;photo.jpg&quot;, &quot;rb&quot;)},
)
</code></pre></div></td></tr></table></div>
<hr />

File diff suppressed because one or more lines are too long

Binary file not shown.