from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import HTMLResponse from PIL import Image from PIL.ExifTags import TAGS from datetime import datetime import os import tempfile app = FastAPI(title="Image Metadata Extractor", description="Upload an image to extract its metadata including creation timestamp") def get_image_metadata(image_path): """Extract metadata from an image file""" result = { "filename": os.path.basename(image_path), "format": None, "size": None, "mode": None, "exif_data": {}, "creation_date": None, "file_system_creation_time": None, "error": None } try: # Open the image with Image.open(image_path) as img: result["format"] = img.format result["size"] = img.size result["mode"] = img.mode # Get EXIF data exif_data = img._getexif() if exif_data is not None: exif_dict = {} for tag_id, value in exif_data.items(): tag = TAGS.get(tag_id, tag_id) exif_dict[tag] = str(value) result["exif_data"] = exif_dict # Try to extract creation date from common EXIF tags date_tags = ['DateTime', 'DateTimeOriginal', 'DateTimeDigitized'] for tag in date_tags: # Find the tag ID for the current tag tag_id = None for tid, tname in TAGS.items(): if tname == tag: tag_id = tid break if tag_id and tag_id in exif_data: raw_date = exif_data[tag_id] try: # Handle different date formats if isinstance(raw_date, bytes): raw_date = raw_date.decode('utf-8') # Try different date formats formats_to_try = [ '%Y:%m:%d %H:%M:%S', '%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M:%S' ] creation_date = None for fmt in formats_to_try: try: creation_date = datetime.strptime(str(raw_date), fmt) break except ValueError: continue if creation_date: result["creation_date"] = { "source": tag, "date": creation_date.isoformat() } break except Exception: continue # Fallback: Use file system creation time stat = os.stat(image_path) creation_time = stat.st_ctime result["file_system_creation_time"] = datetime.fromtimestamp(creation_time).isoformat() except Exception as e: result["error"] = str(e) return result @app.get("/", response_class=HTMLResponse) async def read_root(): """Serve the HTML frontend""" return """ Image Metadata Extractor

📸 Image Metadata Extractor

Upload any image to extract detailed metadata including creation timestamps

📁

Drag & Drop your image here

or click to browse files

Image Metadata Analysis

""" @app.post("/extract-metadata") async def extract_metadata(file: UploadFile = File(...)): """Endpoint to extract metadata from uploaded image""" if not file.content_type.startswith("image/"): raise HTTPException(status_code=400, detail="File must be an image") # Initialize tmp_file_path to None tmp_file_path = None try: # Read the file content contents = await file.read() # Create a temporary file to store the uploaded image with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(contents) tmp_file_path = tmp_file.name # Extract metadata metadata = get_image_metadata(tmp_file_path) return metadata except Exception as e: raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)}") finally: # Clean up temporary file if tmp_file_path and os.path.exists(tmp_file_path): os.unlink(tmp_file_path) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)