{"id":20067710,"url":"https://github.com/ae9is/py-fastapi","last_synced_at":"2026-04-12T01:40:20.099Z","repository":{"id":227896131,"uuid":"762978753","full_name":"ae9is/py-fastapi","owner":"ae9is","description":"Example api with FastAPI + Cognito + Docker + Pytorch","archived":false,"fork":false,"pushed_at":"2024-02-25T12:42:11.000Z","size":62,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-12T23:27:56.498Z","etag":null,"topics":["api","aws","cognito","docker","fastapi","pdm","pytorch"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ae9is.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-02-25T08:20:17.000Z","updated_at":"2024-02-25T12:47:46.000Z","dependencies_parsed_at":"2024-03-15T18:09:38.430Z","dependency_job_id":null,"html_url":"https://github.com/ae9is/py-fastapi","commit_stats":null,"previous_names":["ae9is/py-fastapi"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ae9is%2Fpy-fastapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ae9is%2Fpy-fastapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ae9is%2Fpy-fastapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ae9is%2Fpy-fastapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ae9is","download_url":"https://codeload.github.com/ae9is/py-fastapi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241494180,"owners_count":19971871,"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","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":["api","aws","cognito","docker","fastapi","pdm","pytorch"],"created_at":"2024-11-13T14:03:06.714Z","updated_at":"2026-04-12T01:40:15.072Z","avatar_url":"https://github.com/ae9is.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# py-fastapi\n\nBoilerplate example for setting up a FastAPI endpoint with AWS Cognito authorisation.\n\nProvides run scripts to bundle a Docker image and upload to ECR for later deployment.\n\n## Setup\n\n### Environment variables\n\nSetup loading .env variables: https://direnv.net/\n\n```bash\ndirenv allow\n```\n\n### Python\n\nUses Python 3.11. To easily switch between versions of python, consider setting up [pyenv](https://github.com/pyenv/pyenv).\n\n[PDM](https://github.com/pdm-project/pdm) is used for proper dependency resolution and convenience scripts.\n\n```bash\npip install pipx\npipx install pdm\n```\n\nPre-commit is used for some commit hooks:\n```bash\npip install pre-commit\npre-commit install\n```\n\n### IAM Identity Center (SSO)\n\n1. Enable IAM Identity Center following: https://aws.amazon.com/iam/identity-center/\n1. Add user `admin`\n1. Add group `Admins` to Groups\n1. Add `admin` to `Admins`\n1. Add a permission set `AdministratorAccess` based on the `AdministratorAccess` AWS managed policy\n1. Assign the permission set to the `Admins` group under `AWS accounts → Assign users or groups`\n\n### AWS CLI\n1. Install AWS CLI\n\n    ```bash\n    curl \"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip\" -o \"awscliv2.zip\"\n    unzip awscliv2.zip\n    sudo ./aws/install\n    # or update:\n    $ sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update\n    ```\n\n    (ref: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)\n\n1. Configure CLI session and login\n\n    ```bash\n    aws configure sso\n    # enter info...\n    aws sso login --sso-session admin\n    ```\n\n1. Check the resulting config at `~/.aws/config` and make sure it matches what you expect, for ex:\n\n    ```\n    [profile admin]\n    region = us-east-1\n    sso_session = admin\n    sso_account_id = 123456789012\n    sso_role_name = AdministratorAccess\n\n    [sso-session admin]\n    sso_region = us-east-1\n    sso_start_url = https://my-sso-portal.awsapps.com/start\n    sso_registration_scopes = sso:account:access\n    ```\n\n    (ref: https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html)\n\n### Cognito\n\nYou'll need to setup an authentication provider for the FastAPI endpoints.\n\nThe FastAPI authentication library used is [fastapi-cloudauth](https://github.com/tokusumi/fastapi-cloudauth/), which supports AWS Cognito / Auth0 / Firebase Auth. The app is setup to use Cognito.\n\n1. Create a new user pool in [Cognito in the AWS console](https://us-east-1.console.aws.amazon.com/cognito/v2/idp/user-pools).\n1. Sign-in and sign-up options should be arbitrary, just don't enable public sign-up. You don't need any actual users or groups.\n1. Once the user pool is created, select it and click \"App integration\" options.\n1. Under \"Domain\" setup a new cognito domain\n1. Create a resource server, with Resource server identifier `pyapi` and custom scope `user` for example. These values should match `.env` environment variable `COGNITO_AUTH_USER_SCOPE`, i.e. as in `pyapi/user` (resource_server_id/custom_scope_name).\n1. Under \"App client list\" click \"Create app client\" \u0026rarr; App type \"Confidential client\"\n1. Client secret \u0026rarr; Generate a client secret\n1. Accept default and create\n1. Once created, select the app client again and configure Hosted UI\n    - Callback URLs: http://localhost\n    - OAuth grant types: enable Client credentials grant\n    - Custom scopes: `pyapi/user` (for example)\n\nOnce this setup is complete, note your:\n- Custom Cognito user pool domain\n- Custom scope\n- App integration \u0026rarr; app client \u0026rarr; Client ID\n- App integration \u0026rarr; app client \u0026rarr; Client secret\n\nThese will be needed to generate access tokens to authenticate requests against the api later.\n\n## Install\n\n```bash\npdm install-all\n```\n\n## Build\n\n```bash\npdm docker-build\n```\n\n## Deploy\n\nSet environment variables for Dockerfile images in `.env.dockerfile`. Make sure to set `PYTHON_ENV=production`, or unset it. The app needs some Cognito config to be set in `.env.dockerfile` so that it knows what user pool to authenticate against.\n\nMake sure `AWS_REGION` and `AWS_ACCOUNT_ID` are set in `.env` environment variables. These are needed to login Docker to ECR.\n\nLogin Docker to AWS ECR:\n```bash\npdm docker-login\n```\n\nCreate a new private registry called `fastapi` (adjust the PDM run scripts in `pyproject.toml` to change this): https://console.aws.amazon.com/ecr/get-started\n\nPush the built docker image to ECR:\n\n```bash\npdm docker-push\n```\n\nNo infrastructure is provisioned in code for this example.\n\nAn example deploying on Fargate:\n\n1. Create a new ECS cluster, type Fargate.\n1. Create an `ecsTaskExecutionRole` following: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html#create-task-execution-role\n1. Attach the following inline policy to `ecsTaskExecutionRole` (in addition to AmazonECSTaskExecutionRolePolicy):\n    ```json\n    {\n        \"Version\": \"2012-10-17\",\n        \"Statement\": [\n            {\n                \"Effect\": \"Allow\",\n                \"Action\": [\n                    \"logs:CreateLogGroup\"\n                ],\n                \"Resource\": \"*\"\n            }\n        ]\n    }\n    ```\n1. Create a new task definition from JSON file `task-definition.json`, editing the file with the `ecsTaskExecutionRole`'s ARN.\n1. In the ECS cluster, create a new service:\n    - Specify FARGATE_SPOT capacity provider\n    - Select Task definition \u0026rarr; Family: pyapi\n    - Service name: fastapi\n1. Edit security group config at: AWS ECS \u0026rarr; Clusters \u0026rarr; \u003ccluster_name\u003e \u0026rarr; Services \u0026rarr; \u003cservice_name\u003e \u0026rarr; Configuration and networking \u0026rarr; Network configuration \u0026rarr; Security groups\n1. Edit inbound rules \u0026rarr; Add new custom TCP inbound rule for port 5000, source \"My IP\" (or anywhere)\n1. Grab the endpoint's Public ID from Tasks \u0026rarr; \u003ctask_id\u003e \u0026rarr; Public IP\n\n*Note: memory requirements for each task varies depending on what kind of model and job you're running! Check the task definition JSON file to adjust: `task-definition.json`.* \n\n## Run (local api)\n\nDifferent pdm scripts exist for testing the endpoint locally:\n\n- asgi: run the FastAPI app via an ASGI server, without docker\n- docker-run fastapi: run the FastAPI app via the docker image\n\n### Authentication\n\nIn order to authenticate against the FastAPI endpoints, you need to provide credentials. This section assumes a Cognito User Pool and App Client have already been setup previously [(see here)](#cognito), and is an example for using [Postman](https://www.postman.com/) from a [trusted client](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#user-pool-settings-client-app-client-types) to side step having to setup any actual users and login in Cognito.\n\n1. Create a new postman environment, and edit it, adding the following variables:\n```\n    client_id       \u003cclient_id_from_cognito_app_client\u003e\n    client_secret   \u003cclient_secret_from_cognito_app_client\u003e\n    token_url       https://\u003ccognito_subdomain\u003e.\u003caws_region\u003e.amazoncognito.com/oauth2/token\n    scope           pyapi/user (or whatever scope you wish, i.e. pyapi/write, pyapi/read, ..., matching the values configured in the Cognito App Client)\n```\n1. Create a new request\n1. Click Authorization \u0026rarr; OAuth 2.0 \u0026rarr; Add auth data to Request Headers\n1. Fill in the Configuration Options:\n```\n    Token Name             pyapi (arbitrary)\n    Grant Type             Client credentials\n    Access Token URL       {{token_url}}\n    Client ID              {{client_id}}\n    Client Secret          {{client_secret}}\n    Scope                  {{scope}}\n    Client Authentication  Send client credentials in body (arbitrary)\n```\n1. Click \"Get New Access Token\" and copy the access_token in the response body\n1. Alternatively, you can just directly send a POST request yourself to the endpoint at `{{token_url}}`, specifying a `x-www-form-urlencoded` body:\n```\n    grant_type    client_credentials\n    client_id     {{client_id}}\n    client_secret {{client_secret}}\n    scope         {{scope}}\n```\n1. Open a new request to the development endpoint at (for ex.) `GET http://localhost:5000/v1/healthz`\n1. Click Authorization \u0026rarr; OAuth 2.0 \u0026rarr; Add auth data to Request Headers\n1. Paste the access token into Current Token \u0026rarr; Access Token, just above Header Prefix \"Bearer\"\n\n## Test\n\nMake sure to set the `.env` environment variables for [Cognito](#cognito).\n\nStart up endpoint:\n```bash\npdm docker-build\npdm docker-run\n```\n\nThen:\n```bash\npdm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fae9is%2Fpy-fastapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fae9is%2Fpy-fastapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fae9is%2Fpy-fastapi/lists"}