Skip to content

API Reference

This page documents the public surface of the top-level arvel package — every symbol in arvel.__all__. It's generated from the installed package's docstrings and type signatures, so it always matches the version you have.

Note

Anything not listed here is internal and may change without a major version bump. Import from arvel (e.g. from arvel import Route), not from deep submodules, unless a guide tells you otherwise.

Application & lifecycle

Application

Application()

The framework kernel — owns the root container + provider lifecycle.

register_service

register_service(service: BaseService) -> None

Register a BaseService into the managed lifecycle.

connect() runs at boot (registration order); disconnect() at shutdown (reverse). Registering after boot connects immediately is not supported — register before boot().

register

register() -> None

Bootstrap the framework's baseline providers without a project base_path.

Convenience for test setups that need a minimal Application with container bindings but don't need a full project directory. Production code should use Application.configure(base_path).create() instead.

make

make(key: str, **overrides: object) -> Any

Resolve a named binding from the container.

iter_providers

iter_providers() -> Iterator[ServiceProvider]

Yield each registered ServiceProvider instance, in registration order.

Used by ConsoleServiceProvider.boot to collect commands from every provider without reaching into _provider_instances directly.

into_asgi

into_asgi(
    *,
    lifespan: Lifespan[FastAPI] | None = None,
    **fastapi_kwargs: Any,
) -> FastAPI

Produce a fully wired ASGI app. The framework owns the lifecycle.

Boot and shutdown are driven by the ASGI lifespan protocol, not by this factory call. That keeps the method loop-agnostic — it works the same whether called from a plain sync entrypoint or from inside a uvicorn --factory callback (which uvicorn invokes from within its own running event loop).

Behaviour:

  • Always returns a configured FastAPI instance (re-exported as arvel.ASGIApp). Routes are mounted, the exception handler is wired, and the container is stashed on app.state.arvel_container.
  • When lifespan is omitted, wires a default lifespan that calls await self.boot() on startup (skipped if already booted) and await self.shutdown() on graceful exit.
  • When lifespan is provided, uses it verbatim — the caller takes ownership of boot and shutdown.
  • **fastapi_kwargs are forwarded verbatim to the FastAPI constructor (e.g. docs_url, redoc_url, openapi_url, title, version).

The returned app expects to be driven by a lifespan-aware ASGI host (uvicorn, hypercorn, Starlette TestClient used as a context manager). Routing still works without a lifespan, but providers will not have booted.

ApplicationBuilder

ApplicationBuilder(base_path: Path)

Fluent builder for Application.

with_routing

with_routing(
    *,
    web: Path | str | None = None,
    api: Path | str | None = None,
    console: Path | str | None = None,
) -> Self

Register routing file paths to be loaded at register time.

   ``web`` and ``api`` are loaded by ``HttpServiceProvider.register``.
   ``console`` is stored on the application but not loaded until the
   Console provider ships.

   At least one of the three must be non-None. Subsequent calls

accumulate (last-write-wins per key).

with_config_dir

with_config_dir(path: Path | str) -> Self

Discover and load every .py config file in path at register() time.

See arvel.application._loader.discover_config_files for the discovery rules and arvel.config.lookup for the runtime accessor. Files are loaded under namespaced module names so a user's config/logging.py never shadows stdlib logging.

serve

serve(
    app: Application,
    *,
    host: str = "127.0.0.1",
    port: int = 8000,
) -> None

Run the app under uvicorn.

Auto-boots the application if it has not been booted yet (via Application.into_asgi()), so this is callable from a plain sync entrypoint.

BootError

BootError(
    provider: type[ServiceProvider], original: BaseException
)

Bases: RuntimeError

Raised when a provider fails during register() or boot().

ShutdownError

ShutdownError(
    provider: type[ServiceProvider], original: BaseException
)

Bases: RuntimeError

Raised when a provider fails during shutdown().

ASGIApp module-attribute

ASGIApp = FastAPI

HttpLifespan module-attribute

HttpLifespan = Lifespan[FastAPI]

Service container & dependency injection

Container

Container(*, parent: Container | None = None)

The DI container.

call

call(
    cls: type[Any],
    method: str,
    *,
    overrides: dict[str, Any] | None = None,
) -> Any

Resolve cls from the container, then call method with injected params.

Parameters are resolved from the container; overrides bypass injection for the specified parameter names. If cls is not bound, instantiates it directly (no-arg constructor assumed).

acall async

acall(
    cls: type[Any],
    method: str,
    *,
    overrides: dict[str, Any] | None = None,
) -> Any

Async variant of call() — supports async methods and async-resolved deps.

Scope

Bases: StrEnum

Lifetime of a binding's resolved instance.

dep

FastAPI bridge: Depends(arvel.dep(MyService)) resolves from the request scope.

dep

dep(abstract: type[T]) -> Callable[..., T]

Return a FastAPI-compatible resolver for abstract.

The resolver expects the request to expose request.state.arvel_scope, an instance of arvel.container.Container (created per-request by the framework's scope middleware, shipped fully).

AsyncBindingError

AsyncBindingError(abstract: type)

Bases: BindingResolutionError

Raised when make() (sync) is called on an async-only binding.

BindingResolutionError

BindingResolutionError(
    path: tuple[type, ...], *, reason: str = "unresolved"
)

Bases: Exception

Raised when the container cannot resolve a binding.

CircularDependencyError

CircularDependencyError(cycle: tuple[type, ...])

Bases: BindingResolutionError

Raised when a cycle is detected during resolution.

Configuration & environment

config

Typed configuration layer (pydantic-settings v2 based).

ConfigKeyError

Bases: KeyError

Raised when a dotted config key cannot be resolved.

Distinct from the stdlib KeyError so callers can disambiguate config-lookup failures from generic dict misses.

CacheConfig

Bases: ArvelSettings

Cache subsystem settings.

Two sources, in priority order:

  1. CACHE_URL — full Redis URL (e.g. redis://host:6379/0). Wins when set.
  2. CACHE_CONNECTION + fine-grained CACHE_*:

  3. CACHE_CONNECTION driver name: redis, file, array, database, null

  4. CACHE_HOST Redis host (default: localhost)
  5. CACHE_PORT Redis port (default: 6379)
  6. CACHE_PASSWORD Redis password (default: empty)
  7. CACHE_DATABASE Redis DB index (default: 0)
  8. CACHE_PREFIX key prefix (default: arvel_cache)
  9. CACHE_TTL default TTL in seconds (default: 3600)
  10. CACHE_FILE_PATH path for file store (default: storage/framework/cache)
  11. CACHE_GC_PROBABILITY file store GC % (default: 2)

When neither CACHE_URL nor CACHE_CONNECTION is set, enabled is False and the manager defaults to the array store (safe in-process default, no external connection needed).

Redis has no async driver suffix like SQLAlchemy. The redis.asyncio package handles async natively — specify CACHE_CONNECTION=redis and the manager uses redis.asyncio.Redis (or from_url when CACHE_URL is set).

array cache is fully supported: an in-process dict store with optional TTL. Useful in tests and single-process dev environments.

enabled property

enabled: bool

True when cache is explicitly configured via env.

driver property

driver: CacheDriver

Resolve the active driver.

Defaults to array when neither CACHE_URL nor CACHE_CONNECTION is set, so local dev works without Redis.

DbConfig

Bases: ArvelSettings

Database connection settings.

Two sources, in priority order:

  1. DB_URL — full SQLAlchemy async URL. Wins when set; all other fine-grained vars are ignored for the connection string itself (echo, pool_size, max_overflow, pool_recycle still come from their own vars).
  2. DB_CONNECTION + fine-grained DB_* — composed into a URL by async_url():

  3. DB_CONNECTION friendly name: postgresql, mysql, sqlite, memory

  4. DB_HOST (default: empty)
  5. DB_PORT (default: 0)
  6. DB_DATABASE (default: <base_path>/database/database.sqlite for sqlite, :memory: when DB_CONNECTION=memory)
  7. DB_USERNAME (default: empty)
  8. DB_PASSWORD (default: empty)
  9. DB_ECHO bool; default False
  10. DB_POOL_SIZE (default: 5)
  11. DB_MAX_OVERFLOW (default: 10)
  12. DB_POOL_RECYCLE seconds; default 1800

When neither DB_URL nor DB_CONNECTION is set the database subsystem is treated as disabled (enabled == False). The provider skips its startup ping and the engine falls back to sqlite+aiosqlite:///:memory: so code that accidentally touches the ORM fails fast rather than silently persisting to a stale file.

enabled property

enabled: bool

True when the database is explicitly configured via env.

async_url

async_url(base_path: Path | None = None) -> str

Return the async SQLAlchemy URL.

DB_URL wins when set. Otherwise the URL is built from DB_CONNECTION + fine-grained fields.

base_path is used to resolve the default SQLite file path (<base_path>/database/database.sqlite) when DB_DATABASE is not set and the driver is SQLite.

public_repr

public_repr() -> str

Redacted summary safe for logs.

ConfigError

Bases: Exception

Base class for all arvel.config errors.

ConfigNotRegisteredError

ConfigNotRegisteredError(settings_cls: type)

Bases: ConfigError

Raised when Config.of(cls) is called for a class not bound to the container.

NoPrefix

Marker: read this field from the bare uppercase env var, no prefix.

Config

Looks up a registered ArvelSettings subclass from the bound container.

SessionConfig

Bases: ArvelSettings

Session subsystem settings.

Env vars (auto-prefixed SESSION_):

  • SESSION_DRIVER (default: cookie)
  • SESSION_LIFETIME (seconds; default: 7200)
  • SESSION_ENCRYPT (bool; default: True)
  • SESSION_COOKIE_NAME (default: arvel_session)
  • SESSION_SECURE (bool; default: False — True in production)
  • SESSION_SAME_SITE (default: lax)
  • SESSION_FILES_PATH (default: storage/framework/sessions)
  • SESSION_GC_PROBABILITY (default: 2 — percentage)
  • SESSION_SECRET_KEY (required when encrypt=True)
  • SESSION_REDIS_URL (default: redis://127.0.0.1:6379/0)
  • SESSION_REDIS_PREFIX (default: arvel:)
  • SESSION_DATABASE_URL (default: sqlite+aiosqlite:///sessions.db)

ArvelSettings

Bases: BaseSettings

Base class for typed configuration sections.

Behavior: - env_prefix is auto-derived from the class name (DbConfigDB_). Override by setting model_config["env_prefix"] in the subclass. - env_nested_delimiter="_" — nested fields use a single underscore. - env_file=".env" — loaded if present. - extra="ignore" — unknown env vars don't blow up. - case_sensitive=False.

Subclasses that need strict .env parsing (extra="forbid") should opt into dotenv_filtering="match_prefix" themselves — applying it on the base would silently drop legitimate aliased fields (e.g. DB_URL reaching DbConfig.url).

from_environment classmethod

from_environment() -> Self

Load + validate the settings, wrapping ValidationError into ConfigError.

S3Config

Bases: ArvelSettings

AWS S3 or any S3-compatible provider (MinIO, R2, Hetzner, B2, …).

Point endpoint at a non-AWS S3 endpoint to use a compatible provider. See docs/site/docs/filesystem.md for per-provider worked examples.

StorageConfig

Bases: ArvelSettings

Storage subsystem settings.

Env vars (auto-prefixed STORAGE_):

  • STORAGE_DEFAULT (default: local)

config

config(key: str) -> Any
config(key: str, default: T) -> T
config(key: str, default: object = _MISSING) -> Any

Laravel-style config accessor with optional default.

Reads from the modules loaded via ApplicationBuilder.with_config_dir(). Uses the same dotted-key syntax as lookup():

  • config("app.timezone") — returns the value, or None if not found
  • config("app.timezone", "UTC") — returns "UTC" when the key is missing
  • config("db.pool_size", 5) — default type informs the return type

Unlike lookup(), this never raises ConfigKeyError — a missing key returns the default (or None when no default is given).

lookup

lookup(key: str) -> Any

Resolve a dotted config key against the loaded config modules.

key is dotted: "<module_stem>.<ATTR>[.<sub_attr>...]". The first segment names the config/<stem>.py file; subsequent segments traverse attribute or subscript access on the result.

Examples (after with_config_dir(p / 'config') loaded config/database.py and config/app.py):

  • lookup('database.DEFAULT') → the DEFAULT attribute on the database module.
  • lookup('database.CONNECTIONS.sqlite') → the sqlite entry of the CONNECTIONS dict.
  • lookup('app.NAME') → the NAME attribute on the app module.

Raises ConfigKeyError if any segment cannot be resolved.

register

register(cls: type[ArvelSettings]) -> type[ArvelSettings]

Mark a config class for auto-registration. Usable as a decorator.

env

env(key: str) -> str | None
env(key: str, default: T) -> T
env(key: str, *, required: Literal[True]) -> str
env(
    key: str,
    default: object = None,
    *,
    required: bool = False,
) -> object

NoPrefix

Marker: read this field from the bare uppercase env var, no prefix.

ConfigError

Bases: Exception

Base class for all arvel.config errors.

ConfigNotRegisteredError

ConfigNotRegisteredError(settings_cls: type)

Bases: ConfigError

Raised when Config.of(cls) is called for a class not bound to the container.

Routing

Route module-attribute

Route: _RouteFacade = _RouteFacade()

Router

Router()

Buffer of declared routes. One per app; use Router.singleton().

bindings

bindings() -> dict[str, RouteBindingResolver]

Snapshot of currently registered global parameter resolvers.

middleware_group

middleware_group(
    name: str, middleware: Sequence[MiddlewareRef]
) -> None

Register a named middleware group.

middleware

middleware(name: str, middleware: Middleware) -> None

Register a single named middleware.

URL module-attribute

URL: _URLFacade = _URLFacade()

url

url(path: str) -> str

Resolve a relative path against APP_URL.

Idempotent for already-absolute URLs.

RouteServiceProvider

RouteServiceProvider(app: Application)

Bases: ServiceProvider, ABC

Subclass and implement map_routes(router) to register your routes.

RoutingError

Bases: ValueError

Raised on routing-layer misuse — missing params, missing APP_URL, etc.

Subclasses ValueError so callers that handled the previous behaviour (ValueError raised when a param was missing) still match.

HTTP — controllers, requests & resources

Controller

Controller()

Marker / convenience base for HTTP controllers.

Subclasses may be: - Multi-action: declare methods (index, show, store, ...) and bind one route per method via Route.get("/...", controller=MyController, action="index"). - Invokable: declare async def __call__(self, ...) and bind via Route.get("/...", controller=MyController).

All controllers are resolved via the Arvel container.

FormRequest

FormRequest(payload: T)

Bases: Generic[T]

Holds a validated payload + per-request authorization decision.

Subclasses parameterize the payload model:

class StoreUserRequest(FormRequest[StoreUserPayload]):
    async def authorize(self, request: Any) -> bool:
        return request.state.user is not None

The Arvel routing layer rewrites the handler signature so FastAPI parses the body as StoreUserPayload, then constructs StoreUserRequest(payload) and awaits authorize(request) before the handler runs.

rules

rules() -> dict[str, str | list[str]]

Return Laravel-style rules applied after Pydantic parsing.

messages

messages() -> dict[str, str]

Custom messages keyed as field.rule (e.g. email.unique).

attributes

attributes() -> dict[str, str]

Human-readable field names substituted into error messages.

with_validator

with_validator(validator: Validator) -> None

Register conditional rules on validator (e.g. Rule.sometimes).

JsonResource

JsonResource(resource: T)

Bases: Generic[T]

Transform a single domain object into a JSON-ready dict.

Subclasses set the generic parameter and implement to_dict(request). Optionally set schema: ClassVar[type[BaseModel]] to surface an OpenAPI schema for this resource — opt-in only.

Any value returned as self.when(...) or self.when_loaded(...) that evaluates to the internal sentinel is automatically stripped from the dict returned by to_dict().

additional

additional(extra: Mapping[str, Any]) -> Self

Merge extra root-level keys into the dict returned by to_dict.

Extras win on key clashes. Chainable.

collection classmethod

collection(
    resources: list[T] | Paginatable[T],
) -> ResourceCollection[T]

Wrap resources (a list or any paginator) in a ResourceCollection.

With a list, the output is {"data": [...]} — overridable via ResourceCollection.wrap. With a paginator, the output mirrors the paginator's own {data, meta, links} envelope with each item transformed by this resource class.

when

when(condition: Any, value: Any) -> Any

Return value when condition is truthy, otherwise a missing sentinel.

The sentinel is stripped from the dict returned by to_dict() automatically.

when_loaded

when_loaded(relation: str) -> Any

Return the relation value if it's already in the resource's __dict__.

Never triggers a lazy load — safe to call on SQLAlchemy models.

merge_when

merge_when(
    condition: Any, data: dict[str, Any]
) -> dict[str, Any]

Return data when condition is truthy, otherwise an empty dict.

response

response(
    request: Any,
    *,
    status_code: int = 200,
    headers: Mapping[str, str] | None = None,
) -> ResourceResponse

Build a Starlette JSON response from to_dict(request).

ResourceCollection

ResourceCollection(
    resources: list[T],
    resource_cls: type[JsonResource[T]],
    *,
    paginator: Paginatable[T] | None = None,
)

Bases: Generic[T]

Transform a list (or paginator) of domain objects under one envelope.

Default wrap returns {"data": data} for the list path. The paginator path bypasses wrap — its envelope is whatever the paginator's own to_dict returns, with items transformed by resource_cls.

additional

additional(extra: Mapping[str, Any]) -> Self

Merge extra root-level keys into the envelope returned by to_dict.

Extras win on key clashes — they merge after the default envelope (or the paginator's envelope) is built. Chainable.

response

response(
    request: Any,
    *,
    status_code: int = 200,
    headers: Mapping[str, str] | None = None,
) -> ResourceResponse

Build a Starlette JSON response from to_dict(request).

wants_json

wants_json(request: object) -> bool

Returns True if the caller wants a JSON response.

Heuristics, in order: 1. URL path starts with /api (case-insensitive). 2. Accept header mentions application/json. 3. X-Requested-With header equals XMLHttpRequest (XHR sentinel).

HTTP — middleware

Middleware

Bases: Protocol

Route-level middleware. Composed by the arvel.support.Pipeline.

Authenticate

Authenticate(guard_name: str = 'web')

Resolves request.state.user via a named guard from AuthManager.

guard_name selects the guard configured in config/auth.py. Defaults to "web", which maps to AuthManager.guard(None).

Cors

Cors(
    app: ASGIApp,
    *,
    allowed_origins: Sequence[str] = (),
    allowed_methods: Sequence[str] = (
        "GET",
        "POST",
        "PUT",
        "PATCH",
        "DELETE",
        "OPTIONS",
    ),
    allowed_headers: Sequence[str] = (
        "Authorization",
        "Content-Type",
        "X-Requested-With",
    ),
    allow_credentials: bool = False,
    max_age: int = 600,
)

Bases: CORSMiddleware

Hardened wrapper around Starlette's CORSMiddleware.

Refuses the wildcard origin with credentials — a well-known browser footgun.

Throttle

Throttle(
    max_attempts: int,
    *,
    decay_seconds: int = 60,
    key: Callable[[Any], str] | None = None,
    store: RateLimiterStore | None = None,
)

Rate-limit by key. Adds X-RateLimit-* headers on every response.

VerifyCsrf

VerifyCsrf(except_paths: Sequence[str] | None = None)

Double-submit CSRF check. Skips safe methods and except_paths.

Uses secrets.compare_digest for constant-time token comparison.

HTTP — authentication & rate limiting

Guard

Bases: ABC

Resolves the current user from a request.

login async

login(_user: Any, _request: Any) -> None

Override in stateful guards. Stateless guards (JWT, Token) ignore this.

logout async

logout(_request: Any) -> None

Override in stateful guards. Stateless guards ignore this.

JwtGuard

JwtGuard(
    *,
    resolver: UserResolver,
    jwt: JwtConfig,
    leeway_seconds: int = 0,
)

Bases: Guard

issue_token async

issue_token(
    *,
    subject: str,
    expires_in: timedelta,
    claims: dict[str, object] | None = None,
) -> str

Mint a short-lived access JWT (typ=access).

Used by the upcoming AuthBroker to mint the access leg of the access+refresh token pair. Refresh tokens are opaque (not JWTs) and live in the refresh_tokens table via :class:RefreshToken.

SessionGuard

SessionGuard(
    *,
    resolver: UserResolver,
    session_key: str = "_auth_id",
    password_field: str = "password",
)

Bases: Guard

Authenticates via Arvel's SessionData stored at request.state.session.

UserResolver

Bases: Protocol

Lookup contract for guards.

Attempt dataclass

Attempt(count: int, reset_at: datetime)

Result of a single store.hit(...) call.

RateLimiterStore

Bases: Protocol

Pluggable backend for the Throttle middleware.

InMemoryStore

InMemoryStore()

Process-local store. Fine for dev, tests, single-process apps.

RedisStore

RedisStore(
    client: object, *, key_prefix: str = "arvel:rl:"
)

Redis-backed store for multi-process deployments.

Imports redis lazily so the dependency is only required when this store is actually instantiated (arvel[redis] extra).

HTTP — exceptions

HttpException

HttpException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: Exception

Base class for typed HTTP errors thrown by handlers/middleware.

HttpExceptionHandler

HttpExceptionHandler(
    *,
    translators: Mapping[
        type[Exception], ExceptionTranslator
    ]
    | None = None,
)

Central translator: HttpException → JSON response. Wires into a FastAPI app.

add_translator

add_translator(
    exc_type: type[Exception],
    translator: ExceptionTranslator,
) -> None

Register a foreign exception → HttpException translator.

AuthorizationException

AuthorizationException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

BadRequestException

BadRequestException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

ConflictException

ConflictException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

MethodNotAllowedException

MethodNotAllowedException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

NotFoundException

NotFoundException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

ServerErrorException

ServerErrorException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

ThrottleException

ThrottleException(
    message: str,
    *,
    retry_after_seconds: int,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

UnauthenticatedException

UnauthenticatedException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

ValidationException

ValidationException(
    message: str,
    *,
    status_code: int | None = None,
    details: Sequence[dict[str, Any]] | None = None,
)

Bases: HttpException

Service providers

ServiceProvider

ServiceProvider(app: Application)

Bootstrap unit. Subclass to register bindings and run boot/shutdown logic.

safe_config

safe_config(cls: type[_T], *, default: _T) -> _T

Resolve a config class from the container; return default on any failure.

Use this when config is optional — the provider falls back to a safe default when the application hasn't registered the settings class.

register

register() -> None

Sync. Container bindings only — no I/O, no other providers.

boot async

boot() -> None

Async. May do I/O. Runs after every provider's register().

shutdown async

shutdown() -> None

Async. Tear down resources. Runs in reverse registration order.

commands

commands() -> list[type[Command] | Command]

Console commands shipped by this provider.

Each item may be either a Command subclass (instantiated with no args by ConsoleServiceProvider.boot) or a pre-built Command instance (used when the provider needs to inject dependencies that come from the container).

provides

provides() -> list[type]

Abstracts this provider promises to bind. Used by deferred-provider logic (future WI).

publishes

publishes(
    paths: Mapping[str | Path, str | Path],
    *,
    tag: str = "default",
    is_migrations: bool = False,
) -> None

Register source-to-destination publishables under tag.

Mirrors Laravel's $this->publishes([...], 'tag'). Consumers run arvel vendor:publish --tag=<tag> (or --provider=<class>) to copy the registered files into their app.

Parameters

paths: Mapping of source file path → destination path. Both may be str or Path. Relative destinations resolve against Application.base_path. tag: Group label used by vendor:publish --tag=.... is_migrations: When True, each destination is treated as a target directory and the basename is rewritten with a UTC timestamp at publish time so the file lands chronologically in database/migrations/.

HttpServiceProvider

HttpServiceProvider(app: Application)

Bases: ServiceProvider

Bind every HTTP-layer service the rest of the framework expects.

Support helpers

Arr

Laravel Illuminate\Support\Arr parity helpers.

flatten staticmethod

flatten(
    items: Iterable[object], *, depth: int = -1
) -> list[object]

Flatten nested lists/tuples. depth=-1 (default) flattens fully.

dot staticmethod

dot(
    data: Mapping[str, object], prefix: str = ""
) -> dict[str, object]

Flatten a nested mapping into a.b.c keys.

undot staticmethod

undot(data: Mapping[str, object]) -> dict[str, object]

Inverse of :meth:dot — rebuild nested dicts from dotted keys.

wrap staticmethod

wrap(value: object) -> list[Any]

Normalize None/scalar/tuple to a list. Returns list[Any] by design.

shuffle staticmethod

shuffle(items: Sequence[T]) -> list[T]

Cryptographically secure shuffle. For deterministic shuffles use random.Random.

Str

Laravel Illuminate\Support\Str parity helpers, all static.

studly staticmethod

studly(text: str) -> str

PascalCase; Laravel calls this Str::studly.

plural staticmethod

plural(value: str) -> str

Naive English pluralization used by the code generators.

postposts, categorycategories. Already-plural words (trailing s) are left alone. Irregulars (person, child) aren't handled — override the table name when it matters.

headline staticmethod

headline(text: str) -> str

hello_world_greeting / helloWorldHello World ….

password staticmethod

password(
    length: int = 32,
    *,
    letters: bool = True,
    numbers: bool = True,
    symbols: bool = True,
    spaces: bool = False,
) -> str

Generate a cryptographically secure random password string.

Matches Laravel's Str::password — returns the password plaintext, not a hash. Pass the result to Hash.make() to store it.