Module 1: Setup and First API
Instalación y Estructura de Proyecto
Descripción de la cápsula
En esta cápsula configuras tu entorno de desarrollo para FastAPI desde cero. Crearás un virtual environment aislado, instalarás FastAPI y uvicorn, definirás un requirements.txt profesional, y armarás la estructura de carpetas que usarás en toda la guía.
No es solo "pip install fastapi." Un setup profesional incluye aislamiento de dependencias, versionado explícito y estructura de proyecto que escale. Al terminar, tendrás un proyecto listo para escribir tu primer endpoint en la siguiente cápsula.
Virtual environment: Aislamiento de dependencias
¿Por qué un virtual environment?
Imagina que tienes dos proyectos Python en tu máquina:
- Proyecto A usa FastAPI 0.109 y Pydantic v2
- Proyecto B usa Flask 2.3 y Pydantic v1
Sin virtual environments, ambos comparten las mismas dependencias globales. Instalar Pydantic v2 para el Proyecto A rompe el Proyecto B. Un virtual environment crea un espacio aislado donde cada proyecto tiene sus propias dependencias sin conflictos.
Crear y activar el virtual environment
# 1. Crear carpeta del proyecto
mkdir fastapi-fundamentals
cd fastapi-fundamentals
# 2. Crear virtual environment
python -m venv venv
# En algunos sistemas:
python3 -m venv venv
# 3. Activar (Mac/Linux)
source venv/bin/activate
# Windows (Command Prompt)
venv\Scripts\activate
# Windows (PowerShell)
venv\Scripts\Activate.ps1
¿Cómo sabes que está activo? Tu terminal muestra (venv) al inicio del prompt:
(venv) $
Desactivar cuando termines
deactivate
Instalar FastAPI y uvicorn
Con el virtual environment activo:
pip install fastapi
pip install "uvicorn[standard]"
¿Qué es cada paquete?
| Paquete | Rol |
|---|---|
| FastAPI | Framework: decoradores, validación, documentación |
| uvicorn | Servidor ASGI que recibe requests HTTP y los pasa a FastAPI |
Cliente → uvicorn (servidor) → FastAPI (framework) → tu código
La opción [standard] de uvicorn instala extras como uvloop y httptools para mejor rendimiento.
Verificar instalación
pip show fastapi
pip show uvicorn
requirements.txt: Versionado de dependencias
Un proyecto profesional documenta exactamente qué dependencias usa. Así cualquier persona (o tú en 6 meses) puede recrear el mismo entorno.
Generar requirements.txt
pip freeze > requirements.txt
Opción manual (solo dependencias directas)
Crea requirements.txt manualmente con solo lo que instalaste:
fastapi==0.115.6
uvicorn[standard]==0.32.1
Instalar desde requirements.txt
python -m venv venv
source venv/bin/activate # Mac/Linux
pip install -r requirements.txt
Estructura de proyecto profesional
Estructura recomendada
fastapi-fundamentals/
├── venv/ # Virtual environment (NO se sube a git)
├── app/
│ ├── __init__.py # Marca app/ como paquete Python
│ └── main.py # Punto de entrada de la aplicación
├── requirements.txt # Dependencias del proyecto
└── .gitignore # Archivos a ignorar en git
Crear la estructura
mkdir -p app
touch app/__init__.py
touch app/main.py
¿Por qué esta estructura?
app/como paquete: Permite importar módulos cuando el proyecto crezca (app.models,app.routers)__init__.py: Marca la carpeta como paquete Python (puede estar vacío)main.pydentro deapp/: Convención profesional que facilita deployment
Crear .gitignore
# Virtual environment
venv/
.venv/
# Python
__pycache__/
*.py[cod]
*.pyo
*.egg-info/
dist/
build/
# IDE
.vscode/
.idea/
# Environment variables
.env
.env.local
# OS
.DS_Store
Thumbs.db
Tu primer main.py
Escribe el mínimo necesario en app/main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "FastAPI is running"}
Desglose del código
| Línea | Qué hace |
|---|---|
from fastapi import FastAPI | Importa la clase principal del framework |
app = FastAPI() | Crea la instancia de la aplicación |
@app.get("/") | Registra un endpoint GET en la ruta raíz |
def root(): | Función que se ejecuta cuando alguien hace GET a / |
return {"message": "..."} | FastAPI convierte el dict a JSON automáticamente |
Verificar que funciona
# Desde la raíz del proyecto
uvicorn app.main:app --reload
Deberías ver:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Application startup complete.
Abre http://127.0.0.1:8000 en tu navegador:
{"message": "FastAPI is running"}
Presiona Ctrl+C para detener el servidor.
Entendiendo uvicorn app.main:app
| Parte | Significado |
|---|---|
uvicorn | El servidor ASGI |
app.main | Módulo: carpeta app/, archivo main.py |
:app | Variable dentro de main.py que contiene la instancia FastAPI |
--reload | Reinicia automáticamente al cambiar código (solo desarrollo) |
Si tu archivo se llamara server.py, usarías uvicorn app.server:app.
Troubleshooting
Problema 1: command not found: uvicorn
Causa: Virtual environment no activo o uvicorn no instalado.
Solución:
source venv/bin/activate # Mac/Linux
pip install "uvicorn[standard]"
Problema 2: ModuleNotFoundError: No module named 'app'
Causa: Ejecutando uvicorn desde el directorio incorrecto.
Solución:
# Debes estar EN la raíz del proyecto (donde está app/)
cd /ruta/a/fastapi-fundamentals
uvicorn app.main:app --reload
Problema 3: ERROR: Address already in use
Causa: Puerto 8000 ocupado por otro proceso.
Solución:
# Usar otro puerto
uvicorn app.main:app --reload --port 8001
# O matar el proceso en 8000 (Mac/Linux)
lsof -i :8000
kill -9 <PID>
Problema 4: pip install falla con permisos
Causa: Instalando sin virtual environment activo.
Solución: Nunca uses sudo pip install. Activa el venv primero:
source venv/bin/activate
pip install fastapi "uvicorn[standard]"
Ejercicios
Ejercicio 1: Setup completo desde cero (Fácil)
Crea un proyecto FastAPI llamado mi-api con virtual environment, instala las dependencias y verifica que uvicorn inicia sin errores.
Ver solución
mkdir mi-api
cd mi-api
python -m venv venv
source venv/bin/activate # Mac/Linux
pip install fastapi "uvicorn[standard]"
mkdir -p app
touch app/__init__.py
# Crear app/main.py con:
# from fastapi import FastAPI
# app = FastAPI()
# @app.get("/")
# def root():
# return {"message": "mi-api is running"}
pip freeze > requirements.txt
uvicorn app.main:app --reload
Explicación: Flujo completo: crear carpeta → venv → instalar → estructura → verificar. Este es el proceso que repetirás en cada proyecto FastAPI.
Ejercicio 2: requirements.txt manual (Fácil)
Genera un requirements.txt con pip freeze. Luego crea uno manual que solo liste fastapi y uvicorn[standard] con sus versiones.
Ver solución
# Obtener versiones
pip show fastapi | grep Version # Version: 0.115.x
pip show uvicorn | grep Version # Version: 0.32.x
# Crear requirements.txt manual
# fastapi==0.115.6
# uvicorn[standard]==0.32.1
Explicación: El manual es más limpio; pip freeze captura todas las subdependencias para máxima reproducibilidad.
Ejercicio 3: Diagnosticar error (Medio)
Un compañero tiene este error:
$ uvicorn main:app --reload
ModuleNotFoundError: No module named 'fastapi'
Su estructura es:
mi-proyecto/
├── venv/
├── app/
│ ├── __init__.py
│ └── main.py
└── requirements.txt
¿Qué está mal?
Ver solución
Hay dos posibles problemas:
1. Virtual environment no activo:
source venv/bin/activate
2. Ruta incorrecta: Usa main:app en vez de app.main:app.
# Incorrecto — busca main.py en la raíz
uvicorn main:app --reload
# Correcto — busca app/main.py
uvicorn app.main:app --reload
Explicación: main:app busca main.py en el directorio actual. El archivo está en app/main.py, así que la ruta correcta es app.main:app.
Ejercicio 4: Estructura alternativa (Medio)
Algunos proyectos usan main.py en la raíz en vez de dentro de app/. ¿Cómo cambiarías el comando uvicorn si tu archivo fuera main.py en la raíz?
Ver solución
# Si main.py está en la raíz:
uvicorn main:app --reload
La sintaxis es módulo:variable. Si main.py está en la raíz, el módulo es main. Si está en app/, el módulo es app.main.
Explicación: La convención con app/main.py es más común en proyectos que escalan, porque permite tener app/models.py, app/routers/, etc.
Ejercicio 5: Estructura con run.py (Medio)
Algunos proyectos incluyen un run.py en la raíz que ejecuta uvicorn. Crea ese archivo y documenta por qué puede ser útil (ej: script único para arrancar con configuración custom).
Ver solución
# run.py en la raíz
import uvicorn
if __name__ == "__main__":
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
python run.py
Por qué útil: Permite cambiar host/port/reload sin recordar flags de CLI. Puedes agregar lógica pre-inicio (cargar .env, verificar DB). Útil para scripts de desarrollo o Docker.
Explicación: run.py es un patrón común cuando la configuración de arranque crece.
Ejercicio 6: Cambiar puerto (Fácil)
Levanta uvicorn en el puerto 3000 y haz que sea accesible desde cualquier IP (no solo localhost).
Ver solución
uvicorn app.main:app --reload --port 3000 --host 0.0.0.0
Explicación: --port 3000 cambia el puerto. --host 0.0.0.0 permite conexiones desde cualquier interfaz (útil con Docker o dispositivos en la red local).
Ejercicio 6: Verificar instalación (Fácil)
Escribe comandos para verificar que FastAPI, uvicorn, Pydantic y Starlette están instalados. ¿Cuáles vienen con FastAPI y cuáles instalaste explícitamente?
Ver solución
pip show fastapi
pip show uvicorn
pip show pydantic
pip show starlette
Explicación: FastAPI incluye Pydantic y Starlette como dependencias. Solo instalaste fastapi y uvicorn[standard] explícitamente. Los otros se instalaron automáticamente.
Dependencias transitivas: ¿Qué instala pip?
Cuando ejecutas pip install fastapi, pip instala no solo FastAPI sino también:
- starlette — Framework web bajo nivel
- pydantic — Validación y serialización
- pydantic-settings — Configuración desde variables de entorno
- Y sus subdependencias (anyio, click, h11, etc.)
pip freeze muestra todo el árbol. Para requirements.txt puedes usar solo las directas (fastapi, uvicorn[standard]) o el output completo de pip freeze para reproducibilidad exacta.
ASGI vs WSGI: Contexto técnico
Puede que hayas oído WSGI si vienes de Flask o Django. FastAPI usa ASGI:
| Aspecto | WSGI (Flask, Django) | ASGI (FastAPI) |
|---|---|---|
| Protocolo | Síncrono | Asíncrono |
| Concurrencia | Un request por worker | Múltiples simultáneos |
| WebSockets | No nativo | Soportado |
| Servidor típico | Gunicorn | Uvicorn |
uvicorn es un servidor ASGI. Eso significa que puede manejar múltiples requests sin bloquear, útil cuando tu API hace llamadas a bases de datos o APIs externas.
Conexión con el proyecto del módulo
La estructura que configuraste es la base del proyecto evolutivo:
Módulo 1 (ahora): Módulo 6 (proyecto final):
app/ app/
├── __init__.py ├── __init__.py
└── main.py ├── main.py
├── models.py
├── database.py
└── routers/
└── tasks.py
La evolución es gradual — nunca reestructurarás todo desde cero.
Alternativa: main.py en la raíz
Algunos tutoriales usan main.py en la raíz del proyecto en vez de app/main.py:
proyecto/
├── main.py
├── venv/
└── requirements.txt
En ese caso: uvicorn main:app --reload. La estructura con app/ como paquete escala mejor cuando agregas app/models.py, app/routers/, etc. Para esta guía usamos app/main.py.
Versiones recomendadas
En requirements.txt conviene fijar versiones para reproducibilidad:
fastapi>=0.100.0,<0.120.0
uvicorn[standard]>=0.20.0,<0.30.0
O versiones exactas con pip freeze. En proyectos reales, >= con límite superior evita roturas por actualizaciones mayores.
Verificación final del setup
Antes de continuar, verifica que todo funciona:
# 1. venv activo
which python
# Debe apuntar a venv/bin/python
# 2. Dependencias instaladas
pip list | grep -E "fastapi|uvicorn"
# 3. Estructura correcta
ls -la app/
# __init__.py main.py
# 4. Servidor arranca
uvicorn app.main:app --reload
# Debe mostrar: Uvicorn running on http://127.0.0.1:8000
Si los cuatro pasos pasan, tu setup está completo.
Qué hacer si algo falla
- which python no apunta a venv: Activa el venv con
source venv/bin/activate - pip list no muestra fastapi:
pip install fastapi "uvicorn[standard]" - ls app/ falla: Crea la carpeta con
mkdir -p app - uvicorn no arranca: Revisa que
app/main.pyexiste y contiene una instanciaapp = FastAPI()
Resumen
- ✅ Un virtual environment aísla las dependencias de tu proyecto
- ✅ FastAPI es el framework; uvicorn es el servidor ASGI
- ✅
requirements.txtdocumenta dependencias para reproducibilidad - ✅ Estructura recomendada:
app/con__init__.pyymain.py - ✅
uvicorn app.main:app --reload= servidor + módulo:variable + hot reload - ✅
.gitignoredebe excluirvenv/,__pycache__/y.env
Próxima cápsula: uvicorn y Servidor de Desarrollo — profundizarás en el servidor ASGI, hot reload, puertos y logs.
Recursos Adicionales
- FastAPI - First Steps - Tutorial oficial
- Python venv - Virtual environments
- Uvicorn Settings - Opciones de configuración
- pip - Requirements - Formato requirements.txt
- Real Python - Virtual Environments - Tutorial detallado
- ASGI Specification - Estándar que usa uvicorn
Módulo 1, Cápsula 03 — FastAPI Fundamentals Guide