import requests import logging import hashlib # Настройка логирования logger = logging.getLogger(__name__) # Уровень логирования настраивается в основном модуле app.py # logger.setLevel(logging.DEBUG) class ReqModule: def __init__(self, host, rmsLogin, password): self.host = host self.rmsLogin = rmsLogin # Пароль для API iiko/Syrve должен передаваться в виде SHA1-хэша self.password = hashlib.sha1(password.encode('utf-8')).hexdigest() self.token = None self.session = requests.Session() def login(self): """Выполняет авторизацию на сервере RMS и получает токен.""" logger.info(f"Вызов метода login с логином: {self.rmsLogin}") try: response = self.session.post( f'{self.host}/api/auth', data={'login': self.rmsLogin, 'pass': self.password}, headers={'Content-Type': 'application/x-www-form-urlencoded'} ) response.raise_for_status() # Вызовет исключение для статусов 4xx/5xx self.token = response.text logger.info(f'Успешно получен токен: {self.token[:8]}...') # Логируем только часть токена return True except requests.exceptions.HTTPError as e: if e.response.status_code == 401: logger.error(f'Ошибка авторизации (401). Неверный логин или пароль. Ответ сервера: {e.response.text}') else: logger.error(f'HTTP ошибка при авторизации: {e}') return False # Возвращаем False вместо выброса исключения для удобства обработки в app.py except Exception as e: logger.error(f'Непредвиденная ошибка в login: {str(e)}') raise # Выбрасываем исключение для критических ошибок (например, недоступность хоста) def logout(self): """Освобождает токен авторизации на сервере RMS.""" if not self.token: logger.warning("Попытка вызова logout без активного токена.") return False try: response = self.session.post( f'{self.host}/api/logout', data={'key': self.token}, headers={'Content-Type': 'application/x-www-form-urlencoded'} ) if response.status_code == 200: logger.info(f"Токен {self.token[:8]}... успешно освобожден.") self.token = None return True else: logger.warning(f"Не удалось освободить токен. Статус: {response.status_code}, Ответ: {response.text}") return False except Exception as e: logger.error(f'Ошибка при освобождении токена: {str(e)}') raise def take_olap(self, params): """Отправляет кастомный OLAP-запрос на сервер RMS.""" if not self.token: raise Exception("Невозможно выполнить запрос take_olap: отсутствует токен авторизации.") try: cookies = {'key': self.token} response = self.session.post( f'{self.host}/api/v2/reports/olap', json=params, cookies=cookies ) response.raise_for_status() # Проверка на HTTP ошибки return response.json() except requests.exceptions.RequestException as e: logger.error(f'Ошибка при выполнении OLAP-запроса: {e}. URL: {e.request.url if e.request else "N/A"}') raise Exception(f'Ошибка сети при запросе OLAP: {e}') except Exception as e: logger.error(f'Непредвиденная ошибка в take_olap: {str(e)}') raise def take_presets(self): """Получает список доступных OLAP-отчетов (пресетов) с сервера RMS.""" if not self.token: raise Exception("Невозможно выполнить запрос take_presets: отсутствует токен авторизации.") try: cookies = {'key': self.token} response = self.session.get( f'{self.host}/api/v2/reports/olap/presets', cookies=cookies ) response.raise_for_status() # Проверка на HTTP ошибки presets = response.json() logger.info(f"Успешно получено {len(presets)} пресетов OLAP-отчетов.") return presets except requests.exceptions.RequestException as e: logger.error(f"Сетевая ошибка при получении пресетов: {e}") raise Exception(f'Ошибка сети при получении пресетов: {e}') except Exception as e: logger.error(f'Непредвиденная ошибка в take_presets: {str(e)}') raise