<p dir="auto"><strong>Description</strong></p>
<p dir="auto">How can I [...]?</p>
<p dir="auto">Is it possible to [...]?</p>
<p dir="auto"><strong>Additional context</strong><br>
Add any other context or screenshots about the feature request here.</p>
<h3 dir="auto">First check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> After submitting this, I commit to:
<ul dir="auto">
<li>Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.</li>
<li>Or, I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.</li>
<li>Implement a Pull Request for a confirmed bug.</li>
</ul>
</li>
</ul>
<h3 dir="auto">Example</h3>
<p dir="auto">I propse to allow transforming:</p>

<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from typing import Optional

from fastapi import Depends, FastAPI

app = FastAPI()


async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
    return {&quot;q&quot;: q, &quot;skip&quot;: skip, &quot;limit&quot;: limit}


@app.get(&quot;/items/&quot;)
async def read_items(commons: dict = Depends(common_parameters)):
    return commons"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">Optional</span>

<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">Depends</span>, <span class="pl-v">FastAPI</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()


<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">common_parameters</span>(<span class="pl-s1">q</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>, <span class="pl-s1">skip</span>: <span class="pl-s1">int</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>, <span class="pl-s1">limit</span>: <span class="pl-s1">int</span> <span class="pl-c1">=</span> <span class="pl-c1">100</span>):
    <span class="pl-k">return</span> {<span class="pl-s">"q"</span>: <span class="pl-s1">q</span>, <span class="pl-s">"skip"</span>: <span class="pl-s1">skip</span>, <span class="pl-s">"limit"</span>: <span class="pl-s1">limit</span>}


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">commons</span>: <span class="pl-s1">dict</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">common_parameters</span>)):
    <span class="pl-k">return</span> <span class="pl-s1">commons</span></pre></div>
<p dir="auto">to</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from typing import Annotated, Optional

from fastapi import Depends, FastAPI

app = FastAPI()


async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
    return {&quot;q&quot;: q, &quot;skip&quot;: skip, &quot;limit&quot;: limit}


@app.get(&quot;/items/&quot;)
async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
    return commons"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">Annotated</span>, <span class="pl-v">Optional</span>

<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">Depends</span>, <span class="pl-v">FastAPI</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()


<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">common_parameters</span>(<span class="pl-s1">q</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-c1">None</span>, <span class="pl-s1">skip</span>: <span class="pl-s1">int</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>, <span class="pl-s1">limit</span>: <span class="pl-s1">int</span> <span class="pl-c1">=</span> <span class="pl-c1">100</span>):
    <span class="pl-k">return</span> {<span class="pl-s">"q"</span>: <span class="pl-s1">q</span>, <span class="pl-s">"skip"</span>: <span class="pl-s1">skip</span>, <span class="pl-s">"limit"</span>: <span class="pl-s1">limit</span>}


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">commons</span>: <span class="pl-v">Annotated</span>[<span class="pl-s1">dict</span>, <span class="pl-v">Depends</span>(<span class="pl-s1">common_parameters</span>)]):
    <span class="pl-k">return</span> <span class="pl-s1">commons</span></pre></div>
<h3 dir="auto">Discussion</h3>
<p dir="auto"><a href="https://www.python.org/dev/peps/pep-0593/" rel="nofollow">PEP 593</a> Added <code class="notranslate">Annotated</code> for adding additional annotations beyond type annotations. I think FastAPI's <code class="notranslate">Depends</code>, <code class="notranslate">Query</code>, <code class="notranslate">Body</code> and the likes fit well with the kind of additional annotations this supports.</p>
<p dir="auto">This would also make default values less awkward:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@app.get(&quot;/items/&quot;)
async def read_items(q: Optional[str] = Query(None, max_length=50)):
    pass"><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">q</span>: <span class="pl-v">Optional</span>[<span class="pl-s1">str</span>] <span class="pl-c1">=</span> <span class="pl-v">Query</span>(<span class="pl-c1">None</span>, <span class="pl-s1">max_length</span><span class="pl-c1">=</span><span class="pl-c1">50</span>)):
    <span class="pl-k">pass</span></pre></div>
<p dir="auto">Could become</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@app.get(&quot;/items/&quot;)
async def read_items(q: Annotated[Optional[str], Query(max_length=50)] = None):
    pass"><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">q</span>: <span class="pl-v">Annotated</span>[<span class="pl-v">Optional</span>[<span class="pl-s1">str</span>], <span class="pl-v">Query</span>(<span class="pl-s1">max_length</span><span class="pl-c1">=</span><span class="pl-c1">50</span>)] <span class="pl-c1">=</span> <span class="pl-c1">None</span>):
    <span class="pl-k">pass</span></pre></div>
<p dir="auto">This will also solve the issue mentioned <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need" rel="nofollow">in the docs</a> of parameter ordering.</p>
<p dir="auto">Finally, it is sometimes convenient to use the same function as both a FastAPI dependency and a regular function. In these cases, because <code class="notranslate">= Depends(...)</code> is a default parameter value, if you forget to pass a parameter the error is not caught by your IDE. Worse, it is not caught at runtime because Python will just pass along the <code class="notranslate">Depends</code> object. This will probably cause an error down the road, but may silently succeed in some cases.</p>
<p dir="auto">I'm willing to implement this if you think it's a good idea.</p>