Пишем API на Python (с Flask и RapidAPI)

Пишем API на Python (с Flask и RapidAPI)

Ако четете тази статия, вероятно вече сте запознати с възможностите, които предоставя API (Application Programming Interface).

Добавяйки един от многото отворени API в приложението си, можете да разширите функционалността му или да добавите необходимите данни. Но какво да направите, ако сте разработили уникална функция, с която искате да споделите с общността?

Отговорът е прост: необходимо е да създадете собствен API.

Въпреки че първоначално изглежда сложно, всъщност е много просто. Ще ви покажем как да го направите с помощта на Python.

Какво е необходимо за стартиране

За разработването на API са необходими:

  • Python 3;
  • Flask — прост и лесен за ползване фреймворк за създаване на уеб приложения;
  • Flask-RESTful — разширение за Flask, което позволява бързото разработване на REST API с минимална конфигурация.

Инсталацията се извършва с командата:

pip install flask-restful

Препоръчваме безплатен интензивен курс по програмиране за начинаещи:
Разработка на telegram бот на C# — 26–28 август. Безплатен интензив, който позволява да разберете как работят помощните ботове, особеностите на работа с API на Telegram и други нюанси. Трима от най-добрите участници ще получат от Skillbox 30 000 рубли..

Преди да започнем

Ние ще разработим RESTful API с основна CRUID функционалност..

За да разберем задачата напълно, нека разгледаме две термина, споменати по-горе.

Какво е REST?

REST API (Representational State Transfer) — това е API, което използва HTTP заявки за обмен на данни.

REST API трябва да отговарят на определени критерии:

  • Архитектура клиент-сървър: клиентът взаимодействува с потребителския интерфейс, а сървърът — с бекенда и хранилището на данни. Клиентът и сървърът са независими, всеки от тях може да бъде заменен отделно от другия.
  • Stateless — никакви клиентски данни не се съхраняват на сървъра. Състоянието на сесията се съхранява отстрани на клиента.
  • Кешируемост — клиентите могат да кешират отговорите на сървъра за подобряване на общата производителност.

Какво е CRUD?

CRUD — концепция за програмиране, която описва четирите основни действия (създаване, четене, актуализиране и изтриване).

В REST API типовете заявки и методите за заявка отговарят за действия като post, get, put, delete.

Сега, когато разгледахме основните термини, можем да преминем към създаването на API.

Разработка

Нека създадем репозиторий от цитати за изкуствения интелект. ИИ е една от най-бързо развиващите се технологии днес, а Python е популярен инструмент за работа с ИИ.

С този API разработчикът на Python ще може бързо да получава информация за ИИ и да се вдъхновява от новите постижения. Ако разработчикът има ценни мисли по темата, той може да ги добави в репозитория.

Нека започнем с импортирането на необходимите модули и настройката на Flask:

from flask import Flask
from flask_restful import Api, Resource, reqparse
import random
app = Flask(__name__)
api = Api(app)

В този фрагмент от Flask, Api и Resource са класовете, от които се нуждаем.

Reqparse е интерфейс за парсване на заявки в Flask-RESTful… Ще ни е нужен и модул random за показване на случайна цитата.

Сега ще създадем репозиторий от цитати за ИИ.

Всяка запис в репото ще съдържа:

  • цифров ID;
  • името на автора на цитатата;
  • цитата.

Тъй като това е само пример за обучение, ще запазим всички записи в списък на Python. В реално приложение обаче най-вероятно бихме използвали база данни.

ai_quotes = [
    {
        "id": 0,
        "author": "Кевин Кели",
        "quote": "Бизнес плановете на следващите 10,000 стартъпа са лесни за прогноза: " +
                 "Помислете за X и добавете ИИ."
    },
    {
        "id": 1,
        "author": "Стивън Хокинг",
        "quote": "Развитието на пълна изкуствена интелигентност може " +
                 "да означава края на човешкия род… " +
                 "То ще се развива само по себе си и ще се " +
                 "преразработва с нарастваща скорост. " +
                 "Хората, които са ограничени от бавната биологична еволюция, " +
                 "няма да могат да се конкурират и ще бъдат изместени."
    },
    {
        "id": 2,
        "author": "Клод Шанон",
        "quote": "Представям си времена, когато ние ще бъдем за роботите, каквото " +
                 "кучетата са за хората, " +
                 "и аз съм на страната на машините."
    },
    {
        "id": 3,
        "author": "Илон Мъск",
        "quote": "Темпът на напредъка в изкуствената интелигенция " +
                 "(не говоря за тесен ИИ) " +
                 "е изключително бърз. Освен ако нямате пряк " +
                 "контакт с групи като Deepmind, " +
                 "нямате представа колко бързо – то нараства " +
                 "с темп, близък до експоненциалния. " +
                 "Рискът от нещо наистина опасно " +
                 "да се случи е в рамките на пет години. " +
                 "10 години максимум."
    },
    {
        "id": 4,
        "author": "Джефри Хинтън",
        "quote": "Винаги съм бил убеден, че единственият начин " +
                 "да накараме изкуствената интелигентност да работи " +
                 "е да правим изчисления по начин, подобен на човешкия мозък. " +
                 "Това е целта, която преследвам. Правим напредък, " +
                 "въпреки че все още имаме много да научим за " +
                 "начина, по който мозъкът всъщност работи."
    },
    {
        "id": 5,
        "author": "Педро Домингос",
        "quote": "Хората се притесняват, че компютрите ще " +
                 "станат прекалено умни и ще завладеят света, " +
                 "но истинският проблем е, че те са прекалено глупави " +
                 "и вече са завладели света."
    },
    {
        "id": 6,
        "author": "Алан Тюринг",
        "quote": "Изглежда вероятно, че веднъж след като методът на машинното мислене " +
                 "започне, няма да отнеме много време " +
                 "да надмине нашите крехки способности… " +
                 "Те ще могат да общуват " +
                 "помежду си, за да усъвършенстват ума си. " +
                 "На определен етап следователно, трябва " +
                 "да очакваме машините да поемат контрол."
    },
    {
        "id": 7,
        "author": "Рей Кърцвайл",
        "quote": "Изкуствената интелигентност ще достигне " +
                 "човешки нива около 2029 година. " +
                 "Ако продължим по-далеч, да кажем, до 2045, " +
                 "ще сме увеличили интелигентността, " +
                 "интелигентността на човешката биологична машина " +
                 "на нашата цивилизация хиляда пъти."
    },
    {
        "id": 8,
        "author": "Себастиан Трун",
        "quote": "Никой не го формулира по този начин, но мисля, " +
                 "че изкуствената интелигентност " +
                 "е почти дисциплина от хуманитарните науки. Това е наистина опит " +
                 "да разберем човешката интелигентност и човешката когниция."
    },
    {
        "id": 9,
        "author": "Андрю Нг",
        "quote": "Правим аналогия, че ИИ е новото електричество." +
                 "Електричеството трансформира индустрии: земеделие, " +
                 "транспорт, комуникации, производство."
    }
]

Сега е необходимо да създадем ресурсен клас Quote, който да определи операциите на крайна точка на нашия API. Вътре в класа трябва да декларираме четири метода: get, post, put, delete.

Да започнем с метода GET

Той позволява да получим конкретна цитата, посочвайки нейния ID, или случайна цитата, ако ID не е указан.

class Quote(Resource):
    def get(self, id=0):
        if id == 0:
            return random.choice(ai_quotes), 200
        for quote in ai_quotes:
            if(quote["id"] == id):
                return quote, 200
        return "Цитата не е намерена", 404

Методът GET връща случайна цитата, ако ID съдържа стойност по подразбиране, т.е. при извикване на метода ID не е зададен.

Ако е задан, то методът търси сред цитатите и намира тази, която съдържа зададения ID. Ако не се намери нищо, излиза съобщение “Цитата не е намерена, 404”.

Помнете: методът връща HTTP статус 200 при успешна заявка и 404, ако записа не е намерен.

Сега нека създадем POST-метод за добавяне на нова цитата в репозитория.

Той ще получава идентификатора на всяка нова цитата при въвеждане. Освен това, POST ще използва reqparse за парсинг на параметрите, които ще дойдат в тялото на заявката (автор и текст на цитата).

def post(self, id):
      parser = reqparse.RequestParser()
      parser.add_argument("author")
      parser.add_argument("quote")
      params = parser.parse_args()
      for quote in ai_quotes:
          if(id == quote["id"]):
              return f"Цитата с id {id} вече съществува", 400
      quote = {
          "id": int(id),
          "author": params["author"],
          "quote": params["quote"]
      }
      ai_quotes.append(quote)
      return quote, 201

В кода по-горе POST-методът прие ID на цитата. След това, използвайки reqparse, получи автора и цитатата от заявката, запазвайки ги в речника params.

Ако цитата с указан ID вече съществува, то методът изведе съответно съобщение и код 400.

Ако цитата с указан ID все още не е била създадена, методът създава нов запис с указан ID и автор, както и други параметри. След това добавя записа в списъка ai_quotes и връща записа с новата цитата заедно с код 201.

Сега създаваме PUT-метод за промяна на съществуваща цитата в репозитория.

def put(self, id):
      parser = reqparse.RequestParser()
      parser.add_argument("author")
      parser.add_argument("quote")
      params = parser.parse_args()
      for quote in ai_quotes:
          if(id == quote["id"]):
              quote["author"] = params["author"]
              quote["quote"] = params["quote"]
              return quote, 200
      
      quote = {
          "id": id,
          "author": params["author"],
          "quote": params["quote"]
      }
      
      ai_quotes.append(quote)
      return quote, 201

PUT метод, подобно предыдущему примеру, взимает ID и ввод и парсит параметры цитаты с использованием reqparse.

Если цитата с указанным ID существует, метод обновит её с новыми параметрами и затем выведет обновлённую цитату с кодом 200. Если цитаты с указанным ID ещё нет, будет создана новая запись с кодом 201.

Наконец, давайте создадим DELETE метод для удаления цитаты, которая больше не вдохновляет.

def delete(self, id):
      global ai_quotes
      ai_quotes = [qoute for qoute in ai_quotes if qoute["id"] != id]
      return f"Цитата с id {id} удалена.", 200

Этот метод получает ID цитаты при вводе и обновляет список ai_quotes, используя общий список.

Теперь, когда мы создали все методы, всё, что нам нужно сделать, — это просто добавить ресурс к API, задать путь и запустить Flask.

api.add_resource(Quote, "\/ai-quotes", "\/ai-quotes\/")
if __name__ == '__main__':
    app.run(debug=True)

Наш REST API сервис готов!

Далее мы можем сохранить код в файл app.py, запустив его в консоли с помощью команды:

python3 app.py

Если всё хорошо, то мы получим что-то вроде этого:

* Режим отладки: включен
* Запуск на 127.0.0.1:5000\/ (Нажмите CTRL+C для выхода)
* Перезапуск с помощью stat
* Отладчик активен!
* PIN для отладчика: XXXXXXX

Тестируем API

После того как API создан, его нужно протестировать.

Это можно сделать с помощью консольного инструмента curl или клиента Insomnia REST, либо опубликовав API на Rapid API.

Пишем API на Python (с Flask и RapidAPI)

Публикуем наш API

RapidAPI — крупнейший в мире маркетплейс с более чем 10 000 API (и около 1 млн разработчиков).

RapidAPI не только предоставляет единый интерфейс для работы со сторонними API, но и даёт возможность быстро и без проблем опубликовать ваш собственный API.

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

Как опубликовать ваш API на Heroku

1. Устанавливаем Heroku.

В первую очередь нужно зарегистрироваться и установить Heroku Command Line Interface (CLI). Это работает на Ubuntu 16+.

sudo snap install heroku —classic

Затем логинимся:

heroku login

2. Добавляем необходимые файлы.

Теперь необходимо добавить файлы для публикации в папку в нашем приложении:

  • requirements.txt со списком необходимых модулей Python;
  • Procfile, который указывает, какие команды должны быть выполнены для запуска приложения;
  • .gitignore — для исключения файлов, которые не нужны на сервере.

Файл requirements.txt будет содержать следующие строки:

  • flask
  • flask-restful
  • gunicorn

Моля, обърнете внимание: добавихме gunicorn (Python WSGI HTTP Server) в списъка, тъй като е необходимо да стартираме приложението на сървъра.

Procfile ще съдържа:

web: gunicorn app:app

Съдържанието на .gitignore:

*.pyc
__pycache__/

Сега, когато файловете са създадени, нека инициализираме git-репо и да направим комит:

git init
git add
git commit -m "First API commit"

3. Създаваме ново Heroku-приложение.

heroku create

Изпращаме master branch в отдалеченото репо Heroku:

git push heroku master

Сега можем да започнем, отваряйки API услугата с командите:

heroku ps:scale web=1
heroku open
 

API ще бъде достъпно на адреса your-random-heroku-name.herokuapp.com/ai-quotes.

Как да добавите вашия Python API в маркетплейса RapidAPI

След като API услугата е публикувана на Heroku, можете да я добавите към Rapid API. Тук има подробна документация по тази тема.

1. Създайте акаунт в RapidAPI.

Пишем API на Python (с Flask и RapidAPI)

Регистрирайте безплатен акаунт - може да го направите чрез Facebook, Google, GitHub.

Пишем API на Python (с Flask и RapidAPI)

2. Добавете API в контролния панел.

Пишем API на Python (с Flask и RapidAPI)

3. След това въвеждаме обща информация за нашия API.

Пишем API на Python (с Flask и RapidAPI)

4. След натискане на “Add API” се появява нова страница, където може да въведете информация за нашия API.

Пишем API на Python (с Flask и RapidAPI)

5. Сега можете или ръчно да въведете ендпойнтовете на API, или да качите swagger-file чрез OpenAPI.

Пишем API на Python (с Flask и RapidAPI)

Сега трябва да зададете ендпойнтовете на нашия API на страницата Endpoints. В нашия случай ендпойнтовете съответстват на концепцията CRUD (get, post, put, delete).

Пишем API на Python (с Flask и RapidAPI)

След това трябва да създадете GET AI Quote ендпойнт, който извежда произволна цитата (в случай, че ID е по подразбиране) или цитата за указаното ID.

За да създадете ендпойнт, трябва да натиснете бутона “Create Endpoint”.

Пишем API на Python (с Flask и RapidAPI)

Повторете този процес за всички останали ендпойнти на API. Това е всичко! Честито, публикувахте вашия API!

Ако всичко е наред, страницата на API ще изглежда по следния начин:

Пишем API на Python (с Flask и RapidAPI)

Заключение

В тази статия разгледахме процеса на създаване на собствен RESTful API Service на Python, заедно с процеса на публикуване на API в облака Heroku и добавянето му в каталога RapidAPI.

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

При разработване на реален API всичко това трябва да се вземе предвид.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster