Skip to main content

fastapi_core/
lib.rs

1//! Core types and traits for fastapi_rust.
2//!
3//! This crate provides the fundamental building blocks:
4//! - [`Request`] and [`Response`] types
5//! - [`RequestContext`] wrapping asupersync's `Cx`
6//! - [`FromRequest`] trait for extractors
7//! - Error types and [`IntoResponse`] trait
8//!
9//! # Design Principles
10//!
11//! - Zero-copy where possible
12//! - No runtime reflection
13//! - All types support `Send + Sync`
14//! - Cancel-correct via asupersync integration
15//!
16//! # Role In The System
17//!
18//! `fastapi-core` is the heart of the framework. It defines the request/response
19//! model, extractors, dependency injection, middleware, and application builder.
20//! Other crates layer on top of these types:
21//!
22//! - `fastapi` re-exports this crate as the public facade.
23//! - `fastapi-http` uses core types when parsing and serving HTTP.
24//! - `fastapi-router` plugs into core routing and parameter extraction.
25//! - `fastapi-openapi` builds schemas and specs from core metadata.
26//!
27//! This crate intentionally contains no network I/O. That separation keeps
28//! business logic and protocol parsing decoupled, and makes deterministic tests
29//! straightforward.
30//!
31//! # Asupersync Integration
32//!
33//! This crate uses [asupersync](https://github.com/Dicklesworthstone/asupersync) as its async
34//! runtime foundation, providing:
35//!
36//! - **Structured concurrency**: Request handlers run in regions
37//! - **Cancel-correctness**: Graceful cancellation via checkpoints
38//! - **Budgeted timeouts**: Request timeouts via budget exhaustion
39//! - **Deterministic testing**: Lab runtime for reproducible tests
40
41#![forbid(unsafe_code)]
42// Pedantic clippy lints allowed (style suggestions, not correctness issues)
43#![allow(clippy::uninlined_format_args)]
44#![allow(clippy::single_char_pattern)]
45#![allow(clippy::unused_async)]
46#![allow(clippy::cast_possible_truncation)]
47#![allow(clippy::unreadable_literal)]
48#![allow(clippy::type_complexity)]
49#![allow(clippy::must_use_candidate)]
50#![allow(clippy::derivable_impls)]
51#![allow(clippy::missing_fields_in_debug)]
52#![allow(clippy::single_match)]
53#![allow(clippy::unused_self)]
54#![allow(clippy::redundant_closure)]
55#![allow(clippy::semicolon_if_nothing_returned)]
56#![allow(clippy::never_loop)]
57#![allow(clippy::needless_lifetimes)]
58#![allow(clippy::needless_pass_by_value)]
59#![allow(clippy::needless_borrow)]
60#![allow(clippy::match_same_arms)]
61#![allow(clippy::items_after_statements)]
62#![allow(clippy::manual_strip)]
63#![allow(clippy::format_push_string)]
64#![allow(clippy::struct_field_names)]
65#![allow(clippy::single_match_else)]
66#![allow(clippy::elidable_lifetime_names)]
67#![allow(clippy::map_unwrap_or)]
68
69pub mod api_router;
70pub mod app;
71pub mod bench;
72mod context;
73pub mod coverage;
74mod dependency;
75pub mod docs;
76pub mod error;
77mod extract;
78pub mod fault;
79pub mod fixtures;
80pub mod health;
81pub mod loadtest;
82pub mod logging;
83pub mod middleware;
84pub mod ndjson;
85pub mod password;
86mod request;
87mod response;
88pub mod routing;
89pub mod shutdown;
90pub mod sse;
91pub mod static_files;
92pub mod testing;
93pub mod versioning;
94
95#[cfg(feature = "proptest")]
96pub mod proptest;
97
98pub use context::{
99    BodyLimitConfig, CancelledError, DEFAULT_MAX_BODY_SIZE, IntoOutcome, RequestContext,
100};
101pub use dependency::{
102    CircularDependencyError, CleanupFn, CleanupStack, DefaultConfig, DefaultDependencyConfig,
103    DependencyCache, DependencyOverrides, DependencyScope, DependencyScopeError, Depends,
104    DependsCleanup, DependsConfig, FromDependency, FromDependencyWithCleanup, NoCache,
105};
106pub use error::{
107    DebugConfig, DebugInfo, HttpError, LocItem, ResponseValidationError, ValidationError,
108    ValidationErrors, disable_debug_mode, enable_debug_mode, is_debug_mode_enabled,
109};
110pub use extract::{
111    Accept, AcceptEncodingHeader, AcceptEncodingItem, AcceptHeader, AcceptItem,
112    AcceptLanguageHeader, AcceptLanguageItem, ApiKeyCookie, ApiKeyCookieConfig, ApiKeyCookieError,
113    ApiKeyHeader, ApiKeyHeaderConfig, ApiKeyHeaderError, ApiKeyQuery, ApiKeyQueryConfig,
114    ApiKeyQueryError, AppState, Authorization, BackgroundTasks, BackgroundTasksInner, BasicAuth,
115    BasicAuthError, BearerToken, BearerTokenError, Bytes, ContentType, Cookie, CookieExtractError,
116    CookieName, CookiePrefix, CookiePrefixError, CsrfTokenCookie, DEFAULT_API_KEY_COOKIE,
117    DEFAULT_API_KEY_HEADER, DEFAULT_API_KEY_QUERY_PARAM, DEFAULT_FORM_LIMIT, DEFAULT_JSON_LIMIT,
118    DEFAULT_MULTIPART_FILE_SIZE, DEFAULT_MULTIPART_MAX_FIELDS, DEFAULT_MULTIPART_TOTAL_SIZE,
119    DEFAULT_PAGE, DEFAULT_PER_PAGE, DEFAULT_RAW_BODY_LIMIT, DigestAuth, DigestAuthError, File,
120    FileConfig, Form, FormConfig, FormExtractError, FromHeaderValue, FromRequest, Header,
121    HeaderExtractError, HeaderName, HeaderValues, Host, Json, JsonConfig, JsonExtractError,
122    MAX_PER_PAGE, MediaType, Multipart, MultipartConfig, MultipartExtractError, MultipartPart,
123    NamedHeader, NotAcceptableError, OAuth2AuthorizationCodeBearer,
124    OAuth2AuthorizationCodeBearerConfig, OAuth2BearerError, OAuth2BearerErrorKind,
125    OAuth2PasswordBearer, OAuth2PasswordBearerConfig, OAuth2PasswordFormError,
126    OAuth2PasswordRequestForm, OAuth2PasswordRequestFormStrict, Page, Pagination, PaginationConfig,
127    Path, PathExtractError, PathParams, Query, QueryExtractError, QueryParams, RawBodyConfig,
128    RawBodyError, RequestCookie, RequestCookies, RequestRef, ResponseMut, ResponseMutations,
129    SameSite, SecureCompare, SecurityScopes, SecurityScopesError, SessionIdCookie, State,
130    StateExtractError, StringBody, UploadedFile, UserAgent, VaryBuilder, XRequestId,
131    constant_time_eq, constant_time_str_eq, snake_to_header_case,
132};
133pub use middleware::{
134    AddResponseHeader, BoxFuture, CompositeKeyExtractor, ConditionalInterceptor, ControlFlow, Cors,
135    CorsConfig, CsrfConfig, CsrfMiddleware, CsrfMode, CsrfToken, DebugInfoInterceptor,
136    ErrorResponseTransformer, Handler, HeaderKeyExtractor, HeaderTransformInterceptor,
137    HttpsRedirectConfig, HttpsRedirectMiddleware, InspectionVerbosity, IpKeyExtractor,
138    KeyExtractor, Layer, Layered, Middleware, MiddlewareStack, NoopMiddleware, OriginPattern,
139    PathKeyExtractor, PathPrefixFilter, RateLimitAlgorithm, RateLimitBuilder, RateLimitConfig,
140    RateLimitMiddleware, RateLimitResult, ReferrerPolicy, RequestId, RequestIdConfig,
141    RequestIdMiddleware, RequestInspectionMiddleware, RequestResponseLogger, RequireHeader,
142    ResponseBodyTransform, ResponseInterceptor, ResponseInterceptorContext,
143    ResponseInterceptorMiddleware, ResponseInterceptorStack, SecurityHeaders,
144    SecurityHeadersConfig, ServerTimingBuilder, ServerTimingEntry, TimingHistogram,
145    TimingHistogramBucket, TimingInterceptor, TimingMetrics, TimingMetricsConfig,
146    TimingMetricsMiddleware, TraceRejectionMiddleware, XFrameOptions,
147};
148#[cfg(feature = "compression")]
149pub use middleware::{CompressionConfig, CompressionMiddleware};
150pub use ndjson::{
151    NDJSON_CONTENT_TYPE, NDJSON_CONTENT_TYPE_ALT, NdjsonConfig, NdjsonResponse, NdjsonStream,
152    ndjson_iter, ndjson_response,
153};
154pub use request::{
155    Body, Headers, HttpVersion, Method, Request, RequestBodyStream, RequestBodyStreamError,
156};
157pub use response::{
158    Binary, BinaryWithType, BodyStream, FileResponse, Html, IntoResponse, Link, LinkHeader,
159    LinkRel, NoContent, Redirect, Response, ResponseBody, ResponseModel, ResponseModelConfig,
160    ResponseProduces, StatusCode, Text, ValidatedResponse, apply_conditional, check_if_match,
161    check_if_none_match, exclude_fields, include_fields, mime_type_for_extension,
162};
163pub use sse::{SseConfig, SseEvent, SseResponse, SseStream, sse_response};
164pub use static_files::{StaticFiles, StaticFilesConfig};
165
166// Re-export key asupersync types for convenience
167pub use asupersync::{Budget, Cx, Outcome, RegionId, TaskId};
168
169// Re-export testing utilities
170pub use testing::{
171    CapturedLog, CookieJar, E2ECapture, E2EReport, E2EScenario, E2EStep, E2EStepResult,
172    FixtureGuard, IntegrationTest, IntegrationTestContext, LogCapture, RequestBuilder,
173    ResponseDiff, ResponseSnapshot, TestClient, TestFixture, TestLogger, TestResponse, TestServer,
174    TestServerConfig, TestServerLogEntry, TestTimings, json_contains,
175};
176// Note: e2e_test!, assert_with_logs!, assert_eq_with_logs! macros are automatically exported
177// at crate root via #[macro_export]
178
179// Re-export assertion macros (defined via #[macro_export] in testing module)
180// Note: The macros assert_status!, assert_header!, assert_body_contains!,
181// assert_json!, and assert_body_matches! are automatically exported at the crate root
182// due to #[macro_export]. Users can import them with `use fastapi_core::assert_status;`
183
184// Re-export coverage utilities
185pub use coverage::{
186    BranchHits, CoverageConfig, CoverageReport, CoverageTracker, EndpointHits, OutputFormat,
187};
188
189// Re-export fault injection utilities
190pub use fault::{FaultConfig, FaultInjector, FaultRule, FaultType};
191
192// Re-export fixture factories
193pub use fixtures::{
194    AuthFactory, CommonFixtures, JsonArrayFactory, JsonFactory, JsonObjectFactory, JwtFactory,
195    RequestFactory, ResponseFactory, UserFactory,
196};
197
198// Re-export load testing utilities
199pub use loadtest::{LoadTest, LoadTestConfig, LoadTestReport};
200
201// Re-export password hashing utilities
202pub use password::{Algorithm, HashConfig, PasswordHasher};
203
204// Re-export logging utilities
205pub use logging::{AutoSpan, LogConfig, LogEntry, LogLevel, Span};
206
207// Re-export health check utilities
208pub use health::{
209    HealthCheckRegistry, HealthCheckResult, HealthReport, HealthStatus, basic_health_handler,
210    detailed_health_handler, liveness_handler, readiness_handler,
211};
212
213// Re-export documentation utilities
214pub use docs::{
215    DocsConfig, oauth2_redirect_html, oauth2_redirect_response, redoc_html, redoc_response,
216    swagger_ui_html, swagger_ui_response,
217};
218
219// Re-export api_router utilities
220pub use api_router::{APIRouter, IncludeConfig, ResponseDef, RouterDependency, RouterRoute};
221
222// Re-export app utilities
223pub use app::{
224    App, AppBuilder, AppConfig, BoxLifespanFn, ConfigError, ExceptionHandlers, HasState,
225    LifespanError, LifespanScope, MountedApp, RequiresState, RouteEntry, StartupHook,
226    StartupHookError, StartupOutcome, StateContainer, StateRegistry,
227};
228
229// Re-export shutdown utilities
230pub use shutdown::{
231    GracefulConfig, GracefulShutdown, InFlightGuard, ShutdownAware, ShutdownController,
232    ShutdownHook, ShutdownOutcome, ShutdownPhase, ShutdownReceiver, grace_expired_cancel_reason,
233    shutdown_cancel_reason, subdivide_grace_budget,
234};
235
236// Re-export routing utilities
237// Re-export versioning utilities
238pub use versioning::{ApiVersion, VersionConfig, VersionStrategy};
239
240pub use routing::{
241    Converter, ParamInfo, PathSegment, RouteLookup, RoutePattern, RouteTable, TrailingSlashMode,
242    format_allow_header,
243};