Проект “Погода” #
Веб-приложение для просмотра текущей погоды. Пользователь может зарегистрироваться и добавить в коллекцию одну или несколько локаций (городов, сёл, других пунктов), после чего главная страница приложения начинает отображать список локаций с их текущей погодой.
Что нужно знать #
- Python - коллекции, ООП
- Паттерн MVC(S)
- pip/Poetry
- Backend
- Django
- Базы данных
- Postgres
- DjangoORM
- Миграции
- Frontend - HTML/CSS, Bootstrap
- Тесты - интеграционное тестирование, моки
- Деплой - облачный хостинг, командная строка Linux
Мотивация проекта #
- Реализация многопользовательского приложения
- Работа с внешними API
Функционал приложения #
Работа с пользователями:
- Регистрация
- Авторизация
- Logout
Работа с локациями:
- Поиск
- Добавление в список
- Просмотр списка локаций, для каждой локации отображается название и температура
- Удаление из списка
Интерфейс приложения #
Для вёрстки предлагаю пользоваться Bootstrap 5.
Главная страница #
- Заголовок
- Для неавторизованных пользователей - кнопки регистрации и авторизации
- Для авторизованных пользователей - логин текущего пользователя и кнопка Logout
- Контент
- Поле ввода для поиска локации по названию
- Список добавленных локаций. Каждый элемент списка отображает название, текущую температуру и кнопку “удалить”
Страница результатов поиска локаций по названию #
Переход на эту страницу осуществляется в результате заполнения поля ввода на главной странице, либо на странице результатов поиска.
Содержимое:
- Заголовок, такой же как на главной странице
- Поле ввода для поиска по названию - такое же, как на главной странице, чтобы не возвращаться туда для каждого нового поиска
- Список найденных локаций с кнопкой “добавить”. При нажатии на кнопку происходит переход на главную страницу
Остальное #
- Страницы с формами регистрации и авторизации
Работа с сессиями и cookies #
Чтобы реализовать авторизацию пользователя и позволить браузеру “запоминать” авторизован ли текущий пользователь, необходимы сессии и cookies. Подразумевается, что студент имеет общее представление об этих понятиях.
За авторизацию, управление доступом к страницам в Django отвечает django.contrib.auth
.
За работу с сессиями отвечает SessionMiddleware
. По умолчанию Django хранит сессии в базе данных в таблице django_session, так и сделаем. При каждом запросе Django извлекает данные сессии из базы данных по идентификатору сессии, хранящемуся в куках (cookies) запроса. После завершения запроса Django обновляет данные сессии в базе данных, если они были изменены, и обновляет срок действия сессии.
База данных #
В этом проекте предлагаю использовать Postgres, а таблицы создавать с помощью Django Migrations.
Таблица Users
#
Колонка | Тип | Комментарий |
---|---|---|
ID | int | Айди пользователя, автоинкремент, первичный ключ |
Login | Varchar | Логин пользователя, username или email |
Password | Varchar | Хранить пароль в открытом виде небезопасно, лучше использовать шифрование, например BCrypt |
Таблица Locations
#
Локации пользователя, в которых он хочет знать погоду. Одна и та же локация может повторяться для нескольких пользователей.
Колонка | Тип | Комментарий |
---|---|---|
ID | int | Айди локации, автоинкремент, первичный ключ |
Name | Varchar | Название |
UserId | int | Пользователь, добавивший эту локацию |
Latitude | Decimal | Широта локации |
Longitude | Decimal | Долгота локации |
Получение информации о погоде с помощью OpenWeatherMap API #
В предыдущих проектах мы писали своё API, в этом будем пользоваться чужим. Нам нужно искать локации по названию и получать погоду для локации.
OpenWeather #
Существует множество сервисов, предоставляющих API с таким функционалом, один из них - https://openweathermap.org/. Я выбрал этот вариант, потому что он позволяет бесплатно совершать 60 запросов в минуту.
Для выполнения запросов к API нужен ключ, для его получения необходимо:
- Зарегистрироваться на https://openweathermap.org/
- Создать бесплатный ключ с лимитом 60 запросов в минуту
- Дождаться активации ключа (
Работа с API #
Документация - https://openweathermap.org/api.
Нам нужно 2 метода API:
- Поиск локаций по названию - https://openweathermap.org/current#geocoding
- Получение погоды по координатам локации - https://openweathermap.org/current#one
Первым делом следует поэкспериментировать с API вручную, чтобы понять как делать запросы, и что приходит в ответе. Сделать это можно в HTTP клиенте встроенном в среды JetBrains (IDEA/PyCharm), либо воспользоваться отдельным приложением, например Postman или https://insomnia.rest/.
Интеграция OpenWeather API с приложением #
Шаги:
- Делаем запрос
- Получаем ответ
- Десериализуем ответ в объект
Для работы с API потребуется HTTP Client, например Requests.
С десериализацией поможет встроенный в Requests JSON decoder - https://requests.readthedocs.io/en/latest/user/quickstart/#json-response-content.
Тесты #
Интеграционные тесты сервисов по работе с пользователями и сессиями #
❗️ TODO адаптировать под Python ❗️
Покроем тестами связку слоя данных с классами-сервисами, отвечающими за пользователей и сессии.
Пример - вызов метода регистрации в классе-сервисе, отвечающем за работу с пользователями, должен привести к тому, что в таблице Users
появляется новая запись. Если при регистрации автоматически создается сессия, так же можем проверить, что она была создана.
Что ещё стоит проверить тестами:
- Регистрация юзера с неуникальным логином приводит к exception
- Истекание сессии
Детали:
- Для тестов должна использоваться БД, отдельная от основной (in-memory БД или независимая schema в основной БД), которая пересоздается (или очищается) перед каждым тест кейсом
- Понадобится 2 конфигурации приложения - основная (для разработки и деплоя) и для прогона тестов. Конфигурации могут отличаться настройками доступа к БД для DjangoORM, настройками приложения (длительность сессии, например)
Интеграционные тесты для сервиса по работе с OpenWeather API #
Покроем тестами связку HTTP клиента и класса-сервиса, который пользуется этим клиентом для получения данных. Для того чтобы не делать настоящие запросы к API во время прогона тестов, следует использовать мок HTTP клиента и его ответов.
Пример - запрашиваем список локаций у сервиса, мок HTTP клиента возвращает заданный в тесте ответ (в виде строки, например), сервис его парсит и возвращает коллекцию объектов-моделей. Проверяем, что коллеция содержит ожидаемую локацию.
Что ещё стоит проверить тестами:
- В случай ошибки (статусы 4xx, 5xx) от OpenWeather API сервис выбрасывает ожидаемый тип исключения
Деплой #
Будем вручную деплоить приложение на удалённый сервер. Потребуется установка внешней SQL DB - Postgres.
Шаги:
- В хостинг-провайдере по выбору арендовать облачный сервер на Linux
- Установить Python, Postgres
- Скопировать код приложения
- Установить зависимости
- Запустить приложение
Ожидаемый результат - приложение доступно по адресу http://$server_ip:$port/$app_root_path
.
План работы над приложением #
- Создать заготовку Django приложения
- Написать модели сущностей БД -
User
,Location
- Реализовать работу с сессиями
- С помощью Jinja2 создать страницы авторизации и регистрации
- Написать сервис для работы с OpenWeather API
- Интеграционные тесты для OpenWeather API
- Реализовать бизнес логику приложения - поиск, добавление, удаление локаций, просмотр погоды
- Создать интерфейс главной страницы и страницы поиска локаций
- Деплой
Ресурсы для работы над ошибками #
- Реализации проекта другими студентами и мои ревью этих реализаций
- Готовый проект можете отправить мне на ревью - https://t.me/zhukovsd