{"id":20247234,"url":"https://github.com/shreyansh26/iris_classification-aws-lambda-poc","last_synced_at":"2025-04-10T21:32:22.847Z","repository":{"id":83435107,"uuid":"434898321","full_name":"shreyansh26/Iris_classification-AWS-Lambda-PoC","owner":"shreyansh26","description":"A step-wise tutorial to demonstrate the steps required to deploy a ML model using AWS Lambda, Github Actions, API Gateway and use Streamlit to access the model API through a UI.","archived":false,"fork":false,"pushed_at":"2021-12-12T18:54:39.000Z","size":969,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T18:52:36.846Z","etag":null,"topics":["aws","aws-api-gateway","aws-lambda","deployment","github-actions","iris-classification","machine-learning","streamlit"],"latest_commit_sha":null,"homepage":"https://shreyansh26.github.io/post/2022-01-23_model_deployment_using_aws_lambda/","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/shreyansh26.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,"publiccode":null,"codemeta":null}},"created_at":"2021-12-04T12:43:53.000Z","updated_at":"2024-09-22T14:01:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"f0f6d9b2-4e8d-4ad5-bc96-8eb9237baacc","html_url":"https://github.com/shreyansh26/Iris_classification-AWS-Lambda-PoC","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/shreyansh26%2FIris_classification-AWS-Lambda-PoC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shreyansh26%2FIris_classification-AWS-Lambda-PoC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shreyansh26%2FIris_classification-AWS-Lambda-PoC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shreyansh26%2FIris_classification-AWS-Lambda-PoC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shreyansh26","download_url":"https://codeload.github.com/shreyansh26/Iris_classification-AWS-Lambda-PoC/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248301654,"owners_count":21080928,"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","aws-api-gateway","aws-lambda","deployment","github-actions","iris-classification","machine-learning","streamlit"],"created_at":"2024-11-14T09:36:22.873Z","updated_at":"2025-04-10T21:32:22.817Z","avatar_url":"https://github.com/shreyansh26.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Iris classification PoC deployed using AWS Lambda and Github Actions\n\n## What this repo contains?\n\nThis repository has the code to train, save and test a simple ML model on the Iris Dataset. \nThe Iris dataset is a small dataset which contains attributes of the flower - Sepal length, Sepal width, Petal length and Petal width.\nThe goal of the task is to classify based on these dimensions, the type of the Iris, which in the dataset is among three classes - Setosa, Versicolour and Virginica.\n\nI also detail the steps required to package the model, push to Amazon ECR, deploy the model on AWS Lambda, expose the model using the Amazon API Gateway and finally automate the entire process using Github Actions.\nThe repository also contains the code to run a Streamlit app with the model deployed on AWS.\n\n## Package Requirements\n* An Amazon Web Services account (I intentionally use a simple ML model to deploy as it remains in the AWS Free tier constraints across all the services I mention above. Larger models will require more storage and hence could be chargeable.)\n* Python 3.6+\n* A simple \n`pip install -r requirements.txt` from the [iris_classification](iris_classification) directory will install the other Python packages required.\n\n\n## Steps to follow\nIn this PoC, I will be training and deploying a simple ML model. If you follow this tutorial, deploying complex models should be fairly easy as well. (I had to scratch my head a lot though :sweat_smile:)\n\n\n### 1. Training and Deploying the model locally\n\n1. Clone this repo\n```\ngit clone https://github.com/shreyansh26/Iris_classification-AWS-Lambda-PoC\n```\n\n2. Create a virtual environment - I use [Miniconda](https://docs.conda.io/en/latest/miniconda.html), but you can use any method (virtualenv, venv)\n```\nconda create -n iris_project python=3.8\nconda activate iris_project\n```\n\n3. Install the required dependencies\n```\npip install -r requirements.txt\n```\n\n4. Train the model\n```\ncd iris_classification/src\npython train.py\n```\n\n3. Verify the model trained correctly using pytest\n```\npytest\n```\n\n4. Activate Streamlit and run `app.py`\n```\nstreamlit run app.py\n```\n![](images/ini-streamlit.PNG)\n\nRight now, the `Predict AWS` button will give an error on clicking. It is required to set up an API of your own that the code will send the POST request to.\n\nA `main.py` file contains the event handler which will be used by Lambda later.\n\n### 2. Packaging the model\nI have included a Dockerfile which is used to package the model. Later I will automate all this using Github Actions.\n\n```\ncd iris_classification\ndocker build --tag iris_classification:latest .\n```\n\n### 3. Push the Docker container to Amazon ECR\nFirst, create a private repository. The free tier only allows for 500MB of storage in a month in a private repository.\n\n![](images/ecr1.PNG)\n\nUse the following set of commands to push the local Docker container to the created repository.\n\n```\naws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 863244415814.dkr.ecr.us-east-1.amazonaws.com\n\ndocker tag iris_classification:latest 863244415814.dkr.ecr.us-east-1.amazonaws.com/iris_classification:latest\n\ndocker push 863244415814.dkr.ecr.us-east-1.amazonaws.com/iris_classification:latest\n```\n\n### 4. Create a Lambda function\n\n![](images/lambda1.PNG)\n\nThe container image URI can be selected from the AWS console itself.\n\n![](images/lambda2.PNG)\n\n### 5. Test the Lambda\n\nWe can now test that the Lambda is correctly handling the request as we want it to. AWS allows for that. When we click on the Lambda function, it allows a Test option as well.\n\n![](images/lambda3.PNG)\n\nThe test works and gives the correct result!!\n\n![](images/lambda4.PNG)\n\n### 6. Create an API from the Amazon API Gateway\n\nMake sure to make a REST API.\n\n![](images/api1.PNG)\n\n![](images/api2.PNG)\n\nAdd a `/classify` resource to the API and and add a `POST` method to the API.\nAdd a POST request to the API under a `/classify` resource.\n\n![](images/api3.PNG)\n\nIntegrate the Lambda function with the API.\n\n![](images/api4.PNG)\n\nNow, if you head back to the Lambda functions page, you will see that a Trigger has been added to the function.\n\n![](images/api5.PNG)\n\nThe endpoint is clearly visible in the screenshot.\nIt will be something like `https://{SOME_ID}.execute-api.us-east-1.amazonaws.com/test/classify`.\n\n\n### 7. Test the REST API\n\nWe use a client like Postman to check the API.\n\n![](images/postman.PNG)\n\n#### AND IT WORKS\n\nProgrammatically, we can also check the API that it works.\n\n```python\nimport requests\n\nurl = 'https://ti53furxkb.execute-api.us-east-1.amazonaws.com/test/classify'\n\nmyobj = {\n    \"data\": [\n        [6.5, 3.0, 5.8, 2.2],\n        [6.1, 2.8, 4.7, 1.2]\n    ]\n}\n\nx = requests.post(url, json = myobj)\n\nprint(x.text)\n```\n\n```\n{\"prediction\": [\"virginica\", \"versicolor\"], \"log_proba\": [[-35.82910355985537, -1.5907654693356144, -0.22786665344763715], [-26.20011949521101, -0.0783441410298827, -2.585560434227453]]}\n```\n\n#### THIS WORKS TOO\n\n## Streamlit app to test the model\n\nAfter making the appropriate changes to the configuration, running\n\n```\nstreamlit run app.py\n```\n\nallows you to get the predictions from the AWS hosted model as well.\n\n![](images/fin-streamlit.PNG)\n\n\n## Time to automate the whole thing using Github Actions\n\nWe use Github Actions to automate this whole process i.e. pushing the container to ECR, updating the Lambda function. The API then points to updated Lambda function automatically.\n\nFirst, we will need to add the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to Github secrets (in the Github repo settings).\n\nYou can refer to the yml file in [.github/workflows](.github/workflows) to see how the automation works. The Github Action is triggered when a pull request is made to the `master` branch.\n\nIf required, you can also restrict any pushes to the master branch from Github ([link](https://stackoverflow.com/questions/46146491/prevent-pushing-to-master-on-github)).\n\n\n### AND WE ARE DONE!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshreyansh26%2Firis_classification-aws-lambda-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshreyansh26%2Firis_classification-aws-lambda-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshreyansh26%2Firis_classification-aws-lambda-poc/lists"}