turboapi 0.3.21__tar.gz → 0.3.23__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.3.21 → turboapi-0.3.23}/Cargo.lock +1 -1
- {turboapi-0.3.21 → turboapi-0.3.23}/Cargo.toml +1 -1
- {turboapi-0.3.21 → turboapi-0.3.23}/PKG-INFO +1 -1
- {turboapi-0.3.21 → turboapi-0.3.23}/pyproject.toml +1 -1
- {turboapi-0.3.21 → turboapi-0.3.23}/python/pyproject.toml +1 -1
- {turboapi-0.3.21 → turboapi-0.3.23}/src/server.rs +16 -5
- turboapi-0.3.23/tests/async_benchmark.sh +64 -0
- turboapi-0.3.23/tests/quick_benchmark.sh +63 -0
- turboapi-0.3.23/tests/test_async_benchmark.py +55 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/test_v0_3_20_server.py +6 -5
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/scripts/check_performance_regression.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/scripts/compare_benchmarks.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/README.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/benchmark.yml +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/build-and-release.yml +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/build-wheels.yml +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/ci.yml +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.github/workflows/release.yml +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/.gitignore +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/AGENTS.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/CHANGELOG.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/FASTAPI_COMPATIBILITY.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/FASTAPI_FIXES_SUMMARY.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/LICENSE +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/PYTHON_313_FREE_THREADING_SETUP.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/PYTHON_SETUP_COMPLETE.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/README.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/RELEASE_NOTES_v0.3.1.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/RELEASE_NOTES_v0.3.13.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/WINDOWS_FIX_SUMMARY.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/adaptive_rate_test.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/benches/performance_bench.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/benchmark_comparison.png +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/benchmark_graphs/turbo_vs_fastapi_performance_20250929_025531.png +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/benchmark_output.txt +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/claude.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/adr_python_handler_integration.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/phase_1.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/phase_2.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/phase_3.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/phase_4.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/blog/phase_5.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/delete/twitterpost.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/install_benchmark_deps.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/001-foundation.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/002-routing-breakthrough.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/003-production-ready.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/004-zero-copy-revolution.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/005-middleware-mastery.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/006-python-handler-breakthrough.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/README.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/mini-notes/lessons-learned.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/MANIFEST.in +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/setup.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/__init__.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/decorators.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/main_app.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/middleware.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/models.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/request_handler.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/routing.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/rust_integration.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/server_integration.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/python/turboapi/version_check.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/setup_python313t.sh +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/http2.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/lib.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/micro_bench.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/middleware.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/request.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/response.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/router.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/threadpool.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/validation.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/websocket.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/src/zerocopy.rs +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/test_no_rate_limit.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/test_rate_limiting.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/test_zerocopy.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/README.md +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/benchmark_comparison.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/comparison_before_after.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/fastapi_equivalent.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/fastapi_v0_3_20_equivalent.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/quick_body_test.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/quick_test.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/run_v0_3_20_benchmark.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/test.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/test_fastapi_compatibility.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/test_v0_3_20_fixes.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/test_v0_3_21_async.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/wrk_benchmark.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/tests/wrk_comparison.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turbo_vs_fastapi_benchmark_20250929_025526.json +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/__init__.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/decorators.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/main_app.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/middleware.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/models.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/request_handler.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/routing.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/rust_integration.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/server_integration.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/turboapi/version_check.py +0 -0
- {turboapi-0.3.21 → turboapi-0.3.23}/wrk_rate_limit_test.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "turboapi"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.23"
|
|
8
8
|
description = "Revolutionary Python web framework with FastAPI syntax and 5-10x performance (Python 3.13+ free-threading required)"
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "turboapi"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.23"
|
|
8
8
|
description = "Revolutionary Python web framework with FastAPI syntax and 5-10x performance (Python 3.13+ free-threading required)"
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -415,6 +415,7 @@ pub fn configure_rate_limiting(enabled: bool, requests_per_minute: Option<u32>)
|
|
|
415
415
|
|
|
416
416
|
/// PHASE 2: Fast Python handler call with cached modules and optimized object creation
|
|
417
417
|
/// Now supports async Python handlers via pyo3-async-runtimes + tokio
|
|
418
|
+
/// FREE-THREADING: Uses Python::attach() for true parallelism on Python 3.13+
|
|
418
419
|
fn call_python_handler_fast(
|
|
419
420
|
handler: Handler,
|
|
420
421
|
method_str: &str,
|
|
@@ -422,7 +423,9 @@ fn call_python_handler_fast(
|
|
|
422
423
|
query_string: &str,
|
|
423
424
|
body: &Bytes
|
|
424
425
|
) -> Result<String, pyo3::PyErr> {
|
|
425
|
-
Python::with_gil(
|
|
426
|
+
// Use Python::attach() instead of with_gil() for free-threading parallelism!
|
|
427
|
+
// This allows multiple Python handlers to run in parallel on Python 3.13+
|
|
428
|
+
Python::attach(|py| {
|
|
426
429
|
// Get cached modules (initialized once)
|
|
427
430
|
let types_module = CACHED_TYPES_MODULE.get_or_init(|| {
|
|
428
431
|
py.import("types").unwrap().into()
|
|
@@ -465,10 +468,18 @@ fn call_python_handler_fast(
|
|
|
465
468
|
|
|
466
469
|
// Handle sync vs async results differently
|
|
467
470
|
if is_coroutine {
|
|
468
|
-
// Async handler -
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
471
|
+
// Async handler - use pyo3-async-runtimes to convert Python coroutine to Rust future
|
|
472
|
+
// This integrates with tokio's runtime for true async performance!
|
|
473
|
+
|
|
474
|
+
// Convert Python coroutine to Rust future using pyo3-async-runtimes
|
|
475
|
+
let rust_future = pyo3_async_runtimes::tokio::into_future(result.clone_ref(py).into_bound(py))?;
|
|
476
|
+
|
|
477
|
+
// Await the Rust future in tokio's runtime (blocking this thread)
|
|
478
|
+
let awaited_result = py.allow_threads(|| {
|
|
479
|
+
tokio::task::block_in_place(|| {
|
|
480
|
+
tokio::runtime::Handle::current().block_on(rust_future)
|
|
481
|
+
})
|
|
482
|
+
})?;
|
|
472
483
|
|
|
473
484
|
// Serialize the awaited result
|
|
474
485
|
let json_dumps = json_module.getattr(py, "dumps")?;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Async benchmark: TurboAPI v0.3.21 SYNC vs ASYNC vs FastAPI
|
|
3
|
+
|
|
4
|
+
echo "=========================================="
|
|
5
|
+
echo "🏁 TurboAPI v0.3.21: SYNC vs ASYNC vs FastAPI"
|
|
6
|
+
echo "=========================================="
|
|
7
|
+
echo ""
|
|
8
|
+
|
|
9
|
+
# Check for wrk
|
|
10
|
+
if ! command -v wrk &> /dev/null; then
|
|
11
|
+
echo "❌ wrk not found. Install with: brew install wrk"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Test TurboAPI SYNC
|
|
16
|
+
echo "🚀 Test 1: TurboAPI SYNC (baseline)"
|
|
17
|
+
echo "=========================================="
|
|
18
|
+
python tests/test_v0_3_20_server.py > /tmp/turbo_sync.log 2>&1 &
|
|
19
|
+
TURBO_SYNC_PID=$!
|
|
20
|
+
sleep 4
|
|
21
|
+
|
|
22
|
+
echo "Simple GET:"
|
|
23
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8080/ 2>&1 | grep "Requests/sec"
|
|
24
|
+
echo "Parameterized:"
|
|
25
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8080/users/123 2>&1 | grep "Requests/sec"
|
|
26
|
+
|
|
27
|
+
kill $TURBO_SYNC_PID 2>/dev/null
|
|
28
|
+
sleep 2
|
|
29
|
+
|
|
30
|
+
# Test TurboAPI ASYNC
|
|
31
|
+
echo ""
|
|
32
|
+
echo "🚀 Test 2: TurboAPI ASYNC (asyncio.run)"
|
|
33
|
+
echo "=========================================="
|
|
34
|
+
python tests/test_async_benchmark.py > /tmp/turbo_async.log 2>&1 &
|
|
35
|
+
TURBO_ASYNC_PID=$!
|
|
36
|
+
sleep 4
|
|
37
|
+
|
|
38
|
+
echo "Simple GET:"
|
|
39
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8082/ 2>&1 | grep "Requests/sec"
|
|
40
|
+
echo "Parameterized:"
|
|
41
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8082/users/123 2>&1 | grep "Requests/sec"
|
|
42
|
+
|
|
43
|
+
kill $TURBO_ASYNC_PID 2>/dev/null
|
|
44
|
+
sleep 2
|
|
45
|
+
|
|
46
|
+
# Test FastAPI
|
|
47
|
+
echo ""
|
|
48
|
+
echo "🚀 Test 3: FastAPI (async with uvicorn)"
|
|
49
|
+
echo "=========================================="
|
|
50
|
+
python tests/fastapi_v0_3_20_equivalent.py > /tmp/fastapi.log 2>&1 &
|
|
51
|
+
FASTAPI_PID=$!
|
|
52
|
+
sleep 4
|
|
53
|
+
|
|
54
|
+
echo "Simple GET:"
|
|
55
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8081/ 2>&1 | grep "Requests/sec"
|
|
56
|
+
echo "Parameterized:"
|
|
57
|
+
wrk -t4 -c100 -d10s http://127.0.0.1:8081/users/123 2>&1 | grep "Requests/sec"
|
|
58
|
+
|
|
59
|
+
kill $FASTAPI_PID 2>/dev/null
|
|
60
|
+
|
|
61
|
+
echo ""
|
|
62
|
+
echo "=========================================="
|
|
63
|
+
echo "✅ Benchmark Complete!"
|
|
64
|
+
echo "=========================================="
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Quick benchmark: TurboAPI v0.3.21 vs FastAPI
|
|
3
|
+
|
|
4
|
+
echo "=========================================="
|
|
5
|
+
echo "🏁 TurboAPI v0.3.21 vs FastAPI Benchmark"
|
|
6
|
+
echo "=========================================="
|
|
7
|
+
echo ""
|
|
8
|
+
|
|
9
|
+
# Check for wrk
|
|
10
|
+
if ! command -v wrk &> /dev/null; then
|
|
11
|
+
echo "❌ wrk not found. Install with: brew install wrk"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Test TurboAPI
|
|
16
|
+
echo "🚀 Starting TurboAPI v0.3.21..."
|
|
17
|
+
python tests/test_v0_3_20_server.py > /tmp/turbo.log 2>&1 &
|
|
18
|
+
TURBO_PID=$!
|
|
19
|
+
sleep 4
|
|
20
|
+
|
|
21
|
+
echo "📊 Benchmarking TurboAPI (10s, 4 threads, 100 connections)..."
|
|
22
|
+
echo ""
|
|
23
|
+
echo "Test 1: Simple GET /"
|
|
24
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8080/ 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
25
|
+
|
|
26
|
+
echo ""
|
|
27
|
+
echo "Test 2: Parameterized route /users/123"
|
|
28
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8080/users/123 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
29
|
+
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Test 3: Nested params /api/v1/users/1/posts/2"
|
|
32
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8080/api/v1/users/1/posts/2 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
33
|
+
|
|
34
|
+
kill $TURBO_PID 2>/dev/null
|
|
35
|
+
sleep 2
|
|
36
|
+
|
|
37
|
+
# Test FastAPI
|
|
38
|
+
echo ""
|
|
39
|
+
echo "=========================================="
|
|
40
|
+
echo "🚀 Starting FastAPI..."
|
|
41
|
+
python tests/fastapi_v0_3_20_equivalent.py > /tmp/fastapi.log 2>&1 &
|
|
42
|
+
FASTAPI_PID=$!
|
|
43
|
+
sleep 4
|
|
44
|
+
|
|
45
|
+
echo "📊 Benchmarking FastAPI (10s, 4 threads, 100 connections)..."
|
|
46
|
+
echo ""
|
|
47
|
+
echo "Test 1: Simple GET /"
|
|
48
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8081/ 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
49
|
+
|
|
50
|
+
echo ""
|
|
51
|
+
echo "Test 2: Parameterized route /users/123"
|
|
52
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8081/users/123 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
53
|
+
|
|
54
|
+
echo ""
|
|
55
|
+
echo "Test 3: Nested params /api/v1/users/1/posts/2"
|
|
56
|
+
wrk -t4 -c100 -d10s --latency http://127.0.0.1:8081/api/v1/users/1/posts/2 2>&1 | grep -E "Requests/sec|Latency|Thread"
|
|
57
|
+
|
|
58
|
+
kill $FASTAPI_PID 2>/dev/null
|
|
59
|
+
|
|
60
|
+
echo ""
|
|
61
|
+
echo "=========================================="
|
|
62
|
+
echo "✅ Benchmark Complete!"
|
|
63
|
+
echo "=========================================="
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TurboAPI v0.3.21 ASYNC Benchmark Server
|
|
3
|
+
Tests async handler performance with asyncio.run()
|
|
4
|
+
"""
|
|
5
|
+
import asyncio
|
|
6
|
+
from turboapi import TurboAPI
|
|
7
|
+
|
|
8
|
+
app = TurboAPI(title="TurboAPI v0.3.21 ASYNC Benchmark", version="0.3.21")
|
|
9
|
+
|
|
10
|
+
# Simple async GET
|
|
11
|
+
@app.get("/")
|
|
12
|
+
async def root():
|
|
13
|
+
await asyncio.sleep(0.0001) # Minimal async work
|
|
14
|
+
return {"message": "Hello, World!", "version": "0.3.21", "async": True}
|
|
15
|
+
|
|
16
|
+
# Async parameterized route
|
|
17
|
+
@app.get("/users/{user_id}")
|
|
18
|
+
async def get_user(user_id: int):
|
|
19
|
+
await asyncio.sleep(0.0001)
|
|
20
|
+
return {"user_id": user_id, "name": f"User {user_id}", "status": "active", "async": True}
|
|
21
|
+
|
|
22
|
+
# Async computation
|
|
23
|
+
@app.get("/compute")
|
|
24
|
+
async def compute():
|
|
25
|
+
await asyncio.sleep(0.0001)
|
|
26
|
+
result = sum(i * i for i in range(100))
|
|
27
|
+
return {"result": result, "type": "async_compute"}
|
|
28
|
+
|
|
29
|
+
# Async nested params
|
|
30
|
+
@app.get("/api/v1/users/{user_id}/posts/{post_id}")
|
|
31
|
+
async def get_user_post(user_id: int, post_id: int):
|
|
32
|
+
await asyncio.sleep(0.0001)
|
|
33
|
+
return {
|
|
34
|
+
"user_id": user_id,
|
|
35
|
+
"post_id": post_id,
|
|
36
|
+
"title": f"Post {post_id} by User {user_id}",
|
|
37
|
+
"async": True
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
print("=" * 70)
|
|
42
|
+
print("TurboAPI v0.3.21 ASYNC Benchmark Server")
|
|
43
|
+
print("=" * 70)
|
|
44
|
+
print("Endpoints (ALL ASYNC):")
|
|
45
|
+
print(" GET / - Simple async response")
|
|
46
|
+
print(" GET /users/{id} - Async parameterized route")
|
|
47
|
+
print(" GET /compute - Async computation")
|
|
48
|
+
print(" GET /api/v1/users/{uid}/posts/{pid} - Async nested params")
|
|
49
|
+
print("=" * 70)
|
|
50
|
+
print("⚠️ RATE LIMITING: DISABLED for benchmarking")
|
|
51
|
+
print("⚠️ Using asyncio.run() - expect some overhead")
|
|
52
|
+
print("=" * 70)
|
|
53
|
+
|
|
54
|
+
app.configure_rate_limiting(enabled=False)
|
|
55
|
+
app.run(host="127.0.0.1", port=8082)
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
TurboAPI v0.3.20 Test Server for wrk benchmarking
|
|
3
3
|
Tests both sync and async handlers with parameterized routes
|
|
4
4
|
"""
|
|
5
|
-
import asyncio
|
|
6
5
|
from turboapi import TurboAPI
|
|
7
6
|
|
|
8
|
-
app = TurboAPI(title="TurboAPI v0.3.
|
|
7
|
+
app = TurboAPI(title="TurboAPI v0.3.21 Benchmark", version="0.3.21")
|
|
9
8
|
|
|
10
9
|
# Simple GET (baseline)
|
|
11
10
|
@app.get("/")
|
|
@@ -40,15 +39,17 @@ def echo(message: str = ""):
|
|
|
40
39
|
|
|
41
40
|
if __name__ == "__main__":
|
|
42
41
|
print("=" * 70)
|
|
43
|
-
print("TurboAPI v0.3.
|
|
42
|
+
print("TurboAPI v0.3.21 Benchmark Server (SYNC ONLY)")
|
|
44
43
|
print("=" * 70)
|
|
45
44
|
print("Endpoints:")
|
|
46
45
|
print(" GET / - Simple response")
|
|
47
|
-
print(" GET /users/{id} - Parameterized route
|
|
46
|
+
print(" GET /users/{id} - Parameterized route")
|
|
48
47
|
print(" GET /compute - Computation")
|
|
49
|
-
print(" GET /api/v1/users/{uid}/posts/{pid} - Nested params
|
|
48
|
+
print(" GET /api/v1/users/{uid}/posts/{pid} - Nested params")
|
|
50
49
|
print(" POST /echo - Body parsing")
|
|
51
50
|
print("=" * 70)
|
|
51
|
+
print("⚠️ RATE LIMITING: DISABLED for benchmarking")
|
|
52
|
+
print("=" * 70)
|
|
52
53
|
|
|
53
54
|
app.configure_rate_limiting(enabled=False)
|
|
54
55
|
app.run(host="127.0.0.1", port=8080)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|