Python · API · Advanced
API Client Class
Wrap an API in a reusable class using requests.Session for clean, maintainable code.
Quick topic start and explanations before exercises (exercises below):
Building APIClient step by step
#Session and client class reference
#Exercises:
Build APIClient with login()
#Create an APIClient class with __init__() and login() methods. __init__ should create requests.Session(). login() should fetch a token and set the Authorization header. Test it by calling login() and making a direct GET to /api/users/profile/ via session.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
# Create self.session
pass
def login(self, username, password):
# Fetch token and set Authorization header
pass
client = APIClient()
client.login('YOUR_USERNAME', 'YOUR_PASSWORD')
# Verify: session should return profile without extra headers
Solution
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('YOUR_USERNAME', 'YOUR_PASSWORD')
profile = client.session.get(f'{client.BASE_URL}/api/users/profile/').json()
print(profile['username'])
Add a login() method
#Extend APIClient with a login(username, password) method that gets a Token and stores it in session.headers. After calling login(), print the Authorization header to confirm it was set.
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
# POST to /api/auth/token/ and set Authorization header
pass
client = APIClient()
client.login('YOUR_USERNAME', 'YOUR_PASSWORD')
print(client.session.headers.get('Authorization'))
Solution
import requests
class APIClient:
BASE_URL = 'https://apilearn.tukas.dev'
def __init__(self):
self.session = requests.Session()
def login(self, username, password):
response = self.session.post(
f'{self.BASE_URL}/api/auth/token/',
json={'username': username, 'password': password},
)
token = response.json()['token']
self.session.headers['Authorization'] = f'Token {token}'
client = APIClient()
client.login('YOUR_USERNAME', 'YOUR_PASSWORD')
print(client.session.headers.get('Authorization'))
Add get_products()
#Add a get_products(**params) method that calls GET /api/products/ with any keyword args as query parameters and returns the parsed JSON. Use it to fetch kitchen products sorted by price.
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/ with params and return JSON
pass
client = APIClient()
client.login('YOUR_USERNAME', 'YOUR_PASSWORD')
data = client.get_products(category='kitchen', ordering='price', page_size=5)
for p in data['results']:
print(p['name'], p['sell_price'])
Solution
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):
response = self.session.get(
f'{self.BASE_URL}/api/products/', params=params,
)
response.raise_for_status()
return response.json()
client = APIClient()
client.login('YOUR_USERNAME', 'YOUR_PASSWORD')
data = client.get_products(category='kitchen', ordering='price', page_size=5)
for p in data['results']:
print(p['name'], p['sell_price'])
Complete APIClient Capstone
#Build a complete APIClient with methods: login(), get_products(**params), get_profile(), add_to_cart(product_slug, quantity=1), clear_cart(). Then use it to: authenticate, fetch products, add the first to the cart, print the profile, and clear the 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
# Use all methods
Solution
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('YOUR_USERNAME', 'YOUR_PASSWORD')
products = client.get_products()
print(f'Products: {len(products)}')
item = client.add_to_cart(products[0]['slug'])
print(f'Cart item id: {item["id"]}')
profile = client.get_profile()
print(f'Logged in as: {profile["username"]}')
client.clear_cart()
print('Cart cleared')
Use the full client
#Using your complete APIClient: login, get all kitchen products, add the cheapest one to the cart, view the cart total, then clear the cart. Print the product name you added and the cart total before clearing.
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}'
return self
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params,
).json()
def get_cart(self):
return self.session.get(f'{self.BASE_URL}/api/cart/').json()
def add_to_cart(self, product_id, quantity=1):
return self.session.post(
f'{self.BASE_URL}/api/cart/items/',
json={'product_id': product_id, 'quantity': quantity},
).json()
def clear_cart(self):
self.session.delete(f'{self.BASE_URL}/api/cart/items/')
# Use the client to complete the full scenario
Solution
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}'
return self
def get_products(self, **params):
return self.session.get(
f'{self.BASE_URL}/api/products/', params=params,
).json()
def get_cart(self):
return self.session.get(f'{self.BASE_URL}/api/cart/').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('YOUR_USERNAME', 'YOUR_PASSWORD')
# Cheapest kitchen product
data = client.get_products(category='kitchen', ordering='price', page_size=1)
cheapest = data['results'][0]
client.add_to_cart(cheapest['slug'])
cart = client.get_cart()
print(cheapest['name'])
print(cart['total_price'])
client.clear_cart()