Deploy FastAPI animal classification to HF Space
Browse files- README.md +34 -7
- app.py +35 -0
- requirements.txt +6 -0
README.md
CHANGED
|
@@ -1,12 +1,39 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
-
sdk:
|
| 7 |
-
sdk_version:
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Animal Classification API
|
| 3 |
+
emoji: 🐾
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: fastapi
|
| 7 |
+
sdk_version: "0.115.4"
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Animal Classification API
|
| 13 |
+
|
| 14 |
+
A FastAPI inference service for classifying images of animals (Cat, Dog, Panda).
|
| 15 |
+
|
| 16 |
+
## Features
|
| 17 |
+
|
| 18 |
+
- **FastAPI** REST API with automatic documentation
|
| 19 |
+
- **TensorFlow** model for image classification
|
| 20 |
+
- **Swagger UI** at `/docs` for interactive testing
|
| 21 |
+
- Supports JPG, PNG image uploads
|
| 22 |
+
|
| 23 |
+
## Usage
|
| 24 |
+
|
| 25 |
+
1. Open the Space URL
|
| 26 |
+
2. Navigate to `/docs` endpoint
|
| 27 |
+
3. Try the `POST /upload/image` endpoint
|
| 28 |
+
4. Upload an image of a Cat, Dog, or Panda
|
| 29 |
+
5. Get instant classification results!
|
| 30 |
+
|
| 31 |
+
## API Endpoints
|
| 32 |
+
|
| 33 |
+
- `POST /upload/image` - Upload an image for classification
|
| 34 |
+
- `GET /docs` - Interactive API documentation
|
| 35 |
+
- `GET /redoc` - Alternative API documentation
|
| 36 |
+
|
| 37 |
+
## Model
|
| 38 |
+
|
| 39 |
+
Uses a CNN trained on animal images with 64x64 input resolution.
|
app.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
app = FastAPI()
|
| 3 |
+
|
| 4 |
+
from fastapi.middleware.cors import CORSMiddleware
|
| 5 |
+
app.add_middleware(
|
| 6 |
+
CORSMiddleware,
|
| 7 |
+
allow_origins=["*"],
|
| 8 |
+
allow_credentials=True,
|
| 9 |
+
allow_methods=["*"],
|
| 10 |
+
allow_headers=["*"],
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
from tensorflow import keras
|
| 14 |
+
import tensorflow as tf
|
| 15 |
+
import os
|
| 16 |
+
ANIMALS = ['Cat', 'Dog', 'Panda'] # Animal names here, these represent the labels of the images that we trained our model on.
|
| 17 |
+
|
| 18 |
+
# It would've been better to use an environment variable to fix this line actually...
|
| 19 |
+
model_path = os.path.join("animal-classification", "INPUT_model_path", "animal-cnn", "model.keras")
|
| 20 |
+
model = tf.keras.models.load_model(model_path)
|
| 21 |
+
|
| 22 |
+
from fastapi import File, UploadFile
|
| 23 |
+
import numpy as np
|
| 24 |
+
from PIL import Image
|
| 25 |
+
|
| 26 |
+
@app.post('/upload/image')
|
| 27 |
+
async def uploadImage(img: UploadFile = File(...)):
|
| 28 |
+
original_image = Image.open(img.file) # Read the bytes and process as an image
|
| 29 |
+
resized_image = original_image.resize((64, 64)) # Resize
|
| 30 |
+
images_to_predict = np.expand_dims(np.array(resized_image), axis=0) # Our AI Model wanted a list of images, but we only have one, so we expand it's dimension
|
| 31 |
+
predictions = model.predict(images_to_predict) # The result will be a list with predictions in the one-hot encoded format: [ [0 1 0] ]
|
| 32 |
+
prediction_probabilities = predictions
|
| 33 |
+
classifications = prediction_probabilities.argmax(axis=1) # We try to fetch the index of the highest value in this list [ [1] ]
|
| 34 |
+
|
| 35 |
+
return ANIMALS[classifications.tolist()[0]] # Fetch the first item in our classifications array, format it as a list first, result will be e.g.: "Dog"
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastapi==0.101.1
|
| 2 |
+
uvicorn[standard]==0.30.6
|
| 3 |
+
tensorflow==2.16.1
|
| 4 |
+
pillow==10.1.0
|
| 5 |
+
numpy==1.26.0
|
| 6 |
+
python-multipart==0.0.9
|