Streams en asyncio: Reader, Writer y TCP resuelve un problema frecuente en proyectos Python: Lee y escribe protocolos TCP asíncronos con APIs de alto nivel y límites explícitos. Esta guía explica el mecanismo, presenta un ejemplo ejecutable y marca los límites que evitan una implementación frágil.

Concepto y caso de uso

open_connection devuelve reader y writer. reader permite lecturas por línea o tamaño; writer almacena salida y drain controla el flujo.

Para repasar los fundamentos relacionados, consulta también la guía de async y await. La integración es más simple cuando cada función recibe dependencias y datos explícitamente en lugar de depender de estado global.

Ejemplo práctico

import asyncio

async def fetch(host: str, port: int) -> bytes:
    reader, writer = await asyncio.open_connection(host, port)
    try:
        writer.write(b"PING\n")
        await writer.drain()
        return await reader.readline()
    finally:
        writer.close()
        await writer.wait_closed()

Define framing del protocolo, limita mensajes y aplica timeouts a conexiones y lecturas. Cierra y espera siempre wait_closed.

Decisiones importantes

La elección correcta depende del contrato público, del volumen y del comportamiento ante fallos.

Considera concurrencia, entradas vacías y fallos parciales. Documenta cada límite que afecte a consumidores y usa nombres que expresen intención.

Errores frecuentes

El ejemplo mínimo no sustituye límites, manejo de errores y observabilidad. read puede esperar para siempre si el peer incumple el protocolo. Omitir drain aumenta buffers; asumir que un read es un mensaje confunde TCP.

Evita capturar excepciones sin contexto o devolver resultados parciales como si fueran completos. Un fallo explícito suele ser más seguro que datos silenciosamente incorrectos.

Cómo validar

Valida el comportamiento y no solo el camino feliz. Prueba mensajes fragmentados, varios en un paquete, desconexión a mitad y entrada por encima del límite.

La documentación oficial, consultada el 28 de julio de 2026, detalla la API y debe ser la referencia para cambios futuros.