Пішам API на Python (з Flask і RapidAPI)

Пішам API на Python (з Flask і RapidAPI)

Калі вы чытаеце гэты артыкул, верагодна, вы ўжо знаёмыя з магчымасцямі, якія адчыняюцца пры выкарыстанні API (Application Programming Interface).

Дадаўшы ў сваё прыкладанне адзін з шматлікіх адчыненых API, вы можаце пашырыць функцыянальнасць гэтага прыкладання альбо ж дапоўніць яго патрэбнымі дадзенымі. Але што, калі вы распрацавалі ўнікальную функцыю, якой хочаце падзяліцца з кам'юніці?

Адказ просты: трэба стварыць уласны API.

Нягледзячы на ​​тое, што гэта спачатку здаецца складанай задачай, насамрэч усё проста. Мы раскажам, як гэта зрабіць з дапамогай Python.

Што трэба для пачатку працы

Для распрацоўкі API неабходны:

  • Python 3;
  • Колба - просты і лёгкі ў выкарыстанні фрэймворк для стварэння вэб-прыкладанняў;
  • 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?

СЫРЫ — канцэпцыя праграмавання, якая апісвае чатыры базавыя дзеянні (create, read, update і delete).

У API REST тыпы запытаў і метады запыту адказваюць за такія дзеянні, як 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": "Kevin Kelly",
        "quote": "The business plans of the next 10,000 startups are easy to forecast: " +
                 "Take X and add AI."
    },
    {
        "id": 1,
        "author": "Stephen Hawking",
        "quote": "The development of full artificial intelligence could " +
                 "spell the end of the human race… " +
                 "It would take off on its own, and re-design " +
                 "itself at an ever increasing rate. " +
                 "Humans, who are limited by slow biological evolution, " +
                 "couldn't compete, and would be superseded."
    },
    {
        "id": 2,
        "author": "Claude Shannon",
        "quote": "I visualize a time when we will be to robots what " +
                 "dogs are to humans, " +
                 "and I’m rooting for the machines."
    },
    {
        "id": 3,
        "author": "Elon Musk",
        "quote": "The pace of progress in artificial intelligence " +
                 "(I’m not referring to narrow AI) " +
                 "is incredibly fast. Unless you have direct " +
                 "exposure to groups like Deepmind, " +
                 "you have no idea how fast — it is growing " +
                 "at a pace close to exponential. " +
                 "The risk of something seriously dangerous " +
                 "happening is in the five-year timeframe." +
                 "10 years at most."
    },
    {
        "id": 4,
        "author": "Geoffrey Hinton",
        "quote": "I have always been convinced that the only way " +
                 "to get artificial intelligence to work " +
                 "is to do the computation in a way similar to the human brain. " +
                 "That is the goal I have been pursuing. We are making progress, " +
                 "though we still have lots to learn about " +
                 "how the brain actually works."
    },
    {
        "id": 5,
        "author": "Pedro Domingos",
        "quote": "People worry that computers will " +
                 "get too smart and take over the world, " +
                 "but the real problem is that they're too stupid " +
                 "and they've already taken over the world."
    },
    {
        "id": 6,
        "author": "Alan Turing",
        "quote": "It seems probable that once the machine thinking " +
                 "method had started, it would not take long " +
                 "to outstrip our feeble powers… " +
                 "They would be able to converse " +
                 "with each other to sharpen their wits. " +
                 "At some stage therefore, we should " +
                 "have to expect the machines to take control."
    },
    {
        "id": 7,
        "author": "Ray Kurzweil",
        "quote": "Artificial intelligence will reach " +
                 "human levels by around 2029. " +
                 "Follow that out further to, say, 2045, " +
                 "we will have multiplied the intelligence, " +
                 "the human biological machine intelligence " +
                 "of our civilization a billion-fold."
    },
    {
        "id": 8,
        "author": "Sebastian Thrun",
        "quote": "Nobody phrases it this way, but I think " +
                 "that artificial intelligence " +
                 "is almost a humanities discipline. It's really an attempt " +
                 "to understand human intelligence and human cognition."
    },
    {
        "id": 9,
        "author": "Andrew Ng",
        "quote": "We're making this analogy that AI is the new electricity." +
                 "Electricity transformed industries: agriculture, " +
                 "transportation, communication, manufacturing."
    }
]

Цяпер трэба стварыць рэсурсны клас 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 "Quote not found", 404

Метад GET вяртае выпадковую цытату, калі ID утрымоўвае дэфолтнае значэнне, г.зн. пры выкліку метаду ID не быў зададзены.

Калі ён зададзены, то метад шукае сярод цытат і знаходзіць тую, якая змяшчае зададзены ID. Калі ж нічога не знойдзена, выводзіцца паведамленне "Quote not found, 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"Quote with id {id} already exists", 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 і input і парсіць параметры цытаты, выкарыстоўваючы 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"Quote with id {id} is deleted.", 200

Гэты метад атрымлівае ID цытаты пры ўводзе і абнаўляе спіс ai_quotes, выкарыстоўваючы агульны спіс.

Цяпер, калі мы стварылі ўсе метады, усё, што нам трэба, - проста дадаць resource да API, задаць шлях і запусціць Flask.

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

Наш REST API Service гатовы!

Далей мы можам захаваць код у файл app.py, запусціўшы яго ў кансолі пры дапамозе каманды:

python3 app.py

Калі ўсё добра, то мы атрымаем нешта накшталт гэтага:

* Debug mode: on
* Running on 127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger 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-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 Service пры дапамозе каманд:

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

Дадаць каментар