Authentication
Programmatic authentication
Call get_user() inside __render__ or any registered function to require login. If the user is not authenticated, the page returns 401 and the frontend shows a login prompt automatically.
from abstra.pages import register_function, get_user
@register_function
def __render__():
user = get_user()
return f"""
<div style="padding: 2rem; font-family: sans-serif;">
<h1>Welcome, {user.email}</h1>
<p>Your roles: {', '.join(user.roles) or 'none'}</p>
</div>
"""
During local development, any email and code can be used to bypass the login prompt.
Using authentication in functions
You can also call get_user() inside regular functions to protect specific actions:
from abstra.pages import register_function, get_user
@register_function
def approve_payment(payment_id: str):
user = get_user()
if "finance" not in user.roles:
raise Exception("Only finance team can approve payments")
# ... approve logic
return {"status": "approved", "approved_by": user.email}
@register_function
def __render__():
return """
<button onclick="approve('PAY-001')">Approve Payment</button>
<script>
async function approve(id) {
try {
const result = await approve_payment(id);
alert('Approved by ' + result.approved_by);
} catch (e) {
alert(e.message);
}
}
</script>
"""
Declarative access control
Pages support the same access control settings as Forms. Configure via the editor's Settings tab or abstra.json:
- Public — anyone with the URL can access
- Private — requires authentication (any logged-in user)
- Private with roles — requires the user to have at least one of the specified roles
Declarative access control is checked before the Python script runs. If the user doesn't meet the requirements, they are redirected to the login page.
Player layout
Pages render inside the same player layout as Forms — with navbar, sidebar, and branding. The page content appears in an isolated iframe so its CSS does not affect the surrounding layout.
