In this example we will create an endpoint to upload images to a bucket and then run them through an image classification model using ImageAI.
Our application will:
- Load our model from local storage in a dependency ensuring the model is ready before we receive image uploads, and it can be shared across requests.
- Expose an endpoint that allows users to upload images
- When our endpoint receives an image, it will upload the image to a bucket (GCS or S3)
- When the image is uploaded it will trigger a notification to our queue (GCP Pub/Sub or AWS SQS)
- Our consumer will receive this notification and run the image through an image classification model using ImageAI
- The results of the image classification will be stored in a data warehouse (BigQuery) or DuckDB)
- The data warehouse will be exposed by another endpoint
If all goes well, you should have a working image classification app like this:
To run this example on resources created on GCP use this github repo.
In order to run this code you will need to have a GCP project created that you have access to.
Follow the Google Cloud Walkthrough to create a new one if you need to.
Clone the GitHub Repo
git clone firstname.lastname@example.org:launchflow/buildflow-gcp-image-classification.git cd buildflow-gcp-image-classification
Install your requirements
pip install -r requirements.txt
Create a .env file
.env and update all variables
Create your resources
Create all the resources that are required for your system.
Make sure you have logged in with GCP with:
gcloud auth login --update-adc
This will output every primitive that will be created, and ask you to confirm before creating them:
Primitives to create: --------------------- ├── GCSBucket │ └── gcs://<GCP_PROJECT_ID>-image-classification ├── BigQueryDataset │ └── <GCP_PROJECT_ID>.buildflow_image_classification_walkthrough ├── BigQueryTable │ └── <GCP_PROJECT_ID>.buildflow_image_classification_walkthrough.image_classification ├── GCSFileChangeStream │ └── <GCP_PROJECT_ID>-image-classification.<GCP_PROJECT_ID>-image-classification_topic ├── GCPPubSubSubscription │ └── <GCP_PROJECT_ID>/<GCP_PROJECT_ID>-image-classification_subscription └── GCPPubSubTopic └── <GCP_PROJECT_ID>/<GCP_PROJECT_ID>-image-classification_topic Would you like to apply these changes? Enter "y (yes)" to confirm, "n (no) to reject":