Эта серия статей посвящена базовому обучению, необходимому для быстрого создания веб-приложения для хакатона. Я намерен предоставить максимально простую информацию, которая поможет вам освоить что-то, что подойдет для начинающего проекта.

Это не серия статей, в которых вы узнаете, как создать надежное, масштабируемое корпоративное приложение. Так, например, я буду избегать таких тем, как написание тестов 😎 .

Вы можете найти готовый снимок кода в этом руководстве по адресу https://github.com/david-shortman/hackathon-flask-backend-tutorial/tree/main/part%20one

Давайте вместе создадим веб-приложение

Если вы когда-нибудь участвовали в хакатоне раньше, то обнаружите, что наиболее распространенной категорией проектов является веб-приложение. Они распространены, потому что их легко создавать и публиковать, и есть миллион вариантов их создания и развертывания.

Но найти стек технологий для создания веб-приложения для новичка на сцене хакатона может быть пугающим, и трудно понять, что будет хорошо работать вместе, или если то, что вы обнаружили, слишком нишевое, чтобы получить помощь позже.

Вот почему я начинаю эту серию статей о написании очень простого веб-приложения для хакатона. Я выбрал хорошо зарекомендовавшие себя, удобные для новичков технологии, которые можно использовать бесплатно и не привязанные к каким-либо конкретным высокотехнологичным продуктам (извините, Firebase, AWS).

В первой части этой серии я покажу вам некоторые фундаментальные концепции для создания ядра веб-приложения с помощью Flask, невероятно популярной и простой платформы для написания веб-API.

Что мы делаем

Веб-приложению нужна служба для связи. Мы собираемся создать эту услугу, которую отраслевые эксперты могли бы назвать «серверной частью» нашего приложения.

Как уже упоминалось, мы собираемся использовать безумно простой фреймворк для создания нашего бэкэнда под названием Flask, который содержит очень мало кода для настройки работающего веб-сервера.

К концу этой статьи вы сможете запрашивать погоду в определенном городе из браузера с помощью написанной вами серверной службы.

Настройка вашей среды

Нет ничего хуже, чем прийти на хакатон и потратить время на то, чтобы заставить свой компьютер работать. Предварительная подготовка окружающей среды имеет решающее значение. Вот список программного обеспечения, которое мы будем использовать в этом руководстве и которое пригодится вам на хакатонах в будущем.

(В этом руководстве предполагается, что вы будете использовать macOS, подсистему Linux для Windows 10 или Unix-подобную систему для любой из упомянутых команд bash)

Заварить 🍺

Brew - это менеджер пакетов, который может устанавливать для нас другие программы и управлять их обновлением.

Хотя обычно вы никогда не должны запускать сценарий оболочки с произвольного веб-сайта, это именно то, что Homebrew просит нас сделать на своей домашней странице. Так что давайте жить опасно и запустим следующее в нашем приложении Terminal, которое установит Brew:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

После множества бессмысленных выводов из терминала вы можете подтвердить успешную установку Brew, запустив:

brew --version

Пьенв

Наша внутренняя служба Flask будет написана на Python. Давайте установим pyenv, который эффективно управляет Python:

brew install pyenv

Вы можете проверить, установлен ли Pyenv, используя:

pyenv --version

Теперь мы должны настроить Pyenv для управления Python в нашей системе (замените bash_profile на zshrc, если вы используете это вместо bash):

echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile

Затем перезапустите экземпляр терминала или используйте следующую команду:

source ~/.bash_profile

Python 🐍

Теперь мы можем установить Python:

pyenv install 3.8.5

Затем мы переключаем наш терминал на использование версии Python, которую мы установили глобально:

pyenv global 3.8.5

Вы можете проверить, установлен ли Python, используя:

which python

Вы должны увидеть путь к Python в каталоге .pyenv.

virtualenv

Наконец, давайте установим утилиту virtualenv, чтобы мы могли создать виртуальную среду, в которой мы устанавливаем наши зависимости Python:

pip install virtualenv

Вы можете проверить, что virtualenv установлен, используя:

virtualenv --version

Вы закончили установку глобального программного обеспечения, ура 🥳!

Настройка проекта

Создайте новую папку под названием «weather-backend».

mkdir weather-backend && cd weather-backend

Вы можете увидеть путь к папке, которую вы создали:

pwd

Виртуальная среда Python

Наш проект будет зависеть от других библиотек, извлеченных из Интернета. Лучший способ управлять зависимостями для проекта Python - установить их локально в папку проекта, а не глобально.

Создайте виртуальную среду:

virtualenv venv

Затем активируйте окружение:

source venv/bin/activate

Теперь вы заметите, что в вашем терминале начало каждой строки начинается с «(venv)». Это позволяет узнать, что вы находитесь в виртуальной среде.

Если вы когда-нибудь захотите покинуть среду, просто используйте команду «деактивировать». В противном случае, когда вы уйдете и позже вернетесь, чтобы запустить приложение Flask, используйте команду «активировать» выше.

Колба

Давайте установим фреймворк Flask в нашу виртуальную среду, чтобы приступить к работе над нашим приложением:

pip install flask=1.1.2

Получение нашего первого прогноза погоды 🌦

Хорошо, мы установили кучу программного обеспечения, но теперь пора написать собственное.

Как разговаривать с серверами

С помощью Flask мы можем написать сервер, который будет возвращать нам данные, когда мы посещаем определенный URL-адрес в браузере. Продолжайте и попробуйте перейти по следующему URL-адресу в своем браузере:

localhost:5000

Вы должны увидеть следующую ошибку:

Поскольку у нас еще нет службы по этому адресу, наш браузер сообщает нам, что он не может подключиться к localhost.

«Localhost» - это понятное имя локального сервера нашего компьютера, а «5000» - произвольный номер порта, на котором вскоре будет работать наше приложение Flask.

Сделайте так, чтобы он сказал «привет» 👋

Хорошо, давайте заставим наш сервер разговаривать. Сначала создайте файл с именем «app.py». Это будет файл Python, который мы запускаем для запуска нашего приложения. Напишите в run.py следующее:

#!/venv/bin/python
from app import app
from flask import Flask
app = Flask(__name__)
# Keep this at the bottom of app.py
app.run(debug=True)

Все, что до сих пор делает этот файл, - это импорт Flask и создание нового экземпляра приложения. Не забудьте сохранить последнюю строку внизу файла, когда мы добавляем новый код.

Теперь давайте добавим код, чтобы наш сервер приветствовал нас:

@app.route('/')
def hello():
    return 'Hello there' 

Это работает? Давайте запустим его, чтобы узнать:

python run.py

Вы должны увидеть вывод в терминале, который выглядит следующим образом:

* Serving Flask app "app" (lazy loading)
* Environment: production
  WARNING: This is a development server. Do not use it in a production deployment.
  Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 228-732-681

Теперь мы можем перезагрузить localhost: 5000 в нашем браузере.

Ладно, теперь мы говорим о нашем приложении. Конечно, это не такой уж и большой разговор ... но это нечто!

Итак, как вообще работает эта функция «привет»?

Итак, поскольку мы пишем приложение Flask, мы определили код, который работает по определенному маршруту для localhost: 5000. Мы настроили функцию hello для запуска по маршруту по умолчанию / с помощью аннотации app.route.

@app.route('/')
def hello():
    return 'Hello there'

Другой маршрут 🛣

Давайте определим другой маршрут для нашего прогноза погоды. Добавьте в «app.py» следующее:

@app.route('/weather')
def weather():
    return 'It\'s always sunny in Philadelphia'

Затем посетите в браузере localhost: 5000 / weather, и вы должны увидеть следующее:

Видите, как сейчас работает маршрутизация? Мы определяем маршруты с помощью аннотации app.route в app.py, а затем, когда мы посещаем URL-адрес, соответствующий этому маршруту, мы получаем возвращаемое значение аннотированной функции.

Разговорная маршрутизация 🗣

Если нам нужна погода для данного города, нам понадобится способ указать город на нашем сервере.

Но как мы собираемся это сделать без пользовательского интерфейса?

… В тупике? Как насчет того, чтобы использовать маршруты!

Теперь мы можем проложить маршрут для каждого города, в котором хотим узнать погоду. Это было бы в стиле «хакатона», но с Flask есть простой способ быть еще ленивее.

Попробуйте изменить функцию погоды следующим образом:

@app.route('/weather/<city>')
def weather(city):
    return f'It\'s always sunny in {city}' 

Тогда попробуйте посетить localhost: 5000 / weather / boston.

Вы должны увидеть, что название города, которое мы указали в URL-адресе, повторяется нам!

Получение реальной погоды

Теперь, когда у нас есть механизм для присвоения серверу названия города (и есть другие механизмы, к которым мы еще вернемся), мы можем попытаться предоставить точные текущие погодные условия.

У OpenWeather есть бесплатное членство для своего API, который мы можем очень легко запросить с помощью пакета Python «pyowm».

Сначала зарегистрируйте учетную запись на https://home.openweathermap.org. Затем перейдите на вкладку Ключи API и убедитесь, что у вас есть ключ API, который предоставит вам доступ к их данным о погоде.

Вернувшись в терминал, давайте установим пакет pyowm в нашу виртуальную среду:

pip install pyowm==3.0.0

Теперь мы можем использовать пакет pyowm для получения некоторых данных о погоде (и вы можете узнать больше о пакете в их README):

from pyowm import OWM
owm = OWM('YOUR API KEY HERE')
@app.route('/weather/<city>')
def weather(city):
    weather_manager = owm.weather_manager()
    weather_at_place = weather_manager.weather_at_place(f'{city},US')
    return weather_at_place.weather.temperature('celsius')

Если мы повторно посетим http: // localhost: 5000 / weather / boston, вы должны увидеть что-то вроде следующего:

Ого! Погода ⛈! Кто бы мог подумать?!

Вы заметите, что Flask поработал для нас, преобразовав объект Python, который мы вернули в конце функции погоды, и превратил его в строку, которую наш браузер мог интерпретировать и отображать. Эта функция - одна из тех вещей, которые делают Flask настолько простым в использовании прямо из коробки! Мы можем возвращать сложные объекты с нашего сервера в формате, который вы видите выше, который называется JSON, который очень легко интерпретировать другими приложениями (например, пользовательским интерфейсом).

Чтобы доказать свою точку зрения, давайте просто вернем текущую температуру, но как в градусах Цельсия, так и в градусах Кельвина:

@app.route('/weather/<city>')
def weather(city):
    weather_manager = owm.weather_manager()
    weather_at_place = weather_manager.weather_at_place(f'{city},US')
    temperature = weather_at_place.weather.temperature('celsius')
    return {
        'temp_celsius': temperature['temp'],
        'temp_kelvin': temperature['temp'] + 273
    }

А теперь, обновив http: // localhost: 5000 / weather / boston, мы увидим наш новый объект:

Пожалуйста, еще параметры 🙏

Наше приложение погоды сейчас настолько хорошо, что кажется заманчивым пойти дальше и отправить его на следующий хакатон, который вы посещаете, не так ли?

Но наш погодный API сейчас довольно ограничен. Все, что мы можем сделать, это спросить температуру в городах США. А как насчет других стран? А как насчет других погодных условий?

Не пугайтесь, здесь больше параметров. Давайте сначала займемся проблемой страны, расширив нашу функцию погоды, чтобы она могла принимать второй параметр, код страны:

@app.route('/weather/<country>/<city>')
def weather(country, city):
    weather_manager = owm.weather_manager()
    weather_at_place = weather_manager.weather_at_place(f'{country},{city}')
    temperature = weather_at_place.weather.temperature('celsius')
    return {
        'temp_celsius': temperature['temp'],
        'temp_kelvin': temperature['temp'] + 273
    }

Теперь попробуем проверить погоду над прудом по адресу http: // localhost: 5000 / weather / uk / london. Вы должны увидеть, как вернутся новые температуры!

Зная, что температура - это хорошо и все такое, но как мы можем узнать, не стоит ли в Лондоне знаменитая унылая погода? Мы могли бы изменить нашу погодную функцию, чтобы она возвращала кучу данных о погоде, но это может раздражать при прокрутке.

Вместо этого давайте изменим нашу конечную точку, чтобы она принимала параметры запроса, чтобы указать, какие характеристики погоды мы хотим получить.

Параметры запроса указываются в URL-адресе с помощью символа «?» после символа, за которым следует серия пар параметр / значение, разделенных «&».

Например, если мы хотим узнать влажность и текущие осадки, мы могли бы указать

?show_humidity=true&show_precipitation=true

в конце нашего URL.

Мы можем импортировать модуль «запросы» из Flask для загрузки деталей из запроса, таких как параметры запроса:

from flask import request

Затем мы можем изменить функцию погоды в последний раз, чтобы включить влажность и последний час осадков, если указано:

@app.route('/weather/<country>/<city>')
def weather(country, city):
    weather_manager = owm.weather_manager()
    weather_at_place = weather_manager.weather_at_place(f'{country},{city}')
    temperature = weather_at_place.weather.temperature('celsius')
    
    weather_details = {
        'temp_celsius': temperature['temp'],
        'temp_kelvin': temperature['temp'] + 273
    }
    if (request.args.get('show_humidity')):
        weather_details['humidity'] = weather_at_place.weather.humidity
    if (request.args.get('show_precipitation')):
        weather_details['precipitation_last_hour'] = weather_at_place.weather.rain['1h']
    return weather_details

Ура! 🚀

Заворачивать

Создав этот бэкэнд API погоды, вы узнали

  • Как запустить приложение Flask
  • Как делать запросы к серверу в браузере
  • Как указать параметры маршрута и параметры запроса в URL
  • Как использовать сторонний пакет Python
  • Как читать параметры маршрута и параметры запроса с помощью Flask

Это действительно хорошее начало!

Далее я расскажу вам, как отладить приложение и развернуть его в Интернете. После этого я расскажу вам, как создать базовый интерфейс, чтобы другие люди могли взаимодействовать с вашим приложением.