RESTful API для управления новостями, пользователями и комментариями, построенное на FastAPI с системой авторизации через JWT и GitHub OAuth.
- Python 3.10+
- FastAPI
- SQLAlchemy 2.0
- PostgreSQL
- Alembic
- Pydantic
- JWT (python-jose)
- Argon2 (хеширование паролей)
- httpx (GitHub OAuth)
Убедитесь, что установлены:
- Python 3.10 или выше
- PostgreSQL
- pip
- git (опционально)
git clone <repository-url>
cd lab2_Ponomarenko_P_P# Windows
python -m venv venv
# Linux/Mac
python3 -m venv venvWindows PowerShell:
.\venv\Scripts\Activate.ps1Если появится ошибка "execution of scripts is disabled":
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserЗатем снова выполните .\venv\Scripts\Activate.ps1
Windows CMD:
venv\Scripts\activate.batLinux/Mac:
source venv/bin/activateПосле активации в начале строки терминала должно появиться (venv).
ВАЖНО: После активации проверьте, что используется правильный Python:
# Windows
where python
# Должен показать: C:\Users\...\lab2_Ponomarenko_P_P\venv\Scripts\python.exe
# Linux/Mac
which python
# Должен показать путь к venv/bin/pythonЕсли показывает системный Python, значит активация не сработала. Используйте полный путь:
.\venv\Scripts\python.exe -m uvicorn app.main:app --reloadВАЖНО: Убедитесь, что виртуальное окружение активировано (в начале строки должно быть (venv)).
pip install -r requirements.txtЕсли видите ошибку "ModuleNotFoundError: No module named 'sqlalchemy'" или подобную:
-
Проверьте активацию виртуального окружения:
# Windows PowerShell venv\Scripts\Activate.ps1 # Windows CMD venv\Scripts\activate.bat # Linux/Mac source venv/bin/activate
-
Проверьте, что используете правильный Python:
# Должен показать путь к venv where python # Windows which python # Linux/Mac
-
Обновите pip перед установкой:
python -m pip install --upgrade pip
-
Установите зависимости заново:
pip install -r requirements.txt
-
Проверьте установку:
pip list | findstr sqlalchemy # Windows pip list | grep sqlalchemy # Linux/Mac
Должна быть видна строка с
sqlalchemy 2.0.23.
- Запустите PostgreSQL сервер
- Создайте базу данных:
CREATE DATABASE news_db;- Проверьте подключение (опционально):
psql -U postgres -d news_dbСоздайте файл .env в корне проекта со следующим содержимым:
# Database
POSTGRES_SERVER=localhost
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=news_db
# JWT Settings
JWT_SECRET_KEY=your-secret-key-change-in-production-min-32-chars
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=30
# GitHub OAuth (для локального тестирования можно использовать моковые значения)
GITHUB_CLIENT_ID=mock_client_id
GITHUB_CLIENT_SECRET=mock_client_secret
GITHUB_REDIRECT_URI=http://localhost:8000/api/v1/auth/github/callbackВажно:
- Замените
POSTGRES_PASSWORDна ваш реальный пароль PostgreSQL - Замените
JWT_SECRET_KEYна случайную строку минимум 32 символа - Для реального использования GitHub OAuth зарегистрируйте приложение на https://github.com/settings/developers
alembic upgrade headЭта команда создаст все необходимые таблицы:
users(с полями для авторизации)newscommentsrefresh_sessions
ВАЖНО: Убедитесь, что виртуальное окружение активировано! В начале строки должно быть (venv).
uvicorn app.main:app --reloadЕсли видите ошибку "ModuleNotFoundError", проверьте:
-
Виртуальное окружение активировано:
# Должно быть видно (venv) в начале строки # Если нет, активируйте: # Windows venv\Scripts\activate # Linux/Mac source venv/bin/activate
-
Используется правильный Python:
# Проверьте путь к Python where python # Windows which python # Linux/Mac # Должен быть путь к venv\Scripts\python.exe или venv/bin/python
-
Запустите через Python модуль (более надежный способ):
python -m uvicorn app.main:app --reload
Сервер запустится на http://localhost:8000
Для запуска в фоновом режиме (опционально):
# Windows PowerShell
Start-Process uvicorn -ArgumentList "app.main:app --reload"
# Linux/Mac
uvicorn app.main:app --reload &Откройте в браузере:
- Главная страница: http://localhost:8000/
- Документация Swagger: http://localhost:8000/docs
- Документация ReDoc: http://localhost:8000/redoc
- Health check: http://localhost:8000/health
Должен вернуться JSON с информацией о статусе API.
Команда:
curl -X POST "http://localhost:8000/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d "{\"name\": \"Иван Иванов\", \"email\": \"ivan@example.com\", \"password\": \"password123\"}"Ожидаемый результат:
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer"
}Сохраните access_token и refresh_token для следующих шагов!
Команда:
curl -X POST "http://localhost:8000/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\": \"ivan@example.com\", \"password\": \"password123\"}"Ожидаемый результат: Новые токены доступа.
Команда:
curl -X GET "http://localhost:8000/api/v1/users/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Замените YOUR_ACCESS_TOKEN на токен из шага 1.
Ожидаемый результат: Список пользователей в формате JSON.
Команда:
curl -X GET "http://localhost:8000/api/v1/users/"Ожидаемый результат:
{
"detail": "Not authenticated"
}Шаг 5.1: Сначала нужно сделать пользователя верифицированным автором через админ-панель или напрямую в БД:
UPDATE users SET is_verified_author = true WHERE email = 'ivan@example.com';Шаг 5.2: Создание новости:
curl -X POST "http://localhost:8000/api/v1/news/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "title=Тестовая новость" \
-d "content={\"paragraphs\": [\"Первый абзац\", \"Второй абзац\"]}" \
-d "cover_url=https://example.com/image.jpg"Ожидаемый результат: Созданная новость с ID.
Шаг 6.1: Создайте нового пользователя (не верифицированного):
curl -X POST "http://localhost:8000/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d "{\"name\": \"Обычный пользователь\", \"email\": \"user@example.com\", \"password\": \"password123\"}"Шаг 6.2: Попытка создать новость:
curl -X POST "http://localhost:8000/api/v1/news/" \
-H "Authorization: Bearer NEW_USER_ACCESS_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "title=Новость" \
-d "content={\"paragraphs\": [\"Текст\"]}"Ожидаемый результат:
{
"detail": "Only verified authors can perform this action"
}Команда:
curl -X GET "http://localhost:8000/api/v1/news/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Ожидаемый результат: Список всех новостей.
Команда:
curl -X POST "http://localhost:8000/api/v1/comments/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "text=Отличная новость!" \
-d "news_id=1"Замените news_id=1 на ID новости из шага 5.
Ожидаемый результат: Созданный комментарий.
Команда:
curl -X PUT "http://localhost:8000/api/v1/news/1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "title=Обновленный заголовок"Ожидаемый результат: Обновленная новость.
Команда:
curl -X PUT "http://localhost:8000/api/v1/news/1" \
-H "Authorization: Bearer NEW_USER_ACCESS_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "title=Попытка изменить"Ожидаемый результат:
{
"detail": "You can only edit your own news"
}Команда:
curl -X POST "http://localhost:8000/api/v1/auth/refresh" \
-H "Content-Type: application/json" \
-d "{\"refresh_token\": \"YOUR_REFRESH_TOKEN\"}"Ожидаемый результат: Новые access_token и refresh_token.
Команда:
curl -X GET "http://localhost:8000/api/v1/auth/me/sessions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Ожидаемый результат: Список активных сессий с информацией о User-Agent.
Команда:
curl -X POST "http://localhost:8000/api/v1/auth/logout" \
-H "Content-Type: application/json" \
-d "{\"refresh_token\": \"YOUR_REFRESH_TOKEN\"}"Ожидаемый результат: 204 No Content
Шаг 14.1: Откройте в браузере:
http://localhost:8000/api/v1/auth/github/login
Шаг 14.2: После авторизации через GitHub вы будете перенаправлены на callback URL с токенами.
Примечание: Для работы GitHub OAuth нужно зарегистрировать приложение на GitHub и указать реальные GITHUB_CLIENT_ID и GITHUB_CLIENT_SECRET в .env.
- Откройте http://localhost:8000/docs
- Нажмите кнопку "Authorize" в правом верхнем углу
- Введите токен в формате:
Bearer YOUR_ACCESS_TOKEN - Теперь можно тестировать все endpoints через интерфейс Swagger
-
Создайте новую коллекцию "News API"
-
Добавьте переменную коллекции:
base_url:http://localhost:8000/api/v1access_token: (будет заполнено после регистрации/входа)refresh_token: (будет заполнено после регистрации/входа)
-
Настройте авторизацию для коллекции:
- Type: Bearer Token
- Token:
{{access_token}}
-
Создайте запросы:
- Register (POST
/auth/register) - Login (POST
/auth/login) - Get Users (GET
/users/) - Create News (POST
/news/) - Get News (GET
/news/) - Create Comment (POST
/comments/) - Refresh Token (POST
/auth/refresh) - Logout (POST
/auth/logout)
- Register (POST
Решение:
- Проверьте, что PostgreSQL запущен
- Проверьте правильность данных в
.env - Убедитесь, что база данных
news_dbсоздана
Причины:
- Виртуальное окружение не активировано при запуске сервера
- Используется системный Python вместо venv
- Зависимости установлены в другое окружение
Решение пошагово:
-
Проверьте, что пакеты установлены:
pip list
Должны быть видны:
SQLAlchemy,fastapi,uvicornи другие.Если пакеты есть в списке, но ошибка все равно возникает, значит проблема в активации окружения.
-
Убедитесь, что виртуальное окружение активировано:
# Windows PowerShell .\venv\Scripts\Activate.ps1 # Если ошибка "execution of scripts is disabled", выполните: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser # Windows CMD venv\Scripts\activate.bat # Linux/Mac source venv/bin/activate
После активации в начале строки должно появиться
(venv). -
Проверьте, что используете Python из venv:
# Windows where python # Должен показать путь типа: C:\Users\...\lab2_Ponomarenko_P_P\venv\Scripts\python.exe # Linux/Mac which python # Должен показать путь типа: /path/to/lab2_Ponomarenko_P_P/venv/bin/python
-
Запускайте сервер через Python модуль (рекомендуется):
# Вместо просто: uvicorn app.main:app --reload # Используйте: python -m uvicorn app.main:app --reload
Это гарантирует использование правильного интерпретатора Python.
-
Если пакеты не установлены, установите их:
# Обновите pip python -m pip install --upgrade pip # Установите зависимости pip install -r requirements.txt
-
Проверка установки (обратите внимание на регистр):
# Windows - ищите с учетом регистра pip list | findstr /i sqlalchemy # Или просто посмотрите весь список pip list
Должна быть строка
SQLAlchemy 2.0.23(с заглавными буквами). -
Если проблема сохраняется, пересоздайте виртуальное окружение:
# Удалите старое окружение # Windows rmdir /s venv # Linux/Mac rm -rf venv # Создайте новое python -m venv venv # Активируйте # Windows venv\Scripts\activate # Linux/Mac source venv/bin/activate # Установите зависимости pip install -r requirements.txt # Запустите сервер python -m uvicorn app.main:app --reload
Решение:
# Откатить все миграции
alembic downgrade base
# Применить заново
alembic upgrade headРешение:
- Проверьте, что токен передается в заголовке
Authorization: Bearer TOKEN - Убедитесь, что токен не истек (access token живет 30 минут)
- Обновите токен через
/auth/refresh
Решение:
- Пользователь должен иметь
is_verified_author = true - Установите через SQL:
UPDATE users SET is_verified_author = true WHERE email = 'user@example.com';
Решение:
# Использовать другой порт
uvicorn app.main:app --reload --port 8001lab2_Ponomarenko_P_P/
├── alembic/ # Миграции базы данных
│ ├── versions/
│ └── env.py
├── app/
│ ├── api/
│ │ └── v1/
│ │ ├── endpoints/ # Endpoints API
│ │ │ ├── auth.py # Авторизация
│ │ │ ├── users.py
│ │ │ ├── news.py
│ │ │ └── comments.py
│ │ └── api.py
│ ├── core/
│ │ ├── config.py # Настройки
│ │ ├── database.py # Подключение к БД
│ │ ├── dependencies.py # Зависимости для авторизации
│ │ └── security.py # JWT и хеширование
│ ├── models/ # SQLAlchemy модели
│ │ ├── user.py
│ │ ├── news.py
│ │ ├── comment.py
│ │ └── refresh_session.py
│ └── main.py # Точка входа
├── docs/
│ └── auth.md # Документация по авторизации
├── .env # Переменные окружения (создать)
├── requirements.txt # Зависимости
└── README.md # Этот файл
- Документация по авторизации и ролевой модели
- Swagger UI - интерактивная документация API
- ReDoc - альтернативная документация
Этот проект создан в учебных целях.