Skip to content

Commit ff10b2e

Browse files
authored
Improve linting tools + update docs (#47)
* add linting tools and configure pre-commit - Add black, isort, autoflake, flake8, and pre-commit to test-requirements.txt - Set line length to 120 characters for all formatting tools - Configure pre-commit hooks with proper exclusions for test_pypi_env/ - Update GitHub Actions to use 120-character line length - Add test_pypi_env/ to .gitignore apply black formatting and fix linting issues - Reformat all Python files with 120-character line length - Fix import ordering with isort - Add E501 and E722 to flake8 ignore list for remaining edge cases - All code now consistently formatted * . * tweak docs * rabbit feedback
1 parent eafa981 commit ff10b2e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+759
-1090
lines changed

.flake8

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[flake8]
22
max-line-length = 88
33
extend-ignore = E203, W503, E501
4-
exclude =
4+
exclude =
55
.git,
66
__pycache__,
77
venv,
@@ -11,4 +11,4 @@ exclude =
1111
*.egg-info
1212
per-file-ignores =
1313
__init__.py:F401
14-
tests/*:F401,F811
14+
tests/*:F401,F811

.github/workflows/publish.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ jobs:
9393
pip install black isort flake8
9494
9595
- name: Check code formatting with black
96-
run: black --check --diff kinesis tests
96+
run: black --check --diff --line-length=120 kinesis tests
9797

9898
- name: Check import sorting with isort
99-
run: isort --check-only --diff kinesis tests
99+
run: isort --check-only --diff --line-length=120 kinesis tests
100100

101101
- name: Lint with flake8
102-
run: flake8 kinesis tests --max-line-length=88 --extend-ignore=E203,W503,E501
102+
run: flake8 kinesis tests --max-line-length=120 --extend-ignore=E203,W503,E712,E402,F401,F841,F541
103103

104104
publish:
105105
needs: [test, lint]
@@ -144,4 +144,4 @@ jobs:
144144
- name: Publish to PyPI
145145
uses: pypa/gh-action-pypi-publish@release/v1
146146
with:
147-
repository-url: https://upload.pypi.org/legacy/
147+
repository-url: https://upload.pypi.org/legacy/

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ jobs:
111111
pip install black isort flake8
112112
113113
- name: Check code formatting with black
114-
run: black --check --diff kinesis tests
114+
run: black --check --diff --line-length=120 kinesis tests
115115

116116
- name: Check import sorting with isort
117-
run: isort --check-only --diff kinesis tests
117+
run: isort --check-only --diff --line-length=120 kinesis tests
118118

119119
- name: Lint with flake8
120-
run: flake8 kinesis tests --max-line-length=88 --extend-ignore=E203,W503,E501
120+
run: flake8 kinesis tests --max-line-length=120 --extend-ignore=E203,W503,E712,E402,F401,F841,F541

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
venv/
2+
test_pypi_env/
23
dist
34
*.egg-info
45
.idea

.pre-commit-config.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
repos:
2+
- repo: https://github.com/psf/black
3+
rev: 24.10.0
4+
hooks:
5+
- id: black
6+
language_version: python3
7+
args: [--line-length=120]
8+
exclude: ^test_pypi_env/
9+
10+
- repo: https://github.com/pycqa/isort
11+
rev: 5.13.2
12+
hooks:
13+
- id: isort
14+
args: [--profile=black, --line-length=120]
15+
exclude: ^test_pypi_env/
16+
17+
- repo: https://github.com/pycqa/flake8
18+
rev: 7.1.1
19+
hooks:
20+
- id: flake8
21+
args: ["--max-line-length=120", "--extend-ignore=E203,W503,E712,E402,F401,F841,F541,E501,E722"]
22+
exclude: ^test_pypi_env/
23+
24+
- repo: https://github.com/pre-commit/pre-commit-hooks
25+
rev: v5.0.0
26+
hooks:
27+
- id: trailing-whitespace
28+
exclude: ^test_pypi_env/
29+
- id: end-of-file-fixer
30+
exclude: ^test_pypi_env/
31+
- id: check-yaml
32+
- id: check-added-large-files
33+
exclude: ^test_pypi_env/
34+
- id: check-merge-conflict

README.md

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,53 @@
22

33
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black) [![PyPI version](https://badge.fury.io/py/async-kinesis.svg)](https://badge.fury.io/py/async-kinesis) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3100/) [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-3110/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3120/)
44

5-
```
5+
High-performance async Python library for AWS Kinesis with production-ready resharding support.
6+
7+
```bash
68
pip install async-kinesis
79
```
810

9-
## Features
10-
11-
- uses queues for both producer and consumer
12-
- producer flushes with put_records() if has enough to flush or after "buffer_time" reached
13-
- consumer iterates over msg queue independent of shard readers
14-
- Configurable to handle Sharding limits but will throttle/retry if required
15-
- ie multiple independent clients are saturating the Shards
16-
- **Dynamic shard handling and resharding support**
17-
- automatically discovers new shards during Kinesis stream resharding
18-
- graceful handling of closed shards when `NextShardIterator` is null
19-
- robust error recovery for expired shard iterators
20-
- shard status monitoring and operational visibility
21-
- Checkpointing with heartbeats
22-
- deadlock + reallocation of shards if checkpoint fails to heartbeat within "session_timeout"
23-
- processors (aggregator + serializer)
24-
- json line delimited, msgpack
25-
- Address Kinesis streams by name or [ARN]
26-
27-
See [docs/design](./docs/DESIGN.md) for more details.
28-
See [docs/yetanother](docs/YETANOTHER.md) as to why reinvent the wheel.
11+
## Quick Start
12+
13+
**Producer:**
14+
```python
15+
from kinesis import Producer
16+
17+
async with Producer(stream_name="my-stream") as producer:
18+
await producer.put({"message": "hello world"})
19+
```
20+
21+
**Consumer:**
22+
```python
23+
from kinesis import Consumer
24+
25+
async with Consumer(stream_name="my-stream") as consumer:
26+
async for message in consumer:
27+
print(message)
28+
```
29+
30+
## Key Features
31+
32+
**Production-Ready Resharding**: Automatic shard discovery and topology management
33+
**Async/Await Native**: Built for modern Python async patterns
34+
**High Performance**: Queue-based architecture with configurable batching
35+
**AWS Best Practices**: Parent-child shard ordering and proper error handling
36+
**Stream Addressing**: Support for both stream names and ARNs
37+
**Multi-Consumer Support**: Redis-based checkpointing with heartbeats
38+
**Flexible Processing**: Pluggable serialization (JSON, MessagePack, KPL)
39+
**Operational Visibility**: Rich monitoring APIs for production debugging
40+
41+
### Resharding Support Highlights
42+
43+
Unlike basic Kinesis libraries, async-kinesis provides enterprise-grade resharding capabilities:
44+
45+
- **Automatic discovery** of new shards during resharding operations
46+
- **Parent-child ordering** enforcement following AWS best practices
47+
- **Graceful handling** of closed shards and iterator expiration
48+
- **Real-time monitoring** with detailed topology and status reporting
49+
- **Seamless coordination** between multiple consumer instances
50+
51+
📖 **[Architecture Details](./docs/DESIGN.md)** | **[Why Another Library?](docs/YETANOTHER.md)**
2952

3053
## Environment Variables
3154

@@ -241,7 +264,7 @@ Refer https://aws.amazon.com/blogs/big-data/implementing-efficient-and-reliable-
241264
| JsonListProcessor | ListAggregator | JsonSerializer | Multiple JSON record returned by list |
242265
| MsgpackProcessor | NetstringAggregator | MsgpackSerializer | Multiple Msgpack record framed with Netstring Protocol (https://en.wikipedia.org/wiki/Netstring) |
243266
| KPLJsonProcessor | KPLAggregator | JsonSerializer | Multiple JSON record in a KPL Aggregated Record (https://github.com/awslabs/amazon-kinesis-producer/blob/master/aggregation-format.md) |
244-
| KPLStringProcessor | KPLAggregator | StringSerializer | Multiple String record in a KPL Aggregated Record (https://github.com/awslabs/amazon-kinesis-producer/blob/master/aggregation-format.md) |
267+
| KPLStringProcessor | KPLAggregator | StringSerializer | Multiple String record in a KPL Aggregated Record (https://github.com/awslabs/amazon-kinesis-producer/blob/master/aggregation-format.md) |
245268

246269
Note you can define your own processor easily as it's simply a class inheriting the Aggregator + Serializer.
247270

@@ -315,41 +338,62 @@ Choose the optimal processor based on your use case:
315338
**Performance Testing:** Use the benchmark tool with different `--record-size-kb` and `--processors` options to determine the best processor for your specific data patterns.
316339

317340

318-
## Unit Testing
341+
## Development & Testing
319342

320-
Uses https://github.com/mhart/kinesalite for local testing.
343+
### Local Testing
321344

322-
Run tests via docker
345+
Uses LocalStack for integration testing:
323346

324-
```
347+
```bash
348+
# Run full test suite via Docker
325349
docker-compose up --abort-on-container-exit --exit-code-from test
326-
```
327350

328-
For local testing use
329-
330-
```
351+
# Local development setup
331352
docker-compose up kinesis redis
353+
pip install -r test-requirements.txt
354+
pytest
332355
```
333356

334-
then within your virtualenv
357+
### Code Quality
335358

336-
```
337-
nosetests
359+
This project uses automated code formatting and linting:
360+
361+
```bash
362+
# Install development tools
363+
pip install -r test-requirements.txt
364+
365+
# Run formatting and linting
366+
black .
367+
isort .
368+
flake8 .
338369

339-
# or run individual test
340-
nosetests tests.py:KinesisTests.test_create_stream_shard_limit_exceeded
370+
# Or use pre-commit hooks
371+
pre-commit install
372+
pre-commit run --all-files
341373
```
342374

343-
Note there are a few test cases using the *actual* AWS Kinesis (AWSKinesisTests)
344-
These require setting an env in order to run
375+
### AWS Integration Tests
345376

346-
Create an ".env" file with
377+
Some tests require actual AWS Kinesis. Create `.env` file:
347378

348379
```
349380
TESTING_USE_AWS_KINESIS=1
350381
```
351382

352-
Note you can ignore these tests if submitting PR unless core batching/processing behaviour is being changed.
383+
### Resharding Tests
384+
385+
Comprehensive resharding test suite available:
386+
387+
```bash
388+
# Unit tests (no AWS required)
389+
python tests/resharding/test_resharding_simple.py
390+
391+
# Integration tests (requires LocalStack)
392+
python tests/resharding/test_resharding_integration.py
393+
394+
# Production testing (requires AWS)
395+
python tests/resharding/resharding_test.py --scenario scale-up-small
396+
```
353397

354398

355399
[ARN]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html

RELEASING.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Release Process
2+
3+
This document describes the automated release process for async-kinesis.
4+
5+
## Quick Release
6+
7+
For a patch release (1.1.5 → 1.1.6):
8+
```bash
9+
python scripts/release.py --next-patch
10+
```
11+
12+
For a minor release (1.1.5 → 1.2.0):
13+
```bash
14+
python scripts/release.py --next-minor
15+
```
16+
17+
For a major release (1.1.5 → 2.0.0):
18+
```bash
19+
python scripts/release.py --next-major
20+
```
21+
22+
For a specific version:
23+
```bash
24+
python scripts/release.py --version 1.2.3
25+
```
26+
27+
## What Happens
28+
29+
1. **Pre-flight checks**: The script runs linting and tests
30+
2. **Version update**: Updates the version in `setup.py`
31+
3. **Git tag creation**: Creates and optionally pushes a git tag
32+
4. **Automated deployment**: GitHub Actions detects the tag and:
33+
- Runs full test suite across Python 3.10, 3.11, 3.12
34+
- Runs linting checks
35+
- Builds the package
36+
- Publishes to PyPI using trusted publishing
37+
38+
## Manual Process
39+
40+
If you prefer to do it manually:
41+
42+
1. Update version in `setup.py`
43+
2. Commit the version change
44+
3. Create a git tag: `git tag 1.2.3`
45+
4. Push the tag: `git push origin 1.2.3`
46+
5. GitHub Actions will handle the rest
47+
48+
## PyPI Configuration
49+
50+
The deployment uses GitHub's trusted publishing feature, which requires:
51+
52+
1. Configure the PyPI project to trust this GitHub repository
53+
2. Set up the `pypi` environment in GitHub repository settings
54+
3. The workflow uses `id-token: write` permission for OIDC authentication
55+
56+
## Checking Current Version
57+
58+
```bash
59+
python scripts/release.py --check
60+
```
61+
62+
## Development Releases
63+
64+
For testing the release process without affecting the main package:
65+
66+
```bash
67+
# Skip tests and linting for quick iteration
68+
python scripts/release.py --version 1.2.3-dev --skip-tests --skip-lint --no-tag
69+
```
70+
71+
## Troubleshooting
72+
73+
- **Tests fail**: Fix the issues before releasing
74+
- **Linting fails**: Run `black kinesis tests` and `isort kinesis tests`
75+
- **PyPI upload fails**: Check repository settings and trusted publishing configuration
76+
- **Tag already exists**: Delete the tag locally and remotely if needed:
77+
```bash
78+
git tag -d 1.2.3
79+
git push origin :refs/tags/1.2.3
80+
```

0 commit comments

Comments
 (0)