Python 3.12+ Mastery 2026

Programación Moderna · Principios SOLID · Concurrencia Asyncio · Proyectos Reales · 14 Módulos

Capítulo 1 · Introducción a Python 3.12+ y Entorno de Desarrollo

Nivel 1 · Principiante

Python es el lenguaje número #1 en la industria global del software en 2026, dominando desarrollo backend, ciencia de datos, inteligencia artificial, automatización, backend de microservicios y ciberseguridad. Su sintaxis clara y expresiva combinada con un ecosistema gigantesco lo convierten en una herramienta fundamental.

¿Por qué Python 3.12+?
Python 3.12 introdujo mejoras masivas de rendimiento (Interpreter Speedups de 15-60%), mensajes de error hiperprecisos y legibles, mejor sintaxis de tipos genéricos y soporte optimizado de sub-intérpretes aislados (PEP 684).

1.1 El Zen de Python

Ingresa import this en la consola interactiva de Python para leer las directrices de diseño de Tim Peters:

Python REPL
python3
>>> import this
# Beautiful is better than ugly.
# Explicit is better than implicit.
# Simple is better than complex.
# Readability counts.
# Special cases aren't special enough to break the rules.

1.2 Configuración del Entorno de Desarrollo

En el desarrollo moderno se utilizan herramientas ultra rápidas como uv (de Astral) o poetry para gestionar versiones y entornos virtuales aislados.

1
Instalar Python 3.12+
En Windows / Linux / macOS verifica la versión instalada ejecutando python --version o python3 --version.
2
Crear un Entorno Virtual (venv)
Aísla las dependencias de tu proyecto para evitar conflictos globales en el sistema.
3
Activar el Entorno
En Windows PowerShell: .\venv\Scripts\Activate.ps1. En Linux/macOS: source venv/bin/activate.
Bash / Terminal
# Crear directorio e iniciar venv
mkdir mi_proyecto_python && cd mi_proyecto_python
python -m venv venv

# Activar entorno (Linux/macOS)
source venv/bin/activate

# O usar uv (Administrador de paquetes ultra rápido escrito en Rust)
uv venv
uv pip install requests pydantic pytest
Interpretado y Rápido
Python es interpretado mediante código de bytes (bytecode .pyc) y optimizado con un compilador JIT especializado.
Tipado Dinámico Fuertemente Tipado
No necesitas declarar el tipo de una variable explícitamente, pero Python impide operaciones inválidas entre tipos incompatibles.
Multiparadigma
Soporta estilo imperativo, orientado a objetos (POO), funcional y asíncrono en un mismo ecosistema limpio.
Cuestionario — Capítulo 1
1. ¿Qué comando crea un entorno virtual nativo en Python?
El módulo nativo venv incluido en la librería estándar se invoca mediante python -m venv nombre_entorno.
2. ¿Qué significa que Python sea de "tipado dinámico fuertemente tipado"?
En Python, el tipo pertenece al objeto, no a la variable (dinámico). Sin embargo, Python no realiza coerción implícita de tipos peligrosos como C o JS (fuerte).

Capítulo 2 · Sintaxis Básica, Variables y Tipos Primitivos

Nivel 1 · Principiante

En Python todo es un objeto. Las variables actúan como etiquetas de referencia que apuntan a objetos en memoria.

2.1 Tipos de Datos Primitivos

TipoEjemploDescripciónMutabilidad
int42, -1000Enteros de precisión arbitrariaInmutable
float3.14159, 2.5e-3Números de punto flotante de 64-bitInmutable
str"Hola Python"Cadenas de caracteres UnicodeInmutable
boolTrue, FalseBooleanos (subclase de int)Inmutable
bytesb"ASCII"Secuencia inmutable de bytesInmutable
NoneTypeNoneRepresenta la ausencia explícita de valorInmutable

2.2 Manipulación de Strings e Interpolación

Python soporta f-strings (format strings) con expresiones avanzadas evaluadas en tiempo de ejecución:

Python
# Variables
nombre = "AutoNovations"
módulos = 14
tasa_éxito = 0.985

# f-string moderno con especificaciones de formato
mensaje = f"Curso {nombre.upper()} | Módulos: {módulos} | Éxito: {tasa_éxito:.1%}"
print(mensaje)
# Output: Curso AUTONOVATIONS | Módulos: 14 | Éxito: 98.5%

# Operador de autodocumentación (=) disponible desde Python 3.8+
x = 10
y = 25
print(f"{x=}, {y=}, {x+y=}")
# Output: x=10, y=25, x+y=35

2.3 Conversión de Tipos (Casting) y Operadores

Python
# Casting explícito
edad_str = "28"
edad_num = int(edad_str)

# Divisibilidad entera (//) y exponenciación (**)
cuadrado = 5 ** 2   # 25
div_entera = 17 // 5 # 3
modulo = 17 % 5     # 2

# Operadores Lógicos (and, or, not) y de Pertenencia (in, not in)
es_valido = 18 <= edad_num and "Auto" in nombre
Cuestionario — Capítulo 2
1. ¿Qué resultado produce la expresión 10 // 3 en Python?
El operador // realiza división floor (división entera redondeada hacia el infinito negativo).
2. ¿Por qué los strings (str) son considerados inmutables?
Intenta s = "hola"; s[0] = "H" resultará en un TypeError. Cualquier método de string (ej. s.upper()) retorna una *nueva* cadena.

Capítulo 3 · Control de Flujo y Pattern Matching

Nivel 1 · Principiante

Python utiliza la indentación (4 espacios por estándar PEP 8) para delimitar bloques de código. A partir de Python 3.10, la sentencia match-case provee un poderoso sistema de coincidencia de patrones estructurales.

3.1 Condicionales e Iteraciones

Python
# Condicionales con asignación expresión ternaria
estado = "Activo" if limite > 0 else "Inactivo"

# Bucle for con enumerate y range
usuarios = ["Alice", "Bob", "Charlie"]
for indice, usuario in enumerate(usuarios, start=1):
    print(f"[{indice}] Procesando usuario: {usuario}")

# Bucle while con cláusula else (se ejecuta si NO hubo break)
intentos = 0
while intentos < 3:
    if conectar_servidor():
        print("Conexión exitosa")
        break
    intentos += 1
else:
    print("Error: Máximo número de reintentos alcanzado")

3.2 Structural Pattern Matching (match-case)

Mucho más avanzado que un simple switch de C/Java; permite desestructurar diccionarios, tuplas, clases y evaluar guardas if:

Python 3.10+
def procesar_comando(comando):
    match comando.split():
        case ["QUIT" | "EXIT"]:
            return "Saliendo del programa..."
        case ["MOVE", ("NORTH" | "SOUTH" | "EAST" | "WEST") as direccion]:
            return f"Moviéndose hacia {direccion}"
        case ["GET", item, "COUNT", int(cantidad)] if cantidad > 0:
            return f"Obteniendo {cantidad} unidades de {item}"
        case _:
            return "Comando no reconocido"
Cuestionario — Capítulo 3
1. ¿Cuándo se ejecuta el bloque else asociado a un bucle for o while?
La cláusula else de los bucles es perfecta para búsquedas: si encuentras el elemento haces break, pero si recorres todo sin encontrarlo se ejecuta el else.

Capítulo 4 · Estructuras de Datos Integradas y Comprehensions

Nivel 1 · Principiante

Python incluye cuatro estructuras de datos coleccionables fundamentales: Listas, Tuplas, Conjuntos (Sets) y Diccionarios (Dicts).

EstructuraSintaxisOrdenadaMutableDuplicadosUso Principal
list[1, 2, 3]Secuencias mutables generales
tuple(1, 2, 3)NoRegistros inmutables y retornos múltiples
dict{"a": 1}Sí (3.7+)Claves únicasMapeos clave-valor / JSON
set{1, 2, 3}NoNoFiltro de duplicados y operaciones matemáticas

4.1 Comprehensions (Comprensiones)

Permiten construir nuevas colecciones de forma concisa y altamente optimizada en código C subyacente:

Python
# List Comprehension
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cuadrados_pares = [x**2 for x in numeros if x % 2 == 0]
# Result: [4, 16, 36, 64, 100]

# Dict Comprehension
estudiantes = ["Ana", "Pedro", "Maria"]
notas = [95, 88, 92]
mapa_notas = {est: nota for est, nota in zip(estudiantes, notas)}
# Result: {'Ana': 95, 'Pedro': 88, 'Maria': 92}

# Set Comprehension (Elimina duplicados automáticamente)
tags = ["PYTHON", "python", "AI", "ai", "FASTAPI"]
tags_limpios = {t.lower() for t in tags}
# Result: {'python', 'ai', 'fastapi'}

4.2 Slicing Avanzado (Rebanado)

Python
items = [0, 10, 20, 30, 40, 50, 60, 70]

# Sintaxis: lista[inicio:fin:paso]
sub_lista = items[2:6]    # [20, 30, 40, 50]
invertida = items[::-1]   # [70, 60, 50, 40, 30, 20, 10, 0]
saltos = items[::2]       # [0, 20, 40, 60]
Cuestionario — Capítulo 4
1. ¿Cuál es la complejidad temporal promedio de búsqueda (x in s) en un set de Python comparado con una list?
Los conjuntos y claves de diccionarios utilizan tablas Hash internamente, lo que otorga búsquedas instantáneas O(1).

Capítulo 5 · Funciones Avanzadas, Type Hinting y Ámbitos

Nivel 2 · Intermedio

Las funciones en Python son ciudadanos de primera clase (first-class citizens), lo que significa que pueden ser asignadas a variables, pasadas como argumentos y retornadas desde otras funciones.

5.1 Parámetros Flexibles: *args, **kwargs y Posicionales Obligatorios

Python 3.8+ Syntax
def crear_usuario(
    nombre: str,
    /,  # Todo antes de '/' DEBE ser posicional únicamente
    *,  # Todo después de '*' DEBE ser mediante keyword explícito
    email: str,
    rol: str = "developer",
    *habilidades: str,
    **metadatos: any
) -> dict:
    return {
        "nombre": nombre,
        "email": email,
        "rol": rol,
        "habilidades": habilidades,
        "metadatos": metadatos
    }

# Uso correcto
usr = crear_usuario("Carlos", email="carlos@autonovations.com", "Python", "Docker", departamento="AI")
¡Cuidado con Valores por Defecto Mutables! Nunca uses objetos mutables como list o dict por defecto (ej. def f(l=[])). Usa def f(l=None): if l is None: l = [] en su lugar.

5.2 Regla de Scope LEGB (Local, Enclosing, Global, Built-in)

Python busca identificadores en cuatro niveles jerárquicos:

1. L (Local): Variables definidas dentro de la función activa.
2. E (Enclosing): Scope de funciones anidadas contenedoras (Closure).
3. G (Global): Scope a nivel de archivo/módulo actual.
4. B (Built-in): Funciones globales de Python como print, len, range.
Cuestionario — Capítulo 5
1. ¿Qué sucede si ejecutas una función definida como def procesar(datos=[]) y la llamas múltiples veces seguidas?
Los valores por defecto se evalúan en tiempo de *definición* del módulo, no cuando la función se invoca.

Capítulo 6 · POO, Dunder Methods y Data Classes

Nivel 2 · Intermedio

La Programación Orientada a Objetos en Python destaca por el uso de métodos especiales rodeados de doble guion bajo (Dunder Methods / Magic Methods) y encapsulamiento idiomático mediante propiedades.

6.1 Clase Completa con Encapsulamiento y Decoradores

Python
class CuentaBancaria:
    # Atributo de Clase
    banco = "AutoNovations Bank"

    def __init__(self, titular: str, saldo_inicial: float = 0.0):
        self.titular = titular
        self._saldo = saldo_inicial  # Atributo protegido por convención

    @property
    def saldo(self) -> float:
        """Getter idiomático para saldo"""
        return self._saldo

    @saldo.setter
    def saldo(self, nuevo_monto: float):
        """Setter con validación de negocio"""
        if nuevo_monto < 0:
            raise ValueError("El saldo no puede ser negativo")
        self._saldo = nuevo_monto

    # Dunder Methods
    def __repr__(self) -> str:
        return f"CuentaBancaria(titular='{self.titular}', saldo={self._saldo})"

    def __eq__(self, otro) -> bool:
        return isinstance(otro, CuentaBancaria) and self._saldo == otro._saldo

6.2 Data Classes Moderna (@dataclass)

Disponible en el módulo estándar dataclasses; genera automáticamente __init__, __repr__, __eq__ y soporte inmutable con frozen=True:

Python
from dataclasses import dataclass, field
from datetime import datetime

@dataclass(frozen=True, order=True)
class Transaccion:
    id: str
    monto: float
    timestamp: datetime = field(default_factory=datetime.now)

# Inmutable y auto-comparable
tx1 = Transaccion(id="TX-101", monto=250.0)
print(tx1)
# Output: Transaccion(id='TX-101', monto=250.0, timestamp=datetime.datetime(...))
Cuestionario — Capítulo 6
1. ¿Qué ventaja ofrece la propiedad @property sobre los getters tradicionales tipo get_saldo()?
Favorece la sintaxis pythonica manteniendo la encapsulación sin romper el código existente de los clientes.

Capítulo 7 · Manejo Robustos de Excepciones y Debugging

Nivel 2 · Intermedio

Escribir código tolerante a fallos implica usar la filosofía de Python: "It's easier to ask for forgiveness than permission" (EAFP).

7.1 Bloque try-except-else-finally y Excepciones Custom

Python
class APIError(Exception):
    """Excepción personalizada para servicios web"""
    def __init__(self, codigo: int, mensaje: str):
        self.codigo = codigo
        super().__init__(f"[{codigo}] {mensaje}")

def realizar_peticion(url: str):
    try:
        # Simulación de llamada
        res = conectar(url)
    except ConnectionError as err:
        raise APIError(503, "Servicio no disponible") from err
    else:
        # Se ejecuta SOLO si NO hubo excepciones
        print("Petición procesada correctamente")
        return res.json()
    finally:
        # Se ejecuta SIEMPRE para liberar recursos
        cerrar_socket()

7.2 Debugging con breakpoint() nativo

Al invocar breakpoint() en cualquier parte del código, Python pausará la ejecución y abrirá la consola interactiva PDB (Python Debugger).

Cuestionario — Capítulo 7
1. ¿Para qué sirve la cláusula else en un bloque try-except?
Evita colocar código extra dentro del try, previniendo capturar excepciones accidentales.

Capítulo 8 · Gestión de Archivos, Pathlib y Context Managers

Nivel 2 · Intermedio

La gestión de recursos (archivos, conexiones a bases de datos, locks) debe realizarse con la sentencia with para garantizar el cierre seguro de descriptores.

8.1 Pathlib: Manejo Moderno de Rutas

Python
from pathlib import Path
import json

# Rutas orientadas a objetos multiplataforma
directorio_base = Path(__file__).resolve().parent
archivo_config = directorio_base / "config" / "settings.json"

# Crear directorio si no existe
archivo_config.parent.mkdir(parents=True, exist_ok=True)

# Escritura directa
datos = {"app": "AutoNovations", "version": "2026.1"}
archivo_config.write_text(json.dumps(datos, indent=2), encoding="utf-8")

# Lectura directa
contenido = json.loads(archivo_config.read_text(encoding="utf-8"))

8.2 Crear Context Managers Custom con @contextmanager

Python
from contextlib import contextmanager
import time

@contextmanager
def temporizador(etiqueta: str):
    inicio = time.perf_counter()
    try:
        yield
    finally:
        duracion = time.perf_counter() - inicio
        print(f"⏱️ [{etiqueta}] Ejecutado en {duracion:.4f}s")

# Uso práctico
with temporizador("Carga masiva de datos"):
    matriz = [i**2 for i in range(1_000_000)]
Cuestionario — Capítulo 8
1. ¿Qué métodos dunder debe implementar una clase para funcionar con la sentencia with?
__enter__ se ejecuta al iniciar el bloque with y su retorno se asigna a as var. __exit__ atiende la limpieza final.

Capítulo 9 · Arquitectura de Módulos y Estándar pyproject.toml

Nivel 2 · Intermedio

Estructurar paquetes reutilizables requiere adoptar las especificaciones PEP 621 y el archivo estandarizado pyproject.toml.

9.1 Estructura Profesional de Paquete Python

mi_libreria/
├── pyproject.toml
├── README.md
└── src/
└── mi_libreria/
├── __init__.py
├── core.py
└── utils/
├── __init__.py
└── helpers.py

9.2 pyproject.toml Estándar

TOML
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "autonovations-core"
version = "1.0.0"
description = "Librería core de utilidades para sistemas autónomos"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "pydantic>=2.7.0",
    "httpx>=0.27.0",
]

[project.scripts]
auto-cli = "autonovations_core.cli:main"
Cuestionario — Capítulo 9
1. ¿Qué archivo es el estándar moderno actual en empaquetado Python para definir metadatos del proyecto y dependencias?
pyproject.toml unifica la configuración de herramientas (ruff, pytest, mypy) y metadatos de empaquetado.

Capítulo 10 · Decoradores de Alto Nivel y Generadores Memory-Efficient

Nivel 3 · Avanzado

Los decoradores permiten modificar o extender dinámicamente el comportamiento de funciones o clases sin alterar su código fuente.

10.1 Construcción de un Decorador con Parámetros y functools.wraps

Python
from functools import wraps
import time

def reintentar(max_intentos: int = 3, retardo: float = 1.0):
    def decorador(func):
        @wraps(func)  # Preserva el __name__ y __doc__ original
        def wrapper(*args, **kwargs):
            for intento in range(1, max_intentos + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"⚠️ Intento {intento}/{max_intentos} falló: {e}")
                    if intento == max_intentos:
                        raise
                    time.sleep(retardo)
        return wrapper
    return decorador

@reintentar(max_intentos=3, retardo=0.5)
def conectar_sensor_iot():
    """Simula conexión a microcontrolador"""
    raise ConnectionResetError("Sensor no responde")

10.2 Generadores e Iteradores de Memoria Mínima (yield)

En lugar de almacenar millones de registros en memoria RAM, las funciones generadoras devuelven un iterador perezoso (lazy evaluation) mediante yield:

Python
def stream_telemetria_gigante(total_registros: int):
    for i in range(total_registros):
        # Genera un dato a la vez en RAM constante O(1)
        yield {"timestamp": time.time(), "lectura": i * 0.42}

# Procesamiento streaming de 10 millones de items consumiendo < 5MB RAM
for lectura in stream_telemetria_gigante(10_000_000):
    if lectura["lectura"] > 100:
        print("Alerta detectada:", lectura)
        break
Cuestionario — Capítulo 10
1. ¿Qué función cumple el decorador @functools.wraps(func) al construir un decorador personalizado?
Es fundamental para que las herramientas de inspección, documentación e IDEs sigan reconociendo el nombre y la firma original de la función.

Capítulo 11 · Concurrencia Avanzada y Programación Asíncrona (`asyncio`)

Nivel 3 · Avanzado

Elegir el modelo de concurrencia adecuado es vital para escalar aplicaciones en Python:

ModeloMódulo IntegradoIdeal ParaSupera el GIL
ThreadingthreadingOperaciones I/O intensivas simplesNo (GIL activo)
MultiprocessingmultiprocessingCálculo intensivo CPU (Math, ML)Sí (Procesos separados)
AsyncioasyncioI/O concurrente masivo (Web APIs, Sockets)No (Single-thread Event Loop)

11.1 Async / Await y asyncio.TaskGroup (Python 3.11+)

La sintaxis asyncio.TaskGroup ofrece manejo de concurrencia estructurada (structured concurrency), garantizando que si una tarea falla, las demás asociadas sean canceladas limpiamente:

Python 3.11+
import asyncio
import time

async def consultar_servicio(id_servicio: int, retardo: float) -> dict:
    await asyncio.sleep(retardo)  # Cede el control al Event Loop
    return {"id": id_servicio, "status": "OK", "tiempo": retardo}

async def main():
    inicio = time.perf_counter()
    
    # Concurrencia estructurada con TaskGroup
    async with asyncio.TaskGroup() as tg:
        t1 = tg.create_task(consultar_servicio(1, 1.5))
        t2 = tg.create_task(consultar_servicio(2, 0.8))
        t3 = tg.create_task(consultar_servicio(3, 1.2))
        
    # Todas las tareas finalizan aquí
    resultados = [t1.result(), t2.result(), t3.result()]
    duracion = time.perf_counter() - inicio
    print(f"⚡ 3 peticiones completadas en {duracion:.2f}s (en paralelo)")

# Iniciar el Event Loop de asyncio
asyncio.run(main())
Cuestionario — Capítulo 11
1. ¿Para qué tipo de tareas es óptimo utilizar asyncio frente a multiprocessing?
Asyncio aprovecha los tiempos muertos de espera de entrada/salida (I/O) sin el overhead de memoria de crear múltiples procesos.

Capítulo 12 · Type Hinting Avanzado (PEP 695) y Metaprogramación

Nivel 3 · Avanzado

Python 3.12 simplificó radicalmente la sintaxis de tipos genéricos mediante la palabra clave type.

12.1 Sintaxis de Tipos Genéricos de Python 3.12 (PEP 695)

Python 3.12+
# Definición de alias de tipo genérico conciso con la palabra clave type
type Vector[T] = list[T]
type RespuestaAPI[D] = dict[str, D | None]

# Función genérica moderna sin TypeVar verboso
def primero_o_defecto[T](elementos: list[T], defecto: T) -> T:
    return elementos[0] if elementos else defecto

12.2 Metaclases y __init_subclass__

Usa __init_subclass__ como alternativa limpia a las metaclases tradicionales para registrar subclases de forma automática:

Python
class PluginBase:
    registro_plugins = {}

    def __init_subclass__(cls, nombre_plugin: str, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.registro_plugins[nombre_plugin] = cls

class PluginSQL(PluginBase, nombre_plugin="sql"):
    pass

class PluginMongo(PluginBase, nombre_plugin="mongodb"):
    pass

print(PluginBase.registro_plugins)
# Output: {'sql': , 'mongodb': }
Cuestionario — Capítulo 12
1. ¿Qué novedad introdujo la PEP 695 en Python 3.12 para el Type Hinting?
Simplifica radicalmente la escritura de genéricos haciendo el código mucho más limpio.

Capítulo 13 · Testing Profesional con Pytest y Linters Modernos (Ruff)

Nivel 3 · Avanzado

El estándar de la industria para pruebas automatizadas en Python es pytest, complementado por herramientas ultrarrápidas de linting como Ruff.

13.1 Tests Unitarios con Fixtures y Parametrización en Pytest

Python (test_core.py)
import pytest

# Fixture reutilizable
@pytest.fixture
def cliente_base_datos():
    db = {"estado": "conectado", "registros": []}
    yield db  # Setup finalizado, entrega el objeto
    db["registros"].clear()  # Teardown de limpieza

# Test parametrizado (evalúa múltiples entradas)
@pytest.mark.parametrize("entrada,esperado", [
    (2, 4),
    (5, 25),
    (10, 100),
])
def test_calcular_cuadrado(entrada, esperado):
    assert entrada ** 2 == esperado

def test_insercion_db(cliente_base_datos):
    cliente_base_datos["registros"].append("Item 1")
    assert len(cliente_base_datos["registros"]) == 1

13.2 Linting Ultra Rápido con Ruff

Ruff reemplaza a flake8, black, isort y pydocstyle siendo entre 100x y 1000x más rápido al estar escrito en Rust:

Bash
uv pip install ruff pytest pytest-cov
ruff check . --fix     # Revisa y auto-corrige errores de código
ruff format .          # Formateo automático de código
pytest --cov=src       # Ejecuta tests con reporte de cobertura
Cuestionario — Capítulo 13
1. ¿Qué ventaja principal ofrece un @pytest.fixture que utiliza yield en lugar de return?
Es la forma idiomática de pytest para manejar la preparación y limpieza de recursos (bases de datos de prueba, archivos temporales).

Capítulo 14 · Proyectos de Producción e Integración Final

Nivel 3 · Avanzado

Aplica todo lo aprendido en tres proyectos arquitectónicos completos del mundo real.

Proyecto 1 — CLI de Automatización con Typer & Rich

Stack: Typer + Rich + Pydantic

Objetivo: Desarrollar una herramienta de línea de comandos profesional con paneles de color, barras de progreso y autocompletado en shell.

Python (cli_app.py)
import typer
from rich.console import Console
from rich.table import Table

app = typer.Typer(help="AutoNovations CLI Tool 2026")
console = Console()

@app.command()
def listar_servicios(region: str = "us-east-1"):
    """Muestra el estado de microservicios en una región"""
    table = Table(title=f"Estado de Servicios - {region}")
    table.add_column("ID", style="cyan")
    table.add_column("Servicio", style="white")
    table.add_column("Estado", style="green")

    table.add_row("SRV-01", "Auth Service", "HEALTHY")
    table.add_row("SRV-02", "AI Pipeline Engine", "HEALTHY")
    console.print(table)

if __name__ == "__main__":
    app()

Proyecto 2 — API REST Asíncrona de Alto Rendimiento con FastAPI & SQLAlchemy 2.0

Stack: FastAPI + Uvicorn + Pydantic V2 + SQLAlchemy 2.0 Async + PostgreSQL

Python (api_server.py)
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, EmailStr

app = FastAPI(title="AutoNovations Core API", version="2026.1")

class UsuarioCrear(BaseModel):
    nombre: str
    email: EmailStr
    edad: int

@app.post("/api/v1/usuarios", status_code=status.HTTP_201_CREATED)
async def crear_nuevo_usuario(usuario: UsuarioCrear):
    # Simulación de persistencia asíncrona
    if usuario.edad < 18:
        raise HTTPException(status_code=400, detail="Debe ser mayor de edad")
    return {"status": "creado", "datos": usuario}
Proyecto Final Integrador — Crawler / Scraper Web Asyncio con Pipeline ETL

Stack: Asyncio + HTTPX + BeautifulSoup4 + Polars + Pytest

Funcionalidades: Extracción concurrente asíncrona de 1,000+ páginas web, procesamiento ultrarrápido con Polars en lugar de Pandas, validación con Pydantic y tests automatizados en GitHub Actions.

Portfolio Ready: Este proyecto integra patrones de desarrollo profesional solicitados en roles Senior de Python en 2026.
Cuestionario Final — Evaluación General
1. ¿Qué marco de trabajo asíncrono para Python es el referente moderno para crear APIs de altísimo rendimiento con validación de tipos automática?
FastAPI aprovecha asyncio y anotaciones de tipos nativas de Python para ofrecer velocidad comparable a Go y Node.js.
¡Curso Python 3.12+ Mastery Completado!

Has completado exitosamente el curso profesional de Python 2026, dominando sintaxis moderna, arquitectura POO, type hinting, concurrencia asyncio, pytest y desarrollo de proyectos de producción.