swadhinbiswas 📦 v2.0.8: security fixes, documentation, testing improvements · 7/28/2026
84307b8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use pyo3::prelude::*;
pub mod auth;
pub mod background;
pub mod buffer_test;
mod dag;
mod database;
pub mod gil_pool;
mod logging;
#[cfg(feature = "mail")]
mod mail;
#[cfg(feature = "mail")]
mod message_builder;
mod multipart;
mod native;
#[cfg(feature = "redis-rate-limit")]
mod rate_limit;
mod request;
pub mod scheduler;
pub mod status;
mod test_client;
mod websocket;
pub use auth::PyJwtAuth;
pub use dag::{Dag, DagNode};
pub use database::{Database, DbParam, DbPool};
#[cfg(feature = "mail")]
pub use mail::PyMailer;
pub use multipart::UploadFile;
pub use native::{validate_value, TokenStreamResponse, ValidatedStreamResponse};
#[cfg(feature = "redis-rate-limit")]
pub use rate_limit::PyRateLimitResult;
pub use request::{HTTPConnection, Headers, QueryParams, Request, RequestStream, State, URL};
pub use websocket::WebSocket;
pub use websocket::WebSocketState;
/// Start the server with hardcoded Rust routes only (no Python app).
#[pyfunction]
fn serve(addr: String) -> PyResult<()> {
let addr: std::net::SocketAddr = addr
.parse()
.map_err(|e| pyo3::exceptions::PyValueError::new_err(format!("Invalid address: {}", e)))?;
let rt = tokio::runtime::Runtime::new()
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("Runtime error: {}", e)))?;
rt.block_on(async {
let server = justapi_core::Server::new(addr);
server
.run()
.await
.map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("Server error: {}", e)))
})
}
#[pyfunction]
fn _test_zero_copy(data: &[u8]) -> buffer_test::ZeroCopyBuffer {
buffer_test::ZeroCopyBuffer::new(data.to_vec())
}
#[pymodule]
fn _justapi(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(serve, m)?)?;
m.add_function(wrap_pyfunction!(validate_value, m)?)?;
m.add_class::<buffer_test::ZeroCopyBuffer>()?;
auth::register(m)?;
#[cfg(feature = "redis-rate-limit")]
rate_limit::register(m)?;
m.add_function(wrap_pyfunction!(_test_zero_copy, m)?)?;
m.add_class::<native::JustAPIApp>()?;
m.add_class::<native::TokenStreamResponse>()?;
m.add_class::<native::ValidatedStreamResponse>()?;
m.add_class::<native::StreamSender>()?;
m.add_class::<test_client::JustAPITestClient>()?;
m.add_class::<WebSocket>()?;
m.add_class::<WebSocketState>()?;
m.add_class::<Request>()?;
m.add_class::<HTTPConnection>()?;
m.add_class::<Headers>()?;
m.add_class::<QueryParams>()?;
m.add_class::<URL>()?;
m.add_class::<State>()?;
m.add_class::<RequestStream>()?;
m.add_class::<UploadFile>()?;
m.add_class::<Database>()?;
m.add_class::<DbPool>()?;
m.add_class::<DbParam>()?;
m.add_class::<Dag>()?;
m.add_class::<DagNode>()?;
m.add_class::<background::BackgroundTasks>()?;
m.add_class::<scheduler::PyScheduler>()?;
#[cfg(feature = "mail")]
m.add_class::<mail::PyMailer>()?;
status::register(m)?;
logging::register(m)?;
Ok(())
}