Commit
Β·
96a6d41
1
Parent(s):
2f38f7e
Add MongoDB test scripts and documentation (no credentials exposed)
Browse files- MONGODB_DATA_STRUCTURE.md +197 -0
- show_stored_data.py +178 -0
- test_api_mongodb.py +128 -0
- test_mongodb.py +105 -0
- test_mongodb_direct.py +168 -0
- test_with_image.py +208 -0
MONGODB_DATA_STRUCTURE.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MongoDB Data Storage Structure
|
| 2 |
+
|
| 3 |
+
This document describes exactly what data is stored in MongoDB when you use the Image Colorization API.
|
| 4 |
+
|
| 5 |
+
## Database: `colorization_db`
|
| 6 |
+
|
| 7 |
+
### Collection 1: `api_calls`
|
| 8 |
+
|
| 9 |
+
Stores every API endpoint call with timestamp.
|
| 10 |
+
|
| 11 |
+
**Data Structure:**
|
| 12 |
+
```json
|
| 13 |
+
{
|
| 14 |
+
"_id": ObjectId("..."), // MongoDB auto-generated ID
|
| 15 |
+
"endpoint": "/health", // API endpoint path
|
| 16 |
+
"method": "GET", // HTTP method (GET, POST)
|
| 17 |
+
"status_code": 200, // HTTP status code
|
| 18 |
+
"timestamp": ISODate("2025-11-27T04:22:27.823Z"), // UTC timestamp when API was called
|
| 19 |
+
"request_data": { // Request parameters/data
|
| 20 |
+
"filename": "Descratch.png",
|
| 21 |
+
"content_type": "image/png"
|
| 22 |
+
},
|
| 23 |
+
"response_data": { // Response data returned
|
| 24 |
+
"status": "healthy",
|
| 25 |
+
"model_loaded": true
|
| 26 |
+
},
|
| 27 |
+
"error": null, // Error message if any
|
| 28 |
+
"user_id": null, // User ID if authenticated
|
| 29 |
+
"ip_address": "127.0.0.1" // Client IP address
|
| 30 |
+
}
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
**Example for `/upload` endpoint:**
|
| 34 |
+
```json
|
| 35 |
+
{
|
| 36 |
+
"endpoint": "/upload",
|
| 37 |
+
"method": "POST",
|
| 38 |
+
"status_code": 200,
|
| 39 |
+
"timestamp": ISODate("2025-11-27T10:00:00.000Z"),
|
| 40 |
+
"request_data": {
|
| 41 |
+
"filename": "Descratch.png",
|
| 42 |
+
"content_type": "image/png"
|
| 43 |
+
},
|
| 44 |
+
"response_data": {
|
| 45 |
+
"success": true,
|
| 46 |
+
"image_id": "abc123-def456-ghi789",
|
| 47 |
+
"image_url": "https://.../uploads/abc123.jpg",
|
| 48 |
+
"filename": "abc123.jpg"
|
| 49 |
+
},
|
| 50 |
+
"error": null,
|
| 51 |
+
"user_id": null,
|
| 52 |
+
"ip_address": "192.168.1.100"
|
| 53 |
+
}
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
**Example for `/colorize` endpoint:**
|
| 57 |
+
```json
|
| 58 |
+
{
|
| 59 |
+
"endpoint": "/colorize",
|
| 60 |
+
"method": "POST",
|
| 61 |
+
"status_code": 200,
|
| 62 |
+
"timestamp": ISODate("2025-11-27T10:00:05.000Z"),
|
| 63 |
+
"request_data": {
|
| 64 |
+
"filename": "Descratch.png",
|
| 65 |
+
"content_type": "image/png",
|
| 66 |
+
"positive_prompt": "colorize this image",
|
| 67 |
+
"negative_prompt": "low quality",
|
| 68 |
+
"seed": 123,
|
| 69 |
+
"num_inference_steps": 8
|
| 70 |
+
},
|
| 71 |
+
"response_data": {
|
| 72 |
+
"success": true,
|
| 73 |
+
"result_id": "xyz789-abc123-def456",
|
| 74 |
+
"download_url": "https://.../results/xyz789.png",
|
| 75 |
+
"api_download_url": "https://.../download/xyz789",
|
| 76 |
+
"filename": "xyz789.png",
|
| 77 |
+
"caption": "colorized image"
|
| 78 |
+
},
|
| 79 |
+
"error": null,
|
| 80 |
+
"user_id": null,
|
| 81 |
+
"ip_address": "192.168.1.100"
|
| 82 |
+
}
|
| 83 |
+
```
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
+
|
| 87 |
+
### Collection 2: `image_uploads`
|
| 88 |
+
|
| 89 |
+
Stores information about every image upload.
|
| 90 |
+
|
| 91 |
+
**Data Structure:**
|
| 92 |
+
```json
|
| 93 |
+
{
|
| 94 |
+
"_id": ObjectId("..."), // MongoDB auto-generated ID
|
| 95 |
+
"image_id": "abc123-def456-ghi789", // Unique image identifier (UUID)
|
| 96 |
+
"filename": "Descratch.png", // Original filename
|
| 97 |
+
"file_size": 245678, // File size in bytes
|
| 98 |
+
"content_type": "image/png", // MIME type
|
| 99 |
+
"uploaded_at": ISODate("2025-11-27T10:00:00.000Z"), // UTC timestamp
|
| 100 |
+
"user_id": null, // User ID if authenticated
|
| 101 |
+
"ip_address": "192.168.1.100" // Client IP address
|
| 102 |
+
}
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
**Example with Descratch.png:**
|
| 106 |
+
```json
|
| 107 |
+
{
|
| 108 |
+
"image_id": "abc123-def456-ghi789",
|
| 109 |
+
"filename": "Descratch.png",
|
| 110 |
+
"file_size": 245678,
|
| 111 |
+
"content_type": "image/png",
|
| 112 |
+
"uploaded_at": ISODate("2025-11-27T10:00:00.000Z"),
|
| 113 |
+
"user_id": null,
|
| 114 |
+
"ip_address": "192.168.1.100"
|
| 115 |
+
}
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
---
|
| 119 |
+
|
| 120 |
+
### Collection 3: `colorizations`
|
| 121 |
+
|
| 122 |
+
Stores information about every colorization request.
|
| 123 |
+
|
| 124 |
+
**Data Structure:**
|
| 125 |
+
```json
|
| 126 |
+
{
|
| 127 |
+
"_id": ObjectId("..."), // MongoDB auto-generated ID
|
| 128 |
+
"result_id": "xyz789-abc123-def456", // Unique result identifier (UUID)
|
| 129 |
+
"image_id": "abc123-def456-ghi789", // Original image identifier
|
| 130 |
+
"prompt": "colorize this image", // Text prompt used (if any)
|
| 131 |
+
"model_type": "sdxl", // Model type: "fastai", "pytorch", "sdxl", "gan"
|
| 132 |
+
"processing_time": 3.45, // Time taken to process in seconds
|
| 133 |
+
"created_at": ISODate("2025-11-27T10:00:05.000Z"), // UTC timestamp
|
| 134 |
+
"user_id": null, // User ID if authenticated
|
| 135 |
+
"ip_address": "192.168.1.100" // Client IP address
|
| 136 |
+
}
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
**Example with Descratch.png:**
|
| 140 |
+
```json
|
| 141 |
+
{
|
| 142 |
+
"result_id": "xyz789-abc123-def456",
|
| 143 |
+
"image_id": "abc123-def456-ghi789",
|
| 144 |
+
"prompt": "colorize this image with vibrant natural colors",
|
| 145 |
+
"model_type": "sdxl",
|
| 146 |
+
"processing_time": 3.45,
|
| 147 |
+
"created_at": ISODate("2025-11-27T10:00:05.000Z"),
|
| 148 |
+
"user_id": null,
|
| 149 |
+
"ip_address": "192.168.1.100"
|
| 150 |
+
}
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
---
|
| 154 |
+
|
| 155 |
+
## What Gets Stored When You Use Descratch.png
|
| 156 |
+
|
| 157 |
+
When you upload and colorize `Descratch.png`, the following data will be stored:
|
| 158 |
+
|
| 159 |
+
1. **API Call Logs** (`api_calls` collection):
|
| 160 |
+
- `/health` - Health check call
|
| 161 |
+
- `/upload` - Image upload call with request/response data
|
| 162 |
+
- `/colorize` - Colorization call with processing parameters
|
| 163 |
+
- `/download` - Download result call (if you download the result)
|
| 164 |
+
- `/results` - Public result access call (if accessed)
|
| 165 |
+
|
| 166 |
+
2. **Image Upload Record** (`image_uploads` collection):
|
| 167 |
+
- Image ID (UUID)
|
| 168 |
+
- Filename: "Descratch.png"
|
| 169 |
+
- File size in bytes
|
| 170 |
+
- Content type: "image/png"
|
| 171 |
+
- Upload timestamp
|
| 172 |
+
- IP address
|
| 173 |
+
|
| 174 |
+
3. **Colorization Record** (`colorizations` collection):
|
| 175 |
+
- Result ID (UUID)
|
| 176 |
+
- Image ID reference
|
| 177 |
+
- Model type used
|
| 178 |
+
- Processing time
|
| 179 |
+
- Creation timestamp
|
| 180 |
+
- IP address
|
| 181 |
+
|
| 182 |
+
## All Data Includes Timestamps
|
| 183 |
+
|
| 184 |
+
Every record includes a UTC timestamp:
|
| 185 |
+
- `api_calls.timestamp` - When the API endpoint was called
|
| 186 |
+
- `image_uploads.uploaded_at` - When the image was uploaded
|
| 187 |
+
- `colorizations.created_at` - When the colorization was created
|
| 188 |
+
|
| 189 |
+
## Querying the Data
|
| 190 |
+
|
| 191 |
+
You can query MongoDB to:
|
| 192 |
+
- Find all API calls in the last 24 hours
|
| 193 |
+
- Track which images were uploaded
|
| 194 |
+
- Monitor colorization processing times
|
| 195 |
+
- Analyze API usage patterns
|
| 196 |
+
- Track errors and status codes
|
| 197 |
+
|
show_stored_data.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Show what data is stored in MongoDB collections
|
| 3 |
+
"""
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import json
|
| 7 |
+
import logging
|
| 8 |
+
from datetime import datetime, timedelta
|
| 9 |
+
from pymongo import MongoClient
|
| 10 |
+
from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
|
| 11 |
+
from bson import ObjectId
|
| 12 |
+
|
| 13 |
+
# Configure logging
|
| 14 |
+
logging.basicConfig(
|
| 15 |
+
level=logging.INFO,
|
| 16 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 17 |
+
)
|
| 18 |
+
logger = logging.getLogger(__name__)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class JSONEncoder(json.JSONEncoder):
|
| 22 |
+
"""Custom JSON encoder for MongoDB documents"""
|
| 23 |
+
def default(self, obj):
|
| 24 |
+
if isinstance(obj, ObjectId):
|
| 25 |
+
return str(obj)
|
| 26 |
+
if isinstance(obj, datetime):
|
| 27 |
+
return obj.isoformat()
|
| 28 |
+
return super().default(obj)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def show_stored_data():
|
| 32 |
+
"""Show all data stored in MongoDB collections"""
|
| 33 |
+
mongodb_uri = os.getenv("MONGODB_URI")
|
| 34 |
+
if not mongodb_uri:
|
| 35 |
+
logger.error("β MONGODB_URI environment variable not set!")
|
| 36 |
+
return False
|
| 37 |
+
|
| 38 |
+
db_name = os.getenv("MONGODB_DB_NAME", "colorization_db")
|
| 39 |
+
|
| 40 |
+
try:
|
| 41 |
+
client = MongoClient(mongodb_uri, serverSelectionTimeoutMS=5000)
|
| 42 |
+
client.admin.command('ping')
|
| 43 |
+
logger.info("β
Connected to MongoDB\n")
|
| 44 |
+
|
| 45 |
+
db = client[db_name]
|
| 46 |
+
|
| 47 |
+
# Collection 1: api_calls
|
| 48 |
+
logger.info("=" * 80)
|
| 49 |
+
logger.info("COLLECTION 1: api_calls")
|
| 50 |
+
logger.info("=" * 80)
|
| 51 |
+
logger.info("\nπ Data Structure:")
|
| 52 |
+
logger.info("""
|
| 53 |
+
{
|
| 54 |
+
"_id": ObjectId, # MongoDB auto-generated ID
|
| 55 |
+
"endpoint": str, # API endpoint path (e.g., "/health", "/colorize")
|
| 56 |
+
"method": str, # HTTP method ("GET", "POST", etc.)
|
| 57 |
+
"status_code": int, # HTTP status code (200, 400, 500, etc.)
|
| 58 |
+
"timestamp": datetime, # UTC timestamp when API was called
|
| 59 |
+
"request_data": dict, # Request parameters/data
|
| 60 |
+
"response_data": dict, # Response data returned
|
| 61 |
+
"error": str or None, # Error message if any
|
| 62 |
+
"user_id": str or None, # User ID if authenticated
|
| 63 |
+
"ip_address": str or None # Client IP address
|
| 64 |
+
}
|
| 65 |
+
""")
|
| 66 |
+
|
| 67 |
+
api_calls = db["api_calls"]
|
| 68 |
+
total = api_calls.count_documents({})
|
| 69 |
+
logger.info(f"\nπ Total documents: {total}")
|
| 70 |
+
|
| 71 |
+
if total > 0:
|
| 72 |
+
logger.info("\nπ Sample Documents:")
|
| 73 |
+
samples = list(api_calls.find().sort("timestamp", -1).limit(3))
|
| 74 |
+
for i, doc in enumerate(samples, 1):
|
| 75 |
+
logger.info(f"\n Document {i}:")
|
| 76 |
+
logger.info(f" {json.dumps(doc, cls=JSONEncoder, indent=4)}")
|
| 77 |
+
|
| 78 |
+
# Collection 2: image_uploads
|
| 79 |
+
logger.info("\n" + "=" * 80)
|
| 80 |
+
logger.info("COLLECTION 2: image_uploads")
|
| 81 |
+
logger.info("=" * 80)
|
| 82 |
+
logger.info("\nπ Data Structure:")
|
| 83 |
+
logger.info("""
|
| 84 |
+
{
|
| 85 |
+
"_id": ObjectId, # MongoDB auto-generated ID
|
| 86 |
+
"image_id": str, # Unique image identifier (UUID)
|
| 87 |
+
"filename": str, # Original filename
|
| 88 |
+
"file_size": int, # File size in bytes
|
| 89 |
+
"content_type": str, # MIME type (e.g., "image/jpeg")
|
| 90 |
+
"uploaded_at": datetime, # UTC timestamp when image was uploaded
|
| 91 |
+
"user_id": str or None, # User ID if authenticated
|
| 92 |
+
"ip_address": str or None # Client IP address
|
| 93 |
+
}
|
| 94 |
+
""")
|
| 95 |
+
|
| 96 |
+
image_uploads = db["image_uploads"]
|
| 97 |
+
total = image_uploads.count_documents({})
|
| 98 |
+
logger.info(f"\nπ Total documents: {total}")
|
| 99 |
+
|
| 100 |
+
if total > 0:
|
| 101 |
+
logger.info("\nπ Sample Documents:")
|
| 102 |
+
samples = list(image_uploads.find().sort("uploaded_at", -1).limit(3))
|
| 103 |
+
for i, doc in enumerate(samples, 1):
|
| 104 |
+
logger.info(f"\n Document {i}:")
|
| 105 |
+
logger.info(f" {json.dumps(doc, cls=JSONEncoder, indent=4)}")
|
| 106 |
+
|
| 107 |
+
# Collection 3: colorizations
|
| 108 |
+
logger.info("\n" + "=" * 80)
|
| 109 |
+
logger.info("COLLECTION 3: colorizations")
|
| 110 |
+
logger.info("=" * 80)
|
| 111 |
+
logger.info("\nπ Data Structure:")
|
| 112 |
+
logger.info("""
|
| 113 |
+
{
|
| 114 |
+
"_id": ObjectId, # MongoDB auto-generated ID
|
| 115 |
+
"result_id": str, # Unique result identifier (UUID)
|
| 116 |
+
"image_id": str or None, # Original image identifier
|
| 117 |
+
"prompt": str or None, # Text prompt used (if any)
|
| 118 |
+
"model_type": str or None, # Model type ("fastai", "pytorch", "sdxl", "gan")
|
| 119 |
+
"processing_time": float or None, # Time taken to process in seconds
|
| 120 |
+
"created_at": datetime, # UTC timestamp when colorization was created
|
| 121 |
+
"user_id": str or None, # User ID if authenticated
|
| 122 |
+
"ip_address": str or None # Client IP address
|
| 123 |
+
}
|
| 124 |
+
""")
|
| 125 |
+
|
| 126 |
+
colorizations = db["colorizations"]
|
| 127 |
+
total = colorizations.count_documents({})
|
| 128 |
+
logger.info(f"\nπ Total documents: {total}")
|
| 129 |
+
|
| 130 |
+
if total > 0:
|
| 131 |
+
logger.info("\nπ Sample Documents:")
|
| 132 |
+
samples = list(colorizations.find().sort("created_at", -1).limit(3))
|
| 133 |
+
for i, doc in enumerate(samples, 1):
|
| 134 |
+
logger.info(f"\n Document {i}:")
|
| 135 |
+
logger.info(f" {json.dumps(doc, cls=JSONEncoder, indent=4)}")
|
| 136 |
+
|
| 137 |
+
# Summary
|
| 138 |
+
logger.info("\n" + "=" * 80)
|
| 139 |
+
logger.info("SUMMARY")
|
| 140 |
+
logger.info("=" * 80)
|
| 141 |
+
logger.info(f"\nDatabase: {db_name}")
|
| 142 |
+
logger.info(f"Total API calls logged: {api_calls.count_documents({})}")
|
| 143 |
+
logger.info(f"Total image uploads logged: {image_uploads.count_documents({})}")
|
| 144 |
+
logger.info(f"Total colorizations logged: {colorizations.count_documents({})}")
|
| 145 |
+
|
| 146 |
+
# Recent activity (last 24 hours)
|
| 147 |
+
recent_api = api_calls.count_documents({
|
| 148 |
+
"timestamp": {"$gte": datetime.utcnow() - timedelta(hours=24)}
|
| 149 |
+
})
|
| 150 |
+
recent_uploads = image_uploads.count_documents({
|
| 151 |
+
"uploaded_at": {"$gte": datetime.utcnow() - timedelta(hours=24)}
|
| 152 |
+
})
|
| 153 |
+
recent_colorizations = colorizations.count_documents({
|
| 154 |
+
"created_at": {"$gte": datetime.utcnow() - timedelta(hours=24)}
|
| 155 |
+
})
|
| 156 |
+
|
| 157 |
+
logger.info(f"\nπ Activity in last 24 hours:")
|
| 158 |
+
logger.info(f" API calls: {recent_api}")
|
| 159 |
+
logger.info(f" Image uploads: {recent_uploads}")
|
| 160 |
+
logger.info(f" Colorizations: {recent_colorizations}")
|
| 161 |
+
|
| 162 |
+
client.close()
|
| 163 |
+
return True
|
| 164 |
+
|
| 165 |
+
except (ConnectionFailure, ServerSelectionTimeoutError) as e:
|
| 166 |
+
logger.error(f"β Failed to connect to MongoDB: {e}")
|
| 167 |
+
return False
|
| 168 |
+
except Exception as e:
|
| 169 |
+
logger.error(f"β Error: {e}")
|
| 170 |
+
import traceback
|
| 171 |
+
traceback.print_exc()
|
| 172 |
+
return False
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
if __name__ == "__main__":
|
| 176 |
+
success = show_stored_data()
|
| 177 |
+
sys.exit(0 if success else 1)
|
| 178 |
+
|
test_api_mongodb.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Test script to make API calls and verify MongoDB storage
|
| 3 |
+
This script makes a simple health check API call and verifies it's stored in MongoDB
|
| 4 |
+
"""
|
| 5 |
+
import os
|
| 6 |
+
import sys
|
| 7 |
+
import time
|
| 8 |
+
import logging
|
| 9 |
+
import requests
|
| 10 |
+
from datetime import datetime, timedelta
|
| 11 |
+
from pymongo import MongoClient
|
| 12 |
+
from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
|
| 13 |
+
|
| 14 |
+
# Configure logging
|
| 15 |
+
logging.basicConfig(
|
| 16 |
+
level=logging.INFO,
|
| 17 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 18 |
+
)
|
| 19 |
+
logger = logging.getLogger(__name__)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def test_api_and_mongodb(base_url: str = "http://localhost:7860", mongodb_uri: str = None):
|
| 23 |
+
"""Make API calls and verify they're stored in MongoDB"""
|
| 24 |
+
|
| 25 |
+
if not mongodb_uri:
|
| 26 |
+
mongodb_uri = os.getenv("MONGODB_URI")
|
| 27 |
+
if not mongodb_uri:
|
| 28 |
+
logger.error("β MONGODB_URI not provided!")
|
| 29 |
+
return False
|
| 30 |
+
|
| 31 |
+
db_name = os.getenv("MONGODB_DB_NAME", "colorization_db")
|
| 32 |
+
|
| 33 |
+
logger.info("=" * 60)
|
| 34 |
+
logger.info("Testing API calls and MongoDB storage")
|
| 35 |
+
logger.info("=" * 60)
|
| 36 |
+
|
| 37 |
+
# Step 1: Make a health check API call
|
| 38 |
+
logger.info(f"\n1. Making health check API call to {base_url}/health")
|
| 39 |
+
try:
|
| 40 |
+
response = requests.get(f"{base_url}/health", timeout=10)
|
| 41 |
+
logger.info(f" Status Code: {response.status_code}")
|
| 42 |
+
if response.ok:
|
| 43 |
+
logger.info(f" Response: {response.json()}")
|
| 44 |
+
else:
|
| 45 |
+
logger.warning(f" API returned error: {response.text}")
|
| 46 |
+
except requests.exceptions.RequestException as e:
|
| 47 |
+
logger.error(f" β Failed to connect to API: {e}")
|
| 48 |
+
logger.info(" Note: Make sure the API server is running")
|
| 49 |
+
logger.info(" You can start it with: uvicorn app.main_sdxl:app --reload")
|
| 50 |
+
return False
|
| 51 |
+
|
| 52 |
+
# Step 2: Wait a bit for MongoDB write
|
| 53 |
+
logger.info("\n2. Waiting 3 seconds for MongoDB write to complete...")
|
| 54 |
+
time.sleep(3)
|
| 55 |
+
|
| 56 |
+
# Step 3: Verify MongoDB storage
|
| 57 |
+
logger.info("\n3. Verifying MongoDB storage...")
|
| 58 |
+
try:
|
| 59 |
+
client = MongoClient(mongodb_uri, serverSelectionTimeoutMS=5000)
|
| 60 |
+
client.admin.command('ping')
|
| 61 |
+
logger.info(" β
Connected to MongoDB")
|
| 62 |
+
|
| 63 |
+
db = client[db_name]
|
| 64 |
+
|
| 65 |
+
# Check api_calls collection
|
| 66 |
+
api_calls = db["api_calls"]
|
| 67 |
+
|
| 68 |
+
# Count total calls
|
| 69 |
+
total_calls = api_calls.count_documents({})
|
| 70 |
+
logger.info(f" Total API calls in database: {total_calls}")
|
| 71 |
+
|
| 72 |
+
# Check recent calls (last 5 minutes)
|
| 73 |
+
recent_calls = list(api_calls.find({
|
| 74 |
+
"timestamp": {"$gte": datetime.utcnow() - timedelta(minutes=5)}
|
| 75 |
+
}).sort("timestamp", -1).limit(10))
|
| 76 |
+
|
| 77 |
+
logger.info(f" Recent API calls (last 5 minutes): {len(recent_calls)}")
|
| 78 |
+
|
| 79 |
+
if recent_calls:
|
| 80 |
+
logger.info("\n Recent API call details:")
|
| 81 |
+
for call in recent_calls[:5]:
|
| 82 |
+
logger.info(f" - {call.get('method')} {call.get('endpoint')}")
|
| 83 |
+
logger.info(f" Status: {call.get('status_code')}")
|
| 84 |
+
logger.info(f" Timestamp: {call.get('timestamp')}")
|
| 85 |
+
logger.info(f" IP: {call.get('ip_address')}")
|
| 86 |
+
logger.info("")
|
| 87 |
+
|
| 88 |
+
logger.info(" β
MongoDB storage verification PASSED!")
|
| 89 |
+
logger.info(" β
API calls are being stored in MongoDB with timestamps!")
|
| 90 |
+
client.close()
|
| 91 |
+
return True
|
| 92 |
+
else:
|
| 93 |
+
logger.warning(" β οΈ No recent API calls found in MongoDB")
|
| 94 |
+
logger.info(" This might mean:")
|
| 95 |
+
logger.info(" 1. The API server is not logging to MongoDB")
|
| 96 |
+
logger.info(" 2. MONGODB_URI is not set in the API server environment")
|
| 97 |
+
logger.info(" 3. The write hasn't completed yet (try waiting longer)")
|
| 98 |
+
client.close()
|
| 99 |
+
return False
|
| 100 |
+
|
| 101 |
+
except (ConnectionFailure, ServerSelectionTimeoutError) as e:
|
| 102 |
+
logger.error(f" β Failed to connect to MongoDB: {e}")
|
| 103 |
+
return False
|
| 104 |
+
except Exception as e:
|
| 105 |
+
logger.error(f" β Error: {e}")
|
| 106 |
+
import traceback
|
| 107 |
+
traceback.print_exc()
|
| 108 |
+
return False
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
if __name__ == "__main__":
|
| 112 |
+
import argparse
|
| 113 |
+
|
| 114 |
+
parser = argparse.ArgumentParser(description="Test API calls and MongoDB storage")
|
| 115 |
+
parser.add_argument("--base-url", type=str, default="http://localhost:7860",
|
| 116 |
+
help="API base URL (default: http://localhost:7860)")
|
| 117 |
+
parser.add_argument("--mongodb-uri", type=str, default=os.getenv("MONGODB_URI", ""),
|
| 118 |
+
help="MongoDB connection string")
|
| 119 |
+
|
| 120 |
+
args = parser.parse_args()
|
| 121 |
+
|
| 122 |
+
if not args.mongodb_uri:
|
| 123 |
+
logger.error("MongoDB URI required! Set MONGODB_URI environment variable or use --mongodb-uri")
|
| 124 |
+
sys.exit(1)
|
| 125 |
+
|
| 126 |
+
success = test_api_and_mongodb(args.base_url, args.mongodb_uri)
|
| 127 |
+
sys.exit(0 if success else 1)
|
| 128 |
+
|
test_mongodb.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Simple MongoDB verification test script
|
| 3 |
+
This script tests if data is being stored in MongoDB after API calls.
|
| 4 |
+
"""
|
| 5 |
+
import os
|
| 6 |
+
import sys
|
| 7 |
+
import logging
|
| 8 |
+
from datetime import datetime, timedelta
|
| 9 |
+
from pymongo import MongoClient
|
| 10 |
+
from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
|
| 11 |
+
|
| 12 |
+
# Configure logging
|
| 13 |
+
logging.basicConfig(
|
| 14 |
+
level=logging.INFO,
|
| 15 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 16 |
+
)
|
| 17 |
+
logger = logging.getLogger(__name__)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_mongodb_connection():
|
| 21 |
+
"""Test MongoDB connection and verify collections exist"""
|
| 22 |
+
mongodb_uri = os.getenv("MONGODB_URI")
|
| 23 |
+
if not mongodb_uri:
|
| 24 |
+
logger.error("β MONGODB_URI environment variable not set!")
|
| 25 |
+
logger.info("Please set MONGODB_URI environment variable")
|
| 26 |
+
return False
|
| 27 |
+
|
| 28 |
+
db_name = os.getenv("MONGODB_DB_NAME", "colorization_db")
|
| 29 |
+
|
| 30 |
+
try:
|
| 31 |
+
logger.info("Connecting to MongoDB...")
|
| 32 |
+
client = MongoClient(mongodb_uri, serverSelectionTimeoutMS=5000)
|
| 33 |
+
|
| 34 |
+
# Test connection
|
| 35 |
+
client.admin.command('ping')
|
| 36 |
+
logger.info("β
Connected to MongoDB successfully!")
|
| 37 |
+
|
| 38 |
+
db = client[db_name]
|
| 39 |
+
logger.info(f"Using database: {db_name}")
|
| 40 |
+
|
| 41 |
+
# List all collections
|
| 42 |
+
collections = db.list_collection_names()
|
| 43 |
+
logger.info(f"Collections found: {collections}")
|
| 44 |
+
|
| 45 |
+
# Check each collection
|
| 46 |
+
collections_to_check = ["api_calls", "image_uploads", "colorizations"]
|
| 47 |
+
|
| 48 |
+
for collection_name in collections_to_check:
|
| 49 |
+
collection = db[collection_name]
|
| 50 |
+
total_count = collection.count_documents({})
|
| 51 |
+
recent_count = collection.count_documents({
|
| 52 |
+
"timestamp" if collection_name == "api_calls" else
|
| 53 |
+
("uploaded_at" if collection_name == "image_uploads" else "created_at"): {
|
| 54 |
+
"$gte": datetime.utcnow() - timedelta(hours=24)
|
| 55 |
+
}
|
| 56 |
+
})
|
| 57 |
+
|
| 58 |
+
logger.info(f"\nπ Collection: {collection_name}")
|
| 59 |
+
logger.info(f" Total documents: {total_count}")
|
| 60 |
+
logger.info(f" Documents in last 24 hours: {recent_count}")
|
| 61 |
+
|
| 62 |
+
# Show sample document
|
| 63 |
+
sample = collection.find_one(sort=[("_id", -1)])
|
| 64 |
+
if sample:
|
| 65 |
+
logger.info(f" Latest document ID: {sample.get('_id')}")
|
| 66 |
+
if collection_name == "api_calls":
|
| 67 |
+
logger.info(f" Latest endpoint: {sample.get('endpoint')} at {sample.get('timestamp')}")
|
| 68 |
+
elif collection_name == "image_uploads":
|
| 69 |
+
logger.info(f" Latest image: {sample.get('image_id')} at {sample.get('uploaded_at')}")
|
| 70 |
+
elif collection_name == "colorizations":
|
| 71 |
+
logger.info(f" Latest result: {sample.get('result_id')} at {sample.get('created_at')}")
|
| 72 |
+
|
| 73 |
+
# Show recent API calls
|
| 74 |
+
api_calls = db["api_calls"]
|
| 75 |
+
recent_calls = list(api_calls.find({
|
| 76 |
+
"timestamp": {"$gte": datetime.utcnow() - timedelta(minutes=30)}
|
| 77 |
+
}).sort("timestamp", -1).limit(10))
|
| 78 |
+
|
| 79 |
+
if recent_calls:
|
| 80 |
+
logger.info("\nπ Recent API calls (last 30 minutes):")
|
| 81 |
+
for call in recent_calls:
|
| 82 |
+
logger.info(f" {call.get('method')} {call.get('endpoint')} - "
|
| 83 |
+
f"Status: {call.get('status_code')} - "
|
| 84 |
+
f"Time: {call.get('timestamp')}")
|
| 85 |
+
else:
|
| 86 |
+
logger.info("\nπ No API calls in the last 30 minutes")
|
| 87 |
+
|
| 88 |
+
client.close()
|
| 89 |
+
logger.info("\nβ
MongoDB test completed successfully!")
|
| 90 |
+
return True
|
| 91 |
+
|
| 92 |
+
except (ConnectionFailure, ServerSelectionTimeoutError) as e:
|
| 93 |
+
logger.error(f"β Failed to connect to MongoDB: {e}")
|
| 94 |
+
return False
|
| 95 |
+
except Exception as e:
|
| 96 |
+
logger.error(f"β Error: {e}")
|
| 97 |
+
import traceback
|
| 98 |
+
traceback.print_exc()
|
| 99 |
+
return False
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
if __name__ == "__main__":
|
| 103 |
+
success = test_mongodb_connection()
|
| 104 |
+
sys.exit(0 if success else 1)
|
| 105 |
+
|
test_mongodb_direct.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Direct MongoDB test - Insert test data and verify storage
|
| 3 |
+
This test directly writes to MongoDB to verify the connection and storage works
|
| 4 |
+
"""
|
| 5 |
+
import os
|
| 6 |
+
import sys
|
| 7 |
+
import logging
|
| 8 |
+
from datetime import datetime
|
| 9 |
+
from pymongo import MongoClient
|
| 10 |
+
from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
|
| 11 |
+
|
| 12 |
+
# Configure logging
|
| 13 |
+
logging.basicConfig(
|
| 14 |
+
level=logging.INFO,
|
| 15 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 16 |
+
)
|
| 17 |
+
logger = logging.getLogger(__name__)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_mongodb_direct():
|
| 21 |
+
"""Test MongoDB by directly inserting test data"""
|
| 22 |
+
mongodb_uri = os.getenv("MONGODB_URI")
|
| 23 |
+
if not mongodb_uri:
|
| 24 |
+
logger.error("β MONGODB_URI environment variable not set!")
|
| 25 |
+
logger.info("Set it with: $env:MONGODB_URI='your_connection_string'")
|
| 26 |
+
return False
|
| 27 |
+
|
| 28 |
+
db_name = os.getenv("MONGODB_DB_NAME", "colorization_db")
|
| 29 |
+
|
| 30 |
+
logger.info("=" * 60)
|
| 31 |
+
logger.info("Direct MongoDB Storage Test")
|
| 32 |
+
logger.info("=" * 60)
|
| 33 |
+
|
| 34 |
+
try:
|
| 35 |
+
# Connect to MongoDB
|
| 36 |
+
logger.info("\n1. Connecting to MongoDB...")
|
| 37 |
+
client = MongoClient(mongodb_uri, serverSelectionTimeoutMS=10000)
|
| 38 |
+
client.admin.command('ping')
|
| 39 |
+
logger.info(" β
Connected successfully!")
|
| 40 |
+
|
| 41 |
+
db = client[db_name]
|
| 42 |
+
logger.info(f" Using database: {db_name}")
|
| 43 |
+
|
| 44 |
+
# Test 1: Insert into api_calls collection
|
| 45 |
+
logger.info("\n2. Testing api_calls collection...")
|
| 46 |
+
api_calls = db["api_calls"]
|
| 47 |
+
|
| 48 |
+
test_api_call = {
|
| 49 |
+
"endpoint": "/health",
|
| 50 |
+
"method": "GET",
|
| 51 |
+
"status_code": 200,
|
| 52 |
+
"timestamp": datetime.utcnow(),
|
| 53 |
+
"request_data": {},
|
| 54 |
+
"response_data": {"status": "healthy", "model_loaded": True},
|
| 55 |
+
"error": None,
|
| 56 |
+
"user_id": None,
|
| 57 |
+
"ip_address": "127.0.0.1",
|
| 58 |
+
"test": True # Mark as test data
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
result = api_calls.insert_one(test_api_call)
|
| 62 |
+
logger.info(f" β
Inserted test API call with ID: {result.inserted_id}")
|
| 63 |
+
|
| 64 |
+
# Verify it was stored
|
| 65 |
+
stored = api_calls.find_one({"_id": result.inserted_id})
|
| 66 |
+
if stored:
|
| 67 |
+
logger.info(f" β
Verified: API call stored successfully")
|
| 68 |
+
logger.info(f" Endpoint: {stored.get('endpoint')}")
|
| 69 |
+
logger.info(f" Timestamp: {stored.get('timestamp')}")
|
| 70 |
+
else:
|
| 71 |
+
logger.error(" β Failed to retrieve stored document")
|
| 72 |
+
return False
|
| 73 |
+
|
| 74 |
+
# Test 2: Insert into image_uploads collection
|
| 75 |
+
logger.info("\n3. Testing image_uploads collection...")
|
| 76 |
+
image_uploads = db["image_uploads"]
|
| 77 |
+
|
| 78 |
+
test_upload = {
|
| 79 |
+
"image_id": "test-image-123",
|
| 80 |
+
"filename": "test_image.jpg",
|
| 81 |
+
"file_size": 102400,
|
| 82 |
+
"content_type": "image/jpeg",
|
| 83 |
+
"uploaded_at": datetime.utcnow(),
|
| 84 |
+
"user_id": None,
|
| 85 |
+
"ip_address": "127.0.0.1",
|
| 86 |
+
"test": True
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
result = image_uploads.insert_one(test_upload)
|
| 90 |
+
logger.info(f" β
Inserted test upload with ID: {result.inserted_id}")
|
| 91 |
+
|
| 92 |
+
stored = image_uploads.find_one({"_id": result.inserted_id})
|
| 93 |
+
if stored:
|
| 94 |
+
logger.info(f" β
Verified: Image upload stored successfully")
|
| 95 |
+
logger.info(f" Image ID: {stored.get('image_id')}")
|
| 96 |
+
logger.info(f" Uploaded at: {stored.get('uploaded_at')}")
|
| 97 |
+
|
| 98 |
+
# Test 3: Insert into colorizations collection
|
| 99 |
+
logger.info("\n4. Testing colorizations collection...")
|
| 100 |
+
colorizations = db["colorizations"]
|
| 101 |
+
|
| 102 |
+
test_colorization = {
|
| 103 |
+
"result_id": "test-result-456",
|
| 104 |
+
"image_id": "test-image-123",
|
| 105 |
+
"prompt": "Test colorization",
|
| 106 |
+
"model_type": "test",
|
| 107 |
+
"processing_time": 1.23,
|
| 108 |
+
"created_at": datetime.utcnow(),
|
| 109 |
+
"user_id": None,
|
| 110 |
+
"ip_address": "127.0.0.1",
|
| 111 |
+
"test": True
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
result = colorizations.insert_one(test_colorization)
|
| 115 |
+
logger.info(f" β
Inserted test colorization with ID: {result.inserted_id}")
|
| 116 |
+
|
| 117 |
+
stored = colorizations.find_one({"_id": result.inserted_id})
|
| 118 |
+
if stored:
|
| 119 |
+
logger.info(f" β
Verified: Colorization stored successfully")
|
| 120 |
+
logger.info(f" Result ID: {stored.get('result_id')}")
|
| 121 |
+
logger.info(f" Created at: {stored.get('created_at')}")
|
| 122 |
+
|
| 123 |
+
# Summary
|
| 124 |
+
logger.info("\n" + "=" * 60)
|
| 125 |
+
logger.info("Test Summary")
|
| 126 |
+
logger.info("=" * 60)
|
| 127 |
+
|
| 128 |
+
total_api_calls = api_calls.count_documents({})
|
| 129 |
+
total_uploads = image_uploads.count_documents({})
|
| 130 |
+
total_colorizations = colorizations.count_documents({})
|
| 131 |
+
|
| 132 |
+
logger.info(f"Total documents in api_calls: {total_api_calls}")
|
| 133 |
+
logger.info(f"Total documents in image_uploads: {total_uploads}")
|
| 134 |
+
logger.info(f"Total documents in colorizations: {total_colorizations}")
|
| 135 |
+
|
| 136 |
+
logger.info("\nβ
All MongoDB storage tests PASSED!")
|
| 137 |
+
logger.info("β
Collections are created automatically")
|
| 138 |
+
logger.info("β
Data is being stored with timestamps")
|
| 139 |
+
logger.info("β
MongoDB integration is working correctly!")
|
| 140 |
+
|
| 141 |
+
# Optional: Clean up test data
|
| 142 |
+
logger.info("\n5. Cleaning up test data...")
|
| 143 |
+
api_calls.delete_many({"test": True})
|
| 144 |
+
image_uploads.delete_many({"test": True})
|
| 145 |
+
colorizations.delete_many({"test": True})
|
| 146 |
+
logger.info(" β
Test data cleaned up")
|
| 147 |
+
|
| 148 |
+
client.close()
|
| 149 |
+
return True
|
| 150 |
+
|
| 151 |
+
except (ConnectionFailure, ServerSelectionTimeoutError) as e:
|
| 152 |
+
logger.error(f"β Failed to connect to MongoDB: {e}")
|
| 153 |
+
logger.info("\nTroubleshooting:")
|
| 154 |
+
logger.info("1. Check your MongoDB connection string")
|
| 155 |
+
logger.info("2. Verify network connectivity")
|
| 156 |
+
logger.info("3. Check if MongoDB allows connections from your IP")
|
| 157 |
+
return False
|
| 158 |
+
except Exception as e:
|
| 159 |
+
logger.error(f"β Error: {e}")
|
| 160 |
+
import traceback
|
| 161 |
+
traceback.print_exc()
|
| 162 |
+
return False
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
if __name__ == "__main__":
|
| 166 |
+
success = test_mongodb_direct()
|
| 167 |
+
sys.exit(0 if success else 1)
|
| 168 |
+
|
test_with_image.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Test script to test API with Descratch.png image and verify MongoDB storage
|
| 3 |
+
"""
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import time
|
| 7 |
+
import logging
|
| 8 |
+
import requests
|
| 9 |
+
from datetime import datetime, timedelta
|
| 10 |
+
from pymongo import MongoClient
|
| 11 |
+
from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
|
| 12 |
+
|
| 13 |
+
# Configure logging
|
| 14 |
+
logging.basicConfig(
|
| 15 |
+
level=logging.INFO,
|
| 16 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 17 |
+
)
|
| 18 |
+
logger = logging.getLogger(__name__)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def test_api_with_image_and_mongodb(image_path: str, base_url: str = "http://localhost:7860",
|
| 22 |
+
mongodb_uri: str = None, app_check_token: str = None):
|
| 23 |
+
"""Test API with image and verify MongoDB storage"""
|
| 24 |
+
|
| 25 |
+
if not mongodb_uri:
|
| 26 |
+
mongodb_uri = os.getenv("MONGODB_URI")
|
| 27 |
+
if not mongodb_uri:
|
| 28 |
+
logger.error("β MONGODB_URI not provided!")
|
| 29 |
+
return False
|
| 30 |
+
|
| 31 |
+
if not os.path.exists(image_path):
|
| 32 |
+
logger.error(f"β Image not found: {image_path}")
|
| 33 |
+
return False
|
| 34 |
+
|
| 35 |
+
db_name = os.getenv("MONGODB_DB_NAME", "colorization_db")
|
| 36 |
+
|
| 37 |
+
logger.info("=" * 80)
|
| 38 |
+
logger.info("Testing API with Image and MongoDB Storage")
|
| 39 |
+
logger.info("=" * 80)
|
| 40 |
+
logger.info(f"Image: {image_path}")
|
| 41 |
+
logger.info(f"API URL: {base_url}")
|
| 42 |
+
logger.info(f"Database: {db_name}\n")
|
| 43 |
+
|
| 44 |
+
# Step 1: Health check
|
| 45 |
+
logger.info("1. Testing /health endpoint...")
|
| 46 |
+
try:
|
| 47 |
+
response = requests.get(f"{base_url}/health", timeout=10)
|
| 48 |
+
if response.ok:
|
| 49 |
+
logger.info(f" β
Health check passed: {response.json()}")
|
| 50 |
+
else:
|
| 51 |
+
logger.warning(f" β οΈ Health check returned: {response.status_code}")
|
| 52 |
+
except requests.exceptions.RequestException as e:
|
| 53 |
+
logger.error(f" β Failed to connect to API: {e}")
|
| 54 |
+
logger.info(" Note: Make sure the API server is running")
|
| 55 |
+
logger.info(" Start with: uvicorn app.main_sdxl:app --reload")
|
| 56 |
+
return False
|
| 57 |
+
|
| 58 |
+
# Step 2: Upload image
|
| 59 |
+
logger.info("\n2. Uploading image...")
|
| 60 |
+
upload_url = f"{base_url}/upload"
|
| 61 |
+
headers = {}
|
| 62 |
+
if app_check_token:
|
| 63 |
+
headers["X-Firebase-AppCheck"] = app_check_token
|
| 64 |
+
|
| 65 |
+
try:
|
| 66 |
+
with open(image_path, "rb") as f:
|
| 67 |
+
files = {"file": (os.path.basename(image_path), f, "image/png")}
|
| 68 |
+
response = requests.post(upload_url, files=files, headers=headers, timeout=120)
|
| 69 |
+
|
| 70 |
+
if response.ok:
|
| 71 |
+
upload_data = response.json()
|
| 72 |
+
logger.info(f" β
Upload successful!")
|
| 73 |
+
logger.info(f" Image ID: {upload_data.get('image_id')}")
|
| 74 |
+
image_id = upload_data.get('image_id')
|
| 75 |
+
else:
|
| 76 |
+
logger.error(f" β Upload failed: {response.status_code} - {response.text}")
|
| 77 |
+
return False
|
| 78 |
+
except Exception as e:
|
| 79 |
+
logger.error(f" β Upload error: {e}")
|
| 80 |
+
return False
|
| 81 |
+
|
| 82 |
+
# Step 3: Colorize image
|
| 83 |
+
logger.info("\n3. Colorizing image...")
|
| 84 |
+
colorize_url = f"{base_url}/colorize"
|
| 85 |
+
|
| 86 |
+
try:
|
| 87 |
+
with open(image_path, "rb") as f:
|
| 88 |
+
files = {"file": (os.path.basename(image_path), f, "image/png")}
|
| 89 |
+
response = requests.post(colorize_url, files=files, headers=headers, timeout=900)
|
| 90 |
+
|
| 91 |
+
if response.ok:
|
| 92 |
+
colorize_data = response.json()
|
| 93 |
+
logger.info(f" β
Colorization successful!")
|
| 94 |
+
logger.info(f" Result ID: {colorize_data.get('result_id')}")
|
| 95 |
+
result_id = colorize_data.get('result_id')
|
| 96 |
+
else:
|
| 97 |
+
logger.error(f" β Colorization failed: {response.status_code} - {response.text}")
|
| 98 |
+
return False
|
| 99 |
+
except Exception as e:
|
| 100 |
+
logger.error(f" β Colorization error: {e}")
|
| 101 |
+
return False
|
| 102 |
+
|
| 103 |
+
# Step 4: Wait for MongoDB writes
|
| 104 |
+
logger.info("\n4. Waiting 5 seconds for MongoDB writes to complete...")
|
| 105 |
+
time.sleep(5)
|
| 106 |
+
|
| 107 |
+
# Step 5: Verify MongoDB storage
|
| 108 |
+
logger.info("\n5. Verifying MongoDB storage...")
|
| 109 |
+
try:
|
| 110 |
+
client = MongoClient(mongodb_uri, serverSelectionTimeoutMS=5000)
|
| 111 |
+
client.admin.command('ping')
|
| 112 |
+
logger.info(" β
Connected to MongoDB")
|
| 113 |
+
|
| 114 |
+
db = client[db_name]
|
| 115 |
+
|
| 116 |
+
# Check api_calls collection
|
| 117 |
+
api_calls = db["api_calls"]
|
| 118 |
+
recent_calls = list(api_calls.find({
|
| 119 |
+
"timestamp": {"$gte": datetime.utcnow() - timedelta(minutes=10)}
|
| 120 |
+
}).sort("timestamp", -1))
|
| 121 |
+
|
| 122 |
+
logger.info(f"\n π Found {len(recent_calls)} API calls in last 10 minutes:")
|
| 123 |
+
for call in recent_calls[:5]:
|
| 124 |
+
logger.info(f" - {call.get('method')} {call.get('endpoint')} "
|
| 125 |
+
f"(Status: {call.get('status_code')}) at {call.get('timestamp')}")
|
| 126 |
+
|
| 127 |
+
# Check image_uploads collection
|
| 128 |
+
image_uploads = db["image_uploads"]
|
| 129 |
+
recent_uploads = list(image_uploads.find({
|
| 130 |
+
"uploaded_at": {"$gte": datetime.utcnow() - timedelta(minutes=10)}
|
| 131 |
+
}).sort("uploaded_at", -1))
|
| 132 |
+
|
| 133 |
+
logger.info(f"\n π Found {len(recent_uploads)} image uploads in last 10 minutes:")
|
| 134 |
+
for upload in recent_uploads[:3]:
|
| 135 |
+
logger.info(f" - Image ID: {upload.get('image_id')}")
|
| 136 |
+
logger.info(f" Filename: {upload.get('filename')}")
|
| 137 |
+
logger.info(f" Size: {upload.get('file_size')} bytes")
|
| 138 |
+
logger.info(f" Uploaded at: {upload.get('uploaded_at')}")
|
| 139 |
+
|
| 140 |
+
# Check colorizations collection
|
| 141 |
+
colorizations = db["colorizations"]
|
| 142 |
+
recent_colorizations = list(colorizations.find({
|
| 143 |
+
"created_at": {"$gte": datetime.utcnow() - timedelta(minutes=10)}
|
| 144 |
+
}).sort("created_at", -1))
|
| 145 |
+
|
| 146 |
+
logger.info(f"\n π Found {len(recent_colorizations)} colorizations in last 10 minutes:")
|
| 147 |
+
for colorization in recent_colorizations[:3]:
|
| 148 |
+
logger.info(f" - Result ID: {colorization.get('result_id')}")
|
| 149 |
+
logger.info(f" Model: {colorization.get('model_type')}")
|
| 150 |
+
logger.info(f" Processing time: {colorization.get('processing_time')}s")
|
| 151 |
+
logger.info(f" Created at: {colorization.get('created_at')}")
|
| 152 |
+
|
| 153 |
+
# Summary
|
| 154 |
+
logger.info("\n" + "=" * 80)
|
| 155 |
+
logger.info("TEST SUMMARY")
|
| 156 |
+
logger.info("=" * 80)
|
| 157 |
+
|
| 158 |
+
if len(recent_calls) > 0 and len(recent_uploads) > 0 and len(recent_colorizations) > 0:
|
| 159 |
+
logger.info("β
SUCCESS: All data is being stored in MongoDB!")
|
| 160 |
+
logger.info("β
API calls are logged with timestamps")
|
| 161 |
+
logger.info("β
Image uploads are logged with metadata")
|
| 162 |
+
logger.info("β
Colorizations are logged with processing details")
|
| 163 |
+
else:
|
| 164 |
+
logger.warning("β οΈ Some data might be missing:")
|
| 165 |
+
logger.warning(f" API calls: {len(recent_calls)}")
|
| 166 |
+
logger.warning(f" Image uploads: {len(recent_uploads)}")
|
| 167 |
+
logger.warning(f" Colorizations: {len(recent_colorizations)}")
|
| 168 |
+
|
| 169 |
+
client.close()
|
| 170 |
+
return True
|
| 171 |
+
|
| 172 |
+
except (ConnectionFailure, ServerSelectionTimeoutError) as e:
|
| 173 |
+
logger.error(f" β Failed to connect to MongoDB: {e}")
|
| 174 |
+
return False
|
| 175 |
+
except Exception as e:
|
| 176 |
+
logger.error(f" β Error: {e}")
|
| 177 |
+
import traceback
|
| 178 |
+
traceback.print_exc()
|
| 179 |
+
return False
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
if __name__ == "__main__":
|
| 183 |
+
import argparse
|
| 184 |
+
|
| 185 |
+
parser = argparse.ArgumentParser(description="Test API with image and verify MongoDB")
|
| 186 |
+
parser.add_argument("--image", type=str, default="../Descratch.png",
|
| 187 |
+
help="Path to image file")
|
| 188 |
+
parser.add_argument("--base-url", type=str, default="http://localhost:7860",
|
| 189 |
+
help="API base URL")
|
| 190 |
+
parser.add_argument("--mongodb-uri", type=str, default=os.getenv("MONGODB_URI", ""),
|
| 191 |
+
help="MongoDB connection string")
|
| 192 |
+
parser.add_argument("--app-check", type=str, default=os.getenv("APP_CHECK_TOKEN", ""),
|
| 193 |
+
help="Firebase App Check token (optional)")
|
| 194 |
+
|
| 195 |
+
args = parser.parse_args()
|
| 196 |
+
|
| 197 |
+
if not args.mongodb_uri:
|
| 198 |
+
logger.error("MongoDB URI required! Set MONGODB_URI environment variable or use --mongodb-uri")
|
| 199 |
+
sys.exit(1)
|
| 200 |
+
|
| 201 |
+
success = test_api_with_image_and_mongodb(
|
| 202 |
+
args.image,
|
| 203 |
+
args.base_url,
|
| 204 |
+
args.mongodb_uri,
|
| 205 |
+
args.app_check if args.app_check else None
|
| 206 |
+
)
|
| 207 |
+
sys.exit(0 if success else 1)
|
| 208 |
+
|