tharu22 commited on
Commit
c7ccfa3
Β·
1 Parent(s): f9e0758
Files changed (1) hide show
  1. app.py +97 -0
app.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, HTTPException
2
+ from pydantic import BaseModel
3
+ import torch
4
+ import pinecone
5
+ import requests
6
+ from PIL import Image
7
+ from io import BytesIO
8
+ from transformers import AutoProcessor, CLIPModel
9
+ import numpy as np
10
+
11
+ # βœ… Initialize FastAPI
12
+ app = FastAPI(title="Image & Text Search API", version="1.0")
13
+
14
+ # βœ… Initialize Pinecone
15
+ PINECONE_API_KEY = "pcsk_6r4DPn_4P9LckhZak3PhebvSebnEBKQZuzYFeJL2X93LtLxZVBxyJ93inBAktefa8usvJC" # Replace with your API key
16
+ INDEX_NAME = "unsplash-index"
17
+
18
+ pc = pinecone.Pinecone(api_key=PINECONE_API_KEY)
19
+ unsplash_index = pc.Index(INDEX_NAME)
20
+
21
+ # βœ… Load CLIP Model & Processor
22
+ model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
23
+ processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
24
+
25
+ # βœ… Function to Generate Embedding from Text
26
+ def get_text_embedding(text: str):
27
+ inputs = processor(text=[text], return_tensors="pt", padding=True, truncation=True)
28
+ with torch.no_grad():
29
+ text_features = model.get_text_features(**inputs)
30
+ return text_features.detach().cpu().numpy().flatten().tolist()
31
+
32
+ # βœ… Function to Generate Embedding from Image
33
+ def get_image_embedding(image: Image.Image):
34
+ inputs = processor(images=image, return_tensors="pt")
35
+ with torch.no_grad():
36
+ image_features = model.get_image_features(**inputs)
37
+ return image_features.detach().cpu().numpy().flatten().tolist()
38
+
39
+ # βœ… Function to Search Pinecone for Similar Images
40
+ def search_similar_images(embedding, top_k=10):
41
+ results = unsplash_index.query(
42
+ vector=embedding,
43
+ top_k=top_k,
44
+ include_metadata=True,
45
+ namespace="image-search-dataset"
46
+ )
47
+ return results.get("matches", [])
48
+
49
+ # βœ… API Endpoint: Text-to-Image Search
50
+ class TextSearchRequest(BaseModel):
51
+ query: str
52
+
53
+ @app.post("/search/text")
54
+ async def search_by_text(request: TextSearchRequest):
55
+ embedding = get_text_embedding(request.query)
56
+ matches = search_similar_images(embedding, top_k=10)
57
+
58
+ if not matches:
59
+ raise HTTPException(status_code=404, detail="No matching images found.")
60
+
61
+ return {"query": request.query, "results": matches}
62
+
63
+ # βœ… API Endpoint: Image-to-Image Search
64
+ @app.post("/search/image")
65
+ async def search_by_image(file: UploadFile = File(...)):
66
+ # Read image file
67
+ image = Image.open(BytesIO(await file.read())).convert("RGB")
68
+ embedding = get_image_embedding(image)
69
+ matches = search_similar_images(embedding, top_k=10)
70
+
71
+ if not matches:
72
+ raise HTTPException(status_code=404, detail="No similar images found.")
73
+
74
+ return {"filename": file.filename, "results": matches}
75
+
76
+ # βœ… API Endpoint: Upload Image to Store in Pinecone
77
+ @app.post("/store/image")
78
+ async def store_image(file: UploadFile = File(...)):
79
+ try:
80
+ # Read image file
81
+ image = Image.open(BytesIO(await file.read())).convert("RGB")
82
+ embedding = get_image_embedding(image)
83
+
84
+ # Generate a unique ID (use filename or hash)
85
+ image_id = file.filename
86
+
87
+ # Store embedding in Pinecone
88
+ unsplash_index.upsert([(image_id, embedding, {"filename": image_id})])
89
+
90
+ return {"message": f"Image {image_id} stored successfully!"}
91
+ except Exception as e:
92
+ raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")
93
+
94
+ # βœ… Health Check Endpoint
95
+ @app.get("/")
96
+ async def health_check():
97
+ return {"message": "API is running!"}