Python · API · Продвинутый уровень
Класс API-клиента
Оберните API в многоразовый класс с requests.Session для чистого и удобного кода.
Краткое введение в тему и пояснения перед упражнениями (упражнения ниже):
Построение APIClient шаг за шагом
#Справочник Session и класса клиента
#Упражнения:
Базовый класс APIClient
#Создайте класс APIClient с методами __init__() и login(). __init__ должен создавать requests.Session(). login() должен получать токен и устанавливать заголовок авторизации. Протестируйте, вызвав login() и сделав прямой GET к /api/users/profile/ через session.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
# Создать session
pass
def login(self, username, password):
# Получить токен и установить Authorization header
pass
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
# Проверьте: session должна возвращать профиль без дополнительных заголовков
Решение
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
profile = client.session.get(f'{client.BASE_URL}/api/users/profile/').json()
print(profile['username'])
Добавить метод get_products()
#Расширьте APIClient методом get_products(**params), который возвращает список результатов из /api/products/. Протестируйте, вызвав get_products() и get_products(category='chairs').
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
# GET /api/products/ с переданными params
pass
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
print(len(client.get_products()))
print(len(client.get_products(category='chairs')))
Решение
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
print(len(client.get_products()))
print(len(client.get_products(category='chairs')))
Добавить метод add_to_cart()
#Добавьте в APIClient метод add_to_cart(product_slug, quantity=1). Он должен POST-ить к /api/cart/items/ и возвращать ответ. Протестируйте, получив slug первого продукта и добавив его в корзину.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
def add_to_cart(self, product_slug, quantity=1):
# POST к /api/cart/items/ и вернуть ответ
pass
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
slug = client.get_products()[0]['slug']
item = client.add_to_cart(slug, quantity=2)
print(item['id'])
Решение
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
def add_to_cart(self, product_slug, quantity=1):
return self.session.post(
f'{self.BASE_URL}/api/cart/items/',
json={'product_slug': product_slug, 'quantity': quantity},
).json()
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
slug = client.get_products()[0]['slug']
item = client.add_to_cart(slug, quantity=2)
print(item['id'])
Полный класс APIClient
#Соберите полный APIClient с методами: login(), get_products(**params), get_profile(), add_to_cart(product_slug, quantity=1), clear_cart(). Затем используйте его чтобы: авторизоваться, получить продукты, добавить первый в корзину, распечатать профиль и очистить корзину.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
pass
def get_products(self, **params):
pass
def get_profile(self):
pass
def add_to_cart(self, product_slug, quantity=1):
pass
def clear_cart(self):
pass
# Используйте все методы
Решение
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
def get_profile(self):
return self.session.get(f'{self.BASE_URL}/api/users/profile/').json()
def add_to_cart(self, product_slug, quantity=1):
return self.session.post(
f'{self.BASE_URL}/api/cart/items/',
json={'product_slug': product_slug, 'quantity': quantity},
).json()
def clear_cart(self):
self.session.delete(f'{self.BASE_URL}/api/cart/items/')
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
products = client.get_products()
print(f'Продуктов: {len(products)}')
item = client.add_to_cart(products[0]['slug'])
print(f'Добавлен id элемента корзины: {item["id"]}')
profile = client.get_profile()
print(f'Авторизован как: {profile["username"]}')
client.clear_cart()
print('Корзина очищена')
Расширить класс методом place_order()
#Добавьте метод place_order(phone_number) в APIClient. Он должен POST-ить к /api/orders/ и возвращать ответ. Затем напишите скрипт, который использует класс чтобы авторизоваться, добавить продукт, оформить заказ и вывести id и статус заказа.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
def add_to_cart(self, product_slug, quantity=1):
return self.session.post(
f'{self.BASE_URL}/api/cart/items/',
json={'product_slug': product_slug, 'quantity': quantity},
).json()
def place_order(self, phone_number):
# POST к /api/orders/ и вернуть ответ
pass
# Используйте класс для полного процесса заказа
Решение
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
token = self.session.post(f'{self.BASE_URL}/api/auth/token/', json={
'username': username, 'password': password,
}).json()['token']
self.session.headers['Authorization'] = f'Token {token}'
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params
).json()['results']
def add_to_cart(self, product_slug, quantity=1):
return self.session.post(
f'{self.BASE_URL}/api/cart/items/',
json={'product_slug': product_slug, 'quantity': quantity},
).json()
def place_order(self, phone_number):
return self.session.post(
f'{self.BASE_URL}/api/orders/',
json={'phone_number': phone_number},
).json()
client = APIClient()
client.login('ВАШ_ЛОГИН', 'ВАШ_ПАРОЛЬ')
products = client.get_products()
client.add_to_cart(products[0]['slug'])
order = client.place_order('+79991234567')
print(order['id'])
print(order['status'])