Extensions
webfluid.extensions — the base extension and the battery set. All of them
follow the same shape: a class with an expand_fluid method, instantiated once and
reachable through webfluid.core.ext.
FluidExtension
from webfluid.extensions import FluidExtension — the base class for all extensions.
expand_fluid(fluid, *args)— override to hook into the app; called automatically when an extension is constructed with a fluid.cli_entry(app, name)— mounts the extension's_cliTyper app underwf.
SQLAlchemy
Model— the declarative base; resolves__tablename__from the snake-cased class name, supports__bind_key__andModel.set_bind(key).executor(bind_key=None, model=None)/async_executor(...)— context managers yielding an executor withexec,insert,delete,flush; commit/rollback handled for you.ensured_executor(...)/ensured_async_executor(...)— reuse an already-open executor or open a fresh one;current_executor/current_async_executorreach the active one.- The executors subclass
BaseContext, socurrent()andouter()(see Core) work on them too;db.bind_keyslists the configured binds. exec(statement, scalars=True)— returns a ScalarResult by default; passscalars=Falsefor the raw Result.get_bind_for_model(model)/get_bind(key)— resolve theBind(withsync_engine/async_engineand its ownmetadata) for a model or key.- Config:
SQLALCHEMY_DATABASE_URI,SQLALCHEMY_BINDS. Drivers are derived; don't put them in the uri.
Babel
gettext,ngettext,pgettext,npgettextand theirlazy_*variants.locale_selector(fn)/timezone_selector(fn)— register custom resolvers.force(locale, timezone)/aforce(...)— context managers to pin locale/timezone.register_domain(name, package=None)/update_translations(domain, translations)— runtime, db-backed catalogs.load_locale(locale),extract()(CLI), and the helpers inwebfluid.extensions.babel.utils(translation_resolver,get_locale, and theformat_date/format_currency/ ... filters).- Companions:
Domain,I18nKey/I18nMessage(the translation models),LazyString.
Security
Reached through webfluid.core.ext.security; needs EXT_SECURITY and EXT_SQLALCHEMY.
user_service— the current-user dependencies (current_user,require_user,require_2fa,require_admin) and therequire_roles/require_permissions(plus_any_) guard factories.hash_service— argon2hash(password)/verify(hash, password).token_service— CSRF (csrf_protect,csrf_response) and signed one-time tokens (generate_token,validate_token).oauth_service— authlib-backed social login, configured withSECURITY_OAUTH_CLIENTS.- Models in
webfluid.extensions.security.models:User,Identity,Role,Permission,TOTPSecret,WebAuthnCredential,BackupCode; validatorsvalidate_username/validate_password.
EventManager
create_signal(name, singleton=False, internal=False)— declare an event channel.event(name, ...)/query(name, ...)— decorators registering handlers;internal=Falseexposes them to the browser.trigger(event, data)— publish;request(query, data)— ask and await a result;listen(event)— async stream.- Client:
window.wf.ext.events.EventManager.
send(to, subject, body, ...)—bodyis a MIME-subtype map; threads delivery by default (fake_async).send_async(...)— the awaited variant. Both acceptattachments,cc,bcc,from_email.make_message(...),client()/async_client()— raw message building and bare SMTP connections.
Cache
set/get/delete/clearand the asyncaset/aget/adelete/aclear.- Backends selected by
CACHE_TYPE: legacy (in-memory, needs the scheduler) or redis.
JWTManager
encode(payload, audience="default")/decode(token, ...)and the asyncaencode/adecode.- Requires
EXT_SCHEDULINGandEXT_CACHE; rotates its signing secret on a schedule and keeps recent ones in the cache.
Migrate
A CLI-only extension (wf migrate ...) wrapping Alembic:
init <app>— enroll the matching single- or multi-db template.revision <app> [-a] [-m]— create a revision (optionally autogenerated).upgrade <app>/downgrade <app> [-r]— apply / revert migrations.
Continue reading
From here you can continue straight with Surface.