refactor: use requests sync, graceful config import

This commit is contained in:
2026-07-27 00:14:39 +07:00
parent 13f99579f5
commit 42335ce015
+31 -22
View File
@@ -1,18 +1,28 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Получение списка заявок из ServiceDesk Plus с 20 июля 2026. Экспорт: Группа, Описание, Назначено, Категория в JSONL.""" """Получение списка заявок из ServiceDesk Plus. Экспорт: Группа, Описание, Назначено, Категория в JSONL."""
import asyncio import requests
import httpx
import json import json
import urllib3 import urllib3
from datetime import datetime, timezone from datetime import datetime
from html import unescape from html import unescape
import re import re
import sys import sys
import os import os
# Добавляем путь к конфигу # Отключаем ворнинги для чистой работы консоли
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# --- ИМПОРТ КОНФИГУРАЦИИ ---
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config'))
# Пытаемся импортировать конфиг, но не падаем если Passwork недоступен
try:
from config import *
config_loaded = True
except Exception as e:
config_loaded = False
print(f"⚠️ Конфиг не загружен: {e}")
# Локальный Service Desk (для выгрузки данных) # Локальный Service Desk (для выгрузки данных)
LOCAL_SD_URL = "https://192.168.1.237:8080" LOCAL_SD_URL = "https://192.168.1.237:8080"
@@ -43,39 +53,39 @@ def get_name(obj):
return obj.get("name", "") or obj.get("display_value", "") return obj.get("name", "") or obj.get("display_value", "")
return str(obj) return str(obj)
async def fetch_ticket_detail(client, req_id): def get_ticket_detail(ticket_id):
"""Получить детальную информацию по заявке."""
try: try:
resp = await client.get( url = f"{LOCAL_SD_URL}/api/v3/requests/{ticket_id}"
f"{LOCAL_SD_URL}/api/v3/requests/{req_id}", headers = {"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
headers={"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}, resp = requests.get(url, headers=headers, verify=False, timeout=15.0)
timeout=15.0 resp.raise_for_status()
)
data = resp.json() data = resp.json()
return data.get("request", data) return data.get("request", data)
except Exception as e: except Exception as e:
return {} return {}
async def list_tickets(from_date=DEFAULT_FROM_DATE): def list_tickets(from_date=DEFAULT_FROM_DATE):
url = f"{LOCAL_SD_URL}/api/v3/requests" url = f"{LOCAL_SD_URL}/api/v3/requests"
headers = {"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"} headers = {"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
# Вычисляем timestamp с указанной даты # Вычисляем timestamp с указанной даты
date_obj = datetime.strptime(from_date, "%Y-%m-%d") date_obj = datetime.strptime(from_date, "%Y-%m-%d")
from_date_ms = int(date_obj.replace(tzinfo=timezone.utc).timestamp() * 1000) from_date_ms = int(date_obj.replace(tzinfo=__import__('datetime').timezone.utc).timestamp() * 1000)
async with httpx.AsyncClient(verify=False, timeout=30.0) as client: resp = requests.get(url, headers=headers, verify=False, timeout=30.0)
resp = await client.get(url, headers=headers) resp.raise_for_status()
data = resp.json() data = resp.json()
all_reqs = data.get("requests", []) all_reqs = data.get("requests", [])
from_date_reqs = [r for r in all_reqs if get_ts(r) >= from_date_ms] from_date_reqs = [r for r in all_reqs if get_ts(r) >= from_date_ms]
# Получаем детали для каждой заявки # Получаем детали для каждой заявки
tasks = [fetch_ticket_detail(client, r.get("request_id", r.get("id", "?"))) for r in from_date_reqs]
details = await asyncio.gather(*tasks)
rows = [] rows = []
for req, detail in zip(from_date_reqs, details): for req in from_date_reqs:
req_id = req.get("request_id", req.get("id", "?"))
detail = get_ticket_detail(req_id)
# Группа — из списка # Группа — из списка
group = req.get("group", {}) group = req.get("group", {})
group_name = get_name(group) group_name = get_name(group)
@@ -104,6 +114,5 @@ async def list_tickets(from_date=DEFAULT_FROM_DATE):
print(json.dumps(row, ensure_ascii=False)) print(json.dumps(row, ensure_ascii=False))
if __name__ == "__main__": if __name__ == "__main__":
urllib3.disable_warnings()
from_date = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_FROM_DATE from_date = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_FROM_DATE
asyncio.run(list_tickets(from_date)) list_tickets(from_date)