Metadata-Version: 2.4
Name: socket-sim
Version: 0.1.0
Summary: A generic, embeddable Socket.IO test console web component for FastAPI/python-socketio backends.
License: MIT
Keywords: socketio,fastapi,websocket,testing,devtools
Author: Manish
Author-email: ms8750122327@gmail.com
Requires-Python: >=3.9
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: fastapi (>=0.100)
Project-URL: Homepage, https://github.com/Alexeino/socket-sim
Project-URL: Repository, https://github.com/Alexeino/socket-sim
Description-Content-Type: text/markdown

# socket-sim

A generic, embeddable Socket.IO test console for FastAPI + [python-socketio](https://python-socketio.readthedocs.io/) backends.

> Distributed on PyPI as `socket-sim`; the importable Python module is `socketio_test_console` (`from socketio_test_console import build_test_console_router`).

It ships as:

- a **backend router** (`build_test_console_router`) that serves a JS asset and a token-minting endpoint, gated behind whatever auth your host app already uses
- a **`<socketio-test-console>` custom element** (Shadow DOM web component) that your host app drops into any existing internal/admin page

It has no opinion about your auth scheme or token format — it just gives you a connect/disconnect toggle, per-event trigger forms (declared by you), and an auto-logging event stream, per pane. Testing a two-sided flow (e.g. matching two users) is just placing two `<socketio-test-console>` tags side by side on the same page.

## Install

```bash
pip install socket-sim
```

or, with Poetry, as a local path dependency during development:

```toml
[tool.poetry.dependencies]
socket-sim = { path = "../socket-sim", develop = true }
```

## Usage

### 1. Wire up the backend router

```python
from fastapi import Depends, FastAPI
from socketio_test_console import build_test_console_router

app = FastAPI()

app.include_router(
    build_test_console_router(
        auth_dependency=require_docs_token,   # any dependency that raises on failure
        token_dependency=mint_test_token,     # any dependency returning {"access_token": ...}
        prefix="/docs/test-socket",
        enabled=settings.DEBUG,               # 404s everything when False
    )
)
```

This exposes:

- `GET {prefix}/console.js` — the bundled custom-element JS (no auth; no secrets in the asset)
- `POST {prefix}/token` — gated by both `auth_dependency` and `token_dependency`, returns whatever JSON your `token_dependency` produces

### 2. Embed the element in your own page

```html
<script src="/docs/test-socket/console.js"></script>

<h2>Client A</h2>
<socketio-test-console
  token-url="/docs/test-socket/token"
  label="A"
  events='[
    {"name": "join_chat", "params": [{"name": "topic", "type": "string", "default": "general"}]},
    {"name": "send_message", "params": [{"name": "message", "type": "string"}]},
    {"name": "skip_chat", "params": []},
    {"name": "end_chat", "params": []}
  ]'
></socketio-test-console>

<h2>Client B</h2>
<socketio-test-console
  token-url="/docs/test-socket/token"
  label="B"
  events='[...]'
></socketio-test-console>
```

Attributes:

| attribute     | required | default       | purpose                                              |
| ------------- | -------- | ------------- | ----------------------------------------------------- |
| `token-url`   | yes      | —             | endpoint to `POST` for a fresh `{access_token, ...}`   |
| `socket-path` | no       | `/socket.io/` | passed as `path` to `io(...)`                          |
| `label`       | no       | `Client`      | display name for this pane                             |
| `events`      | no       | `[]`          | JSON array declaring which events this pane can trigger |

Each declared event renders as its own Swagger-style form: one labeled input per param, an "expect ack" checkbox, and a Trigger button. `params` entries support:

| field         | required | purpose                                                        |
| ------------- | -------- | --------------------------------------------------------------- |
| `name`        | yes      | param label, and the key used only for display (order is what's sent) |
| `type`        | no       | `"string"` (default) \| `"number"` \| `"boolean"` \| `"json"` — controls how the input's raw text is coerced before being emitted |
| `default`     | no       | pre-fills the input                                            |
| `placeholder` | no       | input placeholder text                                          |

Triggering an event calls `socket.emit(name, ...coercedParamValues)`, optionally with an ack callback that logs the response. Each element is a fully independent client pane with its own connect/disconnect toggle, status pill, and scrolling event log that auto-logs every *incoming* event via `socket.onAny` — the package itself has no hardcoded event names; only what the host declares via the `events` attribute is rendered.

The package deliberately does not ship a full HTML page for the console — only the JS asset and the token endpoint. Where and how you embed the tags, and which events you expose, is entirely up to your host app.

## Development

```bash
poetry install
poetry run pytest
```

## Publishing to PyPI

Releases are published via GitHub Actions (`.github/workflows/publish.yml`) using [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC — no stored API token). One-time setup:

1. Push this repo to GitHub.
2. On PyPI (`https://pypi.org/manage/account/publishing/` if the project doesn't exist yet), add a publisher with:
   - PyPI project name: `socket-sim` (must exactly match the `name` in `pyproject.toml`)
   - Repository owner: your GitHub org/user
   - Repository name: `socket-sim`
   - Workflow filename: `publish.yml`
   - Environment name: `pypi`
3. In the GitHub repo, under **Settings → Environments**, create an environment named `pypi` (add required reviewers/protection rules if desired).
4. Create a GitHub Release (or run the workflow manually via `workflow_dispatch`) — the `publish` job builds and uploads to PyPI automatically.

To publish manually instead (e.g. before Trusted Publishing is configured):

```bash
poetry build
poetry publish   # or: twine upload dist/*
```

This requires `poetry config pypi-token.pypi <token>` with a token from PyPI account settings.

