Integrate Your Own Project¶
- New FastAPI host: copy the complete application below and perform a real login.
- Existing account database: retain accounts/password material and use a sync or async callback.
- Existing frontend: mount
ui=NoneJSON routes and follow the browser contract. - Choose a visual style: use the demo template playground and copy its
LoginUI(...)configuration.
1. Install and Save the Application¶
Save this complete code as app.py. The account is operator; you must explicitly provide its password. It does not reuse the public demo identity or provide a default production password.
"""Minimal host app; provide an explicit password through the environment."""
import os
from urllib.parse import urlsplit
from fastapi import Depends, FastAPI
import uvicorn
from chatlogin import MemorySessionStore, PasswordBackend, Principal, SessionManager, hash_password
from chatlogin.fastapi import CookieSettings, FastAPIAuth
from chatlogin.ui import LoginUI
origin = os.environ.get("MY_SITE_ORIGIN", "http://127.0.0.1:8000")
password = os.environ["MY_SITE_LOGIN_PASSWORD"]
backend = PasswordBackend({
"operator": (Principal("operator", "Operator"), hash_password(password)),
})
app = FastAPI()
auth = FastAPIAuth(
backend,
SessionManager(MemorySessionStore(max_sessions=256), instance="my-site", ttl=3600),
origin=origin,
ui=LoginUI(),
cookie=CookieSettings(secure=urlsplit(origin).scheme == "https"),
)
app.include_router(auth.router)
@app.get("/")
def home():
return {"login": "/auth/?next=/private"}
@app.get("/private")
def private(user=Depends(auth.current_user)):
return user.as_dict()
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000, proxy_headers=False)
2. Set an Explicit Password and Run¶
In Bash/Zsh, enter the following commands and a test password of at least 12 characters. Input is hidden and does not enter command-line arguments.
Open http://127.0.0.1:8000/auth/?next=/private and sign in as operator. /private then returns the server-trusted principal; anonymous direct access returns 401.
The sample uses single-process memory sessions that disappear on restart. Production hosts should select durable storage, a fixed HTTPS origin, and explicit business-data authorization. Never reuse the public demo identity in a real application.
3. Select the Frontend Independently¶
| Preserve | Configuration | Host responsibility |
|---|---|---|
| Default UI | ui=LoginUI(palette="forest", layout="split") |
Account source and business routes |
| Host branding/templates | LoginUI(template_dirs=("templates",), template_name="host/login.html") |
Trusted templates and static assets |
| Existing HTML/JS | ui=None |
Form, error feedback and navigation |
| Standard-library HTTP host | LoginUI.render(context) |
Cookies, Origin, CSRF and HTTP routes |
Template directories must exist and are trusted host code. Do not edit site-packages. Template selection and credential backend choice are independent. Optional script_url accepts a canonical same-origin local path; no host script is loaded by default.
4. Headless Request Sequence¶
GET /auth/sessionreturns HTTP 200 withauthenticated=falsefor an anonymous browser.POST /auth/loginsends JSONusername,password, andnext. The browser supplies Origin. With an existing valid session, bootstrap current CSRF first and sendX-CSRF-Token.- Use
credentials: 'same-origin'for protected requests. Cookies are sent automatically; never read the token manually. - Send current CSRF for writes. Refresh session state before
POST /auth/logout. - Clear private UI after logout; protected endpoints return 401 again.
The installed chatlogin.demo_site/assets/demo.js contains the runnable headless example. Its synthetic business data does not imply your own backend is connected.
Next Steps¶
- Integration and Security: backend selection, exact ChatVoice schema and HTTP/role/owner boundaries.
- Python Interface Tree: importable classes and methods.
- Demo: run the isolated site and preview configuration.