turboapi 0.4.15__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- turboapi-0.5.2/.github/workflows/build-and-release.yml +217 -0
- turboapi-0.5.2/.github/workflows/ci.yml +179 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/.github/workflows/release.yml +12 -12
- {turboapi-0.4.15 → turboapi-0.5.2}/.gitignore +3 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/CHANGELOG.md +50 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/Cargo.lock +312 -2
- {turboapi-0.4.15 → turboapi-0.5.2}/Cargo.toml +17 -2
- turboapi-0.5.2/Makefile +53 -0
- turboapi-0.5.2/PKG-INFO +534 -0
- turboapi-0.5.2/README.md +499 -0
- turboapi-0.5.2/assets/architecture.png +0 -0
- turboapi-0.5.2/assets/benchmark_latency.png +0 -0
- turboapi-0.5.2/assets/benchmark_speedup.png +0 -0
- turboapi-0.5.2/assets/benchmark_throughput.png +0 -0
- turboapi-0.5.2/benches/async_comparison_bench.py +325 -0
- turboapi-0.5.2/benches/performance_bench.rs +564 -0
- turboapi-0.5.2/benches/python_benchmark.py +384 -0
- turboapi-0.5.2/benchmarks/README.md +35 -0
- turboapi-0.5.2/benchmarks/bench_json.py +209 -0
- turboapi-0.5.2/benchmarks/bench_memory.py +192 -0
- turboapi-0.5.2/benchmarks/bench_throughput.py +227 -0
- turboapi-0.5.2/benchmarks/bench_validation.py +241 -0
- turboapi-0.5.2/benchmarks/generate_charts.py +399 -0
- turboapi-0.5.2/benchmarks/run_all.sh +31 -0
- turboapi-0.5.2/benchmarks/run_benchmarks.py +383 -0
- turboapi-0.5.2/docs/ARCHITECTURE.md +205 -0
- turboapi-0.5.2/docs/ASYNC_HANDLERS.md +125 -0
- turboapi-0.5.2/docs/BENCHMARKS.md +158 -0
- turboapi-0.5.2/docs/HTTP2.md +154 -0
- turboapi-0.5.2/docs/PERFORMANCE_TUNING.md +189 -0
- turboapi-0.5.2/docs/README.md +38 -0
- turboapi-0.5.2/docs/TLS_SETUP.md +165 -0
- turboapi-0.5.2/docs/WEBSOCKET.md +206 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/pyproject.toml +20 -34
- turboapi-0.5.2/python/turboapi/__init__.py +141 -0
- turboapi-0.5.2/python/turboapi/background.py +51 -0
- turboapi-0.5.2/python/turboapi/datastructures.py +262 -0
- turboapi-0.5.2/python/turboapi/encoders.py +323 -0
- turboapi-0.5.2/python/turboapi/exceptions.py +111 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/main_app.py +59 -4
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/middleware.py +4 -6
- {turboapi-0.4.15 → turboapi-0.5.2/python}/turboapi/models.py +15 -33
- turboapi-0.5.2/python/turboapi/openapi.py +236 -0
- {turboapi-0.4.15 → turboapi-0.5.2/python}/turboapi/request_handler.py +172 -32
- turboapi-0.5.2/python/turboapi/responses.py +209 -0
- {turboapi-0.4.15 → turboapi-0.5.2/python}/turboapi/routing.py +2 -1
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/rust_integration.py +133 -20
- {turboapi-0.4.15 → turboapi-0.5.2/python}/turboapi/security.py +32 -3
- turboapi-0.5.2/python/turboapi/staticfiles.py +91 -0
- turboapi-0.5.2/python/turboapi/status.py +104 -0
- turboapi-0.5.2/python/turboapi/templating.py +73 -0
- turboapi-0.5.2/python/turboapi/testclient.py +321 -0
- turboapi-0.5.2/python/turboapi/websockets.py +130 -0
- turboapi-0.5.2/src/http2.rs +418 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/src/lib.rs +30 -20
- {turboapi-0.4.15 → turboapi-0.5.2}/src/micro_bench.rs +43 -32
- {turboapi-0.4.15 → turboapi-0.5.2}/src/middleware.rs +157 -104
- {turboapi-0.4.15 → turboapi-0.5.2}/src/python_worker.rs +58 -58
- {turboapi-0.4.15 → turboapi-0.5.2}/src/response.rs +4 -1
- {turboapi-0.4.15 → turboapi-0.5.2}/src/router.rs +49 -17
- turboapi-0.5.2/src/server.rs +1854 -0
- turboapi-0.5.2/src/simd_json.rs +392 -0
- turboapi-0.5.2/src/simd_parse.rs +507 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/src/threadpool.rs +71 -30
- turboapi-0.5.2/src/tls.rs +190 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/src/validation.rs +28 -26
- {turboapi-0.4.15 → turboapi-0.5.2}/src/websocket.rs +115 -44
- {turboapi-0.4.15 → turboapi-0.5.2}/src/zerocopy.rs +65 -53
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/comparison_before_after.py +7 -7
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/quick_body_test.py +3 -3
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_async_handlers.py +12 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_async_simple.py +0 -0
- turboapi-0.5.2/tests/test_comprehensive_parity.py +569 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_comprehensive_v0_4_15.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_fastapi_compatibility.py +10 -10
- turboapi-0.5.2/tests/test_fastapi_parity.py +1080 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_performance_regression.py +15 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_post_body_parsing.py +10 -10
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_query_and_headers.py +8 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_request_parsing.py +10 -1
- turboapi-0.5.2/tests/test_satya_0_4_0_compatibility.py +331 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_wrk_regression.py +0 -0
- turboapi-0.4.15/.github/workflows/build-and-release.yml +0 -377
- turboapi-0.4.15/.github/workflows/build-wheels.yml +0 -212
- turboapi-0.4.15/.github/workflows/ci.yml +0 -151
- turboapi-0.4.15/AGENTS.md +0 -320
- turboapi-0.4.15/ASYNC_FIX_v0_4_15.md +0 -342
- turboapi-0.4.15/BENCHMARK_FAQ.md +0 -204
- turboapi-0.4.15/BENCHMARK_METHODOLOGY_RESPONSE.md +0 -340
- turboapi-0.4.15/BENCHMARK_ONEPAGER.md +0 -140
- turboapi-0.4.15/FASTAPI_COMPATIBILITY.md +0 -606
- turboapi-0.4.15/Makefile +0 -71
- turboapi-0.4.15/PHASE_3_COMPLETE.md +0 -489
- turboapi-0.4.15/PKG-INFO +0 -31
- turboapi-0.4.15/POST_BODY_PARSING_FIX.md +0 -167
- turboapi-0.4.15/QUICK_RESPONSE_MULTICORE.md +0 -252
- turboapi-0.4.15/README.md +0 -929
- turboapi-0.4.15/RELEASE_NOTES_v0.4.13.md +0 -362
- turboapi-0.4.15/RELEASE_NOTES_v0.4.14.md +0 -412
- turboapi-0.4.15/RESPONSE_SUMMARY.md +0 -274
- turboapi-0.4.15/TESTING.md +0 -205
- turboapi-0.4.15/TODO_v0.4.15.md +0 -195
- turboapi-0.4.15/V0.4.13_SUMMARY.md +0 -265
- turboapi-0.4.15/V0.4.14_SUMMARY.md +0 -312
- turboapi-0.4.15/V0.4.15_SUMMARY.md +0 -418
- turboapi-0.4.15/benches/performance_bench.rs +0 -184
- turboapi-0.4.15/benchmark_comparison.png +0 -0
- turboapi-0.4.15/benchmark_graphs/turbo_vs_fastapi_performance_20250929_025531.png +0 -0
- turboapi-0.4.15/benchmarks/comprehensive_wrk_benchmark.py +0 -284
- turboapi-0.4.15/benchmarks/turboapi_vs_fastapi_benchmark.py +0 -310
- turboapi-0.4.15/benchmarks/turboapi_vs_fastapi_simple.py +0 -249
- turboapi-0.4.15/benchmarks/wrk_output.txt +0 -0
- turboapi-0.4.15/docs/ARCHITECTURE_DIAGRAM.md +0 -382
- turboapi-0.4.15/docs/AUTHENTICATION_GUIDE.md +0 -797
- turboapi-0.4.15/python/pyproject.toml +0 -74
- turboapi-0.4.15/python/turboapi/__init__.py +0 -24
- turboapi-0.4.15/python/turboapi/models.py +0 -148
- turboapi-0.4.15/python/turboapi/request_handler.py +0 -462
- turboapi-0.4.15/python/turboapi/routing.py +0 -219
- turboapi-0.4.15/python/turboapi/security.py +0 -542
- turboapi-0.4.15/setup_python313t.sh +0 -97
- turboapi-0.4.15/src/http2.rs +0 -234
- turboapi-0.4.15/src/server.rs +0 -1526
- turboapi-0.4.15/test_package_integrity.py +0 -339
- turboapi-0.4.15/test_simple_post.py +0 -28
- turboapi-0.4.15/tests/test_satya_0_4_0_compatibility.py +0 -247
- turboapi-0.4.15/turbo_vs_fastapi_benchmark_20250929_025526.json +0 -60
- turboapi-0.4.15/turboapi/__init__.py +0 -24
- turboapi-0.4.15/turboapi/async_limiter.py +0 -86
- turboapi-0.4.15/turboapi/async_pool.py +0 -141
- turboapi-0.4.15/turboapi/decorators.py +0 -69
- turboapi-0.4.15/turboapi/main_app.py +0 -314
- turboapi-0.4.15/turboapi/middleware.py +0 -342
- turboapi-0.4.15/turboapi/rust_integration.py +0 -258
- turboapi-0.4.15/turboapi/server_integration.py +0 -436
- turboapi-0.4.15/turboapi/version_check.py +0 -268
- {turboapi-0.4.15 → turboapi-0.5.2}/.github/scripts/check_performance_regression.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/.github/scripts/compare_benchmarks.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/.github/workflows/README.md +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/.github/workflows/benchmark.yml +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/LICENSE +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/examples/authentication_demo.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/examples/multi_route_app.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/MANIFEST.in +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/setup.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/async_limiter.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/async_pool.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/decorators.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/server_integration.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/python/turboapi/version_check.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/src/request.rs +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/README.md +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/benchmark_comparison.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/fastapi_equivalent.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/quick_test.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/test_security_features.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/wrk_benchmark.py +0 -0
- {turboapi-0.4.15 → turboapi-0.5.2}/tests/wrk_comparison.py +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
name: Build & Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
tags: ['v*']
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
check-version:
|
|
15
|
+
name: Check if version is new
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
outputs:
|
|
18
|
+
should_publish: ${{ steps.check.outputs.should_publish }}
|
|
19
|
+
version: ${{ steps.check.outputs.version }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- name: Check PyPI for existing version
|
|
23
|
+
id: check
|
|
24
|
+
run: |
|
|
25
|
+
VERSION=$(grep -m1 'version = "' Cargo.toml | sed 's/.*"\(.*\)"/\1/')
|
|
26
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
27
|
+
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
|
|
28
|
+
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
29
|
+
echo "Tag push detected, will publish v$VERSION"
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/turboapi/$VERSION/json")
|
|
33
|
+
if [ "$HTTP_STATUS" = "404" ]; then
|
|
34
|
+
echo "should_publish=true" >> $GITHUB_OUTPUT
|
|
35
|
+
echo "Version $VERSION not on PyPI, will publish"
|
|
36
|
+
else
|
|
37
|
+
echo "should_publish=false" >> $GITHUB_OUTPUT
|
|
38
|
+
echo "Version $VERSION already on PyPI, skipping"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
linux-x86_64:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
needs: [check-version]
|
|
44
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: |
|
|
50
|
+
3.13
|
|
51
|
+
- name: Build wheels
|
|
52
|
+
uses: PyO3/maturin-action@v1
|
|
53
|
+
with:
|
|
54
|
+
target: x86_64
|
|
55
|
+
args: --release --out dist --find-interpreter
|
|
56
|
+
sccache: 'true'
|
|
57
|
+
manylinux: auto
|
|
58
|
+
- uses: actions/upload-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: wheels-linux-x86_64
|
|
61
|
+
path: dist
|
|
62
|
+
|
|
63
|
+
linux-aarch64:
|
|
64
|
+
runs-on: ubuntu-24.04-arm
|
|
65
|
+
needs: [check-version]
|
|
66
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
- uses: actions/setup-python@v5
|
|
70
|
+
with:
|
|
71
|
+
python-version: |
|
|
72
|
+
3.13
|
|
73
|
+
- name: Build wheels
|
|
74
|
+
uses: PyO3/maturin-action@v1
|
|
75
|
+
with:
|
|
76
|
+
target: aarch64
|
|
77
|
+
args: --release --out dist --find-interpreter
|
|
78
|
+
sccache: 'true'
|
|
79
|
+
manylinux: auto
|
|
80
|
+
- uses: actions/upload-artifact@v4
|
|
81
|
+
with:
|
|
82
|
+
name: wheels-linux-aarch64
|
|
83
|
+
path: dist
|
|
84
|
+
|
|
85
|
+
windows:
|
|
86
|
+
runs-on: windows-latest
|
|
87
|
+
needs: [check-version]
|
|
88
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
89
|
+
strategy:
|
|
90
|
+
matrix:
|
|
91
|
+
target: [x64]
|
|
92
|
+
fail-fast: false
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@v4
|
|
95
|
+
- uses: actions/setup-python@v5
|
|
96
|
+
with:
|
|
97
|
+
python-version: |
|
|
98
|
+
3.13
|
|
99
|
+
- name: Build wheels
|
|
100
|
+
uses: PyO3/maturin-action@v1
|
|
101
|
+
with:
|
|
102
|
+
args: --release --out dist --find-interpreter
|
|
103
|
+
sccache: 'true'
|
|
104
|
+
- uses: actions/upload-artifact@v4
|
|
105
|
+
with:
|
|
106
|
+
name: wheels-windows-${{ matrix.target }}
|
|
107
|
+
path: dist
|
|
108
|
+
|
|
109
|
+
macos:
|
|
110
|
+
runs-on: macos-latest
|
|
111
|
+
needs: [check-version]
|
|
112
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
113
|
+
strategy:
|
|
114
|
+
matrix:
|
|
115
|
+
target: [x86_64-apple-darwin, aarch64-apple-darwin]
|
|
116
|
+
fail-fast: false
|
|
117
|
+
steps:
|
|
118
|
+
- uses: actions/checkout@v4
|
|
119
|
+
- uses: actions/setup-python@v5
|
|
120
|
+
with:
|
|
121
|
+
python-version: |
|
|
122
|
+
3.13
|
|
123
|
+
- name: Build wheels
|
|
124
|
+
uses: PyO3/maturin-action@v1
|
|
125
|
+
with:
|
|
126
|
+
target: ${{ matrix.target }}
|
|
127
|
+
args: --release --out dist --find-interpreter
|
|
128
|
+
sccache: 'true'
|
|
129
|
+
- uses: actions/upload-artifact@v4
|
|
130
|
+
with:
|
|
131
|
+
name: wheels-macos-${{ matrix.target }}
|
|
132
|
+
path: dist
|
|
133
|
+
|
|
134
|
+
sdist:
|
|
135
|
+
runs-on: ubuntu-latest
|
|
136
|
+
needs: [check-version]
|
|
137
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
138
|
+
steps:
|
|
139
|
+
- uses: actions/checkout@v4
|
|
140
|
+
- name: Build sdist
|
|
141
|
+
uses: PyO3/maturin-action@v1
|
|
142
|
+
with:
|
|
143
|
+
command: sdist
|
|
144
|
+
args: --out dist
|
|
145
|
+
- uses: actions/upload-artifact@v4
|
|
146
|
+
with:
|
|
147
|
+
name: sdist
|
|
148
|
+
path: dist
|
|
149
|
+
|
|
150
|
+
publish:
|
|
151
|
+
name: Publish to PyPI
|
|
152
|
+
runs-on: ubuntu-latest
|
|
153
|
+
needs: [linux-x86_64, linux-aarch64, windows, macos, sdist]
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/download-artifact@v4
|
|
156
|
+
with:
|
|
157
|
+
pattern: '{wheels-*,sdist}'
|
|
158
|
+
path: dist
|
|
159
|
+
merge-multiple: true
|
|
160
|
+
- name: Publish to PyPI
|
|
161
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
162
|
+
with:
|
|
163
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
164
|
+
skip-existing: true
|
|
165
|
+
|
|
166
|
+
release:
|
|
167
|
+
name: Create GitHub Release
|
|
168
|
+
runs-on: ubuntu-latest
|
|
169
|
+
needs: [check-version, publish]
|
|
170
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
171
|
+
steps:
|
|
172
|
+
- uses: actions/checkout@v4
|
|
173
|
+
with:
|
|
174
|
+
fetch-depth: 0
|
|
175
|
+
- uses: actions/download-artifact@v4
|
|
176
|
+
with:
|
|
177
|
+
pattern: '{wheels-*,sdist}'
|
|
178
|
+
path: dist
|
|
179
|
+
merge-multiple: true
|
|
180
|
+
- name: Create Release
|
|
181
|
+
uses: softprops/action-gh-release@v2
|
|
182
|
+
with:
|
|
183
|
+
files: dist/*
|
|
184
|
+
generate_release_notes: true
|
|
185
|
+
|
|
186
|
+
tag-and-release:
|
|
187
|
+
name: Tag new version
|
|
188
|
+
runs-on: ubuntu-latest
|
|
189
|
+
needs: [check-version, publish]
|
|
190
|
+
if: github.ref == 'refs/heads/main' && needs.check-version.outputs.should_publish == 'true'
|
|
191
|
+
steps:
|
|
192
|
+
- uses: actions/checkout@v4
|
|
193
|
+
with:
|
|
194
|
+
fetch-depth: 0
|
|
195
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
196
|
+
- name: Configure git
|
|
197
|
+
run: |
|
|
198
|
+
git config user.email "action@github.com"
|
|
199
|
+
git config user.name "GitHub Action"
|
|
200
|
+
- name: Create tag
|
|
201
|
+
env:
|
|
202
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
203
|
+
run: |
|
|
204
|
+
VERSION="${{ needs.check-version.outputs.version }}"
|
|
205
|
+
git tag "v${VERSION}"
|
|
206
|
+
git push origin "v${VERSION}"
|
|
207
|
+
- uses: actions/download-artifact@v4
|
|
208
|
+
with:
|
|
209
|
+
pattern: '{wheels-*,sdist}'
|
|
210
|
+
path: dist
|
|
211
|
+
merge-multiple: true
|
|
212
|
+
- name: Create GitHub Release
|
|
213
|
+
uses: softprops/action-gh-release@v2
|
|
214
|
+
with:
|
|
215
|
+
tag_name: v${{ needs.check-version.outputs.version }}
|
|
216
|
+
files: dist/*
|
|
217
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install Rust
|
|
20
|
+
uses: dtolnay/rust-toolchain@stable
|
|
21
|
+
with:
|
|
22
|
+
components: rustfmt, clippy
|
|
23
|
+
|
|
24
|
+
- name: Cache Rust dependencies
|
|
25
|
+
uses: Swatinem/rust-cache@v2
|
|
26
|
+
|
|
27
|
+
- name: Check formatting
|
|
28
|
+
run: cargo fmt --all -- --check
|
|
29
|
+
|
|
30
|
+
- name: Run clippy
|
|
31
|
+
run: cargo clippy --all-targets -- -W warnings 2>&1 || true
|
|
32
|
+
|
|
33
|
+
test-rust:
|
|
34
|
+
name: Test Rust
|
|
35
|
+
runs-on: ${{ matrix.os }}
|
|
36
|
+
strategy:
|
|
37
|
+
matrix:
|
|
38
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
39
|
+
fail-fast: false
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
|
|
43
|
+
- name: Install Rust
|
|
44
|
+
uses: dtolnay/rust-toolchain@stable
|
|
45
|
+
|
|
46
|
+
- name: Cache Rust dependencies
|
|
47
|
+
uses: Swatinem/rust-cache@v2
|
|
48
|
+
|
|
49
|
+
- name: Check Rust compilation
|
|
50
|
+
run: cargo check --all-targets
|
|
51
|
+
|
|
52
|
+
test-python:
|
|
53
|
+
name: "test (Python ${{ matrix.python-version }})"
|
|
54
|
+
runs-on: ${{ matrix.os }}
|
|
55
|
+
strategy:
|
|
56
|
+
matrix:
|
|
57
|
+
os: [ubuntu-latest, macos-latest]
|
|
58
|
+
python-version: ['3.13']
|
|
59
|
+
fail-fast: false
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v4
|
|
62
|
+
|
|
63
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
64
|
+
uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: ${{ matrix.python-version }}
|
|
67
|
+
allow-prereleases: true
|
|
68
|
+
|
|
69
|
+
- name: Install Rust
|
|
70
|
+
uses: dtolnay/rust-toolchain@stable
|
|
71
|
+
|
|
72
|
+
- name: Cache Rust dependencies
|
|
73
|
+
uses: Swatinem/rust-cache@v2
|
|
74
|
+
|
|
75
|
+
- name: Install dependencies
|
|
76
|
+
run: |
|
|
77
|
+
python -m pip install --upgrade pip
|
|
78
|
+
pip install maturin pytest pytest-asyncio requests
|
|
79
|
+
|
|
80
|
+
- name: Build and install turboapi
|
|
81
|
+
run: |
|
|
82
|
+
maturin build --release -i python --out dist
|
|
83
|
+
pip install dist/*.whl
|
|
84
|
+
# dhi is installed as a dependency automatically
|
|
85
|
+
|
|
86
|
+
- name: Run tests
|
|
87
|
+
run: python -m pytest $GITHUB_WORKSPACE/tests/ -v --tb=short
|
|
88
|
+
|
|
89
|
+
test-free-threaded:
|
|
90
|
+
name: "test (${{ matrix.python-version }} free-threaded)"
|
|
91
|
+
runs-on: ${{ matrix.os }}
|
|
92
|
+
strategy:
|
|
93
|
+
matrix:
|
|
94
|
+
os: [ubuntu-latest, macos-latest]
|
|
95
|
+
python-version: ['3.13t']
|
|
96
|
+
fail-fast: false
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/checkout@v4
|
|
99
|
+
|
|
100
|
+
- name: Set up Python ${{ matrix.python-version }} (free-threaded)
|
|
101
|
+
uses: actions/setup-python@v5
|
|
102
|
+
with:
|
|
103
|
+
python-version: ${{ matrix.python-version }}
|
|
104
|
+
allow-prereleases: true
|
|
105
|
+
|
|
106
|
+
- name: Install Rust
|
|
107
|
+
uses: dtolnay/rust-toolchain@stable
|
|
108
|
+
|
|
109
|
+
- name: Cache Rust dependencies
|
|
110
|
+
uses: Swatinem/rust-cache@v2
|
|
111
|
+
|
|
112
|
+
- name: Install dependencies
|
|
113
|
+
run: |
|
|
114
|
+
python -m pip install --upgrade pip
|
|
115
|
+
pip install maturin pytest pytest-asyncio requests
|
|
116
|
+
|
|
117
|
+
- name: Build and install turboapi (free-threaded)
|
|
118
|
+
run: |
|
|
119
|
+
maturin build --release -i python --out dist
|
|
120
|
+
pip install dist/*.whl
|
|
121
|
+
# dhi is installed as a dependency automatically
|
|
122
|
+
|
|
123
|
+
- name: Run tests (free-threaded)
|
|
124
|
+
run: python -m pytest $GITHUB_WORKSPACE/tests/ -v --tb=short
|
|
125
|
+
|
|
126
|
+
- name: Run thread-safety smoke test
|
|
127
|
+
run: |
|
|
128
|
+
python -c "
|
|
129
|
+
import threading, concurrent.futures
|
|
130
|
+
from turboapi import TurboAPI, TurboRequest, TurboResponse
|
|
131
|
+
|
|
132
|
+
def create_app_and_routes(thread_id):
|
|
133
|
+
app = TurboAPI(title=f'App {thread_id}')
|
|
134
|
+
for i in range(100):
|
|
135
|
+
@app.get(f'/t{thread_id}/route{i}')
|
|
136
|
+
def handler(tid=thread_id, idx=i):
|
|
137
|
+
return {'thread': tid, 'route': idx}
|
|
138
|
+
return thread_id
|
|
139
|
+
|
|
140
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as pool:
|
|
141
|
+
futures = [pool.submit(create_app_and_routes, t) for t in range(8)]
|
|
142
|
+
results = [f.result() for f in futures]
|
|
143
|
+
assert len(results) == 8
|
|
144
|
+
print('Free-threaded smoke test: 8 threads x 100 routes = OK')
|
|
145
|
+
"
|
|
146
|
+
|
|
147
|
+
build-check:
|
|
148
|
+
name: "build (${{ matrix.target }})"
|
|
149
|
+
runs-on: ${{ matrix.os }}
|
|
150
|
+
strategy:
|
|
151
|
+
matrix:
|
|
152
|
+
include:
|
|
153
|
+
- os: ubuntu-latest
|
|
154
|
+
target: x86_64
|
|
155
|
+
- os: macos-latest
|
|
156
|
+
target: aarch64-apple-darwin
|
|
157
|
+
- os: windows-latest
|
|
158
|
+
target: x64
|
|
159
|
+
fail-fast: false
|
|
160
|
+
steps:
|
|
161
|
+
- uses: actions/checkout@v4
|
|
162
|
+
|
|
163
|
+
- uses: actions/setup-python@v5
|
|
164
|
+
with:
|
|
165
|
+
python-version: '3.13'
|
|
166
|
+
|
|
167
|
+
- name: Build wheels
|
|
168
|
+
uses: PyO3/maturin-action@v1
|
|
169
|
+
with:
|
|
170
|
+
target: ${{ matrix.target }}
|
|
171
|
+
args: --release --out dist --find-interpreter
|
|
172
|
+
sccache: 'true'
|
|
173
|
+
manylinux: auto
|
|
174
|
+
|
|
175
|
+
- name: Upload wheels
|
|
176
|
+
uses: actions/upload-artifact@v4
|
|
177
|
+
with:
|
|
178
|
+
name: wheels-${{ matrix.os }}-${{ matrix.target }}
|
|
179
|
+
path: dist
|
|
@@ -51,32 +51,32 @@ jobs:
|
|
|
51
51
|
run: |
|
|
52
52
|
# Install bump2version if not available
|
|
53
53
|
pip install bump2version
|
|
54
|
-
|
|
55
|
-
# Extract current version from
|
|
56
|
-
CURRENT_VERSION=$(grep -Po '(?<=version = ")[^"]*'
|
|
54
|
+
|
|
55
|
+
# Extract current version from pyproject.toml (root)
|
|
56
|
+
CURRENT_VERSION=$(grep -Po '(?<=version = ")[^"]*' pyproject.toml | head -1)
|
|
57
57
|
echo "Current version: $CURRENT_VERSION"
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
# Create .bumpversion.cfg for coordinated version bumping
|
|
60
60
|
cat > .bumpversion.cfg << EOF
|
|
61
61
|
[bumpversion]
|
|
62
62
|
current_version = $CURRENT_VERSION
|
|
63
63
|
commit = False
|
|
64
64
|
tag = False
|
|
65
|
-
|
|
66
|
-
[bumpversion:file:
|
|
65
|
+
|
|
66
|
+
[bumpversion:file:pyproject.toml]
|
|
67
67
|
search = version = "{current_version}"
|
|
68
68
|
replace = version = "{new_version}"
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
[bumpversion:file:Cargo.toml]
|
|
71
71
|
search = version = "{current_version}"
|
|
72
72
|
replace = version = "{new_version}"
|
|
73
73
|
EOF
|
|
74
|
-
|
|
75
|
-
# Bump version in both
|
|
74
|
+
|
|
75
|
+
# Bump version in both pyproject.toml and Cargo.toml
|
|
76
76
|
bump2version ${{ github.event.inputs.version_bump }} --allow-dirty
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
# Get new version
|
|
79
|
-
NEW_VERSION=$(grep -Po '(?<=version = ")[^"]*'
|
|
79
|
+
NEW_VERSION=$(grep -Po '(?<=version = ")[^"]*' pyproject.toml | head -1)
|
|
80
80
|
echo "New version: $NEW_VERSION"
|
|
81
81
|
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
82
82
|
|
|
@@ -108,7 +108,7 @@ jobs:
|
|
|
108
108
|
- name: Commit version bump and create tag
|
|
109
109
|
id: create_tag
|
|
110
110
|
run: |
|
|
111
|
-
git add
|
|
111
|
+
git add pyproject.toml Cargo.toml CHANGELOG.md .bumpversion.cfg
|
|
112
112
|
git commit -m "Bump version to v${{ steps.bump_version.outputs.new_version }}"
|
|
113
113
|
git tag -a "v${{ steps.bump_version.outputs.new_version }}" -m "Release v${{ steps.bump_version.outputs.new_version }}"
|
|
114
114
|
git push && git push --tags
|
|
@@ -5,6 +5,56 @@ All notable changes to TurboAPI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Async Handler Fast Paths** - True async support via Tokio runtime
|
|
13
|
+
- `SimpleAsyncFast` handler type for GET async handlers
|
|
14
|
+
- `BodyAsyncFast` handler type for POST/PUT async handlers
|
|
15
|
+
- `add_route_async_fast()` method for async handler registration
|
|
16
|
+
- pyo3-async-runtimes integration for Python coroutine conversion
|
|
17
|
+
- Automatic handler classification for sync vs async detection
|
|
18
|
+
|
|
19
|
+
- **HTTP/2 Support** - Full HTTP/2 implementation
|
|
20
|
+
- `Http2Server` class with h2 protocol support
|
|
21
|
+
- Server push capabilities via `ServerPush`
|
|
22
|
+
- Stream multiplexing for concurrent requests
|
|
23
|
+
|
|
24
|
+
- **TLS Support** - Secure HTTPS connections
|
|
25
|
+
- rustls backend (default, pure Rust)
|
|
26
|
+
- Optional OpenSSL backend via feature flag
|
|
27
|
+
- PEM certificate and key loading
|
|
28
|
+
|
|
29
|
+
- **WebSocket Improvements** - Better message handling
|
|
30
|
+
- Improved text message routing to Python handlers
|
|
31
|
+
- Binary message handler support
|
|
32
|
+
- Clean connection lifecycle management
|
|
33
|
+
|
|
34
|
+
- **Comprehensive Benchmarks** - Performance testing suite
|
|
35
|
+
- `python_benchmark.py` - Full framework benchmarks
|
|
36
|
+
- `async_comparison_bench.py` - Sync vs async comparison
|
|
37
|
+
- `performance_bench.rs` - Low-level Rust benchmarks
|
|
38
|
+
|
|
39
|
+
- **Documentation**
|
|
40
|
+
- `docs/ASYNC_HANDLERS.md` - Async handler guide
|
|
41
|
+
- `docs/BENCHMARKS.md` - Benchmarking guide
|
|
42
|
+
- `docs/ARCHITECTURE.md` - Internal architecture
|
|
43
|
+
- DeepWiki integration for documentation
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Handler classification now detects coroutine functions
|
|
48
|
+
- Async handlers route through Tokio instead of Enhanced path
|
|
49
|
+
- Simplified TokioRuntime (removed loop sharding complexity)
|
|
50
|
+
|
|
51
|
+
### Performance
|
|
52
|
+
|
|
53
|
+
- Async handlers use Tokio work-stealing scheduler
|
|
54
|
+
- Sequential latency: 1.3-1.4x faster than FastAPI
|
|
55
|
+
- Concurrent latency: 1.2-1.8x faster than FastAPI
|
|
56
|
+
- JSON endpoints show largest improvement (1.8x concurrent)
|
|
57
|
+
|
|
8
58
|
## [0.3.0] - 2025-09-30
|
|
9
59
|
|
|
10
60
|
### Fixed
|