A full-stack application for uploading images, extracting and editing EXIF metadata (GPS coordinates, timestamps, descriptions), and downloading modified images with complete edit history tracking.
Mini SaaS MVP is a lightweight but powerful EXIF metadata editor built with a modern tech stack:
- Frontend: React 19 + Vite + Tailwind CSS
- Backend: FastAPI + SQLModel + PostgreSQL/SQLite
- Authentication: Supabase Auth
Perfect for photographers, data analysts, geospatial professionals, or anyone needing to programmatically edit image metadata.
- 📸 Extract EXIF Data - Instantly read GPS coordinates, timestamps, and descriptions from uploaded images
- ✏️ Edit Metadata - Modify latitude/longitude, EXIF timestamps, and image descriptions
- 📍 Live Map Preview - Visualize GPS coordinates on an interactive map before saving
- 💾 Download Modified Images - Export images with updated EXIF data
- 📋 Edit History - Track all metadata changes per user with full audit trail
- 🔐 Secure Authentication - Supabase Auth integration for user management
- 🎨 Modern UI - Responsive design with Tailwind CSS
- Python 3.9+
- Node.js 18+
- PostgreSQL 12+ (or use built-in SQLite for local development)
- Supabase account (free tier available at supabase.com)
-
Navigate to the backend directory:
cd Backend -
Create and activate a Python virtual environment:
# Windows python -m venv .venv .venv\Scripts\activate # macOS / Linux python -m venv .venv source .venv/bin/activate
-
Install dependencies:
pip install -r requirements.txt
-
Create a
.envfile in theBackend/directory:# Optional: PostgreSQL connection string (falls back to SQLite if not set) DATABASE_URL=postgresql://user:password@localhost:5432/exif_db
-
Initialize the database:
python init_db.py
-
Start the FastAPI server:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
The API will be available at
http://localhost:8000
-
Navigate to the frontend directory:
cd Frontend -
Install dependencies:
npm install
-
Create a
.envfile in theFrontend/directory:VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_ANON_KEY=your-anon-key
Get these values from your Supabase project settings.
-
Start the development server:
npm run dev
Open your browser and navigate to the URL shown in the terminal (typically
http://localhost:5173)
The frontend currently uses hardcoded API URLs pointing to a hosted backend. For local testing:
-
Update the API endpoints in these files to point to
http://localhost:8000/api: -
Endpoints to update:
/api/upload- Image upload and EXIF extraction/api/modify- Metadata modification and download/api/history/{user_id}- Retrieve edit history
mini-saas-mvp/
├── Backend/
│ ├── main.py # FastAPI application entrypoint
│ ├── init_db.py # Database initialization
│ ├── requirements.txt # Python dependencies
│ ├── api/
│ │ └── routes.py # API endpoints (upload, modify, history)
│ ├── core/
│ │ ├── exif_reader.py # EXIF data extraction logic
│ │ └── exif_modifier.py # EXIF data modification logic
│ └── db/
│ ├── connection.py # Database connection setup
│ └── models.py # SQLModel data models
└── Frontend/
├── package.json # Frontend dependencies
├── vite.config.js # Vite configuration
├── tailwind.config.js # Tailwind CSS config
├── src/
│ ├── App.jsx # Main app with routing
│ ├── App.css # Global styles
│ ├── main.jsx # Entry point
│ ├── pages/
│ │ ├── Auth.jsx # Authentication UI
│ │ └── Dashboard.jsx # Main dashboard with history
│ ├── components/
│ │ ├── ImageUploader.jsx # Image upload component
│ │ └── MetadataEditor.jsx # Metadata editing UI
│ └── lib/
│ └── supabase.js # Supabase client configuration
└── public/ # Static assets
The FastAPI server provides automatic interactive API documentation:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
POST /api/upload- Upload image and extract EXIF metadataPOST /api/modify- Modify image metadata and downloadDELETE /api/history/{record_id}- Remove a history recordGET /- Health check endpoint
- Sign up using Supabase Auth
- Upload an image via the dashboard
- View extracted metadata - GPS coordinates display on an interactive map
- Edit metadata - Modify GPS coordinates, timestamp, or description
- Download - Save the modified image with updated EXIF data
- Review history - Browse all past edits for audit purposes
- FastAPI - Modern async web framework
- SQLModel - SQL database ORM combining SQLAlchemy and Pydantic
- Pillow - Image processing
- piexif - EXIF data handling
- React 19 - UI framework
- Vite - Next-generation build tool
- Tailwind CSS - Utility-first CSS framework
- Lucide React - Icon library
- React Router - Client-side routing
- Supabase JS - Authentication and API client
Issue: Database connection fails
- Ensure PostgreSQL is running or set
DATABASE_URLcorrectly - The app falls back to SQLite if
DATABASE_URLis not set
Issue: Frontend can't reach backend
- Verify both servers are running (
localhost:8000for backend,localhost:5173for frontend) - Update hardcoded API URLs in frontend components as described above
- Check CORS settings in Backend/main.py
Issue: Supabase authentication not working
- Verify
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYare correctly set - Check Supabase project is active at supabase.com
For additional help, review the backend routes in Backend/api/routes.py and frontend components to understand the data flow.
Contributions are welcome! To get started:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes and commit:
git commit -m "Add feature description" - Push to your fork:
git push origin feature/your-feature-name - Open a Pull Request with a clear description of your changes
This project is open source and available under the MIT License.