Module 1: Setup and First API

Instalación y Setup

Descripción

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 empezar a escribir endpoints en la siguiente cápsula.

Si ya tienes experiencia creando virtual environments en Python, este contenido te resultará familiar — la diferencia es que aquí lo aplicamos específicamente al stack FastAPI + uvicorn.


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.

Analogía: Un virtual environment es como un departamento en un edificio. Cada departamento tiene su propia cocina y baño — no compartes instalaciones con el vecino.

Crear 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

¿Qué creó este comando? Una carpeta venv/ con una copia aislada de Python y pip. Todo lo que instales con pip dentro de este environment queda ahí, no afecta tu sistema.

Activar virtual environment

# 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:

# Antes de activar:
$ 

# Después de activar:
(venv) $ 

Verificar activación

# Verifica que Python apunta al venv
which python
# Mac/Linux: /ruta/al/proyecto/venv/bin/python

# Windows:
where python
# C:\ruta\al\proyecto\venv\Scripts\python.exe

# Verifica versión de pip
pip --version
# pip XX.X from /ruta/al/proyecto/venv/lib/...

Desactivar (cuando termines de trabajar)

deactivate
# El prompt vuelve a la normalidad (sin "(venv)")

Regla importante: Siempre activa el virtual environment antes de trabajar en el proyecto. Siempre.


Instalar FastAPI y uvicorn

Con el virtual environment activo, instala las dependencias:

# Instalar FastAPI (incluye Pydantic, Starlette y dependencias core)
pip install fastapi

# Instalar uvicorn (servidor ASGI para correr FastAPI)
pip install "uvicorn[standard]"

¿Qué es cada paquete?

FastAPI es el framework. Proporciona:

  • Decoradores para definir endpoints (@app.get, @app.post)
  • Integración con Pydantic para validación automática
  • Generación de documentación OpenAPI

uvicorn es el servidor. FastAPI por sí solo no puede escuchar conexiones HTTP — necesita un servidor ASGI que reciba requests y los pase al framework. uvicorn es ese servidor.

Cliente (browser/curl)
    ↓ HTTP request
uvicorn (servidor ASGI) ← recibe el request
    ↓ pasa a FastAPI
FastAPI (framework) ← procesa y genera response
    ↓ retorna a uvicorn
uvicorn → HTTP response al cliente

La opción [standard] de uvicorn instala extras útiles como uvloop (mejor rendimiento) y httptools (parser HTTP más rápido).

Verificar instalación

# Verifica que FastAPI se instaló
pip show fastapi
# Name: fastapi
# Version: 0.115.x
# ...

# Verifica uvicorn
pip show uvicorn
# Name: uvicorn
# Version: 0.32.x
# ...

# Ver todas las dependencias instaladas
pip list

requirements.txt: Versionado de dependencias

Un proyecto profesional documenta exactamente qué dependencias usa y en qué versiones. Esto garantiza que cualquier persona (o tú en 6 meses) pueda recrear el mismo entorno.

Generar requirements.txt

# Opción 1: Generar desde lo instalado (incluye subdependencias)
pip freeze > requirements.txt

El archivo generado se ve así:

annotated-types==0.7.0
anyio==4.8.0
click==8.1.8
fastapi==0.115.6
h11==0.14.0
httptools==0.6.4
idna==3.10
pydantic==2.10.4
pydantic-core==2.27.2
sniffio==1.3.1
starlette==0.41.3
typing-extensions==4.12.2
uvicorn==0.32.1
uvloop==0.21.0

Opción preferida: requirements.txt manual

Para proyectos donde quieres control explícito, crea un requirements.txt manual con solo las dependencias directas:

fastapi==0.115.6
uvicorn[standard]==0.32.1

¿Cuál usar? pip freeze captura todo (incluyendo subdependencias). El manual es más limpio pero requiere que sepas qué instalaste. Para esta guía, usa pip freeze — es más seguro para reproducibilidad.

Instalar desde requirements.txt

Cuando alguien clone tu proyecto (o tú en otra máquina):

# Crear venv y activar
python -m venv venv
source venv/bin/activate  # Mac/Linux

# Instalar dependencias
pip install -r requirements.txt

Estructura de proyecto profesional

Ahora crea la estructura de carpetas. No pongas todo en un solo archivo main.py — desde el inicio organiza profesionalmente:

Estructura recomendada

# Crear estructura
mkdir -p app
touch app/__init__.py
touch app/main.py

Tu proyecto debe verse así:

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

¿Por qué esta estructura?

  • app/ como paquete: Permite importar módulos entre archivos cuando el proyecto crezca. En módulos posteriores agregarás app/models.py, app/routers/, etc.
  • __init__.py: Marca la carpeta como paquete Python. Puede estar vacío — su presencia es lo que importa.
  • main.py dentro de app/: No en la raíz. Esto es convención profesional y facilita deployment con Docker.

Crear .gitignore

# Crear .gitignore en la raíz del proyecto

Contenido del .gitignore:

# Virtual environment
venv/
.venv/

# Python
__pycache__/
*.py[cod]
*.pyo
*.egg-info/
dist/
build/

# IDE
.vscode/
.idea/
*.swp
*.swo

# Environment variables
.env
.env.local

# OS
.DS_Store
Thumbs.db

Tu primer main.py

Escribe el mínimo necesario en app/main.py para verificar que todo funciona:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {"message": "FastAPI is running"}

Este código hace tres cosas:

  1. Importa FastAPI del paquete fastapi
  2. Crea una instancia de la aplicación llamada app
  3. Define un endpoint GET en la ruta / que retorna un diccionario JSON

Verificar que funciona

# Desde la raíz del proyecto (donde está la carpeta app/)
uvicorn app.main:app --reload

Debes ver:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [xxxxx] using StatReload
INFO:     Started server process [xxxxx]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Abre http://127.0.0.1:8000 en tu navegador. Verás:

{"message": "FastAPI is running"}

Si ves eso, tu setup está completo. Presiona Ctrl+C en terminal para detener el servidor.


Comparación: uvicorn app.main:app descompuesto

El comando uvicorn app.main:app --reload tiene cuatro partes:

ParteSignificado
uvicornEl servidor ASGI
app.mainMódulo Python: carpeta app/, archivo main.py
:appVariable dentro de main.py que contiene la instancia FastAPI
--reloadReinicia automáticamente cuando cambias código (solo desarrollo)

Error común: Si tu archivo se llama server.py en vez de main.py, el comando sería uvicorn app.server:app. El nombre después de : siempre es el nombre de la variable FastAPI().


Troubleshooting

Problema 1: command not found: uvicorn

Causa: El virtual environment no está activo, o uvicorn no se instaló.

Solución:

# Verificar que venv está activo (debe verse "(venv)" en el prompt)
source venv/bin/activate  # Mac/Linux

# Reinstalar uvicorn
pip install "uvicorn[standard]"

Problema 2: ModuleNotFoundError: No module named 'app'

Causa: Estás ejecutando uvicorn desde el directorio incorrecto.

Solución:

# Debes estar EN la carpeta raíz del proyecto (donde está app/)
cd /ruta/a/fastapi-fundamentals

# Verificar estructura
ls app/
# Debe mostrar: __init__.py  main.py

# Ahora sí:
uvicorn app.main:app --reload

Problema 3: ERROR: Address already in use

Causa: Otro proceso ya está usando el puerto 8000.

Solución:

# Opción 1: Usar otro puerto
uvicorn app.main:app --reload --port 8001

# Opción 2: Encontrar y matar el proceso en el puerto 8000
# Mac/Linux:
lsof -i :8000
kill -9 <PID>

# Windows:
netstat -ano | findstr :8000
taskkill /PID <PID> /F

Problema 4: pip install falla con permisos

Causa: Estás instalando sin virtual environment activo (intenta instalar globalmente).

Solución:

# NUNCA uses sudo pip install
# En lugar de eso, asegúrate de que venv esté activo:
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
# Crear proyecto
mkdir mi-api
cd mi-api

# Virtual environment
python -m venv venv
source venv/bin/activate  # Mac/Linux

# Instalar dependencias
pip install fastapi "uvicorn[standard]"

# Crear estructura
mkdir -p app
touch app/__init__.py

# Crear main.py con contenido mínimo
cat > app/main.py << 'EOF'
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {"message": "mi-api is running"}
EOF

# Generar requirements.txt
pip freeze > requirements.txt

# Verificar
uvicorn app.main:app --reload
# Debe mostrar: Uvicorn running on http://127.0.0.1:8000

Explicación: Seguiste el flujo completo: crear carpeta → venv → instalar → estructura → verificar. Este es el proceso que repetirás cada vez que inicies un proyecto FastAPI.

Ejercicio 2: Cambiar puerto y host (Fácil)

Levanta uvicorn en el puerto 3000 en vez de 8000, y haz que sea accesible desde cualquier IP (no solo localhost).

Ver solución
# Cambiar puerto y host
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 de red (útil cuando otros dispositivos en tu red necesitan acceder, o cuando trabajas con Docker).

Ejercicio 3: Diagnosticar error de setup (Medio)

Un compañero te muestra este error al intentar correr su proyecto. ¿Qué está mal?

$ uvicorn main:app --reload
ModuleNotFoundError: No module named 'fastapi'

Su estructura es:

mi-proyecto/
├── venv/
├── app/
│   ├── __init__.py
│   └── main.py
└── requirements.txt
Ver solución

Hay dos posibles problemas:

Problema 1: El virtual environment no está activo.

# Solución: Activar venv primero
source venv/bin/activate

Problema 2: El comando usa main:app en vez de app.main:app.

# Incorrecto (busca main.py en raíz, no existe ahí):
uvicorn main:app --reload

# Correcto (busca app/main.py):
uvicorn app.main:app --reload

Explicación: El error No module named 'fastapi' suele significar que pip no instaló en el venv activo. Pero si las dependencias sí están, el error real es la ruta del módulo — main:app busca main.py en la carpeta actual, no dentro de app/.

Ejercicio 4: requirements.txt selectivo (Medio)

Tienes un requirements.txt generado con pip freeze que tiene 15 paquetes. Crea un requirements.txt manual que solo liste las dependencias directas (las que tú instalaste explícitamente).

Ver solución
# requirements.txt - Solo dependencias directas
fastapi==0.115.6
uvicorn[standard]==0.32.1

Para obtener las versiones exactas:

pip show fastapi | grep Version
# Version: 0.115.6

pip show uvicorn | grep Version
# Version: 0.32.1

Explicación: Solo instalaste dos paquetes: fastapi y uvicorn[standard]. Los otros 13 son subdependencias (starlette, pydantic, click, etc.) que pip instala automáticamente. Un requirements.txt manual es más legible, pero si quieres reproducibilidad exacta, usa pip freeze.


Comparación: ASGI vs WSGI

Puede que hayas escuchado el término WSGI si vienes de Flask o Django. FastAPI usa ASGI — la versión moderna:

AspectoWSGI (Flask, Django)ASGI (FastAPI, Starlette)
ProtocoloSíncronoAsíncrono
ConcurrenciaUn request a la vez por workerMúltiples requests simultáneos
WebSocketsNo soportado nativamenteSoportado
Servidor típicoGunicornUvicorn
RendimientoBueno para I/O simpleExcelente para I/O intensivo

¿Por qué importa? Uvicorn es un servidor ASGI. Eso significa que puede manejar múltiples requests simultáneamente sin bloquear, lo cual es crítico cuando tu API hace llamadas a bases de datos o servicios externos. No necesitas entender los detalles ahora — solo saber que elegiste el stack moderno.


Conexión con proyecto

Todo lo que configuraste en esta cápsula es la base del proyecto evolutivo de la guía:

  • El virtual environment lo usarás en los 6 módulos — no lo recreas
  • La estructura app/ crecerá: agregarás app/models.py, app/routers/ en módulos posteriores
  • El requirements.txt acumulará dependencias conforme avances
  • uvicorn con --reload será tu compañero constante durante desarrollo

En el Módulo 6 (proyecto final), tu estructura será mucho más rica, pero la base es exactamente esta.

Módulo 1 (ahora):          Módulo 6 (proyecto final):
app/                        app/
├── __init__.py             ├── __init__.py
└── main.py                 ├── main.py
                            ├── models.py
                            ├── database.py
                            └── routers/
                                ├── __init__.py
                                └── tasks.py

La evolución es gradual — nunca te pediremos reestructurar todo desde cero.


Resumen

  • Un virtual environment aísla las dependencias de tu proyecto del sistema global
  • FastAPI es el framework y uvicorn es el servidor ASGI que lo ejecuta
  • requirements.txt documenta las dependencias exactas para reproducibilidad
  • La estructura recomendada usa app/ como paquete con __init__.py y main.py
  • El comando uvicorn app.main:app --reload descompone en: servidor + módulo:variable + hot reload
  • .gitignore debe excluir venv/, __pycache__/ y .env

Próxima cápsula: Primer endpoint y uvicorn — Crearás endpoints GET, entenderás decoradores como path operations, y usarás hot reload para iterar rápido.


Recursos adicionales

  1. FastAPI - Tutorial First Steps - El tutorial oficial paso a paso
  2. Python venv documentation - Referencia completa de virtual environments
  3. Uvicorn Settings - Todas las opciones de configuración de uvicorn
  4. pip documentation - Requirements files - Formato y opciones de requirements.txt
  5. Real Python - Virtual Environments - Tutorial detallado de venv
  6. ASGI Specification - El estándar que conecta uvicorn con FastAPI