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?

PaqueteRol
FastAPIFramework: decoradores, validación, documentación
uvicornServidor 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.py dentro de app/: 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íneaQué hace
from fastapi import FastAPIImporta 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

ParteSignificado
uvicornEl servidor ASGI
app.mainMódulo: carpeta app/, archivo main.py
:appVariable dentro de main.py que contiene la instancia FastAPI
--reloadReinicia 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:

AspectoWSGI (Flask, Django)ASGI (FastAPI)
ProtocoloSíncronoAsíncrono
ConcurrenciaUn request por workerMúltiples simultáneos
WebSocketsNo nativoSoportado
Servidor típicoGunicornUvicorn

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.py existe y contiene una instancia app = FastAPI()

Resumen

  • ✅ Un virtual environment aísla las dependencias de tu proyecto
  • FastAPI es el framework; uvicorn es el servidor ASGI
  • requirements.txt documenta dependencias para reproducibilidad
  • ✅ Estructura recomendada: app/ con __init__.py y main.py
  • uvicorn app.main:app --reload = servidor + módulo:variable + hot reload
  • .gitignore debe excluir venv/, __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

  1. FastAPI - First Steps - Tutorial oficial
  2. Python venv - Virtual environments
  3. Uvicorn Settings - Opciones de configuración
  4. pip - Requirements - Formato requirements.txt
  5. Real Python - Virtual Environments - Tutorial detallado
  6. ASGI Specification - Estándar que usa uvicorn

Módulo 1, Cápsula 03 — FastAPI Fundamentals Guide