Skip to content

Commit 5876430

Browse files
committed
final v2 release - assorted fixes + bandaids so it will at least run again
1 parent e94096e commit 5876430

39 files changed

Lines changed: 2180 additions & 339 deletions

.github/workflows/codeql-analysis.yml

Lines changed: 0 additions & 71 deletions
This file was deleted.

.github/workflows/lint.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
name: flake8 Lint
1+
name: ruff lint
22

33
on: [push, pull_request]
44

55
jobs:
6-
flake8-lint:
6+
ruff:
77
runs-on: ubuntu-latest
8-
name: Lint
98
steps:
10-
- name: Check out source repository
11-
uses: actions/checkout@v3
12-
- name: Set up Python environment
13-
uses: actions/setup-python@v4
9+
- uses: actions/checkout@v4
10+
- name: Install uv
11+
uses: astral-sh/setup-uv@v7
1412
with:
15-
python-version: "3.11"
16-
- name: flake8 Lint
17-
uses: py-actions/flake8@v2
13+
python-version: '3.13'
14+
- name: Install dependencies
15+
run: uv sync
16+
- name: ruff check
17+
run: uv run ruff check .

.github/workflows/nightly.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: nightly live tests
2+
3+
4+
on:
5+
schedule:
6+
- cron: '17 1 * * *'
7+
workflow_dispatch:
8+
9+
jobs:
10+
live:
11+
runs-on: ubuntu-latest
12+
continue-on-error: true
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v7
17+
with:
18+
python-version: '3.13'
19+
- name: Install dependencies
20+
run: uv sync
21+
- name: Run live tests against real exchanges
22+
run: uv run pytest -m live -o addopts="" tests/

.github/workflows/publish.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: publish
2+
3+
4+
on:
5+
push:
6+
tags: ['v*']
7+
workflow_dispatch:
8+
9+
jobs:
10+
sdist:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v7
16+
- name: Build sdist
17+
run: uv build --sdist
18+
- uses: actions/upload-artifact@v4
19+
with:
20+
name: dist-sdist
21+
path: dist/*.tar.gz
22+
23+
wheels:
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest]
28+
runs-on: ${{ matrix.os }}
29+
steps:
30+
- uses: actions/checkout@v4
31+
- name: Build wheels
32+
uses: pypa/cibuildwheel@v3.4.1
33+
- uses: actions/upload-artifact@v4
34+
with:
35+
name: dist-wheels-${{ matrix.os }}
36+
path: wheelhouse/*.whl
37+
38+
publish:
39+
if: startsWith(github.ref, 'refs/tags/v')
40+
needs: [sdist, wheels]
41+
runs-on: ubuntu-latest
42+
environment: pypi
43+
permissions:
44+
id-token: write
45+
steps:
46+
- uses: actions/download-artifact@v4
47+
with:
48+
pattern: dist-*
49+
merge-multiple: true
50+
path: dist/
51+
- name: Publish to PyPI (trusted publishing)
52+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/tests.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,19 @@ name: cryptofeed tests
33
on: [push, pull_request]
44

55
jobs:
6-
build:
7-
6+
test:
87
runs-on: ubuntu-latest
98
strategy:
109
matrix:
1110
python-version: ['3.12', '3.13', '3.14']
1211

1312
steps:
13+
- uses: actions/checkout@v4
1414
- name: Install uv
1515
uses: astral-sh/setup-uv@v7
16-
- uses: actions/checkout@v3
17-
- name: Set up Python ${{ matrix.python-version }}
18-
uses: actions/setup-python@v2
1916
with:
2017
python-version: ${{ matrix.python-version }}
2118
- name: Install dependencies
22-
run: |
23-
uv sync
24-
uv pip install pytest
25-
uv pip install -e .
26-
- name: Test with pytest
27-
run: |
28-
uv run pytest tests/
19+
run: uv sync
20+
- name: Run tests (offline suite)
21+
run: uv run pytest tests/

CHANGES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
## Changelog
22

3+
### 2.5.0 (2026-08-08)
4+
* Update: Python 3.12+ required, completed move to uv, `setup.py` removed
5+
* Update: CI/CD overhaul
6+
* Bugfix: various bugs in FeedHandler that prevented it from running on 3.14+
7+
* Bugfix: various backend issues that prevented them from working with later versions of Python
8+
* Bugfix: Gemini authenticated issue with newer version of websocket library
9+
* Bugfix: Binance listenKey refresh now uses aiohttp
10+
* Update: Binance per connection stream limit (issue #1087)
11+
* Bugfix: Bybit L2_BOOK callback timestamp normalization (issue #1083)
12+
313
### 2.4.1 (2025-02-08)
414
* Update: Added `is_data_json` to `write()` in `HTTPSync` from `connection.py` to support JSON payloads (#1071)
515
* Bugfix: Handle empty nextFundingRate in OKX

README.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
# Note - Cryptofeed is in a state of flux. Modernization is underway - expect a 3.0 release sometime in the near future. Be aware breaking changes will take place. Before the 3.0 release the library is only semi-functional
2-
3-
4-
51
# Cryptocurrency Exchange Feed Handler
62
[![License](https://img.shields.io/badge/license-XFree86-blue.svg)](LICENSE)
7-
![Python](https://img.shields.io/badge/Python-3.8+-green.svg)
3+
![Python](https://img.shields.io/badge/Python-3.12+-green.svg)
84
[![PyPi](https://img.shields.io/badge/PyPi-cryptofeed-brightgreen.svg)](https://pypi.python.org/pypi/cryptofeed)
95
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/efa4e0d6e10b41d0b51454d08f7b33b1)](https://www.codacy.com/app/bmoscon/cryptofeed?utm_source=github.com&utm_medium=referral&utm_content=bmoscon/cryptofeed&utm_campaign=Badge_Grade)
106

@@ -151,7 +147,7 @@ Supported Backends:
151147

152148
## Installation
153149

154-
**Note:** cryptofeed requires Python 3.8+
150+
**Note:** cryptofeed requires Python 3.12+
155151

156152
Cryptofeed can be installed from PyPi. (It's recommended that you install in a virtual environment of your choosing).
157153

@@ -161,13 +157,13 @@ Cryptofeed has optional dependencies, depending on the backends used. You can in
161157

162158
pip install cryptofeed[all]
163159

164-
If you wish to clone the repository and install from source, run this command from the root of the cloned repository.
160+
If you wish to clone the repository and work on it (development uses [uv](https://docs.astral.sh/uv/)), run this from the root of the cloned repository:
165161

166-
python setup.py install
162+
uv sync
167163

168-
Alternatively, you can install in 'edit' mode (also called development mode):
164+
Alternatively, you can install from source in editable mode with pip:
169165

170-
python setup.py develop
166+
pip install -e .
171167

172168
See more discussion of package installation in [INSTALL.md](https://github.com/bmoscon/cryptofeed/blob/master/INSTALL.md).
173169

cryptofeed/backends/kafka.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,10 @@ def _default_serializer(self, to_bytes: dict | str) -> ByteString:
5656

5757
async def _connect(self):
5858
if not self.producer:
59-
loop = asyncio.get_event_loop()
6059
try:
6160
config_keys = ', '.join([k for k in self.producer_config.keys()])
6261
LOG.info(f'{self.__class__.__name__}: Configuring AIOKafka with the following parameters: {config_keys}')
63-
self.producer = AIOKafkaProducer(**self.producer_config, loop=loop)
62+
self.producer = AIOKafkaProducer(**self.producer_config)
6463
# Quit if invalid config option passed to AIOKafka
6564
except (TypeError, ValueError) as e:
6665
LOG.error(f'{self.__class__.__name__}: Invalid AIOKafka configuration: {e.args}{chr(10)}See https://aiokafka.readthedocs.io/en/stable/api.html#aiokafka.AIOKafkaProducer for list of configuration options')

cryptofeed/backends/rabbitmq.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
Please see the LICENSE file for the terms and conditions
55
associated with this software.
66
'''
7-
import asyncio
87
from collections import defaultdict
98

109
import aio_pika
@@ -44,11 +43,11 @@ def __init__(self, host='localhost', none_to=None, numeric_type=float, queue_nam
4443
async def connect(self):
4544
if not self.conn:
4645
if self.exchange_mode:
47-
connection = await aio_pika.connect_robust(f"amqp://{self.host}", loop=asyncio.get_running_loop())
46+
connection = await aio_pika.connect_robust(f"amqp://{self.host}")
4847
self.conn = await connection.channel()
4948
self.conn = await self.conn.declare_exchange(self.exchange_name, self.exchange_type, durable=True, auto_delete=False)
5049
else:
51-
connection = await aio_pika.connect_robust(f"amqp://{self.host}", loop=asyncio.get_running_loop())
50+
connection = await aio_pika.connect_robust(f"amqp://{self.host}")
5251
self.conn = await connection.channel()
5352
await self.conn.declare_queue(self.queue_name, auto_delete=False, durable=True)
5453

cryptofeed/backends/redis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(self, host='127.0.0.1', port=6379, socket=None, key=None, none_to='
2424
prefix = 'unix://'
2525
port = None
2626

27-
self.redis = f"{prefix}{host}" + f":{port}" if port else ""
27+
self.redis = f"{prefix}{host}" + (f":{port}" if port else "")
2828
self.key = key if key else self.default_key
2929
self.numeric_type = numeric_type
3030
self.none_to = none_to

0 commit comments

Comments
 (0)