Skip to content

Commit 9f6deee

Browse files
committed
feat(python): v3 client and release workflow
1 parent 42ac3c1 commit 9f6deee

29 files changed

Lines changed: 2468 additions & 1102 deletions

.github/workflows/publish.yaml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Publish New Release To PyPI
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
publish:
12+
name: Publish New Release To PyPI
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
ref: ${{ github.event.release.target_commitish }}
20+
21+
- name: Use Python 3.9
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.9"
25+
26+
- name: Install Poetry
27+
run: python -m pip install poetry==1.8.5
28+
29+
- name: Configure Git
30+
run: |
31+
git config --global user.name "GitHub Release Bot"
32+
git config --global user.email "deploy@tardis.dev"
33+
34+
- name: Resolve Release Version
35+
run: |
36+
VERSION="${{ github.event.release.tag_name }}"
37+
VERSION="${VERSION#v}"
38+
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
39+
40+
- name: Update Package Version
41+
run: poetry version "${VERSION}"
42+
43+
- name: Install Dependencies
44+
run: poetry install
45+
46+
- name: Run Tests
47+
run: poetry run pytest tests/ -q -m "not live"
48+
49+
- name: Run Import Smoke Test
50+
run: |
51+
poetry run python -c "from tardis_dev import DEFAULT_ENDPOINT, DEFAULT_DATASETS_ENDPOINT, DEFAULT_CACHE_DIR, Channel, Response, replay, download_datasets, download_datasets_async, get_exchange_details, get_exchange_details_async, clear_cache, default_file_name; print('OK')"
52+
53+
- name: Build Package
54+
run: poetry build
55+
56+
- name: Publish Package
57+
run: poetry publish -u __token__ -p "${{ secrets.PYPI_TOKEN }}"
58+
59+
- name: Commit Version Changes
60+
run: |
61+
git add pyproject.toml
62+
git diff --cached --quiet && exit 0
63+
git commit -m "bump version to ${VERSION}"
64+
65+
- name: Push Version Changes To GitHub
66+
run: git push

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ _build
44
.vscode
55
__pycache__
66
build/
7-
dist/
8-
tardis_client.egg-info
7+
dist/
8+
*.egg-info

README.md

Lines changed: 128 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,128 @@
1-
# tardis-client
2-
3-
[![PyPi](https://img.shields.io/pypi/v/tardis-client.svg)](https://pypi.org/project/tardis-client/)
4-
[![Python](https://img.shields.io/pypi/pyversions/tardis-client.svg)](https://pypi.org/project/tardis-client/)
5-
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
6-
7-
Python client for [tardis.dev](https://tardis.dev) - historical tick-level cryptocurrency market data replay API.
8-
Provides fast, high level and developer friendly wrapper for more low level [HTTP API](https://docs.tardis.dev/api#http-api) with local file based caching build in.
9-
10-
## Installation
11-
12-
Requires Python 3.7.0+ installed.
13-
14-
```sh
15-
pip install tardis-client
16-
```
17-
18-
## Usage
19-
20-
```python
21-
import asyncio
22-
from tardis_client import TardisClient, Channel
23-
24-
async def replay():
25-
tardis_client = TardisClient()
26-
27-
# replay method returns Async Generator
28-
# https://rickyhan.com/jekyll/update/2018/01/27/python36.html
29-
messages = tardis_client.replay(
30-
exchange="bitmex",
31-
from_date="2019-06-01",
32-
to_date="2019-06-02",
33-
filters=[Channel(name="trade", symbols=["XBTUSD","ETHUSD"]), Channel("orderBookL2", ["XBTUSD"])],
34-
)
35-
36-
# this will print all trades and orderBookL2 messages for XBTUSD
37-
# and all trades for ETHUSD for bitmex exchange
38-
# between 2019-06-01T00:00:00.000Z and 2019-06-02T00:00:00.000Z (whole first day of June 2019)
39-
async for local_timestamp, message in messages:
40-
# local timestamp is a Python datetime that marks timestamp when given message has been received
41-
# message is a message object as provided by exchange real-time stream
42-
print(message)
43-
44-
asyncio.run(replay())
45-
```
46-
47-
[![Try on repl.it](https://repl-badge.jajoosam.repl.co/try.png)](https://repl.it/@TardisThad/tardis-python-client-example)
48-
49-
## API
50-
51-
`tardis-client` package provides `TardisClient` and `Channel` classes.
52-
53-
```python
54-
from tardis_client import TardisClient, Channel
55-
```
56-
57-
### TardisClient
58-
59-
Optional client constructor parameters.
60-
61-
| name | type | default value | description |
62-
| ---------------------- | -------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63-
| `api_key` (optional) | `string` | `""` | optional `string` containing API key for [tardis.dev](https://tardis.dev) API. If not provided only first day of each month of data is accessible (free access) |
64-
| `cache_dir` (optional) | `string` | `<os.tmpdir>/.tardis-cache` | optional `string` with path to local dir that will be used as cache location. If not provided default `temp` dir for given OS will be used. |
65-
66-
Example:
67-
68-
```python
69-
# creates new client instance with access only to sample data (first day of each month)
70-
tardis_client = TardisClient()
71-
72-
# creates new client with access to all data for given API key
73-
tardis_client = TardisClient(api_key="YOUR_API_KEY")
74-
75-
# creates new client with custom cache dir
76-
tardis_client = TardisClient(cache_dir="./cache")
77-
```
78-
79-
- ### `tardis_client.clear_cache()`
80-
81-
Removes local file cache dir and it's contents.
82-
83-
Example:
84-
85-
```python
86-
tardis_client = TardisClient()
87-
88-
tardis_client.clear_cache()
89-
```
90-
91-
- ### `tardis_client.replay(exchange, from_date, to_date, filters=[])`
92-
93-
Replays historical market data messages for given replay arguments.
94-
95-
Returns [Async Generator](https://rickyhan.com/jekyll/update/2018/01/27/python36.html) with named tuples (`namedtuple("Response", ["local_timestamp", "message"])`).
96-
97-
- `local_timestamp` is a Python datetime object specyfying when message has been received from the exchange real-time data feed.
98-
99-
- `message` is Python dict with parsed JSON that has exactly the same format as message provided by particular exchange's real-time data feed.
100-
101-
#### `replay` method parameters:
102-
103-
| name | type | default value | description |
104-
| -------------------- | --------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
105-
| `exchange` | `string` | - | requested exchange name - Use [/exchanges](https://docs.tardis.dev/api/http#exchanges) API call to get allowed exchanges ids |
106-
| `from_date` | `string` | - | requested UTC start date of data feed - [valid ISO date string](https://docs.python.org/3/library/datetime.html#datetime.date.fromisoformat), eg: `2019-04-05` or `2019-05-05T00:00:00` |
107-
| `to_date` | `string` | - | requested UTC end date of data feed - [valid ISO date string](https://docs.python.org/3/library/datetime.html#datetime.date.fromisoformat), eg: `2019-04-05` or `2019-05-05T00:00:00` |
108-
| `filters` (optional) | [`List[Channel]`](#channel-class) | [] | optional filters of requested data feed. Use [/exchanges/:exchange](https://docs.tardis.dev/api/http#exchanges-exchange) API call to get allowed channel names and symbols for requested exchange |
109-
110-
##### `Channel` class
111-
112-
`Channel` class constructor parameters.
113-
114-
| name | type | description |
115-
| --------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
116-
| `name` | `string` | Use [/exchanges/:exchange](https://docs.tardis.dev/api#exchanges-exchange) API call to get allowed channel names and symbols for requested exchange |
117-
| `symbols` | `List[string]` | Use [/exchanges/:exchange](https://docs.tardis.dev/api#exchanges-exchange) API call to get allowed channel names and symbols for requested exchange |
118-
119-
```python
120-
Channel(name="trade", symbols=["XBTUSD","ETHUSD"])
121-
Channel("orderBookL2", ["XBTUSD"])
122-
```
123-
124-
## FAQ
125-
126-
#### How to debug it if something went wrong?
127-
128-
`tardis-client` uses Python logging on `DEBUG` level for that purpose. In doubt please create issue in this repository with steps how to reproduce the issue.
129-
130-
#### Where can I find more details about tardis.dev API?
131-
132-
Check out [API docs](https://docs.tardis.dev/api).
133-
134-
## License
135-
136-
MPL-2.0
1+
# tardis-dev
2+
3+
[![PyPi](https://img.shields.io/pypi/v/tardis-dev.svg)](https://pypi.org/project/tardis-dev/)
4+
[![Python](https://img.shields.io/pypi/pyversions/tardis-dev.svg)](https://pypi.org/project/tardis-dev/)
5+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
6+
7+
<br/>
8+
9+
Python `tardis-dev` package provides convenient access to tick-level historical cryptocurrency market data in exchange-native format. It focuses on two primary workflows: replaying historical market data and downloading CSV datasets. If you need normalized replay or real-time streaming, use the Node.js client or Tardis Machine.
10+
11+
<br/>
12+
13+
```python
14+
import asyncio
15+
from tardis_dev import Channel, replay
16+
17+
18+
async def main():
19+
async for local_timestamp, message in replay(
20+
exchange="binance",
21+
from_date="2024-03-01",
22+
to_date="2024-03-02",
23+
filters=[Channel("trade", ["btcusdt"]), Channel("depth", ["btcusdt"])],
24+
api_key="YOUR_API_KEY",
25+
):
26+
print(local_timestamp, message)
27+
28+
29+
asyncio.run(main())
30+
```
31+
32+
<br/>
33+
34+
## Features
35+
36+
- historical tick-level [market data replay](https://docs.tardis.dev/python-client/replaying-historical-data) backed by Tardis.dev [HTTP API](https://docs.tardis.dev/api/http-api-reference#data-feeds-exchange)
37+
38+
<br/>
39+
40+
- [CSV dataset downloads](https://docs.tardis.dev/downloadable-csv-files/overview)
41+
42+
<br/>
43+
44+
- support for many cryptocurrency exchanges — see [docs.tardis.dev](https://docs.tardis.dev/historical-data-details/overview) for the full list
45+
46+
<br/>
47+
<br/>
48+
<br/>
49+
50+
## Installation
51+
52+
Requires Python 3.9+ installed.
53+
54+
```bash
55+
pip install tardis-dev
56+
```
57+
58+
<br/>
59+
<br/>
60+
61+
## Documentation
62+
63+
### [See official docs](https://docs.tardis.dev/python-client/quickstart)
64+
65+
- [Quickstart](https://docs.tardis.dev/python-client/quickstart)
66+
- [Replaying Historical Data](https://docs.tardis.dev/python-client/replaying-historical-data)
67+
- [Downloadable CSV files](https://docs.tardis.dev/downloadable-csv-files/overview)
68+
- [Migration Notice](https://docs.tardis.dev/python-client/migration-notice)
69+
70+
<br/>
71+
<br/>
72+
73+
## Examples
74+
75+
### Replay historical market data
76+
77+
```python
78+
import asyncio
79+
from tardis_dev import Channel, replay
80+
81+
82+
async def main():
83+
async for local_timestamp, message in replay(
84+
exchange="binance",
85+
from_date="2024-03-01",
86+
to_date="2024-03-02",
87+
filters=[Channel("trade", ["btcusdt"]), Channel("depth", ["btcusdt"])],
88+
):
89+
print(local_timestamp, message)
90+
91+
92+
asyncio.run(main())
93+
```
94+
95+
<br/>
96+
97+
### Download CSV datasets
98+
99+
```python
100+
from tardis_dev import download_datasets
101+
102+
103+
download_datasets(
104+
exchange="binance",
105+
data_types=["trades", "incremental_book_L2"],
106+
symbols=["BTCUSDT"],
107+
from_date="2024-03-01",
108+
to_date="2024-03-02",
109+
api_key="YOUR_API_KEY",
110+
)
111+
```
112+
113+
<br/>
114+
115+
### Migration from `tardis-client`
116+
117+
This package is the v3 API. Existing `tardis-client` and `tardis_dev.datasets.download()` users should migrate to the new top-level functions:
118+
119+
- replay: `TardisClient().replay(...)` -> `replay(...)`
120+
- datasets: `from tardis_dev import datasets; datasets.download(...)` -> `from tardis_dev import download_datasets`
121+
- cache cleanup: `tardis_client.clear_cache()` -> `clear_cache()`
122+
123+
See [Migration Notice](https://docs.tardis.dev/python-client/migration-notice) for the full migration guide.
124+
125+
<br/>
126+
<br/>
127+
128+
## See the [tardis-dev docs](https://docs.tardis.dev/python-client/quickstart) for more examples.

0 commit comments

Comments
 (0)