Пишем 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 типовете заявки и методите на заявките отговарят за действия като пост, гет, пут, делит.

Сега, когато разгледахме основните термини, можем да пристъпим към създаването на 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 "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 и вход и обработва параметрите на цитата, използвайки reqparse.

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

Накрая, нека създадем DELETE метод за изтриване на цитата, която вече не вдъхновява.

def delete(self, id):
      global ai_quotes
      ai_quotes = [quote for quote in ai_quotes if quote["id"] != id]
      return f"Цитатът с id {id} е изтрит.", 200

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

Сега, когато сме създали всички методи, всичко, от което се нуждаем, е да добавим ресурс към 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

Ако всичко е наред, ще получим нещо подобно на това:

* Режим на отстраняване на грешки: включен
* Работи на 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 репото и да направим commit:

git init
git add
git commit -m "Първи 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 в marketplace 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