from fastapi import FastAPI, Request from fastcore.transform import Transform from fastapi.responses import HTMLResponse from fastapi.middleware.cors import CORSMiddleware from fastbook import * from pydantic import BaseModel, Field import urllib.request import base64 from fastai.vision.widgets import * from fastai.vision import * from fastai.vision.all import * from fastai.metrics import * from fastai.data.external import * from fastai.vision.all import * import torchvision.transforms as transforms import os import pathlib import base64 from pathlib import * import PIL from PIL import Image from PIL import Image, ImageOps from fastai.vision.all import * import torchvision.transforms as transforms import uvicorn import asyncio from pathlib import Path class GrayscaleTransform(Transform): def __init__(self): pass def encodes(self, img: PILImage): return PIL.ImageOps.grayscale(img) def get_fingers(fingers_path): print('fingers path', fingers_path) return [] def get_finger_label(finger_path: Path): print('finger path', finger_path) return '' current_path = Path(os.getcwd()) print(f'Current path: {current_path}') print('current_path', os.listdir(current_path)) print('current_path/data', os.listdir(current_path/'data')) print('current_path/data/fingers', os.listdir(current_path/'data/fingers')) fingers_path = Path(current_path/'data/fingers') train_path = Path(fingers_path/'train') test_path = Path(fingers_path/'test') print('train_path', os.listdir(train_path)) print('test_path', os.listdir(test_path)) def get_fingers(fingers_path): print('fingers path', fingers_path) return [] def get_finger_label(finger_path: Path): print('finger path', finger_path) return '' fingers: DataBlock = DataBlock( blocks=(ImageBlock, CategoryBlock), get_items=get_fingers, splitter=RandomSplitter(valid_pct=0.2, seed=42), get_y=get_finger_label, item_tfms=Resize(128) ) # Define the normalization transform normalize_transform = Normalize.from_stats(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # Define the image transformations image_transforms = [RandomResizedCrop(128, min_scale=0.3), GrayscaleTransform] processed_fingers = fingers.new(item_tfms=image_transforms, batch_tfms=[*aug_transforms(), normalize_transform]) # dls = processed_fingers.dataloaders(fingers_path) # learn_inf: Learner = load_learner(current_path/'models/export.pkl') # print(f'Bear Model successfully loaded: {learn_inf}') print(f'Model file exists? ', Path(current_path/'models/fingers-2023-06-30-00_06_35.pkl').exists()) print(f'Stats ', os.lstat(current_path/'models/fingers-2023-06-30-00_06_35.pkl')) finger_learn_inf: Learner = load_learner(current_path/'models/fingers-2023-06-30-00_06_35.pkl') print(f'Finger Model successfully loaded: {finger_learn_inf}') app = FastAPI() ## Full documentation on https://thiagoh-simple-predictor.hf.space/docs ## Usage # curl -X GET 'https://thiagoh-simple-predictor.hf.space/?name=uia' -H "Content-Type: application/json" origins = [ "http://thiagoh.github.io", "https://thiagoh.github.io", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/", response_class=HTMLResponse) def read_root(): routes = app.routes print(f'Routes: {routes}') content = f""" Some HTML in here

Here's the available routes in this app

Navigation details

Navigate to https://thiagoh-simple-predictor.hf.space to hit the application. You can also curl it

""" return HTMLResponse(content=content, status_code=200) @app.middleware("http") async def add_process_time_header(request: Request, call_next): print(f'Printing this to the log stream', request.url) response = await call_next(request) return response @app.get("/do-that") def do_that(name: str = ""): return {"action": 'do that'} @app.get("/do-this") def do_this(name: str = ""): return {"action": 'do this'} class Item(BaseModel): imageUrl: Union[str, None] = Field(default=None, title="Url of an image", max_length=2400) image_base64_bytes: Union[str, None] = None class Prediction(BaseModel): prediction: str probability: float imageEncodedBytes: Union[str, None] = None @app.post("/display-image") def display_image(item: Item): if item.imageUrl: with urllib.request.urlopen(item.imageUrl) as f: decoded_bytes = f.read() encoded_bytes = base64.b64encode(decoded_bytes) else: decoded_bytes = base64.b64decode(item.image_base64_bytes) encoded_bytes = item.image_base64_bytes # content = f""" # # # Display Image # # # # # """ # return HTMLResponse(content=content, status_code=200) prediction, prediction_idx, probabilities = learn_inf.predict(PILImage.create(decoded_bytes)) probability: int = probabilities[prediction_idx] print(f'Prediction: {prediction}; Probability: {probability:.04f}') return Prediction(prediction=prediction, probability=probability, imageEncodedBytes=encoded_bytes) @app.post("/predict", response_model=Prediction) def predict(item: Item): bytes = BytesIO(base64.b64decode(item.image_base64_bytes)) img = PILImage.create(bytes) prediction, prediction_idx, probabilities = learn_inf.predict(img) probability: int = probabilities[prediction_idx] print(f'Prediction: {prediction}; Probability: {probability:.04f}') return Prediction(prediction=prediction, probability=probability) @app.get("/do-something-else/{person}") def do_something_else(person: str): return {"action": f'do something else with person {person}'} @app.post("/predict-bear") def predict_bear(item: Item): if item.imageUrl: with urllib.request.urlopen(item.imageUrl) as f: decoded_bytes = f.read() encoded_bytes = base64.b64encode(decoded_bytes) else: decoded_bytes = base64.b64decode(item.image_base64_bytes) encoded_bytes = item.image_base64_bytes prediction, prediction_idx, probabilities = learn_inf.predict(PILImage.create(decoded_bytes)) probability: int = probabilities[prediction_idx] print(f'Prediction: {prediction}; Probability: {probability:.04f}') return Prediction(prediction=prediction, probability=probability, imageEncodedBytes=encoded_bytes) class InputItem(BaseModel): imageUrl: Union[str, None] = Field(default=None, title="Url of an image", max_length=2400) imageEncodedBytes: Union[str, None] = None @app.post("/predict-finger") def predict_finger(item: InputItem): if item.imageUrl: with urllib.request.urlopen(item.imageUrl) as f: decoded_bytes = f.read() encoded_bytes = base64.b64encode(decoded_bytes) else: decoded_bytes = base64.b64decode(item.imageEncodedBytes) encoded_bytes = item.imageEncodedBytes prediction, prediction_idx, probabilities = learn_inf.predict(PILImage.create(decoded_bytes)) probability: int = probabilities[prediction_idx] print(f'Prediction: {prediction}; Probability: {probability:.04f}') return Prediction(prediction=prediction, probability=probability, imageEncodedBytes=encoded_bytes)