refactor: use requests sync, graceful config import

This commit is contained in:
2026-07-27 00:14:39 +07:00
parent 13f99579f5
commit 42335ce015
+60 -51
View File
@@ -1,18 +1,28 @@
#!/usr/bin/env python3
"""Получение списка заявок из ServiceDesk Plus с 20 июля 2026. Экспорт: Группа, Описание, Назначено, Категория в JSONL."""
"""Получение списка заявок из ServiceDesk Plus. Экспорт: Группа, Описание, Назначено, Категория в JSONL."""
import asyncio
import httpx
import requests
import json
import urllib3
from datetime import datetime, timezone
from datetime import datetime
from html import unescape
import re
import sys
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 (для выгрузки данных)
LOCAL_SD_URL = "https://192.168.1.237:8080"
@@ -43,67 +53,66 @@ def get_name(obj):
return obj.get("name", "") or obj.get("display_value", "")
return str(obj)
async def fetch_ticket_detail(client, req_id):
def get_ticket_detail(ticket_id):
"""Получить детальную информацию по заявке."""
try:
resp = await client.get(
f"{LOCAL_SD_URL}/api/v3/requests/{req_id}",
headers={"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"},
timeout=15.0
)
url = f"{LOCAL_SD_URL}/api/v3/requests/{ticket_id}"
headers = {"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
resp = requests.get(url, headers=headers, verify=False, timeout=15.0)
resp.raise_for_status()
data = resp.json()
return data.get("request", data)
except Exception as e:
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"
headers = {"authtoken": LOCAL_SD_API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
# Вычисляем timestamp с указанной даты
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 = await client.get(url, headers=headers)
data = resp.json()
all_reqs = data.get("requests", [])
resp = requests.get(url, headers=headers, verify=False, timeout=30.0)
resp.raise_for_status()
data = resp.json()
all_reqs = data.get("requests", [])
from_date_reqs = [r for r in all_reqs if get_ts(r) >= from_date_ms]
# Получаем детали для каждой заявки
rows = []
for req in from_date_reqs:
req_id = req.get("request_id", req.get("id", "?"))
detail = get_ticket_detail(req_id)
from_date_reqs = [r for r in all_reqs if get_ts(r) >= from_date_ms]
# Группа — из списка
group = req.get("group", {})
group_name = get_name(group)
# Получаем детали для каждой заявки
tasks = [fetch_ticket_detail(client, r.get("request_id", r.get("id", "?"))) for r in from_date_reqs]
details = await asyncio.gather(*tasks)
# Описание — из детального запроса
desc = detail.get("description", "")
desc_clean = clean_html(desc)
rows = []
for req, detail in zip(from_date_reqs, details):
# Группа — из списка
group = req.get("group", {})
group_name = get_name(group)
# Описание — из детального запроса
desc = detail.get("description", "")
desc_clean = clean_html(desc)
# Назначено (специалист) — из детального запроса
tech = detail.get("technician", {})
assignee = get_name(tech)
# Категория — из детального запроса
cat = detail.get("category", {})
category = get_name(cat)
rows.append({
"group": group_name,
"description": desc_clean,
"assignee": assignee,
"category": category
})
# Назначено (специалист) — из детального запроса
tech = detail.get("technician", {})
assignee = get_name(tech)
# Выводим JSONL
for row in rows:
print(json.dumps(row, ensure_ascii=False))
# Категория — из детального запроса
cat = detail.get("category", {})
category = get_name(cat)
rows.append({
"group": group_name,
"description": desc_clean,
"assignee": assignee,
"category": category
})
# Выводим JSONL
for row in rows:
print(json.dumps(row, ensure_ascii=False))
if __name__ == "__main__":
urllib3.disable_warnings()
from_date = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_FROM_DATE
asyncio.run(list_tickets(from_date))
list_tickets(from_date)