turboapi 0.4.13__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.13 → turboapi-0.4.16}/.github/workflows/release.yml +12 -12
- turboapi-0.4.16/ASYNC_FIX_v0_4_15.md +342 -0
- turboapi-0.4.16/BENCHMARK_FAQ.md +204 -0
- turboapi-0.4.16/BENCHMARK_METHODOLOGY_RESPONSE.md +340 -0
- turboapi-0.4.16/BENCHMARK_ONEPAGER.md +140 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/Cargo.lock +108 -2
- {turboapi-0.4.13 → turboapi-0.4.16}/Cargo.toml +5 -1
- turboapi-0.4.16/PHASE_3_COMPLETE.md +489 -0
- turboapi-0.4.16/PKG-INFO +423 -0
- turboapi-0.4.16/QUICK_RESPONSE_MULTICORE.md +252 -0
- turboapi-0.4.16/README.md +388 -0
- turboapi-0.4.16/RELEASE_NOTES_v0.4.14.md +412 -0
- turboapi-0.4.16/RESPONSE_SUMMARY.md +274 -0
- turboapi-0.4.16/TODO_v0.4.15.md +195 -0
- turboapi-0.4.16/V0.4.14_SUMMARY.md +312 -0
- turboapi-0.4.16/V0.4.15_SUMMARY.md +418 -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.13 → 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.16/docs/ARCHITECTURE_DIAGRAM.md +382 -0
- {turboapi-0.4.13 → 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.13 → turboapi-0.4.16/python}/turboapi/main_app.py +59 -4
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/middleware.py +4 -6
- {turboapi-0.4.13 → turboapi-0.4.16/python}/turboapi/models.py +15 -33
- turboapi-0.4.16/python/turboapi/openapi.py +236 -0
- turboapi-0.4.16/python/turboapi/request_handler.py +602 -0
- turboapi-0.4.16/python/turboapi/responses.py +209 -0
- {turboapi-0.4.13 → turboapi-0.4.16/python}/turboapi/routing.py +2 -1
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/rust_integration.py +111 -20
- {turboapi-0.4.13 → 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.13 → turboapi-0.4.16}/setup_python313t.sh +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/src/http2.rs +53 -33
- {turboapi-0.4.13 → turboapi-0.4.16}/src/lib.rs +28 -20
- {turboapi-0.4.13 → turboapi-0.4.16}/src/micro_bench.rs +43 -32
- {turboapi-0.4.13 → turboapi-0.4.16}/src/middleware.rs +157 -104
- {turboapi-0.4.13 → turboapi-0.4.16}/src/python_worker.rs +58 -58
- {turboapi-0.4.13 → turboapi-0.4.16}/src/response.rs +4 -1
- {turboapi-0.4.13 → turboapi-0.4.16}/src/router.rs +49 -17
- turboapi-0.4.16/src/server.rs +2287 -0
- turboapi-0.4.16/src/simd_json.rs +392 -0
- turboapi-0.4.16/src/simd_parse.rs +507 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/src/threadpool.rs +71 -30
- {turboapi-0.4.13 → turboapi-0.4.16}/src/validation.rs +28 -26
- {turboapi-0.4.13 → turboapi-0.4.16}/src/websocket.rs +43 -31
- {turboapi-0.4.13 → turboapi-0.4.16}/src/zerocopy.rs +65 -53
- {turboapi-0.4.13 → turboapi-0.4.16}/test_package_integrity.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/comparison_before_after.py +7 -7
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/quick_body_test.py +3 -3
- turboapi-0.4.16/tests/test_async_handlers.py +466 -0
- turboapi-0.4.16/tests/test_async_simple.py +89 -0
- turboapi-0.4.16/tests/test_comprehensive_parity.py +569 -0
- turboapi-0.4.16/tests/test_comprehensive_v0_4_15.py +106 -0
- {turboapi-0.4.13 → 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.16/tests/test_performance_regression.py +372 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/test_post_body_parsing.py +10 -10
- turboapi-0.4.16/tests/test_query_and_headers.py +308 -0
- turboapi-0.4.16/tests/test_request_parsing.py +406 -0
- turboapi-0.4.16/tests/test_satya_0_4_0_compatibility.py +331 -0
- turboapi-0.4.16/tests/test_wrk_regression.py +289 -0
- turboapi-0.4.13/.github/workflows/build-and-release.yml +0 -377
- turboapi-0.4.13/.github/workflows/build-wheels.yml +0 -212
- turboapi-0.4.13/.github/workflows/ci.yml +0 -151
- turboapi-0.4.13/PKG-INFO +0 -31
- turboapi-0.4.13/README.md +0 -882
- turboapi-0.4.13/benchmarks/comprehensive_wrk_benchmark.py +0 -284
- turboapi-0.4.13/benchmarks/turboapi_vs_fastapi_benchmark.py +0 -310
- turboapi-0.4.13/benchmarks/turboapi_vs_fastapi_simple.py +0 -249
- turboapi-0.4.13/benchmarks/wrk_output.txt +0 -0
- turboapi-0.4.13/python/pyproject.toml +0 -74
- turboapi-0.4.13/python/turboapi/__init__.py +0 -24
- turboapi-0.4.13/python/turboapi/main_app.py +0 -314
- turboapi-0.4.13/python/turboapi/models.py +0 -148
- turboapi-0.4.13/python/turboapi/request_handler.py +0 -277
- turboapi-0.4.13/python/turboapi/routing.py +0 -219
- turboapi-0.4.13/src/server.rs +0 -1505
- turboapi-0.4.13/tests/test_satya_0_4_0_compatibility.py +0 -247
- turboapi-0.4.13/turboapi/__init__.py +0 -24
- turboapi-0.4.13/turboapi/async_limiter.py +0 -86
- turboapi-0.4.13/turboapi/async_pool.py +0 -141
- turboapi-0.4.13/turboapi/decorators.py +0 -69
- turboapi-0.4.13/turboapi/middleware.py +0 -342
- turboapi-0.4.13/turboapi/request_handler.py +0 -277
- turboapi-0.4.13/turboapi/rust_integration.py +0 -258
- turboapi-0.4.13/turboapi/security.py +0 -542
- turboapi-0.4.13/turboapi/server_integration.py +0 -436
- turboapi-0.4.13/turboapi/version_check.py +0 -268
- {turboapi-0.4.13 → turboapi-0.4.16}/.github/scripts/check_performance_regression.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/.github/scripts/compare_benchmarks.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/.github/workflows/README.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/.github/workflows/benchmark.yml +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/.gitignore +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/AGENTS.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/CHANGELOG.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/FASTAPI_COMPATIBILITY.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/LICENSE +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/Makefile +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/POST_BODY_PARSING_FIX.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/RELEASE_NOTES_v0.4.13.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/TESTING.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/V0.4.13_SUMMARY.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/benchmark_comparison.png +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/benchmark_graphs/turbo_vs_fastapi_performance_20250929_025531.png +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/docs/AUTHENTICATION_GUIDE.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/examples/authentication_demo.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/examples/multi_route_app.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/MANIFEST.in +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/setup.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/async_limiter.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/async_pool.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/decorators.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/server_integration.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/python/turboapi/version_check.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/src/request.rs +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/test_simple_post.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/README.md +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/benchmark_comparison.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/fastapi_equivalent.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/quick_test.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/test.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/test_security_features.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/wrk_benchmark.py +0 -0
- {turboapi-0.4.13 → turboapi-0.4.16}/tests/wrk_comparison.py +0 -0
- {turboapi-0.4.13 → 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
|