Skip to content

feat: describe typed Socket.IO operations with AsyncAPI - #4

Merged
atomiechen merged 2 commits into
mainfrom
codex/operation-contract
Sep 25, 2026
Merged

atomiechen merged 2 commits into
mainfrom
codex/operation-contract

Conversation

@atomiechen

Copy link
Copy Markdown
Owner

Why

Outgoing event validation previously knew only an event name and payload type. It could not describe a stable namespace or acknowledgement type, so runtime behavior and generated protocol descriptions had no shared, complete operation contract.

Changes

  • Record local send and receive contracts by namespace, event, direction, payload, and declared ACK type.
  • Add optional keyword-only namespace and ack_type to register_emit(). An unscoped registration retains its previous event-wide behavior; a scoped registration overrides it only in that namespace. ack_type is declarative and does not change call(response_model=...) validation.
  • Add pydantic_socketio.asyncapi_schema(sio, *, title, version) to project those registrations into AsyncAPI 3.1. Socket.IO-specific event, role, namespace fallback, and ACK semantics live under x-pydantic-socketio.
  • Remove the never-implemented schema() placeholder, which had only returned None and had no documented use. This is technically an API removal, with no working behavior to migrate.
  • Keep lifecycle and catch-all handlers explicitly listed as omitted instead of representing them as concrete business events.

Verification

  • Pytest: 63 passed on each Python 3.8–3.13; 63 passed with both python-socketio==5.12.1 and ==5.17.0.
  • Ruff and Pyright pass. Tests cover all four server/client variants, monkey patching, namespace fallback/override, ACK shapes, real Socket.IO round-trip, and deterministic export keys.
  • A document generated from real registrations passes the official AsyncAPI 3.1 JSON Schema and parser with zero diagnostics.
  • The official AsyncAPI HTML template renders the generated document. A schema-only probe recovered the matching client emit/on operations, namespaces, payload examples, and ACK shapes.

Product boundary

The schema is useful for documentation and machine-readable contracts. Generic tooling currently renders multi-argument payloads as arrays and does not provide a ready-made Socket.IO client SDK from AsyncAPI 3.1. This PR does not add a generator, runtime dependency, wrapper, DI system, or documentation server.

Record namespace-scoped outgoing payloads and declared ACK types alongside inbound handler contracts while preserving existing emit and call behavior. Project the local contract to AsyncAPI 3.1 with Socket.IO semantics kept in a library-specific extension. Remove the never-implemented schema() placeholder and cover runtime, typing, and export behavior.
@atomiechen
atomiechen merged commit 84309f3 into main Sep 25, 2026
18 checks passed
@atomiechen
atomiechen deleted the codex/operation-contract branch September 27, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant