turboapi 0.4.15__tar.gz → 0.4.16__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.4.16/.github/workflows/build-and-release.yml +199 -0
- turboapi-0.4.16/.github/workflows/ci.yml +179 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/.github/workflows/release.yml +12 -12
- {turboapi-0.4.15 → turboapi-0.4.16}/Cargo.lock +108 -2
- {turboapi-0.4.15 → turboapi-0.4.16}/Cargo.toml +5 -1
- turboapi-0.4.16/PKG-INFO +423 -0
- turboapi-0.4.16/README.md +388 -0
- turboapi-0.4.16/assets/architecture.png +0 -0
- turboapi-0.4.16/assets/benchmark_latency.png +0 -0
- turboapi-0.4.16/assets/benchmark_speedup.png +0 -0
- turboapi-0.4.16/assets/benchmark_throughput.png +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/benches/performance_bench.rs +23 -23
- turboapi-0.4.16/benchmarks/README.md +35 -0
- turboapi-0.4.16/benchmarks/bench_json.py +209 -0
- turboapi-0.4.16/benchmarks/bench_memory.py +192 -0
- turboapi-0.4.16/benchmarks/bench_throughput.py +227 -0
- turboapi-0.4.16/benchmarks/bench_validation.py +241 -0
- turboapi-0.4.16/benchmarks/generate_charts.py +399 -0
- turboapi-0.4.16/benchmarks/run_all.sh +31 -0
- turboapi-0.4.16/benchmarks/run_benchmarks.py +383 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/pyproject.toml +20 -34
- turboapi-0.4.16/python/turboapi/__init__.py +141 -0
- turboapi-0.4.16/python/turboapi/background.py +51 -0
- turboapi-0.4.16/python/turboapi/datastructures.py +262 -0
- turboapi-0.4.16/python/turboapi/encoders.py +323 -0
- turboapi-0.4.16/python/turboapi/exceptions.py +111 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/main_app.py +59 -4
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/middleware.py +4 -6
- {turboapi-0.4.15 → turboapi-0.4.16/python}/turboapi/models.py +15 -33
- turboapi-0.4.16/python/turboapi/openapi.py +236 -0
- {turboapi-0.4.15 → turboapi-0.4.16/python}/turboapi/request_handler.py +172 -32
- turboapi-0.4.16/python/turboapi/responses.py +209 -0
- {turboapi-0.4.15 → turboapi-0.4.16/python}/turboapi/routing.py +2 -1
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/rust_integration.py +111 -20
- {turboapi-0.4.15 → turboapi-0.4.16/python}/turboapi/security.py +32 -3
- turboapi-0.4.16/python/turboapi/staticfiles.py +91 -0
- turboapi-0.4.16/python/turboapi/status.py +104 -0
- turboapi-0.4.16/python/turboapi/templating.py +73 -0
- turboapi-0.4.16/python/turboapi/testclient.py +321 -0
- turboapi-0.4.16/python/turboapi/websockets.py +130 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/setup_python313t.sh +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/src/http2.rs +53 -33
- {turboapi-0.4.15 → turboapi-0.4.16}/src/lib.rs +28 -20
- {turboapi-0.4.15 → turboapi-0.4.16}/src/micro_bench.rs +43 -32
- {turboapi-0.4.15 → turboapi-0.4.16}/src/middleware.rs +157 -104
- {turboapi-0.4.15 → turboapi-0.4.16}/src/python_worker.rs +58 -58
- {turboapi-0.4.15 → turboapi-0.4.16}/src/response.rs +4 -1
- {turboapi-0.4.15 → turboapi-0.4.16}/src/router.rs +49 -17
- {turboapi-0.4.15 → turboapi-0.4.16}/src/server.rs +1228 -467
- turboapi-0.4.16/src/simd_json.rs +392 -0
- turboapi-0.4.16/src/simd_parse.rs +507 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/src/threadpool.rs +71 -30
- {turboapi-0.4.15 → turboapi-0.4.16}/src/validation.rs +28 -26
- {turboapi-0.4.15 → turboapi-0.4.16}/src/websocket.rs +43 -31
- {turboapi-0.4.15 → turboapi-0.4.16}/src/zerocopy.rs +65 -53
- {turboapi-0.4.15 → turboapi-0.4.16}/test_package_integrity.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/comparison_before_after.py +7 -7
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/quick_body_test.py +3 -3
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_async_handlers.py +12 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_async_simple.py +0 -0
- turboapi-0.4.16/tests/test_comprehensive_parity.py +569 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_comprehensive_v0_4_15.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_fastapi_compatibility.py +10 -10
- turboapi-0.4.16/tests/test_fastapi_parity.py +1080 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_performance_regression.py +15 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_post_body_parsing.py +10 -10
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_query_and_headers.py +8 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_request_parsing.py +10 -1
- turboapi-0.4.16/tests/test_satya_0_4_0_compatibility.py +331 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/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/PKG-INFO +0 -31
- turboapi-0.4.15/README.md +0 -929
- 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/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/tests/test_satya_0_4_0_compatibility.py +0 -247
- 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.4.16}/.github/scripts/check_performance_regression.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/.github/scripts/compare_benchmarks.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/.github/workflows/README.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/.github/workflows/benchmark.yml +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/.gitignore +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/AGENTS.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/ASYNC_FIX_v0_4_15.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/BENCHMARK_FAQ.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/BENCHMARK_METHODOLOGY_RESPONSE.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/BENCHMARK_ONEPAGER.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/CHANGELOG.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/FASTAPI_COMPATIBILITY.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/LICENSE +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/Makefile +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/PHASE_3_COMPLETE.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/POST_BODY_PARSING_FIX.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/QUICK_RESPONSE_MULTICORE.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/RELEASE_NOTES_v0.4.13.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/RELEASE_NOTES_v0.4.14.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/RESPONSE_SUMMARY.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/TESTING.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/TODO_v0.4.15.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/V0.4.13_SUMMARY.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/V0.4.14_SUMMARY.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/V0.4.15_SUMMARY.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/benchmark_comparison.png +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/benchmark_graphs/turbo_vs_fastapi_performance_20250929_025531.png +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/docs/ARCHITECTURE_DIAGRAM.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/docs/AUTHENTICATION_GUIDE.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/examples/authentication_demo.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/examples/multi_route_app.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/MANIFEST.in +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/setup.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/async_limiter.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/async_pool.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/decorators.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/server_integration.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/python/turboapi/version_check.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/src/request.rs +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/test_simple_post.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/README.md +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/benchmark_comparison.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/fastapi_equivalent.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/quick_test.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/test_security_features.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/wrk_benchmark.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/tests/wrk_comparison.py +0 -0
- {turboapi-0.4.15 → turboapi-0.4.16}/turbo_vs_fastapi_benchmark_20250929_025526.json +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
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:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
needs: [check-version]
|
|
44
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
45
|
+
strategy:
|
|
46
|
+
matrix:
|
|
47
|
+
target: [x86_64, aarch64]
|
|
48
|
+
fail-fast: false
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v4
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: |
|
|
54
|
+
3.13
|
|
55
|
+
- name: Build wheels
|
|
56
|
+
uses: PyO3/maturin-action@v1
|
|
57
|
+
with:
|
|
58
|
+
target: ${{ matrix.target }}
|
|
59
|
+
args: --release --out dist --find-interpreter
|
|
60
|
+
sccache: 'true'
|
|
61
|
+
manylinux: auto
|
|
62
|
+
- uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: wheels-linux-${{ matrix.target }}
|
|
65
|
+
path: dist
|
|
66
|
+
|
|
67
|
+
windows:
|
|
68
|
+
runs-on: windows-latest
|
|
69
|
+
needs: [check-version]
|
|
70
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
71
|
+
strategy:
|
|
72
|
+
matrix:
|
|
73
|
+
target: [x64]
|
|
74
|
+
fail-fast: false
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v4
|
|
77
|
+
- uses: actions/setup-python@v5
|
|
78
|
+
with:
|
|
79
|
+
python-version: |
|
|
80
|
+
3.13
|
|
81
|
+
- name: Build wheels
|
|
82
|
+
uses: PyO3/maturin-action@v1
|
|
83
|
+
with:
|
|
84
|
+
args: --release --out dist --find-interpreter
|
|
85
|
+
sccache: 'true'
|
|
86
|
+
- uses: actions/upload-artifact@v4
|
|
87
|
+
with:
|
|
88
|
+
name: wheels-windows-${{ matrix.target }}
|
|
89
|
+
path: dist
|
|
90
|
+
|
|
91
|
+
macos:
|
|
92
|
+
runs-on: macos-latest
|
|
93
|
+
needs: [check-version]
|
|
94
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
95
|
+
strategy:
|
|
96
|
+
matrix:
|
|
97
|
+
target: [x86_64-apple-darwin, aarch64-apple-darwin]
|
|
98
|
+
fail-fast: false
|
|
99
|
+
steps:
|
|
100
|
+
- uses: actions/checkout@v4
|
|
101
|
+
- uses: actions/setup-python@v5
|
|
102
|
+
with:
|
|
103
|
+
python-version: |
|
|
104
|
+
3.13
|
|
105
|
+
- name: Build wheels
|
|
106
|
+
uses: PyO3/maturin-action@v1
|
|
107
|
+
with:
|
|
108
|
+
target: ${{ matrix.target }}
|
|
109
|
+
args: --release --out dist --find-interpreter
|
|
110
|
+
sccache: 'true'
|
|
111
|
+
- uses: actions/upload-artifact@v4
|
|
112
|
+
with:
|
|
113
|
+
name: wheels-macos-${{ matrix.target }}
|
|
114
|
+
path: dist
|
|
115
|
+
|
|
116
|
+
sdist:
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
needs: [check-version]
|
|
119
|
+
if: needs.check-version.outputs.should_publish == 'true'
|
|
120
|
+
steps:
|
|
121
|
+
- uses: actions/checkout@v4
|
|
122
|
+
- name: Build sdist
|
|
123
|
+
uses: PyO3/maturin-action@v1
|
|
124
|
+
with:
|
|
125
|
+
command: sdist
|
|
126
|
+
args: --out dist
|
|
127
|
+
- uses: actions/upload-artifact@v4
|
|
128
|
+
with:
|
|
129
|
+
name: sdist
|
|
130
|
+
path: dist
|
|
131
|
+
|
|
132
|
+
publish:
|
|
133
|
+
name: Publish to PyPI
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
needs: [linux, windows, macos, sdist]
|
|
136
|
+
steps:
|
|
137
|
+
- uses: actions/download-artifact@v4
|
|
138
|
+
with:
|
|
139
|
+
pattern: '{wheels-*,sdist}'
|
|
140
|
+
path: dist
|
|
141
|
+
merge-multiple: true
|
|
142
|
+
- name: Publish to PyPI
|
|
143
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
144
|
+
with:
|
|
145
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
146
|
+
skip-existing: true
|
|
147
|
+
|
|
148
|
+
release:
|
|
149
|
+
name: Create GitHub Release
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
needs: [check-version, publish]
|
|
152
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
153
|
+
steps:
|
|
154
|
+
- uses: actions/checkout@v4
|
|
155
|
+
with:
|
|
156
|
+
fetch-depth: 0
|
|
157
|
+
- uses: actions/download-artifact@v4
|
|
158
|
+
with:
|
|
159
|
+
pattern: '{wheels-*,sdist}'
|
|
160
|
+
path: dist
|
|
161
|
+
merge-multiple: true
|
|
162
|
+
- name: Create Release
|
|
163
|
+
uses: softprops/action-gh-release@v2
|
|
164
|
+
with:
|
|
165
|
+
files: dist/*
|
|
166
|
+
generate_release_notes: true
|
|
167
|
+
|
|
168
|
+
tag-and-release:
|
|
169
|
+
name: Tag new version
|
|
170
|
+
runs-on: ubuntu-latest
|
|
171
|
+
needs: [check-version, publish]
|
|
172
|
+
if: github.ref == 'refs/heads/main' && needs.check-version.outputs.should_publish == 'true'
|
|
173
|
+
steps:
|
|
174
|
+
- uses: actions/checkout@v4
|
|
175
|
+
with:
|
|
176
|
+
fetch-depth: 0
|
|
177
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
178
|
+
- name: Configure git
|
|
179
|
+
run: |
|
|
180
|
+
git config user.email "action@github.com"
|
|
181
|
+
git config user.name "GitHub Action"
|
|
182
|
+
- name: Create tag
|
|
183
|
+
env:
|
|
184
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
185
|
+
run: |
|
|
186
|
+
VERSION="${{ needs.check-version.outputs.version }}"
|
|
187
|
+
git tag "v${VERSION}"
|
|
188
|
+
git push origin "v${VERSION}"
|
|
189
|
+
- uses: actions/download-artifact@v4
|
|
190
|
+
with:
|
|
191
|
+
pattern: '{wheels-*,sdist}'
|
|
192
|
+
path: dist
|
|
193
|
+
merge-multiple: true
|
|
194
|
+
- name: Create GitHub Release
|
|
195
|
+
uses: softprops/action-gh-release@v2
|
|
196
|
+
with:
|
|
197
|
+
tag_name: v${{ needs.check-version.outputs.version }}
|
|
198
|
+
files: dist/*
|
|
199
|
+
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
|
|
@@ -17,6 +17,18 @@ version = "2.0.1"
|
|
|
17
17
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
18
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
|
19
19
|
|
|
20
|
+
[[package]]
|
|
21
|
+
name = "ahash"
|
|
22
|
+
version = "0.8.12"
|
|
23
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
24
|
+
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
|
25
|
+
dependencies = [
|
|
26
|
+
"cfg-if",
|
|
27
|
+
"once_cell",
|
|
28
|
+
"version_check",
|
|
29
|
+
"zerocopy",
|
|
30
|
+
]
|
|
31
|
+
|
|
20
32
|
[[package]]
|
|
21
33
|
name = "aho-corasick"
|
|
22
34
|
version = "1.1.3"
|
|
@@ -26,6 +38,12 @@ dependencies = [
|
|
|
26
38
|
"memchr",
|
|
27
39
|
]
|
|
28
40
|
|
|
41
|
+
[[package]]
|
|
42
|
+
name = "allocator-api2"
|
|
43
|
+
version = "0.2.21"
|
|
44
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
45
|
+
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|
46
|
+
|
|
29
47
|
[[package]]
|
|
30
48
|
name = "anes"
|
|
31
49
|
version = "0.1.6"
|
|
@@ -357,6 +375,15 @@ version = "1.0.2"
|
|
|
357
375
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
358
376
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
359
377
|
|
|
378
|
+
[[package]]
|
|
379
|
+
name = "float-cmp"
|
|
380
|
+
version = "0.10.0"
|
|
381
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
382
|
+
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
|
383
|
+
dependencies = [
|
|
384
|
+
"num-traits",
|
|
385
|
+
]
|
|
386
|
+
|
|
360
387
|
[[package]]
|
|
361
388
|
name = "fnv"
|
|
362
389
|
version = "1.0.7"
|
|
@@ -469,8 +496,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
469
496
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
|
470
497
|
dependencies = [
|
|
471
498
|
"cfg-if",
|
|
499
|
+
"js-sys",
|
|
472
500
|
"libc",
|
|
473
501
|
"wasi",
|
|
502
|
+
"wasm-bindgen",
|
|
474
503
|
]
|
|
475
504
|
|
|
476
505
|
[[package]]
|
|
@@ -508,6 +537,26 @@ dependencies = [
|
|
|
508
537
|
"crunchy",
|
|
509
538
|
]
|
|
510
539
|
|
|
540
|
+
[[package]]
|
|
541
|
+
name = "halfbrown"
|
|
542
|
+
version = "0.2.5"
|
|
543
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
544
|
+
checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f"
|
|
545
|
+
dependencies = [
|
|
546
|
+
"hashbrown 0.14.5",
|
|
547
|
+
"serde",
|
|
548
|
+
]
|
|
549
|
+
|
|
550
|
+
[[package]]
|
|
551
|
+
name = "hashbrown"
|
|
552
|
+
version = "0.14.5"
|
|
553
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
554
|
+
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
|
555
|
+
dependencies = [
|
|
556
|
+
"ahash",
|
|
557
|
+
"allocator-api2",
|
|
558
|
+
]
|
|
559
|
+
|
|
511
560
|
[[package]]
|
|
512
561
|
name = "hashbrown"
|
|
513
562
|
version = "0.16.0"
|
|
@@ -628,7 +677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
628
677
|
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
|
629
678
|
dependencies = [
|
|
630
679
|
"equivalent",
|
|
631
|
-
"hashbrown",
|
|
680
|
+
"hashbrown 0.16.0",
|
|
632
681
|
]
|
|
633
682
|
|
|
634
683
|
[[package]]
|
|
@@ -1037,6 +1086,26 @@ dependencies = [
|
|
|
1037
1086
|
"bitflags",
|
|
1038
1087
|
]
|
|
1039
1088
|
|
|
1089
|
+
[[package]]
|
|
1090
|
+
name = "ref-cast"
|
|
1091
|
+
version = "1.0.25"
|
|
1092
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1093
|
+
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
|
|
1094
|
+
dependencies = [
|
|
1095
|
+
"ref-cast-impl",
|
|
1096
|
+
]
|
|
1097
|
+
|
|
1098
|
+
[[package]]
|
|
1099
|
+
name = "ref-cast-impl"
|
|
1100
|
+
version = "1.0.25"
|
|
1101
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1102
|
+
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
|
1103
|
+
dependencies = [
|
|
1104
|
+
"proc-macro2",
|
|
1105
|
+
"quote",
|
|
1106
|
+
"syn",
|
|
1107
|
+
]
|
|
1108
|
+
|
|
1040
1109
|
[[package]]
|
|
1041
1110
|
name = "regex"
|
|
1042
1111
|
version = "1.11.3"
|
|
@@ -1171,6 +1240,27 @@ dependencies = [
|
|
|
1171
1240
|
"libc",
|
|
1172
1241
|
]
|
|
1173
1242
|
|
|
1243
|
+
[[package]]
|
|
1244
|
+
name = "simd-json"
|
|
1245
|
+
version = "0.14.3"
|
|
1246
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1247
|
+
checksum = "aa2bcf6c6e164e81bc7a5d49fc6988b3d515d9e8c07457d7b74ffb9324b9cd40"
|
|
1248
|
+
dependencies = [
|
|
1249
|
+
"getrandom",
|
|
1250
|
+
"halfbrown",
|
|
1251
|
+
"ref-cast",
|
|
1252
|
+
"serde",
|
|
1253
|
+
"serde_json",
|
|
1254
|
+
"simdutf8",
|
|
1255
|
+
"value-trait",
|
|
1256
|
+
]
|
|
1257
|
+
|
|
1258
|
+
[[package]]
|
|
1259
|
+
name = "simdutf8"
|
|
1260
|
+
version = "0.1.5"
|
|
1261
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1262
|
+
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
|
1263
|
+
|
|
1174
1264
|
[[package]]
|
|
1175
1265
|
name = "slab"
|
|
1176
1266
|
version = "0.4.11"
|
|
@@ -1439,7 +1529,7 @@ dependencies = [
|
|
|
1439
1529
|
|
|
1440
1530
|
[[package]]
|
|
1441
1531
|
name = "turbonet"
|
|
1442
|
-
version = "0.4.
|
|
1532
|
+
version = "0.4.16"
|
|
1443
1533
|
dependencies = [
|
|
1444
1534
|
"anyhow",
|
|
1445
1535
|
"bytes",
|
|
@@ -1450,13 +1540,17 @@ dependencies = [
|
|
|
1450
1540
|
"http-body-util",
|
|
1451
1541
|
"hyper",
|
|
1452
1542
|
"hyper-util",
|
|
1543
|
+
"itoa",
|
|
1544
|
+
"memchr",
|
|
1453
1545
|
"num_cpus",
|
|
1454
1546
|
"pin-project-lite",
|
|
1455
1547
|
"pyo3",
|
|
1456
1548
|
"pyo3-async-runtimes",
|
|
1457
1549
|
"rayon",
|
|
1550
|
+
"ryu",
|
|
1458
1551
|
"serde",
|
|
1459
1552
|
"serde_json",
|
|
1553
|
+
"simd-json",
|
|
1460
1554
|
"tokio",
|
|
1461
1555
|
"tokio-test",
|
|
1462
1556
|
"tokio-tungstenite",
|
|
@@ -1494,6 +1588,18 @@ version = "0.1.1"
|
|
|
1494
1588
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1495
1589
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
|
1496
1590
|
|
|
1591
|
+
[[package]]
|
|
1592
|
+
name = "value-trait"
|
|
1593
|
+
version = "0.10.1"
|
|
1594
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1595
|
+
checksum = "9170e001f458781e92711d2ad666110f153e4e50bfd5cbd02db6547625714187"
|
|
1596
|
+
dependencies = [
|
|
1597
|
+
"float-cmp",
|
|
1598
|
+
"halfbrown",
|
|
1599
|
+
"itoa",
|
|
1600
|
+
"ryu",
|
|
1601
|
+
]
|
|
1602
|
+
|
|
1497
1603
|
[[package]]
|
|
1498
1604
|
name = "version_check"
|
|
1499
1605
|
version = "0.9.5"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "turbonet"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.16"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Rach Pradhan <rach@turboapi.dev>"]
|
|
6
6
|
description = "High-performance Python web framework core - Rust-powered HTTP server with Python 3.14 free-threading support, FastAPI-compatible security and middleware"
|
|
@@ -40,6 +40,10 @@ futures = "0.3"
|
|
|
40
40
|
rayon = "1.8"
|
|
41
41
|
crossbeam = "0.8"
|
|
42
42
|
num_cpus = "1.16"
|
|
43
|
+
memchr = "2.7"
|
|
44
|
+
simd-json = "0.14"
|
|
45
|
+
itoa = "1.0"
|
|
46
|
+
ryu = "1.0"
|
|
43
47
|
|
|
44
48
|
[dev-dependencies]
|
|
45
49
|
criterion = { version = "0.5", features = ["html_reports"] }
|