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(
185
186def is_pydantic_v1_model_instance(obj: Any) -> bool:
187▶ # TODO: remove this function once the required version of Pydantic fully
188 # removes pydantic.v1
189 try:
· · ·
197
198def is_pydantic_v1_model_class(cls: Any) -> bool:
199▶ # TODO: remove this function once the required version of Pydantic fully
200 # removes pydantic.v1
201 try:
1225 def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
1226 route = cast(_APIRouteLike, self)
1227▶ # TODO: Replace or deprecate this no-scope hook so included-route
1228 # effective context can be passed explicitly instead of via ContextVar.
1229 effective_context = _effective_route_context_var.get()
· · ·
2210 raise NoMatchFound(name, path_params)
2211
2212▶ # TODO: probably move this out of the Route / Route Group, same in APIRoute
2213 # this should probably be top level FastAPI logic, not part of APIRoute and
2214 # duplicated here
· · ·
2544 # Handle on_startup/on_shutdown locally since Starlette removed support
2545 # Ref: https://github.com/Kludex/starlette/pull/3117
2546▶ # TODO: deprecate this once the lifespan (or alternative) interface is improved
2547 self.on_startup: list[Callable[[], Any]] = (
2548 [] if on_startup is None else list(on_startup)
· · ·
6361 )
6362
6363▶ # TODO: remove this once the lifespan (or alternative) interface is improved
6364 async def _startup(self) -> None:
6365 """
· · ·
6377 handler()
6378
6379▶ # TODO: remove this once the lifespan (or alternative) interface is improved
6380 async def _shutdown(self) -> None:
6381 """
+ 1 more matches in this file
407 # explicit default status_code, and to extract it from them, instead of
408 # doing this inspection tricks, that would probably be in the future
409▶ # TODO: probably make status_code a default class attribute for all
410 # responses in Starlette
411 response_signature = inspect.signature(current_response_class.__init__)
593 dependency_overrides_provider: Any | None = None,
594 dependency_cache: dict[DependencyCacheKey, Any] | None = None,
595▶ # TODO: remove this parameter later, no longer used, not removing it yet as some
596 # people might be monkey patching this function (although that's not supported)
597 async_exit_stack: AsyncExitStack,
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")):
31def get_client(request: pytest.FixtureRequest):
32 clear_sqlmodel()
33▶ # TODO: remove when updating SQL tutorial to use new lifespan API
34 with warnings.catch_warnings(record=True):
35 warnings.simplefilter("always")
· · ·
52
53def test_crud_app(client: TestClient):
54▶ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
55 # this if using obj.model_validate becomes independent of Pydantic v2
56 with warnings.catch_warnings(record=True):
91def test_is_bytes_sequence_annotation_union():
92 # For coverage
93▶ # TODO: in theory this would allow declaring types that could be lists of bytes
94 # to be read from files and other types, but I'm not even sure it's a good idea
95 # to support it as a first class "feature"
· · ·
99def test_is_uploadfile_sequence_annotation():
100 # For coverage
101▶ # TODO: in theory this would allow declaring types that could be lists of UploadFile
102 # and other types, but I'm not even sure it's a good idea to support it as a first
103 # class "feature"
31def get_client(request: pytest.FixtureRequest):
32 clear_sqlmodel()
33▶ # TODO: remove when updating SQL tutorial to use new lifespan API
34 with warnings.catch_warnings(record=True):
35 warnings.simplefilter("always")
· · ·
52
53def test_crud_app(client: TestClient):
54▶ # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor
55 # this if using obj.model_validate becomes independent of Pydantic v2
56 with warnings.catch_warnings(record=True):
927 assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'"
928 assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'"
929▶ # TODO: remove when discarding the openapi_prefix parameter
930 if openapi_prefix:
931 logger.warning(
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
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.
19La CLI detectará automáticamente tu aplicación de FastAPI y la desplegará en la nube. Si no has iniciado sesión, se abrirá tu navegador para completar el proceso de autenticación.
20
21▶¡Eso es todo! Ahora puedes acceder a tu app en esa URL. ✨
22
23## Acerca de FastAPI Cloud { #about-fastapi-cloud }
· · ·
45## Despliega tu propio servidor { #deploy-your-own-server }
46
47▶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. 🤓
48
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
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`.
· · ·
76{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
77
78▶### Sobrescrever o método { #override-the-method }
79
80Agora, você pode substituir o método `.openapi()` pela sua nova função.
· · ·
80▶Agora, você pode substituir o método `.openapi()` pela sua nova função.
81
82{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
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`.
· · ·
76{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
77
78▶### Sobrescribir el método { #override-the-method }
79
80Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
· · ·
80▶Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
81
82{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
28### Qué es "Montar" { #what-is-mounting }
29
30▶"Montar" significa agregar una aplicación completa "independiente" en un path específico, que luego se encargará de manejar todos los sub-paths.
31
32Esto 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.
· · ·
42El `name="static"` le da un nombre que puede ser utilizado internamente por **FastAPI**.
43
44▶Todos estos parámetros pueden ser diferentes a "`static`", ajústalos según las necesidades y detalles específicos de tu propia aplicación.
45
46## Más info { #more-info }
28### O que é "Montagem" { #what-is-mounting }
29
30▶"Montagem" significa adicionar uma aplicação completamente "independente" em um path específico, que então cuida de lidar com todos os sub-paths.
31
32Isso é 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.
· · ·
42O `name="static"` dá a ele um nome que pode ser usado internamente pelo **FastAPI**.
43
44▶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.
45
46## Mais informações { #more-info }
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).
6Un **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.
7
8▶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.
9
10Para declarar un **request** body, usas modelos de [Pydantic](https://pydantic.dev/docs/) con todo su poder y beneficios.
· · ·
10▶Para declarar un **request** body, usas modelos de [Pydantic](https://pydantic.dev/docs/) con todo su poder y beneficios.
11
12/// note | Nota
· · ·
13
14▶Para enviar datos, deberías usar uno de estos métodos: `POST` (el más común), `PUT`, `DELETE` o `PATCH`.
15
16Enviar 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.
· · ·
30Luego, declaras tu modelo de datos como una clase que hereda de `BaseModel`.
31
32▶Usa tipos estándar de Python para todos los atributos:
33
34{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
· · ·
74 * Si los datos son inválidos, devolverá un error claro e indicado, señalando exactamente dónde y qué fue lo incorrecto.
75* Proporcionar los datos recibidos en el parámetro `item`.
76▶ * 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.
77* 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.
78* 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 request bodies no-JSON a JSON (por ejemplo, [`msgpack`](https://msgpack.org/index.html)).
22* Descomprimir request bodies 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] *}
55### Usar el SDK { #using-the-sdk }
56
57▶Ahora puedes importar y usar el código del cliente. Podría verse así, nota que tienes autocompletado para los métodos:
58
59<img src="/img/tutorial/generate-clients/image02.png">
· · ·
98* `UsersService`
99
100▶### Nombres de los métodos del cliente { #client-method-names }
101
102Ahora mismo los nombres de los métodos generados como `createItemItemsPost` no se ven muy limpios:
· · ·
102▶Ahora mismo los nombres de los métodos generados como `createItemItemsPost` no se ven muy limpios:
103
104```TypeScript
· · ·
108...eso es porque el generador del cliente usa el **operation ID** interno de OpenAPI para cada *path operation*.
109
110▶OpenAPI requiere que cada operation ID sea único a través de todas las *path operations*, por lo que FastAPI usa el **nombre de la función**, el **path**, y el **método/operación HTTP** para generar ese operation ID, porque de esa manera puede asegurarse de que los operation IDs sean únicos.
111
112Pero te mostraré cómo mejorar eso a continuación. 🤓
· · ·
113
114▶## Operation IDs personalizados y mejores nombres de métodos { #custom-operation-ids-and-better-method-names }
115
116Puedes **modificar** la forma en que estos operation IDs son **generados** para hacerlos más simples y tener **nombres de métodos más simples** en los clientes.
+ 10 more matches in this file
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///