diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index f575cbf5e..ad20f45b4 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -13,15 +13,22 @@ jobs: run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v2 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: "3.7" + - uses: actions/cache@v2 + id: cache + with: + path: ${{ env.pythonLocation }} + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-docs - name: Install Flit + if: steps.cache.outputs.cache-hit != 'true' run: python3.7 -m pip install flit - name: Install docs extras + if: steps.cache.outputs.cache-hit != 'true' run: python3.7 -m flit install --extras doc - name: Install Material for MkDocs Insiders - if: github.event.pull_request.head.repo.fork == false + if: github.event.pull_request.head.repo.fork == false && steps.cache.outputs.cache-hit != 'true' run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git - name: Build Docs run: python3.7 ./scripts/docs.py build-all diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d5f4de462..9dde4e066 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,12 +15,19 @@ jobs: run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v2 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: "3.6" + - uses: actions/cache@v2 + id: cache + with: + path: ${{ env.pythonLocation }} + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish - name: Install Flit + if: steps.cache.outputs.cache-hit != 'true' run: pip install flit - name: Install Dependencies + if: steps.cache.outputs.cache-hit != 'true' run: flit install --symlink - name: Publish env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef3c6f010..f346cab6b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,12 +16,19 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - uses: actions/cache@v2 + id: cache + with: + path: ${{ env.pythonLocation }} + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test - name: Install Flit + if: steps.cache.outputs.cache-hit != 'true' run: pip install flit - name: Install Dependencies + if: steps.cache.outputs.cache-hit != 'true' run: flit install --symlink - name: Test run: bash scripts/test.sh diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 5b2d9ba04..25c8d03ca 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -2,9 +2,32 @@ ## Latest Changes + +## 0.65.1 + +### Security fixes + +* 📌 Upgrade pydantic pin, to handle security vulnerability [CVE-2021-29510](https://github.com/samuelcolvin/pydantic/security/advisories/GHSA-5jqp-qgf6-3pvh). PR [#3213](https://github.com/tiangolo/fastapi/pull/3213) by [@tiangolo](https://github.com/tiangolo). + +## 0.65.0 + +### Breaking Changes - Upgrade + +* ⬆️ Upgrade Starlette to `0.14.2`, including internal `UJSONResponse` migrated from Starlette. This includes several bug fixes and features from Starlette. PR [#2335](https://github.com/tiangolo/fastapi/pull/2335) by [@hanneskuettner](https://github.com/hanneskuettner). + +### Translations + +* 🌐 Initialize new language Polish for translations. PR [#3170](https://github.com/tiangolo/fastapi/pull/3170) by [@neternefer](https://github.com/neternefer). + +### Internal + +* 👷 Add GitHub Action cache to speed up CI installs. PR [#3204](https://github.com/tiangolo/fastapi/pull/3204) by [@tiangolo](https://github.com/tiangolo). +* ⬆️ Upgrade setup-python GitHub Action to v2. PR [#3203](https://github.com/tiangolo/fastapi/pull/3203) by [@tiangolo](https://github.com/tiangolo). +* 🐛 Fix docs script to generate a new translation language with `overrides` boilerplate. PR [#3202](https://github.com/tiangolo/fastapi/pull/3202) by [@tiangolo](https://github.com/tiangolo). * ✨ Add new Deta banner badge with new sponsorship tier 🙇. PR [#3194](https://github.com/tiangolo/fastapi/pull/3194) by [@tiangolo](https://github.com/tiangolo). * 👥 Update FastAPI People. PR [#3189](https://github.com/tiangolo/fastapi/pull/3189) by [@github-actions[bot]](https://github.com/apps/github-actions). * 🔊 Update FastAPI People to allow better debugging. PR [#3188](https://github.com/tiangolo/fastapi/pull/3188) by [@tiangolo](https://github.com/tiangolo). + ## 0.64.0 ### Features diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml index 4ce180a8d..1c9faf5fa 100644 --- a/docs/en/mkdocs.yml +++ b/docs/en/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -198,6 +199,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/es/mkdocs.yml b/docs/es/mkdocs.yml index cd619ade6..1554cc3ea 100644 --- a/docs/es/mkdocs.yml +++ b/docs/es/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -102,6 +103,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/fr/mkdocs.yml b/docs/fr/mkdocs.yml index d9aac95f8..f1c66c759 100644 --- a/docs/fr/mkdocs.yml +++ b/docs/fr/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -99,6 +100,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/it/mkdocs.yml b/docs/it/mkdocs.yml index 9cadabcbb..f03730466 100644 --- a/docs/it/mkdocs.yml +++ b/docs/it/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -95,6 +96,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/ja/mkdocs.yml b/docs/ja/mkdocs.yml index 7ce4d6445..c2d905b13 100644 --- a/docs/ja/mkdocs.yml +++ b/docs/ja/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -134,6 +135,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/ko/mkdocs.yml b/docs/ko/mkdocs.yml index f5ae4b439..7f1991ed3 100644 --- a/docs/ko/mkdocs.yml +++ b/docs/ko/mkdocs.yml @@ -44,6 +44,7 @@ nav: - it: /it/ - ja: /ja/ - ko: /ko/ + - pl: /pl/ - pt: /pt/ - ru: /ru/ - sq: /sq/ @@ -101,6 +102,8 @@ extra: name: ja - 日本語 - link: /ko/ name: ko - 한국어 + - link: /pl/ + name: pl - link: /pt/ name: pt - português - link: /ru/ diff --git a/docs/pl/docs/index.md b/docs/pl/docs/index.md new file mode 100644 index 000000000..edc19fa48 --- /dev/null +++ b/docs/pl/docs/index.md @@ -0,0 +1,464 @@ + +{!../../../docs/missing-translation.md!} + + +
++ FastAPI framework, high performance, easy to learn, fast to code, ready for production +
+ + +--- + +**Documentation**: https://fastapi.tiangolo.com + +**Source Code**: https://github.com/tiangolo/fastapi + +--- + +FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints. + +The key features are: + +* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). + +* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * +* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * +* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. +* **Easy**: Designed to be easy to use and learn. Less time reading docs. +* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. +* **Robust**: Get production-ready code. With automatic interactive documentation. +* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema. + +* estimation based on tests on an internal development team, building production applications. + +## Gold Sponsors + + + +{% if sponsors %} +{% for sponsor in sponsors.gold -%} +async def...uvicorn main:app --reload...ujson - for faster JSON "parsing".
+* email_validator - for email validation.
+
+Used by Starlette:
+
+* requests - Required if you want to use the `TestClient`.
+* aiofiles - Required if you want to use `FileResponse` or `StaticFiles`.
+* jinja2 - Required if you want to use the default template configuration.
+* python-multipart - Required if you want to support form "parsing", with `request.form()`.
+* itsdangerous - Required for `SessionMiddleware` support.
+* pyyaml - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
+* graphene - Required for `GraphQLApp` support.
+* ujson - Required if you want to use `UJSONResponse`.
+
+Used by FastAPI / Starlette:
+
+* uvicorn - for the server that loads and serves your application.
+* orjson - Required if you want to use `ORJSONResponse`.
+
+You can install all of these with `pip install fastapi[all]`.
+
+## License
+
+This project is licensed under the terms of the MIT license.
diff --git a/docs/pl/mkdocs.yml b/docs/pl/mkdocs.yml
new file mode 100644
index 000000000..a2c6102b8
--- /dev/null
+++ b/docs/pl/mkdocs.yml
@@ -0,0 +1,119 @@
+site_name: FastAPI
+site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
+site_url: https://fastapi.tiangolo.com/pl/
+theme:
+ name: material
+ custom_dir: overrides
+ palette:
+ - scheme: default
+ primary: teal
+ accent: amber
+ toggle:
+ icon: material/lightbulb-outline
+ name: Switch to light mode
+ - scheme: slate
+ primary: teal
+ accent: amber
+ toggle:
+ icon: material/lightbulb
+ name: Switch to dark mode
+ features:
+ - search.suggest
+ - search.highlight
+ icon:
+ repo: fontawesome/brands/github-alt
+ logo: https://fastapi.tiangolo.com/img/icon-white.svg
+ favicon: https://fastapi.tiangolo.com/img/favicon.png
+ language: pl
+repo_name: tiangolo/fastapi
+repo_url: https://github.com/tiangolo/fastapi
+edit_uri: ''
+google_analytics:
+- UA-133183413-1
+- auto
+plugins:
+- search
+- markdownextradata:
+ data: data
+nav:
+- FastAPI: index.md
+- Languages:
+ - en: /
+ - es: /es/
+ - fr: /fr/
+ - it: /it/
+ - ja: /ja/
+ - ko: /ko/
+ - pl: /pl/
+ - pt: /pt/
+ - ru: /ru/
+ - sq: /sq/
+ - tr: /tr/
+ - uk: /uk/
+ - zh: /zh/
+markdown_extensions:
+- toc:
+ permalink: true
+- markdown.extensions.codehilite:
+ guess_lang: false
+- markdown_include.include:
+ base_path: docs
+- admonition
+- codehilite
+- extra
+- pymdownx.superfences:
+ custom_fences:
+ - name: mermaid
+ class: mermaid
+ format: !!python/name:pymdownx.superfences.fence_div_format ''
+- pymdownx.tabbed
+extra:
+ social:
+ - icon: fontawesome/brands/github-alt
+ link: https://github.com/tiangolo/fastapi
+ - icon: fontawesome/brands/discord
+ link: https://discord.gg/VQjSZaeJmf
+ - icon: fontawesome/brands/twitter
+ link: https://twitter.com/tiangolo
+ - icon: fontawesome/brands/linkedin
+ link: https://www.linkedin.com/in/tiangolo
+ - icon: fontawesome/brands/dev
+ link: https://dev.to/tiangolo
+ - icon: fontawesome/brands/medium
+ link: https://medium.com/@tiangolo
+ - icon: fontawesome/solid/globe
+ link: https://tiangolo.com
+ alternate:
+ - link: /
+ name: en - English
+ - link: /es/
+ name: es - español
+ - link: /fr/
+ name: fr - français
+ - link: /it/
+ name: it - italiano
+ - link: /ja/
+ name: ja - 日本語
+ - link: /ko/
+ name: ko - 한국어
+ - link: /pl/
+ name: pl
+ - link: /pt/
+ name: pt - português
+ - link: /ru/
+ name: ru - русский язык
+ - link: /sq/
+ name: sq - shqip
+ - link: /tr/
+ name: tr - Türkçe
+ - link: /uk/
+ name: uk - українська мова
+ - link: /zh/
+ name: zh - 汉语
+extra_css:
+- https://fastapi.tiangolo.com/css/termynal.css
+- https://fastapi.tiangolo.com/css/custom.css
+extra_javascript:
+- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
+- https://fastapi.tiangolo.com/js/termynal.js
+- https://fastapi.tiangolo.com/js/custom.js
diff --git a/docs/pl/overrides/.gitignore b/docs/pl/overrides/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/pt/mkdocs.yml b/docs/pt/mkdocs.yml
index ca5e77b01..230012d3b 100644
--- a/docs/pt/mkdocs.yml
+++ b/docs/pt/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -103,6 +104,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml
index 55ee72fb6..b2b1b9aa7 100644
--- a/docs/ru/mkdocs.yml
+++ b/docs/ru/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -95,6 +96,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/docs/sq/mkdocs.yml b/docs/sq/mkdocs.yml
index 7608f0220..9b255718b 100644
--- a/docs/sq/mkdocs.yml
+++ b/docs/sq/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -95,6 +96,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/docs/tr/mkdocs.yml b/docs/tr/mkdocs.yml
index 30ee0ca2e..b65088447 100644
--- a/docs/tr/mkdocs.yml
+++ b/docs/tr/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -95,6 +96,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/docs/uk/mkdocs.yml b/docs/uk/mkdocs.yml
index ab54f4f21..cecd2444f 100644
--- a/docs/uk/mkdocs.yml
+++ b/docs/uk/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -95,6 +96,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/docs/zh/mkdocs.yml b/docs/zh/mkdocs.yml
index 9cea77745..b88f04382 100644
--- a/docs/zh/mkdocs.yml
+++ b/docs/zh/mkdocs.yml
@@ -44,6 +44,7 @@ nav:
- it: /it/
- ja: /ja/
- ko: /ko/
+ - pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
@@ -135,6 +136,8 @@ extra:
name: ja - 日本語
- link: /ko/
name: ko - 한국어
+ - link: /pl/
+ name: pl
- link: /pt/
name: pt - português
- link: /ru/
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index 332c5aaf7..80f61d9f4 100644
--- a/fastapi/__init__.py
+++ b/fastapi/__init__.py
@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
-__version__ = "0.64.0"
+__version__ = "0.65.1"
from starlette import status as status
diff --git a/fastapi/responses.py b/fastapi/responses.py
index 8d9d62dfb..6cd793157 100644
--- a/fastapi/responses.py
+++ b/fastapi/responses.py
@@ -7,7 +7,12 @@ from starlette.responses import PlainTextResponse as PlainTextResponse # noqa
from starlette.responses import RedirectResponse as RedirectResponse # noqa
from starlette.responses import Response as Response # noqa
from starlette.responses import StreamingResponse as StreamingResponse # noqa
-from starlette.responses import UJSONResponse as UJSONResponse # noqa
+
+try:
+ import ujson
+except ImportError: # pragma: nocover
+ ujson = None # type: ignore
+
try:
import orjson
@@ -15,6 +20,12 @@ except ImportError: # pragma: nocover
orjson = None # type: ignore
+class UJSONResponse(JSONResponse):
+ def render(self, content: Any) -> bytes:
+ assert ujson is not None, "ujson must be installed to use UJSONResponse"
+ return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
+
+
class ORJSONResponse(JSONResponse):
media_type = "application/json"
diff --git a/pyproject.toml b/pyproject.toml
index 66cb00345..f376dcdff 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,8 +32,8 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP",
]
requires = [
- "starlette ==0.13.6",
- "pydantic >=1.0.0,<2.0.0"
+ "starlette ==0.14.2",
+ "pydantic >=1.6.2,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0"
]
description-file = "README.md"
requires-python = ">=3.6"
@@ -57,6 +57,7 @@ test = [
"peewee >=3.13.3,<4.0.0",
"databases[sqlite] >=0.3.2,<0.4.0",
"orjson >=3.2.1,<4.0.0",
+ "ujson >=4.0.1,<5.0.0",
"async_exit_stack >=1.0.1,<2.0.0",
"async_generator >=1.10,<2.0.0",
"python-multipart >=0.0.5,<0.0.6",
@@ -87,7 +88,7 @@ all = [
"itsdangerous >=1.1.0,<2.0.0",
"pyyaml >=5.3.1,<6.0.0",
"graphene >=2.1.8,<3.0.0",
- "ujson >=3.0.0,<4.0.0",
+ "ujson >=4.0.1,<5.0.0",
"orjson >=3.2.1,<4.0.0",
"email_validator >=1.1.1,<2.0.0",
"uvicorn[standard] >=0.12.0,<0.14.0",
diff --git a/scripts/docs.py b/scripts/docs.py
index ec3ad76e6..40569e193 100644
--- a/scripts/docs.py
+++ b/scripts/docs.py
@@ -106,6 +106,9 @@ def new_lang(lang: str = typer.Argument(..., callback=lang_callback)):
en_index_content = en_index_path.read_text(encoding="utf-8")
new_index_content = f"{missing_translation_snippet}\n\n{en_index_content}"
new_index_path.write_text(new_index_content, encoding="utf-8")
+ new_overrides_gitignore_path = new_path / "overrides" / ".gitignore"
+ new_overrides_gitignore_path.parent.mkdir(parents=True, exist_ok=True)
+ new_overrides_gitignore_path.write_text("")
typer.secho(f"Successfully initialized: {new_path}", color=typer.colors.GREEN)
update_languages(lang=None)
diff --git a/tests/test_tutorial/test_custom_response/test_tutorial001.py b/tests/test_tutorial/test_custom_response/test_tutorial001.py
new file mode 100644
index 000000000..430076f88
--- /dev/null
+++ b/tests/test_tutorial/test_custom_response/test_tutorial001.py
@@ -0,0 +1,36 @@
+from fastapi.testclient import TestClient
+
+from docs_src.custom_response.tutorial001 import app
+
+client = TestClient(app)
+
+openapi_schema = {
+ "openapi": "3.0.2",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ }
+ },
+ "summary": "Read Items",
+ "operationId": "read_items_items__get",
+ }
+ }
+ },
+}
+
+
+def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == openapi_schema
+
+
+def test_get_custom_response():
+ response = client.get("/items/")
+ assert response.status_code == 200, response.text
+ assert response.json() == [{"item_id": "Foo"}]