Skip to content

Commit

Permalink
Merge branch 'main' of github.com:OriginalByteMe/AI_Image_cutout_make…
Browse files Browse the repository at this point in the history
…r into develop
  • Loading branch information
OriginalByteMe committed Jun 6, 2024
2 parents b338dbc + e0e18be commit c03685f
Show file tree
Hide file tree
Showing 14 changed files with 971 additions and 870 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
fi
- name: Deploy cutout generator job
run: |
modal deploy --env=${{ steps.vars.outputs.environment }} app.cutout_handler::cutout_handler_stub
modal deploy --env=${{ steps.vars.outputs.environment }} app.cutout_handler::cutout_handler_app
- name: Deploy s3_handler job
run: |
modal deploy --env=${{ steps.vars.outputs.environment }} app.s3_handler.app
modal deploy --env=${{ steps.vars.outputs.environment }} app.s3::s3_handler_app
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Noah Rijkaard

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 2 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# from .cutout_handler import server
# import s3_handler
7 changes: 4 additions & 3 deletions app/common/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from modal import Image, Mount, Stub
from modal import Image, Mount, App

s3_handler_image = Image.debian_slim().pip_install("boto3", "botocore")

Expand Down Expand Up @@ -32,5 +32,6 @@
"app.cutout_handler.grounded_cutouts",
)

cutout_handler_stub = Stub(image=cutout_generator_image, name="cutout_generator")
s3_handler_stub = Stub(image=s3_handler_image, name="s3_handler")
cutout_handler_app = App(image=cutout_generator_image, name="cutout_generator")
s3_handler_cutouts_app = App(image=s3_handler_image, name="s3_handler_cutouts")
s3_handler_app = App(image=s3_handler_image, name="s3_handler")
2 changes: 1 addition & 1 deletion app/cutout_handler/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from app.common import cutout_handler_stub, s3_handler_stub
from app.common import cutout_handler_app, s3_handler_cutouts_app

from .server import cutout_app
4 changes: 2 additions & 2 deletions app/cutout_handler/dino.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from typing import List

from app.common import cutout_handler_stub, cutout_generator_image
from app.common import cutout_handler_app, cutout_generator_image

with cutout_generator_image.imports():
import torch
from groundingdino.util.inference import Model

cutout_handler_stub.cls()
cutout_handler_app.cls()


class Dino:
Expand Down
4 changes: 2 additions & 2 deletions app/cutout_handler/s3_handler.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import os
import logging
from app.common import s3_handler_stub, s3_handler_image
from app.common import s3_handler_app, s3_handler_image

with s3_handler_image.imports():
import boto3
from botocore.exceptions import ClientError, BotoCoreError, NoCredentialsError

s3_handler_stub.cls()
s3_handler_app.cls()
class Boto3Client:
def __init__(self):

Expand Down
4 changes: 2 additions & 2 deletions app/cutout_handler/segment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from app.common import cutout_handler_stub, cutout_generator_image
from app.common import cutout_handler_app, cutout_generator_image


with cutout_generator_image.imports():
Expand All @@ -7,7 +7,7 @@
import numpy as np


cutout_handler_stub.cls()
cutout_handler_app.cls()


class Segmenter:
Expand Down
6 changes: 3 additions & 3 deletions app/cutout_handler/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
from modal import Secret, asgi_app
from starlette.requests import Request

from app.common import cutout_handler_stub, local_packages, cutout_generator_image
from app.common import cutout_handler_app, local_packages

from .grounded_cutouts import CutoutCreator

# ======================
# Constants
Expand Down Expand Up @@ -69,6 +68,7 @@ async def warmup():
Returns:
_type_: return message
"""
from grounded_cutouts import CutoutCreator
# Spins up the container and loads the models, this will make it easier to create cutouts later
CutoutCreator(
classes=[],
Expand Down Expand Up @@ -174,7 +174,7 @@ async def create_all_cutouts(
return result


@cutout_handler_stub.function(
@cutout_handler_app.function(
gpu="T4",
mounts=[local_packages],
secrets=[Secret.from_name("my-aws-secret")],
Expand Down
4 changes: 4 additions & 0 deletions app/s3/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .s3_handler import Boto3Client
from .app import main

from app.common import s3_handler_app
31 changes: 16 additions & 15 deletions app/s3_handler/app.py → app/s3/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@

from fastapi import Body, FastAPI, File, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from modal import Image, Mount, Secret, Stub, asgi_app
from modal import Image, Mount, Secret, App, asgi_app
from app.common import s3_handler_app

stub = Stub(name="s3_handler")
# app = App(name="s3_handler")

app = FastAPI()
s3_app = FastAPI()

origins = [
"http://localhost:3000", # localdevelopment
"https://cutouts.noahrijkaard.com", # main website
]

app.add_middleware(
s3_app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
Expand All @@ -26,7 +27,7 @@
# ================================================
# API Endpoints
# ================================================
@app.post("/upload-image")
@s3_app.post("/upload-image")
async def upload_image_to_s3(image: UploadFile = File(...)):
"""Upload an image to S3.
Expand All @@ -37,7 +38,7 @@ async def upload_image_to_s3(image: UploadFile = File(...)):
str: Message indicating whether the upload was successful.
"""
from botocore.exceptions import BotoCoreError, NoCredentialsError
from s3_handler import Boto3Client
from app.s3.s3_handler import Boto3Client

s3_client = Boto3Client()
try:
Expand All @@ -53,7 +54,7 @@ async def upload_image_to_s3(image: UploadFile = File(...)):
return {"message": "Image uploaded successfully", "status_code": 200}


@app.get("/generate-presigned-urls/{image_name}")
@s3_app.get("/generate-presigned-urls/{image_name}")
async def generate_presigned_urls(image_name: str):
"""Generate presigned urls for the cutouts of an image.
Expand All @@ -63,13 +64,13 @@ async def generate_presigned_urls(image_name: str):
Returns:
List[str]: List of presigned urls for the cutouts of an image.
"""
from s3_handler import Boto3Client
from app.s3.s3_handler import Boto3Client

s3_client = Boto3Client()
return s3_client.generate_presigned_urls(f"cutouts/{image_name}")


@app.get("/get-image/{image_name}")
@s3_app.get("/get-image/{image_name}")
async def get_image(image_name: str):
"""Get an image from S3.
Expand All @@ -80,7 +81,7 @@ async def get_image(image_name: str):
FileResponse: FileResponse object containing the image.
"""
from fastapi.responses import FileResponse
from s3_handler import Boto3Client
from app.s3.s3_handler import Boto3Client

s3_client = Boto3Client()
data = s3_client.generate_presigned_url_with_metadata("images", image_name)
Expand All @@ -89,7 +90,7 @@ async def get_image(image_name: str):
return data


@stub.function(
@s3_handler_app.function(
image=Image.debian_slim().pip_install(
"boto3",
"fastapi",
Expand All @@ -103,18 +104,18 @@ async def get_image(image_name: str):
"httpx[http2]",
"httpx[http1]",
),
mounts=[Mount.from_local_python_packages("s3_handler")],
secret=Secret.from_name("my-aws-secret"),
mounts=[Mount.from_local_python_packages("app.s3.s3_handler")],
secrets=[Secret.from_name("my-aws-secret")],
)
@asgi_app()
def main():
return app
return s3_app


# =================================
# Modal s3 functions
# =================================
# @stub.function(
# @app.function(
# image=Image.debian_slim().pip_install("boto3", "fastapi", "starlette", "uvicorn", "python-multipart", "pydantic", "requests", "httpx", "httpcore", "httpx[http2]", "httpx[http1]"), mounts=[Mount.from_local_python_packages("s3_handler")], secret=Secret.from_name("my-aws-secret")
# )
# def upload_to_s3(file_body, folder, image_name):
Expand Down
4 changes: 3 additions & 1 deletion app/s3_handler/s3_handler.py → app/s3/s3_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import boto3
from botocore.exceptions import BotoCoreError, ClientError, NoCredentialsError


class Boto3Client:
"""
A class to handle S3 operations.
"""
def __init__(self):
self.s3 = boto3.client(
"s3",
Expand Down
Loading

0 comments on commit c03685f

Please sign in to comment.