56
57class GenerateJsonSchema(_GenerateJsonSchema):
58▶ # TODO: remove when this is merged (or equivalent): https://github.com/pydantic/pydantic/pull/12841
59 # and dropping support for any version of Pydantic before that one (so, in a very long time)
60 def bytes_schema(self, schema: CoreSchema) -> JsonSchemaValue:
· · ·
71
72
73▶# TODO: remove when dropping support for Pydantic < v2.12.3
74_Attrs = {
75 "default": ...,
· · ·
97
98
99▶# TODO: remove when dropping support for Pydantic < v2.12.3
100def asdict(field_info: FieldInfo) -> dict[str, Any]:
101 attributes = {}
· · ·
151 "ignore", category=UnsupportedFieldAttributeWarning
152 )
153▶ # TODO: remove after setting the min Pydantic to v2.12.3
154 # that adds asdict(), and use self.field_info.asdict() instead
155 field_dict = asdict(self.field_info)
· · ·
275 json_schema = field_mapping[(field, override_mode or field.mode)]
276 if "$ref" not in json_schema:
277▶ # TODO remove when deprecating Pydantic v1
278 # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207
279 json_schema["title"] = field.field_info.title or field_alias.title().replace(
177
178def is_pydantic_v1_model_instance(obj: Any) -> bool:
179▶ # TODO: remove this function once the required version of Pydantic fully
180 # removes pydantic.v1
181 try:
· · ·
189
190def is_pydantic_v1_model_class(cls: Any) -> bool:
191▶ # TODO: remove this function once the required version of Pydantic fully
192 # removes pydantic.v1
193 try:
344 # explicit default status_code, and to extract it from them, instead of
345 # doing this inspection tricks, that would probably be in the future
346▶ # TODO: probably make status_code a default class attribute for all
347 # responses in Starlette
348 response_signature = inspect.signature(current_response_class.__init__)
605 dependency_overrides_provider: Any | None = None,
606 dependency_cache: dict[DependencyCacheKey, Any] | None = None,
607▶ # TODO: remove this parameter later, no longer used, not removing it yet as some
608 # people might be monkey patching this function (although that's not supported)
609 async_exit_stack: AsyncExitStack,
1294 # Handle on_startup/on_shutdown locally since Starlette removed support
1295 # Ref: https://github.com/Kludex/starlette/pull/3117
1296▶ # TODO: deprecate this once the lifespan (or alternative) interface is improved
1297 self.on_startup: list[Callable[[], Any]] = (
1298 [] if on_startup is None else list(on_startup)
· · ·
4870 )
4871
4872▶ # TODO: remove this once the lifespan (or alternative) interface is improved
4873 async def _startup(self) -> None:
4874 """
· · ·
4886 handler()
4887
4888▶ # TODO: remove this once the lifespan (or alternative) interface is improved
4889 async def _shutdown(self) -> None:
4890 """
· · ·
4902 handler()
4903
4904▶ # TODO: remove this once the lifespan (or alternative) interface is improved
4905 def add_event_handler(
4906 self,
52 return item
53
54▶ # TODO: enable these tests once/if Form(embed=False) is supported
55 # TODO: In that case, define if File() should support example/examples too
56 # @app.post("/form_example")
· · ·
55▶ # TODO: In that case, define if File() should support example/examples too
56 # @app.post("/form_example")
57 # def form_example(firstname: str = Form(example="John")):
30def get_client(request: pytest.FixtureRequest):
31 clear_sqlmodel()
32▶ # TODO: remove when updating SQL tutorial to use new lifespan API
33 with warnings.catch_warnings(record=True):
34 warnings.simplefilter("always")
· · ·
48
49def test_crud_app(client: TestClient):
50▶ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
51 # this if using obj.model_validate becomes independent of Pydantic v2
52 with warnings.catch_warnings(record=True):
83def test_is_bytes_sequence_annotation_union():
84 # For coverage
85▶ # TODO: in theory this would allow declaring types that could be lists of bytes
86 # to be read from files and other types, but I'm not even sure it's a good idea
87 # to support it as a first class "feature"
· · ·
91def test_is_uploadfile_sequence_annotation():
92 # For coverage
93▶ # TODO: in theory this would allow declaring types that could be lists of UploadFile
94 # and other types, but I'm not even sure it's a good idea to support it as a first
95 # class "feature"
30def get_client(request: pytest.FixtureRequest):
31 clear_sqlmodel()
32▶ # TODO: remove when updating SQL tutorial to use new lifespan API
33 with warnings.catch_warnings(record=True):
34 warnings.simplefilter("always")
· · ·
48
49def test_crud_app(client: TestClient):
50▶ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
51 # this if using obj.model_validate becomes independent of Pydantic v2
52 with warnings.catch_warnings(record=True):
925 assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'"
926 assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'"
927▶ # TODO: remove when discarding the openapi_prefix parameter
928 if openapi_prefix:
929 logger.warning(
9O processo normal (padrão) é o seguinte:
10
11▶Uma aplicação (instância) do `FastAPI` possui um método `.openapi()` que deve retornar o esquema OpenAPI.
12
13Como parte da criação do objeto de aplicação, uma *operação de rota* para `/openapi.json` (ou para o que você definir como `openapi_url`) é registrada.
· · ·
14
15▶Ela apenas retorna uma resposta JSON com o resultado do método `.openapi()` da aplicação.
16
17Por padrão, o que o método `.openapi()` faz é verificar se a propriedade `.openapi_schema` tem conteúdo e retorná-lo.
· · ·
17▶Por padrão, o que o método `.openapi()` faz é verificar se a propriedade `.openapi_schema` tem conteúdo e retorná-lo.
18
19Se não tiver, ele gera o conteúdo usando a função utilitária em `fastapi.openapi.utils.get_openapi`.
· · ·
68{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
69
70▶### Sobrescrever o método { #override-the-method }
71
72Agora, você pode substituir o método `.openapi()` pela sua nova função.
· · ·
72▶Agora, você pode substituir o método `.openapi()` pela sua nova função.
73
74{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
7Un origen es la combinación de protocolo (`http`, `https`), dominio (`myapp.com`, `localhost`, `localhost.tiangolo.com`) y puerto (`80`, `443`, `8080`).
8
9▶Así que, todos estos son orígenes diferentes:
10
11* `http://localhost`
· · ·
13* `http://localhost:8080`
14
15▶Aunque todos están en `localhost`, usan protocolos o puertos diferentes, por lo tanto, son "orígenes" diferentes.
16
17## Pasos { #steps }
· · ·
27## Comodines { #wildcards }
28
29▶También es posible declarar la lista como `"*"` (un "comodín") para decir que todos están permitidos.
30
31Pero eso solo permitirá ciertos tipos de comunicación, excluyendo todo lo que implique credenciales: Cookies, headers de autorización como los utilizados con Bearer Tokens, etc.
· · ·
31▶Pero eso solo permitirá ciertos tipos de comunicación, excluyendo todo lo que implique credenciales: Cookies, headers de autorización como los utilizados con Bearer Tokens, etc.
32
33Así que, para que todo funcione correctamente, es mejor especificar explícitamente los orígenes permitidos.
· · ·
33▶Así que, para que todo funcione correctamente, es mejor especificar explícitamente los orígenes permitidos.
34
35## Usa `CORSMiddleware` { #use-corsmiddleware }
+ 6 more matches in this file
9El proceso normal (por defecto) es el siguiente.
10
11▶Una aplicación (instance) de `FastAPI` tiene un método `.openapi()` que se espera que devuelva el esquema de OpenAPI.
12
13Como parte de la creación del objeto de la aplicación, se registra una *path operation* para `/openapi.json` (o para lo que sea que configures tu `openapi_url`).
· · ·
14
15▶Simplemente devuelve un response JSON con el resultado del método `.openapi()` de la aplicación.
16
17Por defecto, lo que hace el método `.openapi()` es revisar la propiedad `.openapi_schema` para ver si tiene contenido y devolverlo.
· · ·
17▶Por defecto, lo que hace el método `.openapi()` es revisar la propiedad `.openapi_schema` para ver si tiene contenido y devolverlo.
18
19Si no lo tiene, lo genera usando la función de utilidad en `fastapi.openapi.utils.get_openapi`.
· · ·
68{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
69
70▶### Sobrescribir el método { #override-the-method }
71
72Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
· · ·
72▶Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
73
74{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
3## Recursos Adicionais { #additional-features }
4
5▶O [Tutorial - Guia de Usuário](../tutorial/index.md) principal deve ser o suficiente para dar a você um tour por todos os principais recursos do **FastAPI**.
6
7Nas próximas seções você verá outras opções, configurações, e recursos adicionais.
20### Qué es "Montar" { #what-is-mounting }
21
22▶"Montar" significa agregar una aplicación completa "independiente" en un path específico, que luego se encargará de manejar todos los sub-paths.
23
24Esto es diferente a usar un `APIRouter`, ya que una aplicación montada es completamente independiente. El OpenAPI y la documentación de tu aplicación principal no incluirán nada de la aplicación montada, etc.
· · ·
34El `name="static"` le da un nombre que puede ser utilizado internamente por **FastAPI**.
35
36▶Todos estos parámetros pueden ser diferentes a "`static`", ajústalos según las necesidades y detalles específicos de tu propia aplicación.
37
38## Más info { #more-info }
20### O que é "Montagem" { #what-is-mounting }
21
22▶"Montagem" significa adicionar uma aplicação completamente "independente" em um path específico, que então cuida de lidar com todos os sub-paths.
23
24Isso é diferente de usar um `APIRouter`, pois uma aplicação montada é completamente independente. A OpenAPI e a documentação da sua aplicação principal não incluirão nada da aplicação montada, etc.
· · ·
34O `name="static"` dá a ele um nome que pode ser usado internamente pelo **FastAPI**.
35
36▶Todos esses parâmetros podem ser diferentes de "`static`", ajuste-os de acordo com as necessidades e detalhes específicos da sua própria aplicação.
37
38## Mais informações { #more-info }
7Uma origem é a combinação de protocolo (`http`, `https`), domínio (`myapp.com`, `localhost`, `localhost.tiangolo.com`), e porta (`80`, `443`, `8080`).
8
9▶Então, todos estes são origens diferentes:
10
11* `http://localhost`
· · ·
13* `http://localhost:8080`
14
15▶Mesmo se todos estiverem em `localhost`, eles usam diferentes protocolos ou portas, portanto, são "origens" diferentes.
16
17## Passos { #steps }
· · ·
44
45* Credenciais (Cabeçalhos de autorização, Cookies, etc).
46▶* Métodos HTTP específicos (`POST`, `PUT`) ou todos eles com o curinga `"*"`.
47* Cabeçalhos HTTP específicos ou todos eles com o curinga `"*"`.
48
· · ·
47▶* Cabeçalhos HTTP específicos ou todos eles com o curinga `"*"`.
48
49{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
· · ·
50
51
52▶Os parâmetros padrão usados pela implementação `CORSMiddleware` são restritivos por padrão, então você precisará habilitar explicitamente as origens, métodos ou cabeçalhos específicos para que os navegadores tenham permissão para usá-los em um contexto cross domain.
53
54Os seguintes argumentos são suportados:
+ 3 more matches in this file
37</div>
38
39▶¡Eso es todo! Ahora puedes acceder a tu app en esa URL. ✨
40
41## Acerca de FastAPI Cloud { #about-fastapi-cloud }
· · ·
63## Despliega tu propio servidor { #deploy-your-own-server }
64
65▶También te enseñaré más adelante en esta guía de **Despliegue** todos los detalles, para que puedas entender qué está pasando, qué tiene que ocurrir o cómo desplegar apps de FastAPI por tu cuenta, también con tus propios servidores. 🤓
66
5## Montar una aplicación **FastAPI** { #mounting-a-fastapi-application }
6
7▶"Montar" significa añadir una aplicación completamente "independiente" en un path específico, que luego se encarga de manejar todo bajo ese path, con las _path operations_ declaradas en esa sub-aplicación.
8
9### Aplicación de nivel superior { #top-level-application }
· · ·
63De esa manera, la sub-aplicación sabrá usar ese prefijo de path para la interfaz de documentación.
64
65▶Y la sub-aplicación también podría tener sus propias sub-aplicaciones montadas y todo funcionaría correctamente, porque FastAPI maneja todos estos `root_path`s automáticamente.
66
67Aprenderás más sobre el `root_path` y cómo usarlo explícitamente en la sección sobre [Detrás de un Proxy](behind-a-proxy.md).
5Un **request** body es un dato enviado por el cliente a tu API. Un **response** body es el dato que tu API envía al cliente.
6
7▶Tu API casi siempre tiene que enviar un **response** body. Pero los clientes no necesariamente necesitan enviar **request bodies** todo el tiempo, a veces solo solicitan un path, quizás con algunos parámetros de query, pero no envían un body.
8
9Para declarar un **request** body, usas modelos de [Pydantic](https://docs.pydantic.dev/) con todo su poder y beneficios.
· · ·
9▶Para declarar un **request** body, usas modelos de [Pydantic](https://docs.pydantic.dev/) con todo su poder y beneficios.
10
11/// info | Información
· · ·
12
13▶Para enviar datos, deberías usar uno de estos métodos: `POST` (el más común), `PUT`, `DELETE` o `PATCH`.
14
15Enviar un body con un request `GET` tiene un comportamiento indefinido en las especificaciones, no obstante, es soportado por FastAPI, solo para casos de uso muy complejos/extremos.
· · ·
29Luego, declaras tu modelo de datos como una clase que hereda de `BaseModel`.
30
31▶Usa tipos estándar de Python para todos los atributos:
32
33{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
· · ·
73 * Si los datos son inválidos, devolverá un error claro e indicado, señalando exactamente dónde y qué fue lo incorrecto.
74* Proporcionar los datos recibidos en el parámetro `item`.
75▶ * Como lo declaraste en la función como de tipo `Item`, también tendrás todo el soporte del editor (autocompletado, etc.) para todos los atributos y sus tipos.
76* Generar definiciones de [JSON Schema](https://json-schema.org) para tu modelo, que también puedes usar en cualquier otro lugar si tiene sentido para tu proyecto.
77* Esos esquemas serán parte del esquema de OpenAPI generado y usados por las <abbr title="User Interfaces - Interfaces de usuario">UIs</abbr> de documentación automática.
+ 4 more matches in this file
21* Convertir cuerpos de requests no-JSON a JSON (por ejemplo, [`msgpack`](https://msgpack.org/index.html)).
22* Descomprimir cuerpos de requests comprimidos con gzip.
23▶* Registrar automáticamente todos los request bodies.
24
25## Manejo de codificaciones personalizadas de request body { #handling-custom-request-body-encodings }
· · ·
37///
38
39▶Primero, creamos una clase `GzipRequest`, que sobrescribirá el método `Request.body()` para descomprimir el request body si hay un header apropiado.
40
41Si no hay `gzip` en el header, no intentará descomprimir el request body.
· · ·
49A continuación, creamos una subclase personalizada de `fastapi.routing.APIRoute` que hará uso de `GzipRequest`.
50
51▶Esta vez, sobrescribirá el método `APIRoute.get_route_handler()`.
52
53Este método devuelve una función. Y esa función es la que recibirá un request y devolverá un response.
· · ·
53▶Este método devuelve una función. Y esa función es la que recibirá un request y devolverá un response.
54
55Aquí lo usamos para crear un `GzipRequest` a partir del request original.
· · ·
91También podemos usar este mismo enfoque para acceder al request body en un manejador de excepciones.
92
93▶Todo lo que necesitamos hacer es manejar el request dentro de un bloque `try`/`except`:
94
95{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
76* Criar uma cópia do modelo armazenado, atualizando seus atributos com as atualizações parciais recebidas (usando o parâmetro `update`).
77* Converter o modelo copiado em algo que possa ser armazenado no seu BD (por exemplo, usando o `jsonable_encoder`).
78▶ * Isso é comparável a usar o método `.model_dump()` do modelo novamente, mas garante (e converte) os valores para tipos de dados que possam ser convertidos em JSON, por exemplo, `datetime` para `str`.
79* Salvar os dados no seu BD.
80* Retornar o modelo atualizado.
· · ·
94Observe que o modelo de entrada ainda é validado.
95
96▶Portanto, se você quiser receber atualizações parciais que possam omitir todos os atributos, você precisa ter um modelo com todos os atributos marcados como opcionais (com valores padrão ou `None`).
97
98Para distinguir entre os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md).
· · ·
98▶Para distinguir entre os modelos com todos os valores opcionais para **atualizações** e modelos com valores obrigatórios para **criação**, você pode usar as ideias descritas em [Modelos Adicionais](extra-models.md).
99
100///
76* Crear una copia del modelo almacenado, actualizando sus atributos con las actualizaciones parciales recibidas (usando el parámetro `update`).
77* Convertir el modelo copiado en algo que pueda almacenarse en tu DB (por ejemplo, usando el `jsonable_encoder`).
78▶ * Esto es comparable a usar el método `.model_dump()` del modelo de nuevo, pero asegura (y convierte) los valores a tipos de datos que pueden convertirse a JSON, por ejemplo, `datetime` a `str`.
79* Guardar los datos en tu DB.
80* Devolver el modelo actualizado.
· · ·
94Observa que el modelo de entrada sigue siendo validado.
95
96▶Entonces, si deseas recibir actualizaciones parciales que puedan omitir todos los atributos, necesitas tener un modelo con todos los atributos marcados como opcionales (con valores por defecto o `None`).
97
98Para distinguir entre los modelos con todos los valores opcionales para **actualizaciones** y modelos con valores requeridos para **creación**, puedes utilizar las ideas descritas en [Modelos Extra](extra-models.md).
· · ·
98▶Para distinguir entre los modelos con todos los valores opcionales para **actualizaciones** y modelos con valores requeridos para **creación**, puedes utilizar las ideas descritas en [Modelos Extra](extra-models.md).
99
100///
47Pela última [Pesquisa do Desenvolvedor Python](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools), isso cobre cerca de 80% dos usuários.
48
49▶Isso significa que o **FastAPI** foi testado especificamente com os editores usados por 80% dos desenvolvedores Python. Como a maioria dos outros editores tendem a funcionar de forma similar, todos os seus benefícios devem funcionar para virtualmente todos os editores.
50
51Dessa forma eu pude encontrar a melhor maneira de reduzir duplicação de código o máximo possível, ter preenchimento automático em todos os lugares, conferência de tipos e erros etc.
· · ·
51▶Dessa forma eu pude encontrar a melhor maneira de reduzir duplicação de código o máximo possível, ter preenchimento automático em todos os lugares, conferência de tipos e erros etc.
52
53Tudo de uma forma que oferecesse a melhor experiência de desenvolvimento para todos os desenvolvedores.
· · ·
53▶Tudo de uma forma que oferecesse a melhor experiência de desenvolvimento para todos os desenvolvedores.
54
55## Requisitos { #requirements }