{"id":21444253,"url":"https://github.com/ahmedbesbes/anonymization-api","last_synced_at":"2025-07-14T18:31:26.096Z","repository":{"id":60639818,"uuid":"380785972","full_name":"ahmedbesbes/anonymization-api","owner":"ahmedbesbes","description":"How to build and deploy an anonymization API with FastAPI and SpaCy","archived":false,"fork":false,"pushed_at":"2021-07-21T15:00:13.000Z","size":33695,"stargazers_count":70,"open_issues_count":0,"forks_count":28,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-08T00:26:04.708Z","etag":null,"topics":["aws","docker","docker-compose","ec2","fastapi","github-actions","named-entity-recognition","ner","nlp","python","spacy"],"latest_commit_sha":null,"homepage":"https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-with-fastapi-docker-and-github-actions-13374cbd638a","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/ahmedbesbes.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}},"created_at":"2021-06-27T16:19:21.000Z","updated_at":"2023-12-11T16:22:45.000Z","dependencies_parsed_at":"2022-10-02T13:40:25.458Z","dependency_job_id":null,"html_url":"https://github.com/ahmedbesbes/anonymization-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmedbesbes%2Fanonymization-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmedbesbes%2Fanonymization-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmedbesbes%2Fanonymization-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmedbesbes%2Fanonymization-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahmedbesbes","download_url":"https://codeload.github.com/ahmedbesbes/anonymization-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225990427,"owners_count":17556155,"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":["aws","docker","docker-compose","ec2","fastapi","github-actions","named-entity-recognition","ner","nlp","python","spacy"],"created_at":"2024-11-23T02:16:49.387Z","updated_at":"2024-11-23T02:16:49.816Z","avatar_url":"https://github.com/ahmedbesbes.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Deploy an inference API on AWS (EC2) using FastAPI Docker and Github Actions\n\nTo learn more about this project: [medium blog post](https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-with-fastapi-docker-and-github-actions-13374cbd638a)\n\n\nThe goal of this project is to streamline the process of building and deploying an inference API on AWS using Docker and Github actions.\n\nThe API's goal is to anonymize text data by detecting named entities (names, organizations, locations) and returning an anonymized text.\n\nHere's a highlevel overview of the API.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/overview_api.png\"/\u003e\n\u003c/p\u003e\n\n## 1- Develop the app locally\n\nThe API route is defined in `api/main.py`\n\nA Dockerfile is defined to create an image for this API: pretty standard.\n\nA docker-compose to manage services between others (as for now, there's only one service: the API)\n\n## 2- Launch an EC2 instance\n\nConnect to your AWS account, go the EC2 section and pick a distribution. I recommend Ubuntu 20.04 LTS for this tutorial.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_1.png\"/\u003e\n\u003c/p\u003e\n\nPick an instance: we're not gonna go crazy here. We'll just pick a relatively small one: a `t2.medium`.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_2.png\"/\u003e\n\u003c/p\u003e\n\nI changed the default storage to 30GB but you can leave it to 8GB (default value)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_3.png\"/\u003e\n\u003c/p\u003e\n\nNow launch the instance.\n\nCreate an elastic IP address and associate it to the running instance. This way this IP won't change everytime the we restart the instance.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_4.png\"/\u003e\n\u003c/p\u003e\n\nAdd a new security group (I named it fastapi) to allow inbound traffic on port 8000.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_5.png\"/\u003e\n\u003c/p\u003e\n\nThen add to the instance security groups:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/aws_6.png\"/\u003e\n\u003c/p\u003e\n\nNow the instance is ready to accept requests.\n\n## 3- SSH to the instance and configure it\n\nSSH into the instance using your terminal.\n\n- Install `docker` and `docker-compose` by following the official Docker [documentation](https://docs.docker.com/engine/install/ubuntu/)\n\n- Generate an ssh key and add it to your Github account so that it can perform git clones seamlessly\n\n## 4- Configure a Gihub Actions workflow\n\n1- Go to your repo and click on the **Actions** tab\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_1.png\"/\u003e\n\u003c/p\u003e\n\n2. Click on **setup a workflow yourself**\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_2.png\"/\u003e\n\u003c/p\u003e\n\n3. Define your workflow\n\nA YAML file will be automatically created inside a `workflows` folder which will be itself created in a `.github` folder at the root of the repo.\n\nThe workflow will be triggered on **push requests** only (on the main branch)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_3.png\"/\u003e\n\u003c/p\u003e\n\nThe job that will be triggered will be run on a remote server that Github Actions will connect to through the **SSH Remote Commands** custom Github Action that you can find from the marketplace.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_4.png\"/\u003e\n\u003c/p\u003e\n\nThe **SSH Remote Commands** Github Action will be called with the following arguments\n\n- host: the hostname of the server (i.e. its public IP)\n- username: the ssh username\n- key: the content of ssh private key\n- script: the script that will be executed once the ssh connection is established\n\nThe script will list the commands that will be run on the server once the SSH connection is established: it'll clone the repo, cd into it and run the docker-compose build and up commands.\n\n```bash\ngit clone git@github.com:ahmedbesbes/anonymization-api.git\ncd anonymization-api\nsudo docker-compose build\nsudo docker-compose up -d\n```\n\n4. Define Github secrets\n\nThe previous arguments `host`, `username` and `key` will not be hard-coded in the YAML file.\n\nThey will rather be stored as Github secrets and referenced with the $ sign, the same way you would call environment variables.\n\nTo create Github secrets, go to the settings of the repository and click on **Secrets** on the left tab.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_5.png\"/\u003e\n\u003c/p\u003e\n\nThen define your secrets by giving setting their name (in capital letters) and their value.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_6.png\"/\u003e\n\u003c/p\u003e\n\nHere's how you would set the `USERNAME` secret for example.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_7.png\"/\u003e\n\u003c/p\u003e\n\n5. Commit, push and look out for the magic happening\n\nOnce you push your code (after testing that everything works fine locally) you will notice a new run queued to start.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_8.png\"/\u003e\n\u003c/p\u003e\n\nBy clicking on it, you can see the different steps of the build.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/ga_9.png\"/\u003e\n\u003c/p\u003e\n\n6. Check that everything is working\n\nOnce the API is successfully deployed on your remote server, fire up Postman and execute some requests on the API endpoint.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./images/postman.png\"/\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmedbesbes%2Fanonymization-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahmedbesbes%2Fanonymization-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmedbesbes%2Fanonymization-api/lists"}