run.py - файл запуска программы
- Python
- SQLAlchemy
- marshmallow
- Flask
- JWT
Нажмите на пункт, чтобы раскрыть его.
-
Аутентификация
Для того чтобы у каждого пользователя была возможность добавлять понравившиеся фильмы в закладки для просмотра позже, нам нужно их как-то разграничивать, поэтому мы организуем страницы с регистрацией и аутентификацией на основе уже изученной спецификации JWT.
-
Пользователи
У каждого пользователя будет страница с его профилем, где он сможет выбрать любимый жанр, указать имя и фамилию, а также в случае необходимости сменить пароль.
Еще для пользователя нужно реализовать механизм добавления и удаления фильмов в/из закладок, а также просмотр всех сохраненных в закладки фильмов.
-
Фильмы, режиссеры, жанры
Конечно же, нужно добавить самые главные сущности — фильмы, режиссеры и жанры. Для них сделаем лишь возможность чтения (get-запросы).
Для всех объектов будет работать пагинация, чтобы мы могли постранично выводить их на экран, а также можно будет посмотреть самые новые фильмы.
pip install -r requirements.txt
pip install -r requirements.dev.txt
- Создание моделей (очистит БД и создаст все модели, указанные в импорте)
python create_tables.py
- Загрузка данных в базу
python load_fixture.py
Скрпит читает файл fixtures.json и загружает данные в базу. Если данные уже загружены - выводит соответсвующее сообщение.
export FLASK_APP=run.py
export FLASK_ENV='development'
flask run
set FLASK_APP=run.py
set FLASK_ENV=development
flask run
$env:FLASK_APP = "run"
$env:FLASK_ENV = "development"
flask run
pytest .
Для работы предоставлены исходники, которые помогут начать проект:
GitHub - skypro-008/course_project_3_source
Также для данной работы был разработан frontend стенд, который вы можете развернуть у себя на локальной машине.
GitHub - skypro-008/skypro_py_stand
Инструкции по запуску находятся в описании к каждому проекту.
Необходимы следующие таблицы:
- Жанры (создана)
- Режиссеры
- Фильмы
- Пользователи
Модель режиссеров имеет те же поля, что и модель с жанрами (заметьте, поле name является уникальным).
Модель с фильмами имеет следующие поля:
- id - первичный ключ
- title- название
- description - описание
- trailer - ссылка на трейлер
- year - год выпуска
- rating - рейтинг
- genre_id - id жанра
- director_id - id режиссера
Модель пользователя имеет следующие поля:
- id - первичный ключ
- email - по нему будет осуществлен доступ на сайт (уникальное)
- password — не забывайте, что пароль тут будет в хешированном виде
- name - имя
- surname - фамилия
- favorite_genre - любимый жанр
Поля, выделенные жирным являются обязательными к заполнению
Вы можете взять исходные модели, вью и все остальное из одного из стартовых репозиториев или взять свою структуру проекта из прошлых уроков.
https://github.com/skypro-008/lesson19_project_hard_source
https://github.com/skypro-008/lesson19_project_easy_source
Обратите внимание, что id = db.Column(Integer(), primary_key=True)
и id = Column(Integer(), primary_key=True)
не имеют разницы.
>>> from flask_sqlalchemy import SQLAlchemy
>>> db = SQLAlchemy()
>>> from sqlalchemy import Column
>>> db.Column is Column
True
Почитать про это можно здесь -
flask-sqlalchemy/init.py at 5ac5ab47db1f0acaaf8e9f94258a6d599a04bb38 · pallets-eco/flask-sqlalchemy
Теперь нужно проверить, что все импортированные модели создаются корректно, и сделать коммит.
На данном шаге мы реализуем следующие эндпоинты:
- GET /movies/
- GET /movies/{id}
- GET /genres/
- GET /genres/{id}
- GET /directors/
- GET /directors/{id}
Для тех эндпоинтов, которые возвращают несколько записей, нужно организовать пагинацию через URL-параметр page, а на страницу будет возвращать по 12 записей. Параметр page - необязательный, а значит, если он не указан - нужно вернуть все записи.
Так как мы хотим получать Новинки, для эндпонта GET /movies/ нужно еще добавить необязательный параметр status. Если он присутствует и имеет значение new — возвращаем записи в отсортированном виде (самые свежие), иначе возвращаем в том порядке, в котором они лежат в базе. Запрос может выглядеть так:
- /movies/?status=new&page=1
- /movies/?page=2
- /movies/
Для реализации авторизации мы напишем следующие три эндпоинта:
-
POST /auth/register — передавая email и пароль, создаем пользователя в системе.
-
POST /auth/login — передаем email и пароль и, если пользователь прошел аутентификацию, возвращаем пользователю ответ в виде:
{ "access_token": "qwesfsdfa", "refresh_token": "kjhgfgjakda", }
-
PUT /auth/login — принимаем пару токенов и, если они валидны, создаем пару новых.
На данном этапе нужно обязательно проверить работу механизма аутентификации через Postman (или используйте любой другой инструмент)
Теперь сделаем коммит и приступим к последнему шагу.
Реализуем следующие эндпоинты:
- GET /user/ — получить информацию о пользователе (его профиль).
- PATCH /user/ — изменить информацию пользователя (имя, фамилия, любимый жанр).
- PUT /user/password — обновить пароль пользователя, для этого нужно отправить два пароля password_1 и password_2.
Для того чтобы все ссылки корректно работали, их нужно обернуть в декоратор, в котором мы будет проверять переданный токен.
Добавьте возможность добавлять фильмы в избранное
На прошлом шаге мы создавали пользователя, ему нужно добавить поле favorite_genre и сделать ссылку на модель с жанрами.
Для хранения понравившихся пользователем фильмов нам понадобится отдельная таблица, которая будет иметь связь «многие ко многим», ее структура:
- user_id
- movie_id
Таким образом, мы сможем однозначно понять, какие фильмы нравятся отдельному пользователю и, например, скольким пользователям понравился отдельный фильм.
Добавьте эндпоинты:
- POST /favorites/movies/{movie_id} — добавить фильм к пользователю в Избранное.
- DELETE /favorites/movies/{movie_id} — удалить фильм из Избранного.
Добавьте тесты
Напишите несколько тестов для DAO
Напишите несколько тестов для сервисов
Напишите несколько тестов на вьюхи
Напишите документацию
Напишите хорошую документацию для swager, согласно спецификации с сайта библиотеки flask_restx.