MingDoan commited on
Commit
65aa0cb
·
0 Parent(s):

feat: First commit

Browse files
.gitattributes ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Hugging Face's logo
2
+ Hugging Face
3
+ Search models, datasets, users...
4
+ Models
5
+ Datasets
6
+ Spaces
7
+ Posts
8
+ Docs
9
+ Pricing
10
+
11
+
12
+
13
+ Spaces:
14
+
15
+ MingDoan
16
+ /
17
+ gloco-backend
18
+
19
+ like
20
+ 0
21
+
22
+ App
23
+ Files
24
+ Community
25
+ Settings
26
+ gloco-backend
27
+ /
28
+ .gitattributes
29
+
30
+ MingDoan's picture
31
+ MingDoan
32
+ initial commit
33
+ 842aefd
34
+ VERIFIED
35
+ 2 minutes ago
36
+ raw
37
+ history
38
+ blame
39
+ edit
40
+ delete
41
+ No virus
42
+ 1.52 kB
43
+ *.7z filter=lfs diff=lfs merge=lfs -text
44
+ *.arrow filter=lfs diff=lfs merge=lfs -text
45
+ *.bin filter=lfs diff=lfs merge=lfs -text
46
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
47
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
48
+ *.ftz filter=lfs diff=lfs merge=lfs -text
49
+ *.gz filter=lfs diff=lfs merge=lfs -text
50
+ *.h5 filter=lfs diff=lfs merge=lfs -text
51
+ *.joblib filter=lfs diff=lfs merge=lfs -text
52
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
53
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
54
+ *.model filter=lfs diff=lfs merge=lfs -text
55
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
56
+ *.npy filter=lfs diff=lfs merge=lfs -text
57
+ *.npz filter=lfs diff=lfs merge=lfs -text
58
+ *.onnx filter=lfs diff=lfs merge=lfs -text
59
+ *.ot filter=lfs diff=lfs merge=lfs -text
60
+ *.parquet filter=lfs diff=lfs merge=lfs -text
61
+ *.pb filter=lfs diff=lfs merge=lfs -text
62
+ *.pickle filter=lfs diff=lfs merge=lfs -text
63
+ *.pkl filter=lfs diff=lfs merge=lfs -text
64
+ *.pt filter=lfs diff=lfs merge=lfs -text
65
+ *.pth filter=lfs diff=lfs merge=lfs -text
66
+ *.rar filter=lfs diff=lfs merge=lfs -text
67
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
68
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
69
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
70
+ *.tar filter=lfs diff=lfs merge=lfs -text
71
+ *.tflite filter=lfs diff=lfs merge=lfs -text
72
+ *.tgz filter=lfs diff=lfs merge=lfs -text
73
+ *.wasm filter=lfs diff=lfs merge=lfs -text
74
+ *.xz filter=lfs diff=lfs merge=lfs -text
75
+ *.zip filter=lfs diff=lfs merge=lfs -text
76
+ *.zst filter=lfs diff=lfs merge=lfs -text
77
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ /env
2
+ __pycache__/
3
+ .env
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10.13-slim-bookworm
2
+
3
+ # Define the working directory
4
+ WORKDIR /code
5
+
6
+ # Copy the requirements file
7
+ COPY ./requirements.txt /code/requirements.txt
8
+
9
+ # Install the requirements
10
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11
+
12
+ # Copy the rest of the files
13
+ COPY . /code
14
+
15
+ # Run the application
16
+ ENTRYPOINT ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Gloco Backend
3
+ emoji: 🏢
4
+ colorFrom: blue
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: false
8
+ ---
apps/create_app.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+
4
+
5
+ def create_app():
6
+ app = FastAPI(
7
+ title="Trash Detection API",
8
+ description="GLOCO Object Detection API using FastAPI and YOLOv8",
9
+ docs_url="/"
10
+ )
11
+
12
+ # Add CORS middleware
13
+ app.add_middleware(
14
+ CORSMiddleware,
15
+ allow_origins=["*"],
16
+ allow_credentials=True,
17
+ allow_methods=["*"],
18
+ allow_headers=["*"],
19
+ )
20
+
21
+ return app
apps/detection/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, UploadFile, File, HTTPException, status
2
+ from fastapi.responses import JSONResponse
3
+ from .model import Detections
4
+ from .controller import detect_object
5
+
6
+
7
+ router = APIRouter(
8
+ prefix="/detection",
9
+ tags=["detection"],
10
+ default_response_class=JSONResponse
11
+ )
12
+
13
+
14
+ @router.post("/", response_model=Detections)
15
+ async def detection(
16
+ image: UploadFile = File(..., description="File to detect"),
17
+ ):
18
+ if not image.content_type.startswith("image"):
19
+ raise HTTPException(
20
+ status_code=status.HTTP_400_BAD_REQUEST,
21
+ detail="Invalid file type. Only image files are allowed."
22
+ )
23
+
24
+ # Read image file
25
+ contents = await image.read()
26
+
27
+ detections = detect_object(contents)
28
+ return detections
apps/detection/controller.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .provider import model
2
+ from io import BytesIO
3
+ from PIL import Image
4
+
5
+
6
+ def detect_object(image: bytes):
7
+ # Convert bytes to PIL image
8
+ image = Image.open(BytesIO(image))
9
+
10
+ detections = model.predict(image)
11
+
12
+ # Format detections
13
+ bboxs = detections[0].boxes.data
14
+ labels = detections[0].names
15
+
16
+ # Get boxs result
17
+ boxs_result = []
18
+ for box in bboxs:
19
+ result_conf = box[4].item()
20
+ if result_conf > model.conf:
21
+ boxs_result.append({
22
+ "class_name": labels[int(box[5].item())],
23
+ "confidence": result_conf,
24
+ "xmin": box[0].item(),
25
+ "ymin": box[1].item(),
26
+ "xmax": box[2].item(),
27
+ "ymax": box[3].item()
28
+ })
29
+
30
+ print(boxs_result)
31
+
32
+ return {
33
+ "detections": boxs_result
34
+ }
apps/detection/model.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class Detection(BaseModel):
5
+ class_name: str = Field(..., example="person")
6
+ confidence: float = Field(..., example=0.99)
7
+ xmin: float = Field(..., example=0.1)
8
+ ymin: float = Field(..., example=0.2)
9
+ xmax: float = Field(..., example=0.3)
10
+ ymax: float = Field(..., example=0.4)
11
+
12
+
13
+ class Detections(BaseModel):
14
+ detections: list[Detection] = Field(..., description="List of detections")
apps/detection/provider.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import os
2
+ from ultralytics import YOLO
3
+
4
+
5
+ model = YOLO(os.path.join(os.getcwd(), "models", "yolo.pt"))
6
+ model.conf = 0.5
apps/query/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+ from fastapi.responses import JSONResponse
3
+
4
+
5
+ router = APIRouter(
6
+ prefix="/query",
7
+ tags=["query"],
8
+ default_response_class=JSONResponse
9
+ )
10
+
11
+
12
+ @router.post("/")
13
+ def query():
14
+ return {"message": "Query"}
apps/recommend/__init__.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+ from fastapi.responses import JSONResponse
3
+ from .model import Recommendations, RecommendType
4
+ from .controller import recycle_recommendation
5
+
6
+
7
+ router = APIRouter(
8
+ prefix="/recommend",
9
+ tags=["recommend"],
10
+ default_response_class=JSONResponse,
11
+ )
12
+
13
+
14
+ @router.post("/", response_model=Recommendations)
15
+ async def recommend(data: RecommendType):
16
+ return recycle_recommendation(data.recommend_type)
apps/recommend/controller.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from fastapi import HTTPException, status
3
+ from .provider import model
4
+
5
+
6
+ prompt_template = '''Think and generate content about how to recycle {type}
7
+ The recycle recommendation should be easy to understand and follow.
8
+ - For example, for the trash type "plastic bottle", provide how to use the plastic for household items.
9
+ - For the trash type "paper", provide how to do origami, etc.
10
+
11
+ You must answer clearly, easy to understand and step by step.
12
+ You must prompt professional and reliable information. No yapping.
13
+
14
+ You must provide an answer as a following JSON format:
15
+ {{
16
+ "recommendations": [
17
+ {{
18
+ "title": "Foo Bar",
19
+ "steps": [
20
+ "Foo",
21
+ "Bar"
22
+ ]
23
+ }}
24
+ ]
25
+ }}
26
+ '''
27
+
28
+
29
+ def recycle_recommendation(trash_type: str):
30
+ prompt = prompt_template.format(type=trash_type)
31
+
32
+ answer = model.generate_content(prompt)
33
+
34
+ try:
35
+ parsed_data = json.loads(answer.text)
36
+ except json.JSONDecodeError:
37
+ raise HTTPException(
38
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
39
+ detail="Failed to parse the answer from the model"
40
+ )
41
+
42
+ return parsed_data
apps/recommend/model.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ class Recommendation(BaseModel):
5
+ title: str = Field(..., title="Title of the recommendation")
6
+ steps: list[str] = Field(...,
7
+ title="Steps to follow to implement the recommendation")
8
+
9
+
10
+ class Recommendations(BaseModel):
11
+ recommendations: list[Recommendation] = Field(
12
+ ..., title="List of recommendations")
13
+
14
+
15
+ class RecommendType(BaseModel):
16
+ recommend_type: str = Field(..., title="Type of recommendation to return")
apps/recommend/provider.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import os
2
+ import google.generativeai as genai
3
+
4
+
5
+ genai.configure(api_key=os.environ.get("GOOGLE_API_KEY"))
6
+
7
+ model = genai.GenerativeModel("gemini-pro")
main.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from apps.create_app import create_app
2
+ from apps.detection import router as detection_router
3
+ from apps.recommend import router as recommend_router
4
+
5
+
6
+ app = create_app()
7
+
8
+
9
+ # Register router
10
+ app.include_router(detection_router, prefix="/api")
11
+ app.include_router(recommend_router, prefix="/api")
models/yolo.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b4292d72e8b4975e9561760e274839c18c066caa43b65c8dcea0fb37287d64eb
3
+ size 22557081
requirements.txt ADDED
Binary file (2.39 kB). View file