Metadata-Version: 2.4
Name: 55tech
Version: 0.1.0
Summary: Python client for the 55Tech REST and WebSocket APIs
Keywords: 55tech,odds,betting,bookmaker,api,sdk
Author: brandon-betdex
Author-email: brandon-betdex <brandon@betdex.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: requests>=2.28
Requires-Dist: websocket-client>=1.6
Requires-Dist: zstandard>=0.22
Requires-Python: >=3.10
Project-URL: Documentation, https://docs.oddspapi.io
Project-URL: Homepage, https://oddspapi.io
Project-URL: Issues, https://github.com/brandon-betdex/55tech-sdk-python/issues
Project-URL: Repository, https://github.com/brandon-betdex/55tech-sdk-python
Description-Content-Type: text/markdown

# 55tech

A Python client for the [55Tech](https://oddspapi.io) REST and WebSocket APIs.

Unofficial: not affiliated with or endorsed by 55Tech.

```sh
pip install 55tech
```

## REST

```python
from fiftyfivetech import FiftyFiveTechClient

client = FiftyFiveTechClient(api_key)

markets = client.get_markets(sport_id=10).markets
fixtures = client.get_fixtures(sport_id=10).fixtures
odds = client.get_fixture_odds(fixtures[0].fixture_id, bookmakers=["pinnacle"]).odds
```

Errors derive from `FiftyFiveTechError`.

## Streaming

```python
import threading
from fiftyfivetech.streaming import FixtureBook, Reconnect, SnapshotRequired, StreamListener

listener = StreamListener()
stream = client.create_stream(listener, channels=["odds", "bookmakers"],
                              bookmakers=["pinnacle"], sport_ids=[10])
threading.Thread(target=stream.start, daemon=True).start()

# Seed each fixture you follow, after the stream is connected
listener.apply_snapshot(client.get_fixture_odds(fixture_id, bookmakers=["pinnacle"]), ["pinnacle"])

while True:
    update = listener.output_queue.get()
    if isinstance(update, FixtureBook):
        if update.is_tradeable("pinnacle"):          # has odds, not stale, not suspended
            record = update.get("pinnacle", outcome_id)
            ...
    elif isinstance(update, SnapshotRequired):
        ...    # updates were missed: call apply_snapshot again for each fixture you follow
    elif isinstance(update, Reconnect):
        stream.stop()    # the gateway is about to close: start() again
```

The listener merges stream updates and snapshots into one `FixtureBook` per fixture, keeping the later `changed_at` per record.
`remove_fixture` frees a finished one.

`start()` raises `FiftyFiveTechSocketError` when the connection drops; call it again to reconnect and resume.
