Skip to main content

Framework ligero HTTP + WebSocket.

Project description

wsbuilder

wsbuilder es un paquete Python para construir servidores HTTP + WebSocket sin dependencias externas.

Lightweight Python HTTP + WebSocket framework for building real-time APIs and custom servers.

Keywords: python, http-server, websocket, framework, real-time, api, socket.

Incluye

  • wsbuilder.framework: router, request/response, servidor HTTP, handshake WS y utilidades de frames.
  • wsbuilder.orm: ORM flexible para SQLite3 (modelos, QuerySet, filtros, transacciones anidadas).
  • wsbuilder.dns: DNS UDP local minimo para registros localhost.
  • wsbuilder.cookies / wsbuilder.headers: utilidades para cookies y headers HTTP.
  • wsbuilder.ws_demo: demo completo HTTP + WebSocket + REST + SQLite.

Documentacion completa

  • Sitio de docs para GitHub Pages: mkdocs.yml + contenido en docs/.
  • Vista local:
python -m pip install -r requirements-docs.txt
mkdocs serve
  • La guia tecnica por secciones vive en el sitio MkDocs y cubre arquitectura, HTTP, WebSocket, ORM, cache, seguridad, metricas, DNS y despliegue.

Instalacion local

python -m pip install -e .

Uso rapido del framework

from wsbuilder import App, Response, parse_close_payload

app = App()

@app.view("/")
def home(_request):
    return Response.html("<h1>wsbuilder</h1>")

@app.api("/api/health")
def health(_request):
    return {"ok": True}

@app.ws("/ws/")
def ws_handler(ws, _request):
    while True:
        fin, opcode, payload, _masked, _mask = ws.recv_frame()
        if opcode == 0x8:
            code, reason = parse_close_payload(payload)
            ws.close(code or 1000, reason or "")
            break
        if opcode == 0x9:
            ws.send_pong(payload)
            continue
        if opcode == 0x1:
            ws.send_text(payload.decode("utf-8", errors="ignore"))
        elif opcode == 0x2:
            ws.send_binary(payload)

app.run("0.0.0.0", 8765)

Para CORS sin variables de entorno:

app = App(cors_allow_origin="*")

Thread Pool en Views

Las view por defecto se ejecutan en el hilo padre (thread_count=0). Puedes configurar un pool por ruta con min/max de hilos y limite de requests por hilo:

from wsbuilder import App

app = App()

@app.view("/jobs", min_threads=1, max_threads=4, requests_per_thread=0)
def jobs(_request):
    return "ok"
  • min_threads: workers iniciales para la view.
  • max_threads: tope de workers para esa view (0 deshabilita pool).
  • requests_per_thread: capacidad por worker (0 = sin limite).
  • Distribucion: siempre por least_busy (worker menos ocupado).
  • Se expone metadata de worker en headers y metrics (/api/metrics, /api/metrics/stream).

ORM SQLite3 rapido

from wsbuilder import Database, IntegerField, Model, TextField

class User(Model):
    id = IntegerField(primary_key=True, auto_increment=True)
    username = TextField(unique=True, index=True, null=False)
    email = TextField(null=False)

db = Database("app.db")
User.create_table(db)

u = User(username="alice", email="alice@example.com")
u.save(db)

admins = User.objects(db).filter(username__contains="ali").order_by("-id").all()
print([x.to_dict() for x in admins])

Metrics (JSON stream)

from wsbuilder import App

app = App()
app.enable_metrics()  # crea /api/metrics y /api/metrics/stream

Probar snapshot:

curl http://127.0.0.1:8765/api/metrics

Probar stream NDJSON:

curl -N "http://127.0.0.1:8765/api/metrics/stream?interval=1&limit=5"

Modo continuo (no termina solo):

curl -N "http://127.0.0.1:8765/api/metrics/stream?interval=1&follow=1"

DNS local minimo

from wsbuilder import LocalDNSServer

dns = LocalDNSServer()  # default: 127.0.0.1:5533
dns.start()
# ...
dns.close()

HTTP streaming (chunked)

import time
from wsbuilder import App, Response

app = App()

@app.view("/stream")
def stream(_request):
    def chunks():
        for i in range(5):
            yield f"chunk {i}\n"
            time.sleep(1)
    return Response.stream(chunks(), content_type="text/plain; charset=utf-8")

Ejecutar demo incluido

python -m wsbuilder --host 0.0.0.0 --port 8765
# o
wsbuilder --host 0.0.0.0 --port 8765

Documentacion en navegador

Si activas GitHub Pages en el repo, el workflow docs-pages.yml publica la documentacion automaticamente desde main.

Para ver el sitio antes de subirlo:

mkdocs serve

Y abre http://127.0.0.1:8000.

Configuracion CORS

  • Usa App(cors_allow_origin="https://tu-dominio.com").
  • Usa App(cors_allow_origin="*") para permitir cualquier origen.

CI/CD (GitHub Actions)

  • package-build.yml: construye sdist + wheel, valida metadata y prueba instalacion/import.
  • release-from-main.yml en push a main: calcula semver automaticamente, crea rama release/v<version> desde main, actualiza version del paquete, crea tag v<version> y publica GitHub Release.
  • publish-packages.yml en push de tag v*: construye y publica a PyPI/TestPyPI (instalable con pip).
  • publish-packages.yml en tags v*: adjunta los paquetes al GitHub Release.
  • main-only-from-develop.yml (workflow main-pr-source-check): valida metadata minima del PR hacia main.

Reglas de versionado automatico

  • major: si algun commit trae BREAKING CHANGE, type(scope)!: o ramas/commits marcados como breaking/major.
  • minor: si hay suficiente peso de feat/feature (proporcional frente a cambios patch) y no hay major.
  • patch: cualquier otro caso.

Recomendado usar Conventional Commits para que el calculo de version sea preciso.

Secrets requeridos

  • RELEASE_BOT_TOKEN (recomendado): PAT/fine-grained token para crear rama release/*, crear tag y publicar GitHub Release.
  • RULESET_ADMIN_TOKEN (fallback): usado automaticamente si no existe RELEASE_BOT_TOKEN.
  • PYPI_API_TOKEN: token de publicacion para PyPI.
  • TEST_PYPI_API_TOKEN (opcional): token de publicacion para TestPyPI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wsbuilder-0.12.2.tar.gz (84.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wsbuilder-0.12.2-py3-none-any.whl (78.4 kB view details)

Uploaded Python 3

File details

Details for the file wsbuilder-0.12.2.tar.gz.

File metadata

  • Download URL: wsbuilder-0.12.2.tar.gz
  • Upload date:
  • Size: 84.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wsbuilder-0.12.2.tar.gz
Algorithm Hash digest
SHA256 9dfc2b6fa34268263f0dd5765d29e1ba98c574f6f2ab5066fa68453f04a77db3
MD5 003441aa8324a5c087b652a52227f5dc
BLAKE2b-256 3e1e93844a854e38f4e23ddd9f7384d5384f76ac7015ff21cce046fd2833853e

See more details on using hashes here.

File details

Details for the file wsbuilder-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: wsbuilder-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 78.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wsbuilder-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 97e25961ae22c78d9daa68ecd0f3f16c4fbd1b30f880b50b53ba1a6ddf34e556
MD5 19fd2e81a9f67dd6a7d15ea80a58d3d4
BLAKE2b-256 b945eff0f90c603bc6eec141ee1007fc604e417baa8893f16fd5bdbf1e6f3f29

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page