PhotoShare API — production-ready REST API для обміну та керування фотографіями. Користувачі можуть завантажувати зображення в Cloudinary, додавати теги, оцінювати та коментувати фото, застосовувати трансформації з QR-кодами та виконувати розширений пошук із фільтрами.
Проєкт побудований на FastAPI, SQLAlchemy 2.0 (async), PostgreSQL, JWT-автентифікації та Docker. Основним deliverable є REST API; Swagger UI дозволяє повністю перевірити функціонал без frontend.
| Можливість | Опис |
|---|---|
| ✅ JWT Authentication | Реєстрація, вхід, вихід із чорним списком токенів |
| ✅ User Roles (User / Moderator / Admin) | Рольова модель доступу; перший користувач стає адміністратором |
| ✅ Registration / Login / Logout | Повний цикл автентифікації через JWT |
| ✅ User Profiles | Приватний профіль /me та публічні профілі з кількістю фото |
| ✅ Ban / Unban | Адміністратор може блокувати та розблоковувати користувачів |
| ✅ Photo Upload | Завантаження зображень (multipart) з валідацією типу файлу |
| ✅ CRUD Photos | Створення, читання, оновлення та видалення фотографій |
| ✅ Cloudinary Integration | Зберігання медіа, трансформації та QR-коди в хмарі |
| ✅ Image Transformations | Зміна розміру, кадрування, ефекти (grayscale, sepia тощо) |
| ✅ QR Code generation | Генерація QR-посилань на трансформовані зображення |
| ✅ Comments | Коментарі до фото; редагування — лише власником |
| ✅ Ratings | Оцінки від 1 до 5 зірок; одна оцінка на користувача на фото |
| ✅ Search & Filtering | Пошук за ключовим словом, тегом, мінімальним рейтингом, діапазоном дат (date_from / date_to), сортування |
| ✅ PostgreSQL | Реляційна база даних PostgreSQL 16 |
| ✅ SQLAlchemy 2.0 | Асинхронний ORM із сучасним API |
| ✅ Alembic | Версіонування та застосування міграцій схеми БД |
| ✅ Docker | Контейнеризація API-сервісу |
| ✅ Docker Compose | Оркестрація API, PostgreSQL та опційного frontend |
| ✅ Swagger | Інтерактивна OpenAPI-документація |
| ✅ Unit & Integration Tests | 187 тестів, покриття коду 93.5% |
Додаткові деталі:
user_id — лише для модератора та адміністратора| Категорія | Технологія | Призначення |
|---|---|---|
| Мова | Python 3.13+ | Backend runtime |
| Framework | FastAPI | REST API, валідація, OpenAPI |
| База даних | PostgreSQL 16 | Зберігання даних |
| ORM | SQLAlchemy 2.0 | Асинхронна робота з БД |
| Міграції | Alembic | Версіонування схеми БД |
| Валідація | Pydantic v2 | DTO та схеми запитів/відповідей |
| Контейнеризація | Docker | Ізоляція середовища |
| Оркестрація | Docker Compose | Запуск повного стеку |
| Автентифікація | JWT (python-jose + bcrypt/passlib) | Токени доступу |
| Медіа | Cloudinary | Зберігання та трансформація зображень |
| QR-коди | qrcode, Pillow | Генерація QR-зображень |
| Тестування | Pytest, pytest-cov | Unit та integration тести |
| Frontend (опційно) | React, Vite, TypeScript | Візуальна демонстрація |
| Стилізація frontend | Tailwind CSS | UI компоненти |
photoshare-api/
├── app/
│ ├── main.py # Точка входу FastAPI
│ ├── config.py # Налаштування з .env
│ ├── database.py # Підключення до БД (async)
│ ├── dependencies.py # DI: auth, DB session
│ ├── api/ # HTTP-роути (auth, users, photos, …)
│ ├── core/ # Безпека (JWT), permissions
│ ├── models/ # SQLAlchemy ORM-моделі
│ ├── schemas/ # Pydantic DTO
│ ├── repository/ # Шар доступу до даних
│ ├── services/ # Бізнес-логіка (auth, cloudinary, qr)
│ └── utils/ # Допоміжні функції
├── alembic/ # Міграції Alembic
│ └── versions/
├── tests/ # Unit та integration тести
│ ├── conftest.py # Фікстури pytest (ізоляція БД)
│ ├── helpers.py # Спільні хелпери для тестів
│ └── test_*.py # Тестові модулі
├── frontend/ # Опційний React frontend (Vite + TS)
│ ├── src/
│ │ ├── api/ # HTTP-клієнт до API
│ │ ├── components/ # UI-компоненти
│ │ ├── context/ # AuthContext
│ │ └── pages/ # Сторінки (Gallery, Upload, Admin, …)
│ └── Dockerfile
├── scripts/
│ └── docker-entrypoint.sh # Міграції + запуск API в Docker
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── pytest.ini
├── alembic.ini
├── .coveragerc
├── LICENSE
├── .env.example
└── README.md
Архітектура шарів:
API (routers) → Services → Repository → Models (ORM)
↓
Schemas (Pydantic)
git clone https://github.com/DmytroHryhorashenko/photoshare-api.git
cd photoshare-api
cp .env.example .env
Відредагуйте .env: встановіть SECRET_KEY та облікові дані Cloudinary (див. розділ 🔑 Змінні середовища).
docker compose up -d --build
Примітка: поточний
docker-compose.ymlналаштований для локальної розробки (--reload, bind-mount.:/app). Для production використовуйте окремий compose-файл або платформу розгортання (Koyeb, Fly.io) без bind-mount і hot-reload.
Міграції Alembic виконуються автоматично при старті контейнера через scripts/docker-entrypoint.sh.
| Сервіс | URL |
|---|---|
| API | http://localhost:8000 |
| Swagger UI | http://localhost:8000/docs |
| ReDoc | http://localhost:8000/redoc |
| Frontend (опційно) | http://localhost:5173 |
| PostgreSQL | localhost:5432 |
Зупинка стеку:
docker compose down
Повне видалення томів (очищення БД):
docker compose down -v
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
Застосуйте міграції та запустіть сервер:
alembic upgrade head
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Перевірка health check:
curl http://localhost:8000/
curl http://localhost:8000/health
Скопіюйте .env.example у .env і налаштуйте значення перед запуском.
| Змінна | Обов’язкова | Опис |
|---|---|---|
APP_ENV |
Ні | Середовище: development або production (за замовчуванням: development) |
DEBUG |
Ні | Режим відладки та SQL echo (за замовчуванням: false) |
DATABASE_URL |
Так | Async URL PostgreSQL: postgresql+asyncpg://user:pass@host:5432/db |
SECRET_KEY |
Так | Секретний ключ для підпису JWT (мінімум 32 випадкових символів) |
ALGORITHM |
Ні | Алгоритм JWT (за замовчуванням: HS256) |
ACCESS_TOKEN_EXPIRE_MINUTES |
Ні | Час життя токена в хвилинах (за замовчуванням: 30) |
CLOUDINARY_NAME |
Так* | Cloud name вашого Cloudinary-акаунту |
CLOUDINARY_API_KEY |
Так* | API Key Cloudinary |
CLOUDINARY_API_SECRET |
Так* | API Secret Cloudinary |
* Обов’язкові для завантаження фото, трансформацій зображень та генерації QR-кодів.
Приклад DATABASE_URL для локальної розробки:
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/photoshare
У Docker Compose змінна DATABASE_URL перевизначається автоматично для підключення до сервісу db:
DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/photoshare
Безпека: ніколи не комітьте
.envу Git. У production використовуйте сильнийSECRET_KEYта змінні середовища платформи розгортання.
docker compose up -d --build
docker compose ps
docker compose logs -f api
alembic upgrade head
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
cd frontend
npm install
npm run dev
За потреби вкажіть URL API у frontend/.env:
VITE_API_URL=http://localhost:8000/api/v1
# Перезапуск API
docker compose restart api
# Виконання команди всередині контейнера API
docker compose exec api bash
# Перегляд логів
docker compose logs api
| Команда | Опис |
|---|---|
alembic revision --autogenerate -m "description" |
Створити міграцію на основі змін моделей |
alembic upgrade head |
Застосувати всі очікувані міграції |
alembic downgrade -1 |
Відкотити останню міграцію |
alembic history |
Переглянути історію міграцій |
alembic current |
Поточна ревізія БД |
У Docker:
docker compose exec api alembic upgrade head
docker compose exec api alembic current
docker compose exec api alembic history
При старті через Docker міграції виконуються автоматично в
scripts/docker-entrypoint.sh.
Проєкт містить 187 unit та integration тести з ізольованою тестовою БД (очищення таблиць перед кожним тестом). Cloudinary та QR-сервіси мокуються — реальні зовнішні виклики не виконуються.
# Усі тести (verbose)
pytest -v
# З покриттям коду
pytest --cov=app --cov-report=term-missing
# HTML-звіт покриття
pytest --cov=app --cov-report=html
docker compose exec api pytest -v
docker compose exec api pytest --cov=app --cov-report=term-missing -v
| Показник | Значення |
|---|---|
| ✅ Тестів пройдено | 187 |
| ✅ Покриття коду | 93.5% |
| ✅ Пропущених тестів | 0 |
Інтерактивна документація OpenAPI — основний інструмент перевірки для ментора та розробника. Через Swagger можна повністю верифікувати REST API без frontend.
| Ресурс | URL |
|---|---|
| Swagger UI | http://localhost:8000/docs |
| ReDoc | http://localhost:8000/redoc |
| OpenAPI JSON | http://localhost:8000/openapi.json |
| Health check | http://localhost:8000/health |
| Root | http://localhost:8000/ |
Як авторизуватися в Swagger:
POST /api/v1/auth/login — отримайте access_tokenBearer <your_access_token>Базовий URL API: http://localhost:8000/api/v1
/auth)| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| POST | /auth/register |
Public | Реєстрація нового користувача |
| POST | /auth/login |
Public | Вхід, повертає JWT |
| POST | /auth/logout |
Authenticated | Додати токен до чорного списку |
/users)| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| GET | /users/me |
Authenticated | Профіль поточного користувача |
| PUT | /users/me |
Authenticated | Оновлення username, email, password |
| GET | /users/{username} |
Public | Публічний профіль + кількість фото |
| PATCH | /users/{id}/ban |
Admin | Заблокувати користувача |
| PATCH | /users/{id}/unban |
Admin | Розблокувати користувача |
| PATCH | /users/{id}/role |
Admin | Змінити роль користувача |
/photos)| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| POST | /photos |
Authenticated | Завантаження фото (multipart) |
| GET | /photos/search |
Public | Пошук та фільтрація |
| GET | /photos/{id} |
Public | Деталі фото |
| PUT | /photos/{id} |
Owner/Admin | Оновлення опису та тегів |
| DELETE | /photos/{id} |
Owner/Admin | Видалення фото |
| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| POST | /photos/{id}/comments |
Authenticated | Додати коментар |
| GET | /photos/{id}/comments |
Public | Список коментарів |
| PUT | /comments/{id} |
Owner | Редагувати власний коментар |
| DELETE | /comments/{id} |
Moderator/Admin | Видалити коментар |
| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| POST | /photos/{id}/ratings |
Authenticated | Оцінити фото (1–5) |
| GET | /photos/{id}/ratings |
Public | Середній рейтинг |
| DELETE | /ratings/{id} |
Moderator/Admin | Видалити оцінку |
| Method | Endpoint | Доступ | Опис |
|---|---|---|---|
| POST | /photos/{id}/transform |
Owner/Admin | Трансформація + QR-код |
| GET | /photos/{id}/transforms |
Public | Список трансформацій |
| GET | /transforms/{id} |
Public | Отримати трансформацію |
| Method | Endpoint | Опис |
|---|---|---|
| GET | / |
Статус кореневого маршруту |
| GET | /health |
Liveness check |
Важливо: основним deliverable проєкту є REST API. Frontend включено лише як опційну візуальну демонстрацію і не замінює перевірку через Swagger.
| Сервіс | URL |
|---|---|
| API | http://localhost:8000 |
| Frontend | http://localhost:5173 |
| Сторінка | URL |
|---|---|
| Landing | http://localhost:5173 |
| Gallery | http://localhost:5173/gallery |
| Upload | http://localhost:5173/upload |
| Photo Detail | http://localhost:5173/photos/:id |
| Profile | http://localhost:5173/profile/:username |
| Admin | http://localhost:5173/admin |
| Login / Register | http://localhost:5173/login, /register |
Посилання на API Docs у frontend відкриває http://localhost:8000/docs.
docker compose up -d --build
docker compose ps
Додайте знімки екрана у папку
docs/screenshots/та оновіть шляхи нижче.






POST /auth/register)POST /auth/login)POST /auth/logout)/users/medate_from / date_to)user_id — Moderator/Admin| Показник | Значення |
|---|---|
| Tests passed | 187 |
| Coverage | 93.5% |
| Docker | ✅ |
| Docker Compose | ✅ |
| Swagger / OpenAPI | ✅ |
| PostgreSQL | ✅ |
| Alembic | ✅ |
| Cloudinary | ✅ |
| JWT Auth | ✅ |
| Role-based Access | ✅ |
| Frontend | ✅ Optional |
.env.example.Команда запуску (якщо не використовується CMD Dockerfile):
alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8000
8000 та задеплойте.fly launch
fly postgres create
fly secrets set SECRET_KEY=... CLOUDINARY_NAME=... CLOUDINARY_API_KEY=... CLOUDINARY_API_SECRET=...
fly secrets set DATABASE_URL=postgresql+asyncpg://...
fly deploy
Міграції після деплою:
fly ssh console -C "alembic upgrade head"
APP_ENV=production та DEBUG=falseSECRET_KEY (32+ випадкових символів)app/main.py для productionПроєкт розповсюджується під ліцензією MIT.
Розроблено як FastAPI REST API проєкт у рамках дипломної / навчальної роботи.
Побудовано з використанням сучасної Python backend-архітектури та найкращих практик розробки: шарове розділення відповідальності, асинхронна робота з БД, JWT-автентифікація, контейнеризація, автоматизоване тестування та повна OpenAPI-документація.
Репозиторій: github.com/DmytroHryhorashenko/photoshare-api