Skip to main content

FastAPI permissions system

Project description

fastapi-has-permissions

license test codecov pypi downloads

Introduction

Declarative permissions system for FastAPI. Define permission checks as classes or functions, compose them with &, |, ~ operators, and plug them into FastAPI's dependency injection.

Installation

pip install fastapi-has-permissions

Usage

Class-Based Permissions

Subclass Permission and implement check_permissions():

from fastapi import Depends, FastAPI, Request

from fastapi_has_permissions import Permission


class HasAuthorizationHeader(Permission):
    async def check_permissions(self, request: Request) -> bool:
        return "Authorization" in request.headers


app = FastAPI()


@app.get(
    "/protected",
    dependencies=[Depends(HasAuthorizationHeader())],
)
async def protected():
    return {"message": "You have access!"}

Permissions with parameters are automatically dataclasses:

class HasRole(Permission):
    role: str

    async def check_permissions(self, request: Request) -> bool:
        return request.headers.get("role") == self.role

Boolean Composition

Combine permissions with & (AND), | (OR), and ~ (NOT):

# All must pass
Depends(HasAuthorizationHeader() & HasRole("admin"))

# Any must pass
Depends(HasAuthorizationHeader() | HasRole("admin"))

# Negated
Depends(~HasAuthorizationHeader())

Function-Based Permissions

Use the @permission decorator for a lightweight alternative:

from typing import Annotated

from fastapi import Header

from fastapi_has_permissions import permission


@permission
async def has_admin_role(role: Annotated[str, Header()]) -> bool:
    return role == "admin"


@app.get("/admin", dependencies=[Depends(has_admin_role())])
async def admin_endpoint():
    return {"message": "Admin access granted"}

Function-based permissions also support Dep arguments for injecting FastAPI dependencies:

from fastapi_has_permissions import Dep, permission


async def get_admin_role() -> str:
    return "admin"


AdminRoleDep = Annotated[str, Depends(get_admin_role)]


@permission
async def has_role(admin_role: Dep[str], /, role: Annotated[str, Header()]) -> bool:
    return role == admin_role


@app.get("/admin", dependencies=[Depends(has_role(AdminRoleDep))])
async def admin_endpoint():
    return {"message": "Admin access granted"}

Function-based permissions support the same &, |, ~ composition.

Lazy Permissions

Defer dependency resolution to request time with lazy() - useful when dependencies may not always be available:

from fastapi.exceptions import RequestValidationError

from fastapi_has_permissions import lazy

# Skip the check instead of failing if the "age" header is missing
Depends(lazy(AgeIsMoreThan(age=18), skip_on_exc=(RequestValidationError,)))

Other Features

  • Custom error responses -- set default_exc_message / default_exc_status_code class variables or override get_exc_message() / get_exc_status_code() methods
  • Skip / Fail helpers -- call skip() or fail() inside check_permissions() for explicit control flow
  • Built-in common permissions -- IsAuthenticated, HasScope, HasRole ready to use with your auth dependencies
  • Full FastAPI DI support -- check_permissions() accepts any FastAPI-injectable parameters

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_has_permissions-0.1.5.tar.gz (98.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_has_permissions-0.1.5-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_has_permissions-0.1.5.tar.gz.

File metadata

  • Download URL: fastapi_has_permissions-0.1.5.tar.gz
  • Upload date:
  • Size: 98.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fastapi_has_permissions-0.1.5.tar.gz
Algorithm Hash digest
SHA256 88b5a782e0ab177776f1221125d998481d541de88c0eb2630de315168d626258
MD5 48d56addc82bf3bd4992dc2b591aac1f
BLAKE2b-256 ceb580bbe11b043f04cc9bfaed09f84f7afe7f6281fce02dfbe499417dfd3455

See more details on using hashes here.

File details

Details for the file fastapi_has_permissions-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: fastapi_has_permissions-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fastapi_has_permissions-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 b734c176ba291b59fc2b5a229446d256b2e2960f78536ae06c0b4315bbfcd256
MD5 104fd3f732399c51c26f6acbf99c88ea
BLAKE2b-256 f649c0fac615c54dbea2d46893f50b0fd3ed93f9353d9dcd6f22953bc5b16671

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page