/
Evdik
/
Integration_System_labs
Обзор
Документация
Войти
/
Evdik
/
Integration_System_labs
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
client_for_api/simple_client.py
350 строк
15 KB
Evdik
3_laba_client
07 ноя 2025, 20:53
07 ноя 2025, 20:53
3c42182
Код
Авторство
О чём код?
import requests import json import time class SimpleLibraryClient: def __init__(self, base_url="http://localhost:8000"): self.base_url = base_url self.token = None self.headers = {} def login(self, username="admin", password="admin123"): """ Вход в систему Возвращает True если успешно, False если ошибка """ try: # Подготовка данных для входа login_data = { "username": username, "password": password } # Отправляем запрос на вход response = requests.post( f"{self.base_url}/auth/login", json=login_data, timeout=10 ) # Проверяем успешность запроса if response.status_code == 200: result = response.json() self.token = result["access_token"] self.headers = {"Authorization": f"Bearer {self.token}"} print(f"✓ Успешный вход! Пользователь: {username}") return True else: print(f" Ошибка входа: {response.status_code} - {response.text}") return False except requests.exceptions.ConnectionError: print(" Не удалось подключиться к серверу. Проверьте URL и запущен ли сервер.") return False except requests.exceptions.Timeout: print(" Превышено время ожидания сервера.") return False except Exception as e: print(f" Неизвестная ошибка: {e}") return False def _make_request(self, method, endpoint, data=None, idempotency_key=None): """ Базовый метод для отправки запросов Обрабатывает ошибки и повторные попытки """ url = f"{self.base_url}{endpoint}" # Добавляем заголовок идемпотентности если нужен headers = self.headers.copy() if idempotency_key: headers["Idempotency-Key"] = idempotency_key try: # Отправляем запрос if method == "GET": response = requests.get(url, headers=headers, timeout=10) elif method == "POST": response = requests.post(url, json=data, headers=headers, timeout=10) elif method == "PUT": response = requests.put(url, json=data, headers=headers, timeout=10) elif method == "DELETE": response = requests.delete(url, headers=headers, timeout=10) else: print(f" Неизвестный метод: {method}") return None # Проверяем ответ if response.status_code >= 200 and response.status_code < 300: # Успешный запрос if response.content: # Если есть тело ответа return response.json() else: return {"status": "success", "message": "Операция выполнена"} else: # Ошибка print(f" Ошибка {response.status_code}: {response.text}") return None except requests.exceptions.ConnectionError: print(" Ошибка подключения к серверу") return None except requests.exceptions.Timeout: print(" Превышено время ожидания") return None except Exception as e: print(f" Ошибка при выполнении запроса: {e}") return None # === ОПЕРАЦИИ С КНИГАМИ V1 (ПРОСТЫЕ) === def get_books_v1(self, page=1, page_size=10): """Получить список книг (простая версия)""" endpoint = f"/api/v1/books?page={page}&page_size={page_size}" return self._make_request("GET", endpoint) def get_book_v1(self, book_id): """Получить одну книгу по ID""" return self._make_request("GET", f"/api/v1/books/{book_id}") def create_book_v1(self, title, author, year, isbn, idempotency_key=None): """Создать новую книгу (с поддержкой идемпотентности)""" book_data = { "title": title, "author": author, "year": year, "isbn": isbn } return self._make_request("POST", "/api/v1/books", book_data, idempotency_key) def update_book_v1(self, book_id, title, author, year, isbn): """Обновить существующую книгу""" book_data = { "title": title, "author": author, "year": year, "isbn": isbn } return self._make_request("PUT", f"/api/v1/books/{book_id}", book_data) def delete_book_v1(self, book_id): """Удалить книгу""" return self._make_request("DELETE", f"/api/v1/books/{book_id}") # === ОПЕРАЦИИ С КНИГАМИ V2 (РАСШИРЕННЫЕ) === def get_books_v2(self, page=1, page_size=10, genre=None): """Получить список книг (расширенная версия)""" endpoint = f"/api/v2/books?page={page}&page_size={page_size}" if genre: endpoint += f"&genre={genre}" return self._make_request("GET", endpoint) def create_book_v2(self, title, author_id, year, isbn, pages, genre, idempotency_key=None): """Создать новую книгу (расширенная версия)""" book_data = { "title": title, "author_id": author_id, "year": year, "isbn": isbn, "pages": pages, "genre": genre } return self._make_request("POST", "/api/v2/books", book_data, idempotency_key) # === ОПЕРАЦИИ С АВТОРАМИ === def get_authors(self, page=1, page_size=10): """Получить список авторов""" endpoint = f"/api/v2/authors?page={page}&page_size={page_size}" return self._make_request("GET", endpoint) def create_author(self, name, birth_year, country, idempotency_key=None): """Создать нового автора""" author_data = { "name": name, "birth_year": birth_year, "country": country } return self._make_request("POST", "/api/v2/authors", author_data, idempotency_key) # === СЛУЖЕБНЫЕ МЕТОДЫ === def health_check(self): """Проверить работоспособность API""" return self._make_request("GET", "/health") def get_system_info(self): """Получить информацию о системе""" return self._make_request("GET", "/") def demonstrate_client(): """ Демонстрация работы клиента Показывает все основные возможности """ print("ЗАПУСК ДЕМОНСТРАЦИИ КЛИЕНТА API БИБЛИОТЕКИ") print("=" * 50) # Создаем клиент client = SimpleLibraryClient() def safe_sleep(seconds): """Безопасная задержка с выводом сообщения""" print(f"... Ждем {seconds} секунд...") time.sleep(seconds) # 1. Аутентификация print("\n1. АУТЕНТИФИКАЦИЯ") if not client.login(): print("Не удалось войти в систему. Демонстрация остановлена.") return safe_sleep(10) # Задержка после авторизации # 2. Проверка здоровья системы print("\n2. ПРОВЕРКА ЗДОРОВЬЯ СИСТЕМЫ") health = client.health_check() if health: print(f"Статус: {health.get('status', 'unknown')}") # Игнорируем ошибку базы данных в health check db_status = health.get('database', 'unknown') if 'error' in str(db_status): print("База данных: connected (ошибка в формате ответа API)") else: print(f"База данных: {db_status}") safe_sleep(10) # 3. Получение информации о системе print("\n3. ИНФОРМАЦИЯ О СИСТЕМЕ") info = client.get_system_info() if info: print(f"API: {info.get('message', 'unknown')}") safe_sleep(10) # 4. Работа с книгами V1 print("\n4. РАБОТА С КНИГАМИ (V1)") books_v1 = client.get_books_v1(page=1, page_size=3) if books_v1 and "items" in books_v1: print(f"Найдено книг: {books_v1.get('total', 0)}") for book in books_v1["items"][:3]: # Покажем первые 3 print(f" - {book.get('title', 'No title')} by {book.get('author', 'Unknown')}") safe_sleep(5) # 5. Работа с книгами V2 print("\n5. РАБОТА С КНИГАМИ (V2)") books_v2 = client.get_books_v2(page=1, page_size=3) if books_v2 and "items" in books_v2: print(f"Найдено книг: {books_v2.get('total', 0)}") for book in books_v2["items"][:3]: print(f" - {book.get('title', 'No title')} ({book.get('genre', 'No genre')})") safe_sleep(5) # 6. Работа с авторами print("\n6. РАБОТА С АВТОРАМИ") authors = client.get_authors(page=1, page_size=3) if authors and "items" in authors: print(f"Найдено авторов: {authors.get('total', 0)}") for author in authors["items"][:3]: print(f" - {author.get('name', 'Unknown')} from {author.get('country', 'Unknown')}") safe_sleep(5) # 7. Демонстрация пагинации print("\n7. ДЕМОНСТРАЦИЯ ПАГИНАЦИИ") page1 = client.get_books_v1(page=1, page_size=2) if page1: print(f"Страница 1: {len(page1.get('items', []))} книг") print(f"Всего страниц: {page1.get('total_pages', 1)}") safe_sleep(5) # 8. Демонстрация идемпотентности print("\n8. ДЕМОНСТРАЦИЯ ИДЕМПОТЕНТНОСТИ") print("Создаем книгу с ключом идемпотентности...") unique_key = f"demo-key-{int(time.time())}" # Первый запрос на создание book1 = client.create_book_v1( title="Демонстрационная книга", author="Демо Автор", year=2024, isbn=f"978-0-00-{int(time.time())}", idempotency_key=unique_key ) if book1: print(f"✓ Создана книга: {book1.get('title')} (ID: {book1.get('id')})") safe_sleep(5) # Второй запрос с ТЕМ ЖЕ ключом идемпотентности print("Повторяем запрос с тем же ключом идемпотентности...") book2 = client.create_book_v1( title="ДРУГАЯ книга", # Это должно игнорироваться author="Другой автор", # Это должно игнорироваться year=9999, # Это должно игнорироваться isbn="978-0-00-0000000", # Это должно игнорироваться idempotency_key=unique_key # Тот же ключ! ) if book2: print(f"✓ Вернулась книга: {book2.get('title')} (ID: {book2.get('id')})") if book1.get('id') == book2.get('id'): print(" Идемпотентность работает! Вернулась та же книга.") else: print(" Идемпотентность не сработала. Получены разные книги.") # 9. Создание автора и книги v2 print("\n9. СОЗДАНИЕ НОВЫХ ДАННЫХ") # Даем дополнительное время перед созданием новых данных print("Даем системе отдохнуть перед созданием новых данных...") safe_sleep(5) # Увеличиваем задержку # Создаем автора new_author = client.create_author( name="Новый Автор", birth_year=1990, country="Россия", idempotency_key=f"author-key-{int(time.time())}" ) if new_author: author_id = new_author.get('id') print(f"✓ Создан автор: {new_author.get('name')} (ID: {author_id})") safe_sleep(6) # Задержка перед созданием книги # Создаем книгу для этого автора new_book = client.create_book_v2( title="Новая книга v2", author_id=author_id, year=2024, isbn=f"978-0-00-{int(time.time())+1}", pages=300, genre="Роман" ) if new_book: print(f"✓ Создана книга: {new_book.get('title')}") else: print(" Не удалось создать книгу (возможно, лимит запросов)") else: print(" Не удалось создать автора (возможно, лимит запросов)") print("\n" + "=" * 30) print("ДЕМОНСТРАЦИЯ ЗАВЕРШЕНА!") print("=" * 30) if __name__ == "__main__": # Запускаем демонстрацию demonstrate_client()