# ¿Qué es FastAPI? El framework mas veloz para el desarrollo web con Python. Enfocado para realizar APIs, es el mas rápido en lo que respecta a la velocidad del servidor superando a Node.Js y a GO. Fue creado por Sebastian Ramirez, es de código abierto y se encuentra en Github, es usado por empresas como Uber, Windows, Netflix y Office. # Ubicación de FastAPI en el ecosistema de Python FastAPI utiliza otros frameworks dentro de si para funcionar * **Uvicorn**: es una librería de Python que funciona de servidor, es decir, permite que cualquier computadora se convierta en un servidor * **Starlette**: es un framework de desarrollo web de bajo nivel, para desarrollar aplicaciones con este requieres un amplio conocimiento de Python, entonces FastAPI se encarga de añadirle funcionalidades por encima para que se pueda usar mas fácilmente * **Pydantic**: Es un framework que permite trabajar con datos similar a pandas, pero este te permite usar modelos los cuales aprovechara FastAPI para crear la API # Hello World: creación del entorno de desarrollo https://fastapi.tiangolo.com/tutorial/first-steps/ ``` #Creamos el entorno virtual - virtualenv venv --python=3.9 #Activamos el entorno virtual - source venv/Scripts/activate #Instalamos las dependencias de fastAPI y ucicorn - pip install fastapi uvicorn ``` ``` from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"} ``` ``` uvicorn main:app --reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [28720] INFO: Started server process [28722] INFO: Waiting for application startup. INFO: Application startup complete. ``` # Documentación interactiva de una API FastAPI también está parado sobre los hombros de OpenAPI, el cual es un conjunto de reglas que permite definir cómo describir, crear y visualizar APIs. Es un conjunto de reglas que permiten decir que una API está bien definida. OpenAPI necesita de un software, el cual es Swagger, que es un conjunto de softwares que permiten trabajar con APIs. FastAPI funciona sobre un programa de Swagger el cual es Swagger UI, que permite mostrar la API documentada. Acceder a la documentación interactiva con Swagger UI: ``` {localhost}/docs ``` Acceder a la documentación interactiva con Redoc: ``` {localhost}/redoc ``` # Path Operations Un path es lo mismo que un route o endpoints y es todo aquello que vaya después de nuestro dominio a la derecha del mismo. **¿Que son las operations?** Un operations es exactamente lo mismo que un método http y tenemos las siguientes más populares: * GET * POST * PUT * DELETE Y otros métodos como **OPTIONS, HEAD, PATCH** ![](https://i.imgur.com/x6BRUia.jpg) # Path Parameters https://fastapi.tiangolo.com/tutorial/path-params/ Los parámetros de ruta son partes variables de una ruta URL . Por lo general, se utilizan para señalar un recurso específico dentro de una colección, como un usuario identificado por ID. Una URL puede tener varios parámetros de ruta. ``` from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_id): return {"item_id": item_id} ``` ![](https://i.imgur.com/qOIpgQn.jpg) # Query Parameters https://fastapi.tiangolo.com/tutorial/query-params/ **Query parameters:** son un conjunto definido de parámetros adjuntos al final de una URL . Son extensiones de la URL que se utilizan para ayudar a definir contenido o acciones específicos en función de los datos que se transmiten. ![](https://i.imgur.com/8abmbDS.jpg) # Request Body y Response Body Documentacion: https://fastapi.tiangolo.com/tutorial/body/ Un **Request Body** son datos enviados por el cliente a su API. Un **Response Body** son los datos que su API envía al cliente. ![](https://i.imgur.com/jZMtBoQ.jpg) # Models **Documentacion Oficial:** https://fastapi.tiangolo.com/tutorial/sql-databases/ Un modelo es la representacion de una entidad en codigo, al menos de una manera descriptiva. **¿Como luce un modelo dentro de FastAPI?** Modelo pydantic para validar datos: ``` from typing import List, Optional from pydantic import BaseModel class ItemBase(BaseModel): title: str description: Optional[str] = None class ItemCreate(ItemBase): pass class Item(ItemBase): id: int owner_id: int class Config: orm_mode = True class UserBase(BaseModel): email: str class UserCreate(UserBase): password: str class User(UserBase): id: int is_active: bool items: List[Item] = [] class Config: orm_mode = True ``` Un modelo para mapear los datos a la base de datos (ORM, SQLalchemy) ``` from sqlalchemy import Boolean, Column, ForeignKey, Integer, String from sqlalchemy.orm import relationship from .database import Base class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) email = Column(String, unique=True, index=True) hashed_password = Column(String) is_active = Column(Boolean, default=True) items = relationship("Item", back_populates="owner") class Item(Base): __tablename__ = "items" id = Column(Integer, primary_key=True, index=True) title = Column(String, index=True) description = Column(String, index=True) owner_id = Column(Integer, ForeignKey("users.id")) owner = relationship("User", back_populates="items") ``` # Validaciones: Query Parameters ``` #Python from typing import Optional #FastAPI from fastapi import FastAPI from fastapi import Body, Query app = FastAPI() @app.get("/person/detail") def show_person( name: Optional[str] = Query(None, min_length=1, max_length=50), age: str = Query(...) ): return {name: age} ``` # Validaciones: Path Parameters ``` #Pydantic from pydantic import BaseModel #FastAPI from fastapi import FastAPI from fastapi import Path app = FastAPI() # Validaciones: Path Parameters @app.get("/person/detail/{person_id}") def show_person( person_id: int = Path(..., gt=0) ): return {person_id: "It exists!"} ``` # Validaciones: Request Body ``` #Pydantic from pydantic import BaseModel #FastAPI from fastapi import FastAPI from fastapi import Path app = FastAPI() # Validaciones: Request Body @app.put("/person/{person_id}") def update_person( person_id: int = Path( ..., title="Person ID", description="This is the person ID", gt=0 ), person: Person = Body(...), location: Location = Body(...) ): results = person.dict() results.update(location.dict()) return results ``` # Validaciones: Models ``` #Python from typing import Optional from enum import Enum #Pydantic from pydantic import BaseModel from pydantic import Field #FastAPI from fastapi import FastAPI from fastapi import Body, Query, Path app = FastAPI() # Models class HairColor(Enum): white = "white" brown = "brown" black = "black" blonde = "blonde" red = "red" class Location(BaseModel): city: str state: str country: str class Person(BaseModel): first_name: str = Field( ..., min_length=1, max_length=50, example="Miguel" ) last_name: str = Field( ..., min_length=1, max_length=50, example="Torres" ) age: int = Field( ..., gt=0, le=115, example=25 ) hair_color: Optional[HairColor] = Field(default=None, example=HairColor.black) is_married: Optional[bool] = Field(default=None, example=False) # class Config: # schema_extra = { # "example": { # "first_name": "Facundo", # "last_name": "García Martoni", # "age": 21, # "hair_color": "blonde", # "is_married": False # } # } @app.get("/") def home(): return {"Hello": "World"} ``` # Tipos de datos especiales https://pydantic-docs.helpmanual.io/usage/types/#pydantic-types ![](https://i.imgur.com/YV6JwZo.jpg)