mirror of
https://github.com/fastapi/fastapi.git
synced 2026-01-23 05:19:46 -05:00
Compare commits
6 Commits
Update-emb
...
additional
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
841c5c3189 | ||
|
|
fa7a5d38a7 | ||
|
|
cf7d4fe7b7 | ||
|
|
02d8c6e258 | ||
|
|
597b435ae7 | ||
|
|
74cc27fd5a |
1
.github/labeler.yml
vendored
1
.github/labeler.yml
vendored
@@ -31,6 +31,7 @@ internal:
|
|||||||
- .pre-commit-config.yaml
|
- .pre-commit-config.yaml
|
||||||
- pdm_build.py
|
- pdm_build.py
|
||||||
- requirements*.txt
|
- requirements*.txt
|
||||||
|
- uv.lock
|
||||||
- docs/en/data/sponsors.yml
|
- docs/en/data/sponsors.yml
|
||||||
- docs/en/overrides/main.html
|
- docs/en/overrides/main.html
|
||||||
- all-globs-to-all-files:
|
- all-globs-to-all-files:
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -164,6 +164,8 @@ $ pip install "fastapi[standard]"
|
|||||||
Create a file `main.py` with:
|
Create a file `main.py` with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -175,7 +177,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -184,7 +186,9 @@ def read_item(item_id: int, q: str | None = None):
|
|||||||
|
|
||||||
If your code uses `async` / `await`, use `async def`:
|
If your code uses `async` / `await`, use `async def`:
|
||||||
|
|
||||||
```Python hl_lines="7 12"
|
```Python hl_lines="9 14"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -196,7 +200,7 @@ async def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
async def read_item(item_id: int, q: str | None = None):
|
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -287,7 +291,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
|
|||||||
|
|
||||||
Declare the body using standard Python types, thanks to Pydantic.
|
Declare the body using standard Python types, thanks to Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="2 7-10 23-25"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -297,7 +303,7 @@ app = FastAPI()
|
|||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
price: float
|
price: float
|
||||||
is_offer: bool | None = None
|
is_offer: Union[bool, None] = None
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -306,7 +312,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ There are other formats and tools to define and install package dependencies.
|
|||||||
* Create a `main.py` file with:
|
* Create a `main.py` file with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -156,7 +158,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ FastAPI also includes these JavaScript-only `presets` settings:
|
|||||||
|
|
||||||
```JavaScript
|
```JavaScript
|
||||||
presets: [
|
presets: [
|
||||||
SwaggerUIBundle.presets.apis,
|
SwaggerUIBundle.presets.apis
|
||||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ $ pip install "fastapi[standard]"
|
|||||||
Create a file `main.py` with:
|
Create a file `main.py` with:
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -172,7 +174,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -181,7 +183,9 @@ def read_item(item_id: int, q: str | None = None):
|
|||||||
|
|
||||||
If your code uses `async` / `await`, use `async def`:
|
If your code uses `async` / `await`, use `async def`:
|
||||||
|
|
||||||
```Python hl_lines="7 12"
|
```Python hl_lines="9 14"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -193,7 +197,7 @@ async def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
async def read_item(item_id: int, q: str | None = None):
|
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -284,7 +288,9 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
|
|||||||
|
|
||||||
Declare the body using standard Python types, thanks to Pydantic.
|
Declare the body using standard Python types, thanks to Pydantic.
|
||||||
|
|
||||||
```Python hl_lines="2 7-10 23-25"
|
```Python hl_lines="4 9-12 25-27"
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
@@ -294,7 +300,7 @@ app = FastAPI()
|
|||||||
class Item(BaseModel):
|
class Item(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
price: float
|
price: float
|
||||||
is_offer: bool | None = None
|
is_offer: Union[bool, None] = None
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
@@ -303,7 +309,7 @@ def read_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/items/{item_id}")
|
@app.get("/items/{item_id}")
|
||||||
def read_item(item_id: int, q: str | None = None):
|
def read_item(item_id: int, q: Union[str, None] = None):
|
||||||
return {"item_id": item_id, "q": q}
|
return {"item_id": item_id, "q": q}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ hide:
|
|||||||
|
|
||||||
### Internal
|
### Internal
|
||||||
|
|
||||||
|
* 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg).
|
||||||
* 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo).
|
* 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo).
|
* 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||||
|
|||||||
@@ -102,16 +102,15 @@ Of course, you can also declare additional query parameters whenever you need, a
|
|||||||
|
|
||||||
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
||||||
|
|
||||||
```Python
|
|
||||||
q: str | None = None
|
|
||||||
```
|
|
||||||
|
|
||||||
Or in Python 3.9:
|
|
||||||
|
|
||||||
```Python
|
```Python
|
||||||
q: Union[str, None] = None
|
q: Union[str, None] = None
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or in Python 3.10 and above:
|
||||||
|
|
||||||
|
```Python
|
||||||
|
q: str | None = None
|
||||||
|
```
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ def get_swagger_ui_html(
|
|||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
|
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
|
||||||
|
swagger_extra_js_urls: Annotated[
|
||||||
|
Optional[list[str]],
|
||||||
|
Doc(
|
||||||
|
"""
|
||||||
|
The URLs of additional JavaScript files to include.
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
] = None,
|
||||||
swagger_css_url: Annotated[
|
swagger_css_url: Annotated[
|
||||||
str,
|
str,
|
||||||
Doc(
|
Doc(
|
||||||
@@ -98,6 +106,14 @@ def get_swagger_ui_html(
|
|||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
] = None,
|
] = None,
|
||||||
|
swagger_extra_presets: Annotated[
|
||||||
|
Optional[list[str]],
|
||||||
|
Doc(
|
||||||
|
"""
|
||||||
|
Extra presets to add to Swagger UI.
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
] = None,
|
||||||
) -> HTMLResponse:
|
) -> HTMLResponse:
|
||||||
"""
|
"""
|
||||||
Generate and return the HTML that loads Swagger UI for the interactive
|
Generate and return the HTML that loads Swagger UI for the interactive
|
||||||
@@ -114,6 +130,13 @@ def get_swagger_ui_html(
|
|||||||
if swagger_ui_parameters:
|
if swagger_ui_parameters:
|
||||||
current_swagger_ui_parameters.update(swagger_ui_parameters)
|
current_swagger_ui_parameters.update(swagger_ui_parameters)
|
||||||
|
|
||||||
|
js_urls = [swagger_js_url]
|
||||||
|
if swagger_extra_js_urls:
|
||||||
|
js_urls.extend(swagger_extra_js_urls)
|
||||||
|
scripts_str = "\n ".join(
|
||||||
|
f'<script src="{js_url}"></script>' for js_url in js_urls
|
||||||
|
)
|
||||||
|
|
||||||
html = f"""
|
html = f"""
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@@ -125,7 +148,7 @@ def get_swagger_ui_html(
|
|||||||
<body>
|
<body>
|
||||||
<div id="swagger-ui">
|
<div id="swagger-ui">
|
||||||
</div>
|
</div>
|
||||||
<script src="{swagger_js_url}"></script>
|
{scripts_str}
|
||||||
<!-- `SwaggerUIBundle` is now available on the page -->
|
<!-- `SwaggerUIBundle` is now available on the page -->
|
||||||
<script>
|
<script>
|
||||||
const ui = SwaggerUIBundle({{
|
const ui = SwaggerUIBundle({{
|
||||||
@@ -138,12 +161,18 @@ def get_swagger_ui_html(
|
|||||||
if oauth2_redirect_url:
|
if oauth2_redirect_url:
|
||||||
html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
|
html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
|
||||||
|
|
||||||
html += """
|
presets = ["SwaggerUIBundle.presets.apis"]
|
||||||
|
if swagger_extra_presets:
|
||||||
|
presets.extend(swagger_extra_presets)
|
||||||
|
presets_str = ",\n ".join(presets)
|
||||||
|
|
||||||
|
html += f"""
|
||||||
presets: [
|
presets: [
|
||||||
SwaggerUIBundle.presets.apis,
|
{presets_str},
|
||||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
|
||||||
],
|
],
|
||||||
})"""
|
"""
|
||||||
|
|
||||||
|
html += " })"
|
||||||
|
|
||||||
if init_oauth:
|
if init_oauth:
|
||||||
html += f"""
|
html += f"""
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ def test_swagger_ui():
|
|||||||
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
|
|
||||||
"default configs should be preserved"
|
|
||||||
)
|
|
||||||
assert '"layout": "BaseLayout",' in response.text, (
|
assert '"layout": "BaseLayout",' in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ def test_swagger_ui():
|
|||||||
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
|
|
||||||
"default configs should be preserved"
|
|
||||||
)
|
|
||||||
assert '"layout": "BaseLayout",' in response.text, (
|
assert '"layout": "BaseLayout",' in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ def test_swagger_ui():
|
|||||||
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
assert "SwaggerUIBundle.presets.apis," in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
|
|
||||||
"default configs should be preserved"
|
|
||||||
)
|
|
||||||
assert '"layout": "BaseLayout",' in response.text, (
|
assert '"layout": "BaseLayout",' in response.text, (
|
||||||
"default configs should be preserved"
|
"default configs should be preserved"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user