Skip to content

Commit a0b0aa4

Browse files
authored
Merge pull request #3 from logtide-dev/develop
Refactor SDK with async client, logging, and CI updates
2 parents 9c6d279 + fc4a19a commit a0b0aa4

File tree

20 files changed

+2106
-636
lines changed

20 files changed

+2106
-636
lines changed

.github/workflows/ci.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["main", "develop"]
6+
pull_request:
7+
branches: ["main", "develop"]
8+
9+
jobs:
10+
test:
11+
name: Test (Python ${{ matrix.python-version }})
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Set up Python ${{ matrix.python-version }}
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: ${{ matrix.python-version }}
26+
cache: pip
27+
28+
- name: Install dependencies
29+
run: pip install -e ".[dev,async]"
30+
31+
- name: Run tests
32+
run: pytest tests/ -v --tb=short

.github/workflows/release.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
# ── 1. Run tests before publishing ────────────────────────────────────────
13+
test:
14+
name: Test before release
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
cache: pip
25+
26+
- name: Install dependencies
27+
run: pip install -e ".[dev,async]"
28+
29+
- name: Run tests
30+
run: pytest tests/ -v --tb=short
31+
32+
# ── 2. Build source distribution and wheel ────────────────────────────────
33+
build:
34+
name: Build distribution
35+
runs-on: ubuntu-latest
36+
needs: test
37+
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Set up Python
42+
uses: actions/setup-python@v5
43+
with:
44+
python-version: "3.12"
45+
cache: pip
46+
47+
- name: Install build
48+
run: pip install build
49+
50+
- name: Build sdist and wheel
51+
run: python -m build
52+
53+
- name: Verify tag matches package version
54+
run: |
55+
TAG="${GITHUB_REF_NAME#v}"
56+
VERSION=$(python -c "
57+
import re, pathlib
58+
content = pathlib.Path('pyproject.toml').read_text()
59+
print(re.search(r'^version\s*=\s*\"(.+?)\"', content, re.MULTILINE).group(1))
60+
")
61+
echo "Tag: $TAG | Package version: $VERSION"
62+
if [ "$TAG" != "$VERSION" ]; then
63+
echo "ERROR: tag '$TAG' does not match package version '$VERSION'"
64+
exit 1
65+
fi
66+
67+
- name: Upload build artifacts
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: dist
71+
path: dist/
72+
73+
# ── 3. Publish to PyPI via OIDC Trusted Publisher ─────────────────────────
74+
publish:
75+
name: Publish to PyPI
76+
runs-on: ubuntu-latest
77+
needs: build
78+
environment: pypi
79+
80+
permissions:
81+
id-token: write # required for OIDC trusted publisher
82+
83+
steps:
84+
- name: Download build artifacts
85+
uses: actions/download-artifact@v4
86+
with:
87+
name: dist
88+
path: dist/
89+
90+
- name: Publish to PyPI
91+
uses: pypa/gh-action-pypi-publish@release/v1

CHANGELOG.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,57 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.8.4] - 2026-03-21
9+
10+
### Added
11+
12+
- `AsyncLogTideClient`: full async client using `aiohttp` with the same API as the
13+
sync client — supports `async with`, `await client.start()`, and all logging,
14+
flush, query, and stream methods as coroutines (`pip install logtide-sdk[async]`)
15+
- `LogTideHandler`: standard `logging.Handler` for drop-in integration with Python's
16+
built-in logging module — forwards records to LogTide with structured exception
17+
metadata when `exc_info=True` is used
18+
- `PayloadLimitsOptions`: configurable safeguards against 413 errors — per-field size
19+
cap, total entry size cap, named field exclusion, and automatic base64 removal
20+
- `LogTideStarletteMiddleware`: standalone Starlette ASGI middleware independent of
21+
FastAPI (`pip install logtide-sdk[starlette]`)
22+
- `serialize_exception()` exported at top level for use in custom integrations
23+
- `payload_limits` field on `ClientOptions`
24+
25+
### Changed
26+
27+
- **BREAKING** API paths updated to match v1 server contract:
28+
- `POST /api/logs``POST /api/v1/ingest`
29+
- `GET /api/logs``GET /api/v1/logs`
30+
- `GET /api/logs/trace/{id}``GET /api/v1/logs/trace/{id}`
31+
- `GET /api/logs/stats``GET /api/v1/logs/aggregated`
32+
- `GET /api/logs/stream``GET /api/v1/logs/stream`
33+
- **BREAKING** Auth header changed from `Authorization: Bearer <key>` to `X-API-Key: <key>`
34+
- **BREAKING** Error metadata key changed from `"error"` to `"exception"`; value is now a
35+
structured object with `type`, `message`, `language`, `stacktrace` (array of
36+
`{file, function, line}` frames), and `raw`
37+
- **BREAKING** `stream()` no longer blocks — it runs in a background daemon thread and
38+
returns a `Callable[[], None]` stop function immediately
39+
- **BREAKING** Buffer overflow no longer raises `BufferFullError`; logs are silently
40+
dropped and `logs_dropped` is incremented (`BufferFullError` class is kept for
41+
backwards-compatible catch blocks)
42+
- `requests.Session` is now created once and reused across all HTTP calls for
43+
connection reuse and reduced TCP overhead
44+
- `datetime.utcnow()` replaced with `datetime.now(timezone.utc)` throughout;
45+
`LogEntry.time` now includes `+00:00` timezone suffix (ISO 8601 compliant)
46+
- Middleware `__init__.py` now uses per-framework `try/except` guards — importing
47+
`logtide_sdk.middleware` no longer fails if only a subset of frameworks are installed
48+
49+
### Fixed
50+
51+
- Flask, Django, and FastAPI middleware `_log_error` methods were passing raw
52+
`Exception` objects into the metadata dict instead of serializing them — exceptions
53+
are now serialized via `serialize_exception()`
54+
- `log()` triggered `flush()` while holding `_buffer_lock`, causing a potential
55+
deadlock under concurrent access — flush is now triggered outside the lock
56+
- `__version__` in `__init__.py` was incorrectly set to `"0.1.0"` despite the
57+
package being at `0.1.2`
58+
859
## [0.1.0] - 2026-01-13
960

1061
### Added
@@ -28,4 +79,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2879
- FastAPI middleware for auto-logging HTTP requests
2980
- Full type hints support for Python 3.8+
3081

31-
[0.1.0]: https://github.com/logtide-dev/logtide-sdk-python/releases/tag/v0.1.0
82+
[0.8.4]: https://github.com/logtide-dev/logtide-python/compare/v0.1.0...v0.8.4
83+
[0.1.0]: https://github.com/logtide-dev/logtide-python/releases/tag/v0.1.0

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Thank you for your interest in contributing!
66

77
1. Clone the repository:
88
```bash
9-
git clone https://github.com/logtide-dev/logtide-sdk-python.git
9+
git clone https://github.com/logtide-dev/logtide-python.git
1010
cd logtide-sdk-python
1111
```
1212

0 commit comments

Comments
 (0)