Surajkumaar commited on
Commit
8a60efe
·
1 Parent(s): 0d029d1
Files changed (7) hide show
  1. .dockerignore +29 -0
  2. Dockerfile +25 -0
  3. README.md +66 -4
  4. api.py +275 -0
  5. data/mushrooms.csv +51 -0
  6. data/recognition_log.csv +36 -0
  7. requirements.txt +9 -0
.dockerignore ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .Python
6
+ env/
7
+ venv/
8
+ pip-log.txt
9
+ pip-delete-this-directory.txt
10
+ .tox/
11
+ .coverage
12
+ .coverage.*
13
+ .cache
14
+ nosetests.xml
15
+ coverage.xml
16
+ *.cover
17
+ *.log
18
+ .git
19
+ .gitignore
20
+ .mypy_cache
21
+ .pytest_cache
22
+ .hypothesis
23
+ *.egg-info/
24
+ dist/
25
+ build/
26
+ *.egg
27
+ data/*.html
28
+ data/recognition_log.csv
29
+ app.py
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y \
7
+ git \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # Copy requirements first for better caching
11
+ COPY requirements.txt .
12
+
13
+ # Install Python dependencies
14
+ RUN pip install --no-cache-dir -r requirements.txt
15
+
16
+ # Copy application files
17
+ COPY api.py .
18
+ COPY data/ ./data/
19
+ COPY .env .
20
+
21
+ # Expose port
22
+ EXPOSE 7860
23
+
24
+ # Run the application
25
+ CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,11 +1,73 @@
1
  ---
2
- title: Greenai
3
- emoji: 🐠
4
  colorFrom: green
5
- colorTo: purple
6
  sdk: docker
7
  pinned: false
8
  license: mit
 
9
  ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Mushroom Species Recognition API
3
+ emoji: 🍄
4
  colorFrom: green
5
+ colorTo: yellow
6
  sdk: docker
7
  pinned: false
8
  license: mit
9
+ app_port: 7860
10
  ---
11
 
12
+ # Mushroom Species Recognition API
13
+
14
+ AI-powered mushroom species identification using BioCLIP and VLM models.
15
+
16
+ ## Features
17
+
18
+ - **BioCLIP Model**: Fast species recognition from biological specimens
19
+ - **VLM Fallback**: Nvidia Nemotron VLM for enhanced accuracy
20
+ - **MCC Campus Database**: Location data for mushrooms found at MCC campus
21
+ - **RESTful API**: Simple JSON-based API
22
+
23
+ ## API Endpoints
24
+
25
+ ### POST /recognize
26
+ Upload an image to identify mushroom species.
27
+
28
+ **Request:**
29
+ ```bash
30
+ curl -X POST "https://your-space.hf.space/recognize" \
31
+ -F "file=@mushroom.jpg"
32
+ ```
33
+
34
+ **Response:**
35
+ ```json
36
+ {
37
+ "success": true,
38
+ "found_in_database": true,
39
+ "species": "Leucocoprinus birnbaumii",
40
+ "location": "MCC Pavilion",
41
+ "latitude": 12.91865,
42
+ "longitude": 80.1213,
43
+ "confidence": 0.615,
44
+ "identified_by": "BioCLIP",
45
+ "top_matches": [...]
46
+ }
47
+ ```
48
+
49
+ ### GET /health
50
+ Check API health status.
51
+
52
+ ### GET /
53
+ API documentation and info.
54
+
55
+ ## Usage
56
+
57
+ Visit `/docs` for interactive Swagger documentation.
58
+
59
+ ## Technology Stack
60
+
61
+ - **FastAPI**: Web framework
62
+ - **BioCLIP**: Biological image recognition
63
+ - **OpenCLIP**: Vision-language model
64
+ - **Nvidia Nemotron VLM**: Fallback identification via OpenRouter
65
+ - **Docker**: Containerization
66
+
67
+ ## Setup
68
+
69
+ Set your `OPENROUTER_API_KEY` in the Space secrets for VLM fallback functionality.
70
+
71
+ ## License
72
+
73
+ MIT
api.py ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ import pandas as pd
4
+ from PIL import Image
5
+ import torch
6
+ import numpy as np
7
+ from datetime import datetime
8
+ import os
9
+ import open_clip
10
+ import base64
11
+ from io import BytesIO
12
+ from dotenv import load_dotenv
13
+ import requests
14
+
15
+ # Load environment variables
16
+ load_dotenv()
17
+
18
+ THRESHOLD = 0.50
19
+ LOG_FILE = "data/recognition_log.csv"
20
+ # Read from environment (works with Hugging Face Spaces secrets)
21
+ OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")
22
+
23
+ # Load BioCLIP model
24
+ model, _, preprocess = open_clip.create_model_and_transforms('hf-hub:imageomics/bioclip')
25
+ tokenizer = open_clip.get_tokenizer('hf-hub:imageomics/bioclip')
26
+
27
+ # Load species database
28
+ db = pd.read_csv("data/mushrooms.csv")
29
+
30
+ # Create labels
31
+ enhanced_labels = [species for species in db["species"]]
32
+ labels = enhanced_labels
33
+ labels.append("unknown species")
34
+
35
+ # Initialize log file
36
+ if not os.path.exists(LOG_FILE):
37
+ log_df = pd.DataFrame(columns=["timestamp", "species", "confidence", "location", "lat", "lon", "status"])
38
+ log_df.to_csv(LOG_FILE, index=False)
39
+
40
+ # Initialize FastAPI
41
+ app = FastAPI(title="Mushroom Recognition API", version="1.0.0")
42
+
43
+ # CORS middleware
44
+ app.add_middleware(
45
+ CORSMiddleware,
46
+ allow_origins=["*"],
47
+ allow_credentials=True,
48
+ allow_methods=["*"],
49
+ allow_headers=["*"],
50
+ )
51
+
52
+ def log_recognition(species, confidence, location="N/A", lat="N/A", lon="N/A", status="success"):
53
+ log_entry = {
54
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
55
+ "species": species,
56
+ "confidence": confidence,
57
+ "location": location,
58
+ "lat": lat,
59
+ "lon": lon,
60
+ "status": status
61
+ }
62
+ log_df = pd.read_csv(LOG_FILE)
63
+ log_df = pd.concat([log_df, pd.DataFrame([log_entry])], ignore_index=True)
64
+ log_df.to_csv(LOG_FILE, index=False)
65
+
66
+ def identify_with_vlm(image):
67
+ if not OPENROUTER_API_KEY:
68
+ return None, "OpenRouter API key not configured", False
69
+
70
+ try:
71
+ buffered = BytesIO()
72
+ image.save(buffered, format="JPEG")
73
+ img_base64 = base64.b64encode(buffered.getvalue()).decode()
74
+
75
+ species_list = "\n".join([f"- {s}" for s in db["species"].tolist()])
76
+
77
+ response = requests.post(
78
+ url="https://openrouter.ai/api/v1/chat/completions",
79
+ headers={
80
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
81
+ "Content-Type": "application/json"
82
+ },
83
+ json={
84
+ "model": "nvidia/nemotron-nano-12b-v2-vl:free",
85
+ "messages": [
86
+ {
87
+ "role": "user",
88
+ "content": [
89
+ {
90
+ "type": "image_url",
91
+ "image_url": {
92
+ "url": f"data:image/jpeg;base64,{img_base64}"
93
+ }
94
+ },
95
+ {
96
+ "type": "text",
97
+ "text": f"""You are an expert mycologist. Analyze this mushroom/fungus image very carefully.
98
+
99
+ Look at:
100
+ - Cap shape, color, and texture
101
+ - Gill structure and color
102
+ - Stem characteristics
103
+ - Size and proportions
104
+ - Growing environment
105
+
106
+ Match it to ONE species from this exact list (use the exact name as written):
107
+
108
+ {species_list}
109
+
110
+ Respond with ONLY the exact species name from the list above that best matches this mushroom. If you're not confident about any match, respond with "Unknown"."""
111
+ }
112
+ ]
113
+ }
114
+ ]
115
+ }
116
+ )
117
+
118
+ response_data = response.json()
119
+
120
+ if "error" in response_data:
121
+ error_msg = response_data["error"].get("message", "Unknown API error")
122
+ return None, f"API Error: {error_msg}", False
123
+
124
+ if "choices" not in response_data:
125
+ return None, f"Unexpected response format", False
126
+
127
+ result = response_data["choices"][0]["message"]["content"].strip()
128
+ result = result.split('\n')[0].strip()
129
+ if '.' in result:
130
+ result = result.split('.')[0].strip()
131
+
132
+ for idx, species in enumerate(db["species"]):
133
+ if species.lower() in result.lower() or result.lower() in species.lower():
134
+ return idx, species, True
135
+
136
+ return None, result, False
137
+
138
+ except Exception as e:
139
+ return None, f"Error: {str(e)}", False
140
+
141
+ def recognize_species_internal(image: Image.Image):
142
+ # BioCLIP inference
143
+ image_input = preprocess(image).unsqueeze(0)
144
+ text_input = tokenizer(labels)
145
+
146
+ with torch.no_grad():
147
+ image_features = model.encode_image(image_input)
148
+ text_features = model.encode_text(text_input)
149
+
150
+ image_features /= image_features.norm(dim=-1, keepdim=True)
151
+ text_features /= text_features.norm(dim=-1, keepdim=True)
152
+
153
+ scores = (100.0 * image_features @ text_features.T).softmax(dim=-1)
154
+
155
+ idx = scores.argmax().item()
156
+ confidence = scores[0][idx].item()
157
+
158
+ # Get top 5 matches
159
+ top_k = min(5, len(scores[0]))
160
+ top_scores, top_indices = scores[0].topk(top_k)
161
+ top_matches = []
162
+ for i in range(top_k):
163
+ match_idx = top_indices[i].item()
164
+ match_score = top_scores[i].item()
165
+ if match_idx < len(labels) - 1:
166
+ top_matches.append({
167
+ "species": db.iloc[match_idx]['species'],
168
+ "confidence": round(float(match_score), 3)
169
+ })
170
+ else:
171
+ top_matches.append({
172
+ "species": "Unknown species",
173
+ "confidence": round(float(match_score), 3)
174
+ })
175
+
176
+ # Check if unknown or low confidence
177
+ if idx == len(labels)-1 or confidence < THRESHOLD:
178
+ log_recognition("Unknown", confidence, status="not_found")
179
+
180
+ # Try VLM fallback
181
+ if OPENROUTER_API_KEY:
182
+ vlm_idx, vlm_species, found_in_db = identify_with_vlm(image)
183
+
184
+ if vlm_idx is not None and found_in_db:
185
+ row = db.iloc[vlm_idx]
186
+ log_recognition(row['species'], 0.85, row['location'], row['lat'], row['lon'], status="vlm_success")
187
+
188
+ return {
189
+ "success": True,
190
+ "found_in_database": True,
191
+ "species": row['species'],
192
+ "location": row['location'],
193
+ "latitude": float(row['lat']),
194
+ "longitude": float(row['lon']),
195
+ "confidence": 0.85,
196
+ "identified_by": "Nvidia Nemotron VLM",
197
+ "top_matches": top_matches
198
+ }
199
+ else:
200
+ # Species identified but not in database
201
+ log_recognition(vlm_species, 0.85, status="not_at_mcc")
202
+ return {
203
+ "success": True,
204
+ "found_in_database": False,
205
+ "identified_species": vlm_species,
206
+ "message": "This mushroom is not available in the MCC campus database",
207
+ "identified_by": "Nvidia Nemotron VLM",
208
+ "top_matches": top_matches
209
+ }
210
+
211
+ return {
212
+ "success": False,
213
+ "message": "Species not found in database",
214
+ "confidence": round(float(confidence), 3),
215
+ "top_matches": top_matches
216
+ }
217
+
218
+ # Found in database with high confidence
219
+ row = db.iloc[idx]
220
+ log_recognition(row['species'], confidence, row['location'], row['lat'], row['lon'], status="success")
221
+
222
+ return {
223
+ "success": True,
224
+ "found_in_database": True,
225
+ "species": row['species'],
226
+ "location": row['location'],
227
+ "latitude": float(row['lat']),
228
+ "longitude": float(row['lon']),
229
+ "confidence": round(float(confidence), 3),
230
+ "identified_by": "BioCLIP",
231
+ "top_matches": top_matches
232
+ }
233
+
234
+ @app.get("/")
235
+ async def root():
236
+ return {
237
+ "message": "Mushroom Recognition API",
238
+ "version": "1.0.0",
239
+ "endpoints": {
240
+ "/recognize": "POST - Upload image for species recognition",
241
+ "/health": "GET - Health check"
242
+ }
243
+ }
244
+
245
+ @app.get("/health")
246
+ async def health():
247
+ return {"status": "healthy", "model_loaded": True}
248
+
249
+ @app.post("/recognize")
250
+ async def recognize(file: UploadFile = File(...)):
251
+ """
252
+ Recognize mushroom species from uploaded image
253
+
254
+ Returns JSON with species information
255
+ """
256
+ try:
257
+ # Read and validate image
258
+ contents = await file.read()
259
+ image = Image.open(BytesIO(contents))
260
+
261
+ # Convert to RGB if needed
262
+ if image.mode != 'RGB':
263
+ image = image.convert('RGB')
264
+
265
+ # Perform recognition
266
+ result = recognize_species_internal(image)
267
+
268
+ return result
269
+
270
+ except Exception as e:
271
+ raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}")
272
+
273
+ if __name__ == "__main__":
274
+ import uvicorn
275
+ uvicorn.run(app, host="0.0.0.0", port=8000)
data/mushrooms.csv ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sno,species,location,lat,lon
2
+ 1,Agaricus trisulpurates,MCC IOB Road,12.92206,80.12306
3
+ 2,Pleurotus sp1,MCC Lake Road,12.91558,80.11692
4
+ 3,Agaricus placomyces,MCC Infirmary,12.92088,80.12301
5
+ 4,Agaricus subrufescens,MCC Barnes hall,12.9196,80.11901
6
+ 5,Chlorophyllum molybdites 1,MCC IOB Road,12.92205,80.12304
7
+ 6,Chlorophyllum rhacodes 1,MCC Pavilion Road,12.91868,80.12091
8
+ 7,Lepiota erythrosticta,MCC Botany Road,12.91946,80.12065
9
+ 8,Lepiota sp1,MCC Botany Tank,12.92052,80.12086
10
+ 9,Lepiota sp2,MCC Botany Road,12.91948,80.12075
11
+ 10,Lepiota citriodora,MCC Lake road,12.91644,80.11697
12
+ 11,Leucoagaricus rhodocephalus,MCC Botany Road,12.91968,80.12076
13
+ 12,Leucoagaricus tropicus,MCC Microbiology Dept.,12.92146,80.12112
14
+ 13,Leucocoprinus birnbaumii,MCC Pavilion,12.91865,80.1213
15
+ 14,Leucocoprinus parvipileus 1,MCC Botany Road,12.91974,80.12077
16
+ 15,Leucocoprinus rubrotinctus,MCC Botany Road,12.91978,80.12077
17
+ 16,Amanita sp1,MCC Botany Road,12.91988,80.12079
18
+ 17,Saproamanita manicata 1,MCC Botany Road,12.91986,80.12079
19
+ 18,Saproamanita aureofloccosa,MCC MacPhail,12.91937,80.12102
20
+ 19,Limacella clavocystidiata,MCC Botany Road,12.92005,80.12078
21
+ 20,Entoloma shwethum,MCC Lake road,12.91622,80.11696
22
+ 21,Entoloma sp1,MCC Lake road,12.91623,80.11696
23
+ 22,Entoloma sp2,MCC Lake road,12.91591,80.11695
24
+ 23,Entoloma sp 3,MCC Lake road,12.91582,80.11693
25
+ 24,Entoloma holmvassdalenense,MCC Lake road,12.91574,80.11691
26
+ 25,Termitomyces medius 1,MCC Thomas hall,12.92158,80.11899
27
+ 26,Termitomyces microcarpus,MCC Farm,12.91612,80.12407
28
+ 27,Termitomyces sp1,MCC Social work department,12.91618,80.12393
29
+ 28,Termitomyces heimii,MCC Thomas hall,12.92179,80.11897
30
+ 29,Termitomyces eurrhizus,MCC Botany Road,12.92055,80.12084
31
+ 30,Omphalotus olivascens,MCC Lake road,12.91566,80.11692
32
+ 31,Gymnophilus dilepis,MCC IOB Road,12.92235,80.12327
33
+ 32,Volvariella pseudovolvacea,MCC Boxing Ring,12.92089,80.12123
34
+ 33,Volvariella sp1,MCC Lake Road,12.91558,80.11691
35
+ 34,Cantharocybe gruberi,MCC Botany Tank Road,12.92031,80.12088
36
+ 35,Macrocybe sardoa,MCC Infirmary,12.92087,80.123
37
+ 36,Trogia infundibuliformis,MCC IGH road,12.91866,80.1205
38
+ 37,Dermoloma sp1,MCC Botany Road,12.92024,80.12088
39
+ 38,Tetrapyrgos nigripes,MCC Farm,12.91613,80.12424
40
+ 39,Lactocollybia epia,MCC Chemistry department,12.92123,80.12365
41
+ 40,Marasmius siccus 1,MCC Botany department Road,12.92,80.12086
42
+ 41,Marasmius midnapurensis 1,MCC Science block,12.92123,80.12363
43
+ 42,Marasmius sp1,MCC Botany Road,12.91973,80.12087
44
+ 43,Schizophyllum commune,Thomas hall Road,12.92196,80.11889
45
+ 44,Lentinus zeyheri,MCC Farm,12.9161,80.12467
46
+ 45,Lentinus sajor-caju,MCC Farm,12.9161,80.12465
47
+ 46,Lentinus sqarrosulus,MCC Barnes hall Road,12.91954,80.11766
48
+ 47,Polyporous alveolaris,Near Botany department,12.91974,80.12063
49
+ 48,Polyporous grammosephalus,Near IOB Bank,12.92278,80.12386
50
+ 49,Phellinus rimosus,Near IACS,12.91933,80.12107
51
+ 50,Hexagonia tenuis,Near IOB Bank,12.922718,80.12366
data/recognition_log.csv ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ timestamp,species,confidence,location,lat,lon,status
2
+ 2026-02-02 20:27:49,Unknown,0.1417810171842575,,,,not_found
3
+ 2026-02-02 20:30:35,Unknown,0.1050124317407608,,,,not_found
4
+ 2026-02-02 20:37:29,Agaricus placomyces,0.9987189769744872,MCC Infirmary,12.92088,80.12301,success
5
+ 2026-02-02 20:38:08,Chlorophyllum molybdites 1,0.9686679244041444,MCC IOB Road,12.92205,80.12304,success
6
+ 2026-02-02 20:39:05,Chlorophyllum molybdites 1,0.9529511332511902,MCC IOB Road,12.92205,80.12304,success
7
+ 2026-02-02 20:39:09,Chlorophyllum molybdites 1,0.9529511332511902,MCC IOB Road,12.92205,80.12304,success
8
+ 2026-02-02 21:05:55,Lepiota sp1,0.1816380321979522,MCC Botany Tank,12.92052,80.12086,success
9
+ 2026-02-02 21:06:48,Unknown,0.0808633044362068,,,,not_found
10
+ 2026-02-02 21:17:03,Lepiota sp1,0.1816380321979522,MCC Botany Tank,12.92052,80.12086,success
11
+ 2026-02-05 19:22:25,Leucocoprinus birnbaumii,0.6153523325920105,MCC Pavilion,12.91865,80.1213,success
12
+ 2026-02-05 19:23:19,Lepiota citriodora,0.3851979374885559,MCC Lake road,12.91644,80.11697,success
13
+ 2026-02-05 19:23:23,Lepiota citriodora,0.3851979374885559,MCC Lake road,12.91644,80.11697,success
14
+ 2026-02-05 19:23:25,Lepiota citriodora,0.3851979374885559,MCC Lake road,12.91644,80.11697,success
15
+ 2026-02-05 19:25:05,Leucocoprinus rubrotinctus,0.4666015207767486,MCC Botany Road,12.91978,80.12077,success
16
+ 2026-02-05 19:25:26,Amanita sp1,0.2804426550865173,MCC Botany Road,12.91988,80.12079,success
17
+ 2026-02-05 19:26:57,Unknown,0.2804426550865173,,,,not_found
18
+ 2026-02-05 19:28:11,Unknown,0.2804426550865173,,,,not_found
19
+ 2026-02-05 19:28:50,Unknown,0.2804426550865173,,,,not_found
20
+ 2026-02-05 19:29:15,Unknown,0.2804426550865173,,,,not_found
21
+ 2026-02-05 19:29:16,Leucocoprinus birnbaumii,0.8,MCC Pavilion,12.91865,80.1213,groq_success
22
+ 2026-02-05 19:30:51,Unknown,0.4511626660823822,,,,not_found
23
+ 2026-02-05 19:31:29,Unknown,0.4511626660823822,,,,not_found
24
+ 2026-02-05 19:33:39,Unknown,0.4511626660823822,,,,not_found
25
+ 2026-02-05 19:35:26,Unknown,0.4511626660823822,,,,not_found
26
+ 2026-02-05 19:35:28,The mushroom in the image exhibits a few distinctive features,0.85,,,,not_at_mcc
27
+ 2026-02-05 19:40:29,Unknown,0.4511626660823822,,,,not_found
28
+ 2026-02-05 19:40:30,Error: 'choices',0.85,,,,not_at_mcc
29
+ 2026-02-05 19:41:42,Unknown,0.4511626660823822,,,,not_found
30
+ 2026-02-05 19:41:42,API Error: No endpoints found for google/gemini-2.0-flash-exp:free.,0.85,,,,not_at_mcc
31
+ 2026-02-05 19:45:47,Unknown,0.4511626660823822,,,,not_found
32
+ 2026-02-05 19:45:58,Agaricus trisulpurates,0.85,MCC IOB Road,12.92206,80.12306,vlm_success
33
+ 2026-02-05 19:46:20,Unknown,0.2804426550865173,,,,not_found
34
+ 2026-02-05 19:46:56,Leucocoprinus rubrotinctus,0.85,MCC Botany Road,12.91978,80.12077,vlm_success
35
+ 2026-02-05 19:50:23,Unknown,0.4511626660823822,,,,not_found
36
+ 2026-02-05 19:50:31,Agaricus trisulpurates,0.85,MCC IOB Road,12.92206,80.12306,vlm_success
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.109.0
2
+ uvicorn[standard]==0.27.0
3
+ python-multipart==0.0.9
4
+ pandas==2.1.4
5
+ pillow==10.2.0
6
+ torch==2.1.2
7
+ open-clip-torch==2.24.0
8
+ python-dotenv==1.0.1
9
+ requests==2.31.0