Skip to content

Public Routes

Sometimes a route must be reachable without authentication even though its controller is protected. lauren-guards provides the @public decorator and the IS_PUBLIC_KEY metadata key for exactly this.

@public

from lauren import controller, get, use_guards
from lauren_guards import bearer_token, public

BearerGuard = bearer_token(verify=verify_token)

@use_guards(BearerGuard)
@controller("/api")
class ApiController:
    @get("/status")
    @public                    # exempt — no token needed
    async def health(self) -> dict:
        return {"status": "ok"}

    @get("/profile")
    async def profile(self) -> dict:   # still requires token
        return {"user": "..."}

@public does two things:

  1. Sets the IS_PUBLIC_KEY metadata key to True on the handler.
  2. Wraps the handler with NullGuard, which always allows.

All authentication guards in this package check IS_PUBLIC_KEY at the start of can_activate and skip authentication when it's set.

IS_PUBLIC_KEY

from lauren_guards import IS_PUBLIC_KEY

assert IS_PUBLIC_KEY == "lauren-guards.authentication.is_public"

Custom guards can honour the same flag:

from lauren_guards import IS_PUBLIC_KEY

class MyCustomGuard:
    async def can_activate(self, ctx) -> bool:
        if ctx.get_metadata(IS_PUBLIC_KEY, False):
            return True
        # ... your authentication logic ...
        return True

Caveats

  • @public opts a route out of the guards applied at the controller level; the guards don't run for that route at all.
  • Put @public below the route decorators in the same stacking as other decorators; order relative to @get(...)/@post(...) follows the usual decorator composition rules.