{"id":15288730,"url":"https://github.com/authup/python-sdk","last_synced_at":"2025-09-10T11:35:26.317Z","repository":{"id":65189660,"uuid":"581339029","full_name":"authup/python-sdk","owner":"authup","description":"Python plugins for the Authup authentication and authorization framework","archived":false,"fork":false,"pushed_at":"2024-02-21T14:49:59.000Z","size":331,"stargazers_count":4,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-30T14:40:00.308Z","etag":null,"topics":["auth","authentication","authorization","fastapi","flask","httpx","python","requests"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/authup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-12-22T22:57:33.000Z","updated_at":"2023-12-11T11:39:13.000Z","dependencies_parsed_at":"2024-02-21T16:20:19.618Z","dependency_job_id":null,"html_url":"https://github.com/authup/python-sdk","commit_stats":null,"previous_names":["migraf/authup-py","authup/python-sdk"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/authup/python-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/authup%2Fpython-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/authup%2Fpython-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/authup%2Fpython-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/authup%2Fpython-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/authup","download_url":"https://codeload.github.com/authup/python-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/authup%2Fpython-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274455577,"owners_count":25288557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auth","authentication","authorization","fastapi","flask","httpx","python","requests"],"created_at":"2024-09-30T15:52:28.849Z","updated_at":"2025-09-10T11:35:26.263Z","avatar_url":"https://github.com/authup.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/migraf/authup-py/actions/workflows/main.yml/badge.svg)](https://github.com/migraf/authup-py/actions/workflows/main.yml)\n[![codecov](https://codecov.io/gh/migraf/authup-py/branch/main/graph/badge.svg?token=qILJEFdh8I)](https://codecov.io/gh/migraf/authup-py)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/authup)\n![PyPI - Downloads](https://img.shields.io/pypi/dw/authup)\n[![Maintainability](https://api.codeclimate.com/v1/badges/520401d6c07170a6e413/maintainability)](https://codeclimate.com/github/migraf/authup-py/maintainability)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n# Authup Python Plugins\n\nThis repository contains python plugins for using the [Authup](https://authup.org) authentication and authorization\nframework in the python language.\nThe plugins are used to integrate Authup with different python frameworks and libraries.\n\n## Supported Python frameworks\n\n### Client\n| Plugin                                      | Extra        | Sync | Async |\n|---------------------------------------------|--------------|:----:|------:|\n| [httpx](https://github.com/encode/httpx)    |              |  ✅   |     ✅ |\n| [requests](https://github.com/psf/requests) | `[requests]` |  ✅   |     ❌ |\n\n### Server\n\n| Plugin                                                        | Extra       | Sync | Async | Middleware | User |\n|---------------------------------------------------------------|-------------|:----:|------:|------------|------|\n| [FastApi](https://fastapi.tiangolo.com/)                      | `[fastapi]` |  ✅   |     ✅ | ✅          | ✅    |\n| [ASGI](https://asgi.readthedocs.io/en/latest/specs/main.html) | `[asgi]`    |  ❌   |     ✅ | ✅          | ✅    |\n| [Flask](https://flask.palletsprojects.com/en/2.2.x/)          | `[flask]`   |  ⏳   |     ⏳ | ⏳          | ⏳    |\n\nTable of Contents\n=================\n\n* [Authup Python Plugins](#authup-python-plugins)\n   * [Supported Python frameworks](#supported-python-frameworks)\n      * [Client](#client)\n      * [Server](#server)\n   * [Installation](#installation)\n      * [Extra dependencies](#extra-dependencies)\n   * [How to use](#how-to-use)\n      * [httpx](#httpx)\n      * [requests](#requests)\n      * [ASGI Middleware](#asgi-middleware)\n         * [Optional user injection](#optional-user-injection)\n      * [FastAPI Dependency](#fastapi-dependency)\n         * [Basic user dependency](#basic-user-dependency)\n         * [Require permissions](#require-permissions)\n   * [How to develop](#how-to-develop)\n      * [Install](#install)\n      * [Test](#test)\n\n\n## Installation\n\nThe plugins are available via [PyPi](https://pypi.org/project/authup-py/).\n\n```bash\npip install authup-py\n```\n\n### Extra dependencies\nThe plugin for the project's base library [httpx](https://github.com/encode/httpx) needs no extra dependencies. To\nuse the additional plugins for other libraries, you need to install with the corresponding extra i.e. for `requests`:\n\n```bash\npip install authup-py[requests]\n```\n\n## How to use\nAll the plugins share the underlying `Authup` class. The class is initialized with the url of the Authup server and\nthe credentials you would like to use (username/password or robot_id/secret).    \nThe class provides both sync and async methods for the different authentication and authorization flows.\n\n```python\n\nfrom authup import Authup\n\nauthup = Authup(\n    url=\"https://authup.org\",\n    username=\"username\",\n    password=\"password\"\n)\n\nauthup_robot = Authup(\n    url=\"https://authup.org\",\n    robot_id=\"robot\",\n    robot_secret=\"secret\"\n)\n\n```\n\nThe following plugins all expect the same arguments as the `Authup` class with the addition of the\napp as a first argument for server side libraries (e.g. FastApi, Flask).\n\n### httpx\nFor synchronously using the plugin with [httpx](https://github.com/encode/httpx) , you can use the `AuthupHttpx` class and pass an instance to your\n`httpx.Client` or a basic `httpx.Request` as the `auth` parameter:\n\n```python\nimport httpx\nfrom authup.plugins.httpx import AuthupHttpx\n\nauthup = AuthupHttpx(\n    url=\"https://authup.org\",\n    username=\"username\",\n    password=\"password\",\n)\n\n# Use the authup instance as the auth parameter for the httpx client\nclient = httpx.Client(auth=authup)\n\nwith client:\n    response = client.get(\"https://authup.org\")\n    print(response.status_code)\n\n\n# Use the authup instance as the auth parameter for a top level request function\nrequest = httpx.get(\"https://authup.org\", auth=authup)\n\n```\n\nIt works the same way for the asynchronous httpx client:\n\n```python\nimport httpx\nfrom authup.plugins.httpx import AuthupHttpxAsync\n\nauthup = AuthupHttpxAsync(\n    url=\"https://authup.org\",\n    username=\"username\",\n    password=\"password\",\n)\n\nasync with httpx.AsyncClient(auth=authup) as client:\n    response = await client.get(\"https://authup.org\")\n    print(response.status_code)\n\n```\n\n### requests\nSince [requests](https://github.com/psf/requests) is a synchronous library, the plugin is also synchronous. You can use the `AuthupRequests` class and\nuse it with the `requests.Session` or the `requests.request` functions:\n\u003e **Note**\n\u003e Requires the `requests` extra to be installed. `pip install authup-py[requests]`\n\n```python\nimport requests\nfrom authup.plugins.requests import AuthupRequests\n\nauthup = AuthupRequests(\n    url=\"https://authup.org\",\n    username=\"username\",\n    password=\"password\",\n)\n\n# Use the authup instance as the auth parameter for the requests session\nwith requests.Session() as session:\n    session.auth = authup\n    response = session.get(\"https://authup.org\")\n    print(response.status_code)\n\n# Use the authup instance as the auth parameter for a top level request function\nresponse = requests.get(\"https://authup.org\", auth=authup)\nprint(response.status_code)\n\n```\n\n### ASGI Middleware\n\nThe `AuthupASGIMiddleware` class can be used as an ASGI middleware for any ASGI framework (i.e. FastAPI, Starlette). \nThe middleware will check the incoming requests for a valid token and otherwise return a 401 response. If you pass the\noptional `user` parameter, the middleware will inject the user object into the request scope (`r.state.user`).\n\nThe first argument is the ASGI application and the second argument is the URL of the authup instance.\n\u003e **Note**\n\u003e Requires the `asgi` extra to be installed. `pip install authup-py[asgi]`\n\nThe following shows a simple example for using the middleware with a FastAPI application but it should work with any ASGI framework.\n\n\u003e **Note**\n\u003e Expects a running authup instance available at the given URL.\n\u003e \n```python\nfrom fastapi import FastAPI\nfrom authup.plugins.asgi import AuthupASGIMiddleware\n\napp = FastAPI()\n\nauthup_url = \"https://authup.org\"  # change to your authup instance\n@app.get(\"/test\")\nasync def test():\n    return {\"message\": \"Hello World\"}\n\n# register the middleware pass the authup url as argument\napp.add_middleware(AuthupASGIMiddleware, authup_url=authup_url)\n\n```\nNow you can access the `/test` endpoint without a token and will receive a 401 response. When using a valid token, you will receive the expected response.\n\n```python\nimport httpx\nfrom authup.plugins.httpx import AuthupHttpx\n\n# no token or invalid token raises 401\nresponse = httpx.get(\"http://localhost:8000/test\") # 401\nprint(response.status_code)\n\n# valid token receives the expected response\nauthup = AuthupHttpx(\n    url=\"https://authup.org\",\n    username=\"username\",\n    password=\"password\",\n)\n\nresponse = httpx.get(\"http://localhost:8000/test\", auth=authup) # 200\nprint(response.status_code)\n\n```\n\n#### Optional user injection\nSet the `user` parameter to `True` when adding the middleware to your ASGI application:\n\n```python\nfrom fastapi import FastAPI, Request\nfrom authup.plugins.asgi import AuthupASGIMiddleware\n\napp = FastAPI()\n\nauthup_url = \"https://authup.org\"  # change to your authup instance\n@app.get(\"/test-user\")\nasync def test(request: Request):\n    return {\"user\": request.state.user}\n\n# register the middleware pass the authup url as argument\napp.add_middleware(AuthupASGIMiddleware, authup_url=authup_url, user=True)\n\n```\n\nCalling the `/test-user` endpoint without a token will return a 401 response. When using a valid token, the user object \nwill be injected into the request scope, and you will receive the expected response containing your user.\n\n### FastAPI Dependency\nThe `AuthupUser` class can be used as a FastAPI dependency. \nIt will check the incoming requests for a valid token and otherwise return a 401 response. If the token is valid a user object\nwill be available in the dependency call.\n\n#### Basic user dependency\nThe following shows a simple example for using the dependency with a FastAPI application that will return the user\nobject obtained from the token.\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom authup.plugins.fastapi import AuthupUser\nfrom authup import User\n\n\napp = FastAPI()\n\nuser_dependency = AuthupUser(url=\"http://localhost:3010\")\n\n@app.get(\"/test\")\nasync def user_test(user: User = Depends(user_dependency)):\n    return {\"user\": user.dict()}\n\n```\n\n#### Require permissions\nYou can also require specific permissions for the user. The following example will only allow users with the \n`client_add` permission and a power level of over `100`. Otherwise, a 401 response will be returned.\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom authup.plugins.fastapi import AuthupUser\nfrom authup import User\nfrom authup.permissions import Permission\n\npermissions = [\n        Permission(name=\"client_add\", inverse=False, power=100),\n    ]\n\nrequired_permissions = AuthupUser(\n    url=\"http://localhost:3010\",\n    permissions=permissions,\n)\n\napp = FastAPI()\n\n@app.get(\"/test\")\nasync def user_test(user: User = Depends(required_permissions)):\n    return {\"user\": user.dict()}\n\n```\n\n\n\n## How to develop\n\n### Install\n\nRequires [poetry](https://python-poetry.org/) and [pre-commit](https://pre-commit.com/) and python 3.7+.\n\n```shell\npoetry install --with dev --all-extras\n```\n\nInstall pre-commit hooks\n\n```shell\npoetry run pre-commit install\n```\n\n### Test\n\n```shell\npoetry run pytest\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauthup%2Fpython-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fauthup%2Fpython-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauthup%2Fpython-sdk/lists"}