Skip to content

zuzuka28/mtuci_m1c2s_python_programming_lab_2

Repository files navigation

Flask Blog

Веб-приложение блога с REST API, черновиками, поиском, пагинацией и Swagger-документацией. Реализовано на Flask + SQLite + Bootstrap 5.


Быстрый старт

# 1. Создать и активировать виртуальное окружение
python -m venv venv
source venv/bin/activate      # Linux / macOS
# venv\Scripts\activate       # Windows

# 2. Установить зависимости
make install

# 3. Создать / мигрировать базу данных
make init-db

# 4. Запустить приложение
make run
# → http://127.0.0.1:5000

Структура проекта

.
├── main.py          # Flask-приложение: веб-маршруты, RSS, Sitemap, CSV, API Docs
├── api.py           # Blueprint REST API (/api/*)
├── database.py      # Общие хелперы БД (get_post, get_published_posts, …)
├── config.py        # Константы: SECRET_KEY, API_KEY, DATABASE, POSTS_PER_PAGE
├── init_db.py       # Скрипт создания / миграции БД
├── schema.sql       # Целевая схема таблицы posts
├── requirements.txt # Зависимости Python
├── Makefile         # Команды: install, init-db, run
└── templates/
    ├── base.html    # Базовый шаблон (Bootstrap 5, навбар)
    ├── index.html   # Главная: список постов, поиск, пагинация, сортировка
    ├── post.html    # Страница поста + модал подтверждения удаления
    ├── create.html  # Форма создания поста
    ├── edit.html    # Форма редактирования поста
    ├── drafts.html  # Черновики с кнопкой быстрой публикации
    ├── stats.html   # Статистика блога
    └── api_docs.html# Swagger UI

Схема базы данных

CREATE TABLE posts (
    id        INTEGER PRIMARY KEY AUTOINCREMENT,
    title     TEXT    NOT NULL,
    content   TEXT    NOT NULL,
    published INTEGER NOT NULL DEFAULT 1,   -- 1 = опубликован, 0 = черновик
    created   TEXT    NOT NULL DEFAULT (datetime('now'))
);

Веб-интерфейс

Маршрут Описание
GET / Список опубликованных постов, поиск, сортировка, пагинация
GET /<id> Страница поста с подсветкой кода
GET /create Форма создания поста
GET /<id>/edit Форма редактирования
POST /<id>/delete Удаление поста
GET /drafts Список черновиков
POST /<id>/publish Опубликовать черновик
GET /stats Статистика (всего / опубликовано / черновиков / даты)
GET /export/csv Скачать все посты в CSV
GET /rss RSS-лента последних 10 постов
GET /sitemap.xml Sitemap для поисковиков
GET /api/docs Swagger UI

Поиск и сортировка

На главной странице доступны параметры URL:

Параметр Значения Описание
q любая строка Поиск по заголовку и содержимому
sort created_desc / created_asc / title_asc / title_desc Порядок сортировки
page целое число Номер страницы

Пример: /?q=flask&sort=title_asc&page=2


REST API

Все эндпоинты требуют заголовок X-API-Key.

API-ключ по умолчанию (dev): changeme-secret-api-key

Эндпоинты

Метод Маршрут Описание Код ответа
GET /api/posts Список постов 200
GET /api/posts/<id> Получить пост 200 / 404
POST /api/posts Создать пост 201
PUT /api/posts/<id> Обновить пост 200 / 404
DELETE /api/posts/<id> Удалить пост 204 / 404

Параметры GET /api/posts

Параметр По умолчанию Описание
page 1 Номер страницы
per_page 10 (max 100) Постов на страницу
q Поиск по заголовку и содержимому
sort created_desc Сортировка: created_desc/asc, title_asc/desc
published 1 Фильтр: 1, 0, all

Формат ответа

{
  "posts": [
    {
      "id": 1,
      "title": "Hello World",
      "content": "My first post",
      "published": 1,
      "created": "2026-03-19 12:00:00"
    }
  ],
  "page": 1,
  "per_page": 10,
  "total": 42,
  "total_pages": 5
}

Примеры запросов

API_KEY="changeme-secret-api-key"
BASE="http://localhost:5000/api"

# Список постов
curl "$BASE/posts" -H "X-API-Key: $API_KEY"

# Поиск с сортировкой и пагинацией
curl "$BASE/posts?q=flask&sort=created_desc&page=1&per_page=5" \
     -H "X-API-Key: $API_KEY"

# Только черновики
curl "$BASE/posts?published=0" -H "X-API-Key: $API_KEY"

# Создать пост
curl -X POST "$BASE/posts" \
     -H "X-API-Key: $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"title": "My post", "content": "Body text", "published": 1}'

# Обновить пост
curl -X PUT "$BASE/posts/1" \
     -H "X-API-Key: $API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"title": "Updated title", "published": 0}'

# Удалить пост
curl -X DELETE "$BASE/posts/1" -H "X-API-Key: $API_KEY"

# Без ключа → 401 Unauthorized
curl "$BASE/posts"

HTTP-коды ответов

Код Значение
200 OK
201 Created (POST)
204 No Content (DELETE)
400 Bad Request (не передан title)
401 Unauthorized (неверный / отсутствует X-API-Key)
404 Not Found
429 Too Many Requests (rate limit)

Rate Limiting

Операция Лимит
GET /api/posts, GET /api/posts/<id> 60 запросов / час (глобальный)
POST /api/posts 10 запросов / минуту
PUT /api/posts/<id> 10 запросов / минуту
DELETE /api/posts/<id> 10 запросов / минуту

При превышении лимита возвращается 429 Too Many Requests с заголовком Retry-After.


Конфигурация

Все настройки в config.py:

Переменная Значение по умолчанию Описание
SECRET_KEY "your secret key" Ключ для Flask-сессий и flash-сообщений
API_KEY "changeme-secret-api-key" Ключ для REST API
DATABASE "database.db" Путь к SQLite-файлу
POSTS_PER_PAGE 5 Постов на странице на главной

Зависимости

Пакет Версия Назначение
Flask >=2.3,<3.0 Веб-фреймворк
flask-limiter >=3.5 Rate limiting
Werkzeug >=2.3 HTTP-утилиты

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors