- 💡 About
- 🎬 Demo Video
- 💻 Tech Stack
- 📐 Architecture & Data Model
- 🚀 Getting Started
- 💾 Database Setup
- ☁️ Cloudinary Setup
- 🧪 Linting & Formatting
- 🛠️ Standalone Executable
- 🤝 Contributing
- 📄 License
PhotoShow is a local desktop application for browsing, organizing, and sharing photo collections. Sign in for a personalized, role-based experience.
✨ Key Features
- 📁 Create and manage albums
- 📸 Upload and view photos
- 🔍 Browse community content
- ❤️ Like and rate photos
- 💬 Comment on photos
- ⭐ Add albums to favorites
- 👥 Follow other users
- 🔔 Receive in-app notifications
- 🚩 Report inappropriate content
- 👨💼 Admin tools for user management
- 📋 Admin tools for category management
- ✅ Admin review system for reports
A demo video for PhotoShow will be added soon.
Core Technologies
- Python 3.14+ - Main programming language.
- Tkinter - GUI framework.
- Pillow - Image processing library.
- pip - Package manager.
Data & Security
- SQLite - Embedded relational database.
- SQLAlchemy - ORM and database toolkit.
- bcrypt - Password hashing.
Cloud Storage
- Cloudinary - Image hosting and management.
- python-cloudinary - Cloudinary SDK.
Code Quality & Linting
- Black - Code formatter.
- flake8 - Code linter.
- isort - Import sorter.
- yamllint - YAML linter.
- mypy - Static type checker.
Testing
- pytest - Testing framework.
- pytest-mock - Mocking in tests.
- pytest-cov - Coverage reporting.
Packaging
- PyInstaller - Build standalone executables.
⚠️ The preview below may be slightly outdated and will be refreshed in a later update.
⚠️ The preview below may be slightly outdated and will be refreshed in a later update.
The database model is shown as a DER (Diagram Entity-Relationship) preview so the main entities and relationships stay readable at a glance.
ORM models live in app/core/db/models/ and are implemented with SQLAlchemy. You can check also in app\core\db\models\__init__.py for a quick overview of all the main entities and their relationships.
- Python 3.14+ — Main programming language (download)
- pip — comes with Python
- Git — for cloning (download)
- (Recommended) Virtual environment support:
python -m venv - DB Browser for SQLite — For viewing and debugging the local database (download)
Verify your tools are available in the PATH:
python --version pip --version git --version
-
Clone the repository:
git clone https://github.com/pedromst2000/PhotoShow.git
-
Navigate to the project directory:
cd PhotoShow -
Create and activate a virtual environment:
Create:
python -m venv .venv
Activate on Windows PowerShell:
.venv\Scripts\Activate
Activate on macOS/Linux:
source .venv/bin/activateTo deactivate:
deactivate -
Install dependencies:
python -m pip install --upgrade pip pip install --upgrade -r dev-requirements.txt
-
Set up environment variables:
cp .env.example .env
Then edit
.envwith your Cloudinary credentials (see Cloudinary Setup below). -
Run the app:
python main.py
PhotoShow uses SQLite for local data storage. The database file (photoshow.db) is created automatically at the project root on first run.
| Command | Description |
|---|---|
python main.py --backupDB |
Backup the database to backups/<timestamp>/ |
python main.py --resetDB |
Reset to initial seed data (auto-backups first) |
python main.py --restoreDB |
Restore from latest backup |
python main.py --restoreDB backups/<folder> |
Restore from specific backup |
When to use:
--backupDB— Before making risky changes--resetDB— Return to initial state for testing--restoreDB— Recover from a previous backup
For detailed instructions on viewing the database in both development and distribution modes, see Database Location in the Standalone Executable section.
⚠️ Backups: Thebackups/folder may contain sensitive data. Keep it local and out of version control (listed in.gitignore).
PhotoShow uses Cloudinary to store photos and avatars. Each developer creates their own free Cloudinary account.
- Sign up for a free account at cloudinary.com
- From your Dashboard, copy these credentials:
- Cloud Name
- API Key
- API Secret
-
If you haven't already, copy
.env.exampleto.env(see Quick Start — Step 5):cp .env.example .env
-
Edit
.envwith your Cloudinary credentials from the dashboard
⚠️ Never commit.envto git. It's in.gitignorefor security.
In your Cloudinary Media Library, create this folder structure:
photo-show/
├── dev/ # Seed data (reference images)
│ ├── profile_avatars/
│ └── photos_gallery/
└── prod/ # Your uploads
├── profile_avatars/
└── photos_gallery/
GUI Path: Media Library → Folders → Home → Create photo-show folder
To add reference images to your dev/ folders:
- Open avatars.csv or photo_image.csv
- For each image URL in the
provider_url_imagecolumn:- Click the URL link to open it in your browser
- Right-click → Save image locally
- Upload to your Cloudinary
photo-show/dev/profile_avatars/orphoto-show/dev/photos_gallery/
💡 Tip: The
dev/folder preserves seed data during--resetDB. Theprod/folder stores your uploads and is cleared on reset.
| Problem | Fix |
|---|---|
ValueError: Must supply api_key |
Check .env has correct CLOUDINARY_* credentials |
| Images show broken links | Verify folders exist in Cloudinary Media Library with correct names |
Images disappear after --resetDB |
Expected — prod/ folder is cleared. Use --backupDB to save uploads first |
Run these checks locally before committing to keep the codebase consistent and avoid CI failures.
Auto-formats all Python files using Black:
python -m black app tests main.pyChecks Python files for style violations and errors (PEP 8 compliance):
python -m flake8 .Runs static type checks on app/ and main.py using mypy:
python -m mypy app main.pyChecks YAML configuration files for syntax and formatting issues:
python -m yamllint .Checks CSV seed data files for structural and formatting issues:
python app/scripts/lint_csv.pyExecutes the test suite:
python -m pytestYou can compile PhotoShow into a self-contained application folder using PyInstaller, which bundles everything needed to run it. However, please note:
⚠️ Warning: The generated executable is intended for use on your own machine. Running the executable on remote or other machines may trigger antivirus false positives or fail due to environment differences. Distribution is not recommended.
To compile locally, follow these steps:
-
Set up your environment and dependencies (see Getting Started above).
-
Activate your virtual environment (see Getting Started above).
-
Install PyInstaller in your virtual environment:
pip install pyinstaller
-
Compile the application (in your activated virtual environment):
⚠️ Before rebuilding: IfPhotoShow.exeis already running, close it first. Windows locks DLLs of running processes and PyInstaller will fail with aPermissionErrorif the exe is open.Using the updated spec file (recommended):
pyinstaller PhotoShow.spec --clean --noconfirm
Or, manual full compilation on Windows:
pyinstaller main.py --onedir --noconsole --icon "app/assets/PhotoShowIcon.ico" --add-data "app/assets;app/assets" --add-data "app/files;app/files" --distpath dist --workpath build --specpath . --name PhotoShow --clean --noconfirm
Or, on Linux/macOS:
pyinstaller main.py --onedir --noconsole --icon "app/assets/PhotoShowIcon.ico" --add-data "app/assets:app/assets" --add-data "app/files:app/files" --distpath dist --workpath build --specpath . --name PhotoShow --clean --noconfirm
⚠️ Antivirus false positives — IMPORTANT: PyInstaller bundles Python DLLs (e.g.ucrtbase.dll,python313.dll,msvcrt.dll) into the_internal/folder.To resolve:
- Add
dist/PhotoShow/folder and all its contents to your antivirus exclusion list - Or allow/verify the exe when your antivirus prompts you (click "Run anyway" or "Allow")
- If antivirus blocks DLL access:
PermissionError: [Errno 13] Permission denied: '..._internal\ucrtbase.dll'→ exclude the entiredist/PhotoShow/_internal/folder from real-time scanning
After building, a
dist/PhotoShowfolder is created. Open it and runPhotoShow.exe— no Python required. Keep the entire folder together (do not remove_internalor other support files). The executable is platform-specific; rebuild separately on Windows, macOS, or Linux.You can move the
dist/PhotoShowfolder to your desktop or another location and run the executable from there. Just keep the entire folder together. - Add
-
Copy your
.envfile into the executable folder:copy .env dist/PhotoShow/.env
PhotoShow reads
.envfrom its folder to access your Cloudinary credentials. -
Run
PhotoShow.exe:- Double-click
dist/PhotoShow/PhotoShow.exelike any desktop app - On first run: Creates
photoshow.dbin the same folder (dist/PhotoShow/photoshow.db) - All photo uploads go to your Cloudinary account (from
.env) - All data stored locally in
photoshow.db
- Double-click
⚠️ CRITICAL: The database location is DIFFERENT depending on how you run PhotoShow. Opening the wrong database file in SQLite Browser will make data changes appear out of sync!
The database location differs between development and distribution modes:
| Mode | Database Location | When to use |
|---|---|---|
| Development (source) | C:\Users\User\Desktop\PhotoShow\photoshow.db (root folder) |
Running python main.py from the repo |
| Distribution (exe) | C:\Users\User\Desktop\PhotoShow\dist\PhotoShow\photoshow.db (dist folder) |
Running dist/PhotoShow/PhotoShow.exe |
Always verify which photoshow.db you're opening in SQLite Browser:
- Dev mode → Open from project root
- Distribution mode → Open from dist/PhotoShow/ folder
- Open DB Browser for SQLite
- File → Open Database
- Select the correct database file based on your mode:
- Dev mode:
photoshow.dbat project root - Distribution mode:
dist/PhotoShow/photoshow.db
- Dev mode:
In development mode: You'll see real-time changes from the app running via python main.py.
In distribution mode: You'll see data from the packaged executable. If changes aren't appearing, verify you opened the correct file in dist/PhotoShow/ folder, not the project root.
⚠️ Do NOT mix them up — opening the wrong file makes it appear data isn't syncing.
Your contributions help improve PhotoShow! Whether you're fixing a bug, improving the UI, or adding a new feature — every contribution matters.
- Found a bug? Report it
- Have an enhancement idea? Suggest it
- Ready to code? Follow the workflow below
| Type | Purpose | Branch Example | Commit Example |
|---|---|---|---|
feat |
New feature | feat/photo-grid |
feat: add photo grid view |
fix |
Bug fix | fix/login-validation |
fix: resolve login error |
docs |
Documentation | docs/update-readme |
docs: update installation steps |
refactor |
Code restructuring | refactor/album-service |
refactor: simplify album logic |
test |
Testing | test/auth-tests |
test: add auth unit tests |
ci |
CI/CD pipelines | ci/add-lint-workflow |
ci: add lint workflow |
chore |
Maintenance | chore/update-deps |
chore: update dependencies |
- Fork the repository and clone your fork
- Create a branch:
git checkout -b <type>/<short-description>
- Make your changes
- Commit:
git commit -m "<type>: <short description>" - Push:
git push origin <type>/<short-description>
- Open a Pull Request
PR checklist:
- ✅ Branch name follows naming conventions ( See above )
- ✅ Description explains changes clearly
- ✅ Passes all CI checks. See GitHub Actions tab for details
- ✅ No merge conflicts
Thanks for contributing! 🎉
This project is licensed under the MIT License. See LICENSE for details.


