Что такое апи программирования python
Перейти к содержимому

Что такое апи программирования python

  • автор:

API — Ключевые аспекты веб-разработки на Python

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

Как работают приложения

Современные сложные веб-приложения чаще всего ведут себя иначе, чем веб-сайты:

  • Пользователь вводит адрес приложения в браузере
  • В ответ сервер единожды отдает HTML-страницу
  • Дальше используется JavaScript — страница сама отвечает за отображение данных, которые не встроены в разметку страницы. Данные загружаются с сервера отдельными запросами от страницы к API

API (Application Programming Interface или «Программный интерфейс приложения») — это протокол взаимодействия между вашим приложением и другими программами. API не отвечает за общение приложения и пользователя. Вместо этого пользователь обычно использует отдельную программу-клиент, которая обращается к серверу по необходимости.

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

Более того, одно такое приложение-клиент может использовать несколько разных API. Причем не все из этих API даже предоставляются тем же сервером, который отдал первоначальную страницу! Например, таким образом один сайт может одновременно показывать новости из Twitter, карту Google Maps и встроенное YouTube-видео — весь этот контент запрашивается у соответствующих сервисов именно через API.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Что такое апи программирования python

Рассмотренного в прошлых темах материала достаточно для создания примитивного приложения. В этой теме попробуем реализовать простейшее приложение Web API в стиле REST. Архитектура REST предполагает применение следующих методов или типов запросов HTTP для взаимодействия с сервером, где каждый тип запроса отвечает за определенное действие:

  • GET (получение данных)
  • POST (добавление данных)
  • PUT (изменение данных)
  • DELETE (удаление данных)

Для каждого из этих типов запросов класс FastAPI предоставляет соответствующие методы. Рассмотрим, как мы можем реализовать с помощью этих методов простейший API. Пусть у нас будет следующий проект:

Создание Web API на FastAPI и Python

Создание сервера

В файле main.py определим следующий код:

import uuid from fastapi import FastAPI, Body, status from fastapi.responses import JSONResponse, FileResponse class Person: def __init__(self, name, age): self.name = name self.age = age self.id = str(uuid.uuid4()) # условная база данных - набор объектов Person people = [Person("Tom", 38), Person("Bob", 42), Person("Sam", 28)] # для поиска пользователя в списке people def find_person(id): for person in people: if person.id == id: return person return None app = FastAPI() @app.get("/") async def main(): return FileResponse("public/index.html") @app.get("/api/users") def get_people(): return people @app.get("/api/users/") def get_person(id): # получаем пользователя по id person = find_person(id) print(person) # если не найден, отправляем статусный код и сообщение об ошибке if person==None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) #если пользователь найден, отправляем его return person @app.post("/api/users") def create_person(data = Body()): person = Person(data["name"], data["age"]) # добавляем объект в список people people.append(person) return person @app.put("/api/users") def edit_person(data = Body()): # получаем пользователя по id person = find_person(data["id"]) # если не найден, отправляем статусный код и сообщение об ошибке if person == None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) # если пользователь найден, изменяем его данные и отправляем обратно клиенту person.age = data["age"] person.name = data["name"] return person @app.delete("/api/users/") def delete_person(id): # получаем пользователя по id person = find_person(id) # если не найден, отправляем статусный код и сообщение об ошибке if person == None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) # если пользователь найден, удаляем его people.remove(person) return person

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

class Person: def __init__(self, name, age): self.name = name self.age = age self.id = str(uuid.uuid4())

Этот класс содержит три атрибута. Два атрибута — name и age будут представлять имя и возраст пользователя и будут устанавливаться через конструктор. А третий атрибут — id будет служить для уникальной идентификации данного объекта и будет хранить значение guid. Для генерации guid применяется функция uuid.uuid4() из пакета uuid . В конструкторе Person сгенерированный guid преобразуется в строку и присваивается атрибуту id.

Для хранения данных в приложении определим список people, который будет выполнять роль условной базы данных и будет хранить объекты Person.

people = [Person("Tom", 38), Person("Bob", 42), Person("Sam", 28)]

Для поиска объекта Person в этом списке определена вспомогательная функция find_person() .

При обращении к корню веб-приложения, то есть по пути «/», оно будет отправлять в ответ файл index.html , то есть веб-страницу, посредством которой пользователь сможет взаимодействовать с сервером:

@app.get("/") def main(): return FileResponse("public/index.html")

Далее определяются функции, которые собственно и представляют API. Вначале определяется функция, которая обрабатывает запрос типа GET по пути «api/users»:

@app.get("/api/users") def get_people(): return people

Запрос GET предполагает получение объектов, и в данном случае отправляем выше определенный список объектов Person.

Когда клиент обращается к приложению для получения одного объекта по id в запрос типа GET по адресу «api/users/», то срабатывает другая функция:

@app.get("/api/users/") def get_person(id): person = find_person(id) if person==None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) return person

Здесь через параметр id получаем из пути запроса идентификатор объекта Person и по этому идентификатору ищем нужный объект в списке people. Если объект по id не был найден, то возвращаем с помощью класса JSONResponse статусный код 404 с некоторым сообщением в формате JSON. Если объект найден, то отправляем найденный объект клиенту.

При получении запроса типа DELETE по маршруту «/api/users/» срабатывает другая функция:

@app.delete("/api/users/") def delete_person(id): person = find_person(id) if person == None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) people.remove(person) return person

Здесь действует аналогичная логика — если объект по id не найден, отправляет статусный код 404. Если же объект найден, то удаляем его из списка и посылаем клиенту.

При получении запроса с методом POST по адресу «/api/users» срабатывает следующая функция:

@app.post("/api/users") def create_person(data = Body()): person = Person(data["name"], data["age"]) people.append(person) return person

Запрос типа POST предполагает передачу приложению отправляемых данных. Причем мы ожидаем, что клиент отправит данные, которые содержат значения name и age. Для краткости мы пока опускаем валидацию входных данных. И для получения данных из тела запроса с помощью класса Body получаем данные в параметр data и затем используем данные из этого параметра для создания объекта Person. Затем созданный объект добавляется в список people и отправляется назад клиенту.

Если приложению приходит PUT-запрос по адресу «/api/users», то аналогичным образом получаем отправленные клиентом данные в виде объекта Person и пытаемся найти подобный объект в списке people. Если объект не найден, отправляем статусный код 404. Если объект найден, то изменяем его данные и отправляем обратно клиенту:

@app.put("/api/users") def edit_person(data = Body()): person = find_person(data["id"]) if person == None: return JSONResponse( status_code=status.HTTP_404_NOT_FOUND, content= < "message": "Пользователь не найден" >) person.age = data["age"] person.name = data["name"] return person

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

Определение клиента

Теперь в проекте определим папку public , в которую добавим новый файл index.html

Определим в файле index.html следующим код для взаимодействия с сервером FastAPI:

    METANIT.COM td button 

Список пользователей

Имя:

Возраст:

ИмяВозраст

Основная логика здесь заключена в коде javascript. При загрузке страницы в браузере получаем все объекты из БД с помощью функции getUsers() :

async function getUsers() < // отправляет запрос и получаем ответ const response = await fetch("/api/users", < method: "GET", headers: < "Accept": "application/json" >>); // если запрос прошел нормально if (response.ok === true) < // получаем данные const users = await response.json(); const rows = document.querySelector("tbody"); // добавляем полученные элементы в таблицу users.forEach(user =>rows.append(row(user))); > >

Для добавления строк в таблицу используется функция row() , которая возвращает строку. В этой строке будут определены ссылки для изменения и удаления пользователя.

Ссылка для изменения пользователя с помощью функции getUser() получает с сервера выделенного пользователя:

async function getUser(id) < const response = await fetch(`/api/users/$`, < method: "GET", headers: < "Accept": "application/json" >>); if (response.ok === true) < const user = await response.json(); document.getElementById("userId").value = user.id; document.getElementById("userName").value = user.name; document.getElementById("userAge").value = user.age; >else < // если произошла ошибка, получаем сообщение об ошибке const error = await response.json(); console.log(error.message); // и выводим его на консоль >>

И выделенный пользователь добавляется в форму над таблицей. Эта же форма применяется и для добавления объекта. С помощью скрытого поля, которое хранит id пользователя, мы можем узнать, какое действие выполняется — добавление или редактирование. Если id не установлен (равен пустой строке), то выполняется функция createUser, которая отправляет данные в POST-запросе:

async function createUser(userName, userAge) < const response = await fetch("api/users", < method: "POST", headers: < "Accept": "application/json", "Content-Type": "application/json" >, body: JSON.stringify(< name: userName, age: parseInt(userAge, 10) >) >); if (response.ok === true) < const user = await response.json(); document.querySelector("tbody").append(row(user)); >else < const error = await response.json(); console.log(error.message); >>

Если же ранее пользователь был загружен на форму, и в скрытом поле сохранился его id, то выполняется функция editUser, которая отправляет PUT-запрос:

async function editUser(userId, userName, userAge) < const response = await fetch("api/users", < method: "PUT", headers: < "Accept": "application/json", "Content-Type": "application/json" >, body: JSON.stringify(< id: userId, name: userName, age: parseInt(userAge, 10) >) >); if (response.ok === true) < const user = await response.json(); document.querySelector(`tr[data-rowid='$']`).replaceWith(row(user)); > else < const error = await response.json(); console.log(error.message); >>

И функция deleteUser() посылает на сервер запрос типа DELETE на удаление пользователя, и при успешном удалении на сервере удаляет объект по id из списка объектов Person.

Теперь запустим проект, и по умолчанию приложение отправит браузеру веб-страницу index.html , которая загрузит список объектов:

взаимодействие javascript с Web API на FastAPI и Python

После этого мы сможем выполнять все базовые операции с пользователями — получение, добавление, изменение, удаление. Например, добавим нового пользователя:

Что такое API и как он работает

Простыми словами объясняем, как программы общаются между собой, и практикуем API-вызовы.

Иллюстрация: Катя Павловская для Skillbox Media

Евгений Кучерявый

Евгений Кучерявый

Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Заходите вы на сайт с вакансиями и ищете работу бэкенд-разработчиком, а там почти в каждой вакансии написано, что нужно уметь работать с REST API, или SOAP API, или просто API. Что всё это значит и зачем нужно программисту? Давайте разбираться.

Что такое API

API (англ. Application Programming Interface — программный интерфейс приложения) — это набор способов и правил, по которым различные программы общаются между собой и обмениваются данными.

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

Допустим, вы покупаете билет в кино с помощью банковской карты. Во время покупки терминал обращается к API банка, который выпустил вашу карту, и отправляет запрос на оплату. А если вы заказываете такси через приложение, оно обращается к платёжной системе тоже через API.

Программный интерфейс похож на договор между клиентом и продавцом. Только клиентом выступает приложение, которому нужны данные, а продавцом — сервер или ресурс, с которого мы эти данные берём. В таком договоре прописываются условия того, как и какие данные может получить клиент.

API встречается практически везде:

  • В языках программирования он помогает функциям корректно общаться друг с другом. Вызывающая функция должна соблюдать тип данных и последовательность параметров вызываемой функции.
  • В операционной системе он помогает программам получать данные из памяти или менять настройки ОС. Поэтому, чтобы разрабатывать приложения под конкретную операционную систему, нужно знать её API.
  • В вебе сервисы общаются друг с другом через программный интерфейс. Если API открытый, то официальную документацию по работе с ним публикуют создатели сервиса-источника. Так, например, выглядит документация Telegram.

Несмотря на то что термин довольно широкий, чаще всего в вакансиях речь идёт именно о третьем варианте.

Почему API называют интерфейсом

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

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

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

Как API помогает писать надёжные программы

Обычно мы не знаем, как программы устроены внутри. Впрочем, нам иногда и не важно, как они работают. Поэтому программную реализацию называют «чёрным ящиком» и прячут за несколькими уровнями абстракций, чтобы пользователям было удобно ими пользоваться.

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

  • работать с файловой системой;
  • отрисовывать графику;
  • хранить данные;
  • использовать сетевые возможности;
  • воспроизводить аудио и так далее.

Windows, Linux или macOS сами определяют, какие функции нужно вызвать и какие параметры передать, чтобы выполнить те или иные действия. Всё это описывается в документации к API, с которым работают разработчики других программ.

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

Почему API так популярны у программистов

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

Вот какие возможности даёт API:

  • Предоставляет доступ к готовым инструментам. Например, к функциям библиотеки для машинного обучения TensorFlow — они помогают быстро создать нейросеть, не тратя время на разработку инструментов с нуля.
  • Повышает безопасность. API позволяет вынести в отдельное приложение функциональность, которая должна быть защищена. Так снижается вероятность некорректного использования этих функций другими программами.
  • Связывает разные системы. Если вам нужно подключить к сайту платёжную систему или авторизацию через соцсети, без API не обойтись.
  • Снижает стоимость разработки. Часто бывает, что дешевле воспользоваться платным API, чем создавать функциональность с нуля.

Стороннее API обычно безопасное, потому что над ним работает коммерческая организация или целое сообщество разработчиков. И конечно, с его помощью даже работа над сложными проектами становится проще и приятнее.

Какие функций могут входить в API

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

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

Функции API могут решать не только утилитарные задачи конкретных приложений. Это может стать элементом маркетинга, когда доступ к API предлагается как отдельная услуга.

Как компании зарабатывают с помощью API

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

Например, «Яндекс» предоставляет платные API таких технологий:

  • переводчика с машинным обучением;
  • системы распознавания и синтеза речи;
  • платформы облачных вычислений и так далее.

Популярные социальные сети тоже предоставляют доступ к своим API. Через них можно, например, создать игру для «ВКонтакте» или добавить на сайт авторизацию через Google.

При этом компании обычно не раскрывают принципы реализации своих интерфейсов, поэтому для программистов они остаются «чёрными ящиками».

Как происходит вызов функций API

Мы уже столько говорим об API, но так и не показали, как с ним работать. На самом деле здесь нет ничего сложного. Как вызывать функции конкретного API — описывается в документации, а принципы работы примерно одни и те же.

Вот пример вызова методов библиотек в языке Python:

# Подключаем библиотеку import numpy as np # Вызываем метод, который возвращает модуль числа -5 x = np.abs(-5) # Выводим переменную x print(x)

Если API предоставляет функции через интернет (Web API), нужно отправить на сервер HTTP-запрос с данными в формате JSON. Пример синтеза речи с помощью API Yandex.SpeechKit:

import requests import json # Помещаем в переменную API_URL адрес API API_URL = "https://tts.api.cloud.yandex.net/speech/v1/tts:synthesize" # Помещаем в словарь data данные для отправки в API Yandex.SpeechKit data = < "text": "Привет! Это пример кода для статьи про API в Skillbox Media", "lang": "ru-RU", "speed": 1, "voice": "filipp", "emotion": "good" > # Преобразуем данные в строку в формате JSON json_str = json.dumps(data) # Отправляем данные на сервер и получаем ответ answer = requests.post(API_URL, json_str)

Можете запустить этот код и послушать результат.

Также бывают косвенные вызовы API — когда вызов происходит при участии посредника (другой функции или другого API). Например, когда пользователь нажимает кнопку «Обновить», он тоже взаимодействует с API браузера, но делает это не напрямую, а через графический интерфейс.

Что запомнить

API — это набор правил, по которым приложения или части программы общаются друг с другом. Его можно встретить везде — от операционных систем до веб-приложений. API позволяет разработчикам использовать готовые инструменты и не переживать за их реализацию. А ещё он делает приложения безопаснее и помогает связывать разные программы между собой.

API экономит время программистов и уменьшает расходы бизнеса на разработку.

Читайте также:

  • 9 софт-скиллов идеального джуна: взгляд тимлида
  • Все любят язык Go: почему он стал популярным и сколько зарабатывают разработчики
  • Что такое тестирование программ и зачем оно нужно

Как создать API с помощью Python и Django

API, Application Programming Interface (программный интерфейс приложения), — очень широкое понятие в бэкенд-разработке. Тот API, который мы рассмотрим сегодня, представляет собой сайт без фронтенд-составляющей. Вместо рендеринга HTML-страниц, бэкенд возвращает данные в JSON формате для использования их в нативных или веб-приложениях. Самое пристальное внимание при написании API (как и при написании вебсайтов) нужно обратить на то, как он будет использоваться. Сегодня мы поговорим о том, как использовать Django для создания API для простого приложения со списком дел.

Нам понадобится несколько инструментов. Для выполнения всех шагов я бы рекомендовал вам, вместе с данной статьей, клонировать вот этот учебный проект из GitHub-репозитория. Также вы должны установить Python 3, Django 2.2, и djangorestframework 3.9 (из репозитория запустите pip install -r requirements.txt для установки библиотек). Если не все будет понятно с установкой Django, можно воспользоваться официальной документацией. Также вам нужно будет скачать бесплатную версию Postman. Postman – отличный инструмент для разработки и тестирования API, но в этой статье мы воспользуемся лишь его самыми базовыми функциями.

Для начала откройте папку taskmanager , содержащую manage.py , и выполните python manage.py migrate в командной строке, чтобы применить миграции баз данных к дефолтной sqlite базе данных Django. Создайте суперпользователя с помощью python manage.py createsuperuser и не забудьте записать имя пользователя и пароль. Они понадобятся нам позже. Затем выполните python manage.py runserver для взаимодействия с API.

Вы можете работать с API двумя способами: просматривая фронтенд Django REST фреймворка или выполняя http-запросы. Откройте браузер и перейдите к 127.0.0.1:8000 или к localhost через порт 8000, где Django-проекты запускаются по умолчанию. Вы увидите веб-страницу со списком доступных конечных точек API. Это важнейший принцип в RESTful подходе к API-разработке: сам API должен показывать пользователям, что доступно и как это использовать.

Сначала давайте посмотрим на функцию api_index в views.py. Она содержит список конечных точек, которые вы посещаете.

 @define_usage(returns='url_usage': 'Dict'>) @api_view(['GET']) @permission_classes((AllowAny,)) def api_index(request): details = <> for item in list(globals().items()): if item[0][0:4] == 'api_': if hasattr(item[1], 'usage'): details[reverse(item[1].__name__)] = item[1].usage return Response(details) 

API функции для каждого представления (view в Django) обернуты тремя декораторами. Мы еще вернемся к @define_usage . @api_view нужен для Django REST фреймворка и отвечает за две вещи: шаблон для веб-страницы, которая в результате получится, и HTTP-метод, поддерживаемый конечной точкой. Чтобы разрешить доступ к этому url без проверки подлинности, @permission_classes , также из Django REST фреймворка, задан как AllowAny . Главная функция API обращается к глобальной области видимости приложения чтобы «собрать» все определенные нами функции. Так как мы добавили к каждой функции представления префикс api_ , мы можем легко их отфильтровать и вернуть словарь, содержащий информацию об их вызовах. Детали вызовов предоставляются пользовательским декоратором, написанным в decorators.py.

 def define_usage(params=None, returns=None): def decorator(function): cls = function.view_class header = None # Нужна ли аутентификация для вызова этого представления? if IsAuthenticated in cls.permission_classes: header = 'Authorization': 'Token String'> # Создаем лист доступных методов, исключая 'OPTIONS' methods = [method.upper() for method in cls.http_method_names if method != 'options'] # Создаем словарь для ответа usage = 'Request Types': methods, 'Headers': header, 'Body': params, 'Returns': returns> # Защита от побочных эффектов @wraps(function) def _wrapper(*args, **kwargs): return function(*args, **kwargs) _wrapper.usage = usage return _wrapper return decorator 

Декоратор — часть синтаксиса, которая позволяет легко определять функции высокого порядка, чтобы добавить функциям представления атрибуты (как классам). Представления на основе функций с декораторами — отличный компромисс между простыми функциями и представлениями на основе классов в Django. Этот декоратор предоставляет четыре информационных элемента: типы запросов, заголовки, параметры и возвращаемое значение каждой функции. Декоратор генерирует заголовок и информацию о методе на основе информации, полученной от других декораторов, прикрепленных к функции, и принимает в качестве входных данных параметры и возвращаемые значения на момент вызова данного декоратора.

Помимо вывода результатов index-запроса, мы также будем использовать наш API для взаимодействия с данными пользователя, так что нам понадобится какой-то способ аутентификации. Если бы это был не просто учебный проект, а что-то посерьезнее, можно было бы реализовать регистрацию пользователей (к тому же, это отличная практика, если вы хотите проверить, насколько вы разобрались с понятиями из этой статьи). Но вместо этого мы просто войдем под учетной записью суперпользователя, которую создали заранее.

 @define_usage(params='username': 'String', 'password': 'String'>, returns='authenticated': 'Bool', 'token': 'Token String'>) @api_view(['POST']) @permission_classes((AllowAny,)) def api_signin(request): try: username = request.data['username'] password = request.data['password'] except: return Response('error': 'Please provide correct username and password'>, status=HTTP_400_BAD_REQUEST) user = authenticate(username=username, password=password) if user is not None: token, _ = Token.objects.get_or_create(user=user) return Response('authenticated': True, 'token': "Token " + token.key>) else: return Response('authenticated': False, 'token': None>) 

Важно отметить, что для того, чтобы идентификация на основе токенов заработала, нужно настроить несколько параметров. Гид по настройке можно найти в файле settings.py учебного проекта.

Чтобы верифицировать пользователя, метод api_signin запрашивает имя пользователя и пароль и использует встроенный в Django метод authenticate . Если предоставленные учетные данные верны, он возвращает токен, позволяющий клиенту получить доступ к защищенным конечным точкам API. Помните о том, что данный токен предоставляет те же права доступа, что и пароль, и поэтому должен надежно храниться в клиентском приложении. Теперь мы наконец можем поработать с Postman. Откройте приложение и используйте его для отправки post-запроса к /signin/, как показано на скриншоте.

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

 class Task(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) #Каждая задача принадлежит только одному пользователю description = models.CharField(max_length=150) #У каждой задачи есть описание due = models.DateField() #У каждой задачи есть дата выполнения, тип datetime.date 

Модель Task представляет собой довольно простой подход к менеджменту задач нашего приложения. Каждый элемент имеет описание, например, «Написать API с помощью Django» и дату выполнения. Задачи также связаны внешним ключом с объектом Django User , что означает, что каждая задача принадлежит только одному конкретному пользователю, но каждый пользователь может иметь неограниченное количество задач или не иметь вовсе. Каждый объект Django также имеет идентификатор, уникальное целое число, которое можно использовать для ссылки на индивидуальные задачи.

Приложения типа этого часто называют CRUD-приложениями, от «Create, Read, Update, Destroy» (Создание, Чтение, Модификация, Удаление), четырех операций, поддерживаемых нашим приложением на объектах Task.

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

 @define_usage(returns='tasks': 'Dict'>) @api_view(['GET']) @authentication_classes((SessionAuthentication, BasicAuthentication, TokenAuthentication)) @permission_classes((IsAuthenticated,)) def api_all_tasks(request): tasks = taskSerializer(request.user.task_set.all(), many=True) return Response('tasks': tasks.data>) 

Функция api_all_tasks довольно проста. Стоит обратить внимание лишь на смену требований к проверке подлинности и классов разрешения на аутентификацию токеном. У нас есть новый декоратор @authentication_classes , позволяющий выполнять как дефолтные методы аутентификации Django REST framework, так и TokenAuthentication . Это позволяет нам ссылаться на все экземпляры User как на request.user , как если бы пользователи залогинились через стандартную Django-сессию. Декоратор @define_usage показывает нам, что api_all_tasks не принимает параметров (в отличие от GET-запроса) и возвращает лишь одну вещь — список задач. Поскольку данная функция возвращает данные в формате JSON (JavaScript Object Notation), мы используем сериализатор, чтобы сообщить Django, как парсить данные для отправки.

 class taskSerializer(serializers.ModelSerializer): class Meta: model = Task fields = ('id', 'description', 'due') 

Эта простая модель определяет данные для класса Task: идентификатор, описание и дату выполнения. Сериализаторы могут добавлять и исключать поля и данные из модели. Например, вот этот сериализатор не возвращает идентификатор пользователя, т.к. он бесполезен для конечного клиента.

 @define_usage(params='description': 'String', 'due_in': 'Int'>, returns='done': 'Bool'>) @api_view(['PUT']) @authentication_classes((SessionAuthentication, BasicAuthentication, TokenAuthentication)) @permission_classes((IsAuthenticated,)) def api_new_task(request): task = Task(user=request.user, description=request.data['description'], due=date.today() + timedelta(days=int(request.data['due_in']))) task.save() return Response('done': True>) 

Теперь нам нужно создать задачу. Для этого используем api_new_task . Обычно для создания объекта в базе данных используется PUT-запрос. Обратите внимание, что этот метод, как и два других, не требует предварительной сериализации данных. Вместо этого мы передаем параметры в конструктор объекта класса Task, их же мы затем сохраним в базу данных. Мы отправляем количество дней для выполнения задачи, так как это гораздо проще, чем пытаться отправить объект Python-класса Date . Затем в API мы сохраняем какую-нибудь дату в далеком будущем. Чтобы увидеть созданный объект, нужно создать запрос к /new/ для создания задачи и повторить запрос к /all/.

 @define_usage(params='task_id': 'Int', 'description': 'String', 'due_in': 'Int'>, returns='done': 'Bool'>) @api_view(['POST']) @authentication_classes((SessionAuthentication, BasicAuthentication, TokenAuthentication)) @permission_classes((IsAuthenticated,)) def api_update_task(request): task = request.user.task_set.get(id=int(request.data['task_id'])) try: task.description = request.data['description'] except: #Обновление описания необязательно pass try: task.due = date.today() + timedelta(days=int(request.data['due_in'])) except: #Обновление даты выполнения необязательно pass task.save() return Response('done': True>) 

Для редактирования только что созданной задачи нужно создать POST-запрос к api_update_task через /update/. Мы включаем task_id для ссылки на правильную задачу из пользовательского task_set . Код здесь будет немного сложнее, т.к. мы хотим иметь возможность обновлять описания и/ или дату выполнения задачи.

 @define_usage(params='task_id': 'Int'>, returns='done': 'Bool'>) @api_view(['DELETE']) @authentication_classes((SessionAuthentication, BasicAuthentication, TokenAuthentication)) @permission_classes((IsAuthenticated,)) def api_delete_task(request): task = request.user.task_set.get(id=int(request.data['task_id'])) task.delete() return Response('done': True>) 

Используйте DELETE-запрос к api_delete_task через /delete/ для удаления задачи. Этот метод работает аналогично функции api_update_task , за исключением того, что вместо изменения задачи он удаляет ее.

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

© Copyright 2014 — 2024 mkdev | Privacy Policy

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *