Skip to content

Commit 1319940

Browse files
API GLPI
1 parent 7550fd8 commit 1319940

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

kiosk_interface/views/glpi_api.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import requests
2+
import json
3+
# --- Configuration ---
4+
from kiosk_interface.config import ConfParameter
5+
6+
conf = ConfParameter()
7+
8+
GLPI_URL = conf.glpi_url
9+
APP_TOKEN = conf.glpi_app_token
10+
API_TOKEN = conf.glpi_api_token
11+
12+
13+
# --- Connexion à la session ---
14+
def init_session():
15+
headers = {
16+
"App-Token": APP_TOKEN,
17+
"Authorization": f"user_token {API_TOKEN}"
18+
}
19+
r = requests.get(f"{GLPI_URL}/initSession", headers=headers)
20+
r.raise_for_status()
21+
session_token = r.json()["session_token"]
22+
23+
# On renvoie directement les headers prêts à être réutilisés
24+
session_headers = {
25+
"App-Token": APP_TOKEN,
26+
"Session-Token": session_token,
27+
"Content-Type": "application/json"
28+
}
29+
return session_headers
30+
31+
# --- Déconnexion ---
32+
def kill_session(session_headers):
33+
requests.get(f"{GLPI_URL}/killSession", headers=session_headers)
34+
35+
# --- Création ticket ---
36+
def create_ticket(session_headers, title, content):
37+
payload = {
38+
"input": {
39+
"name": title,
40+
"content": content
41+
}
42+
}
43+
r = requests.post(f"{GLPI_URL}/Ticket", headers=session_headers, json=payload)
44+
r.raise_for_status()
45+
return r.json()["id"]
46+
47+
# --- Upload capture ---
48+
def upload_document(session_headers, ticket_id, file_path):
49+
headers = {
50+
"App-Token": APP_TOKEN,
51+
"Session-Token": session_headers["Session-Token"]
52+
}
53+
files = {
54+
"uploadManifest": (
55+
None,
56+
'{"input": {"name": "screenshot.png","_filename":"screenshot.png","items_id": %d,"itemtype": "Ticket"}}' % ticket_id,
57+
"application/json"
58+
),
59+
"file": open(file_path, "rb")
60+
}
61+
r = requests.post(f"{GLPI_URL}/Document", headers=headers, files=files)
62+
r.raise_for_status()
63+
return r.json()
64+
65+
# --- Historique (followups) d’un ticket ---
66+
def list_ticket_followups(session_headers, ticket_id: int):
67+
"""Récupère les followups d'un ticket GLPI - VERSION CORRIGÉE"""
68+
try:
69+
# MÉTHODE 1: Essayer avec search
70+
params = {
71+
'criteria[0][field]': '4', # items_id (champ 4)
72+
'criteria[0][searchtype]': 'equals',
73+
'criteria[0][value]': str(ticket_id),
74+
'criteria[1][field]': '3', # itemtype (champ 3)
75+
'criteria[1][searchtype]': 'equals',
76+
'criteria[1][value]': 'Ticket',
77+
'forcedisplay[0]': '2', # content
78+
'forcedisplay[1]': '4', # items_id
79+
'forcedisplay[2]': '5', # date
80+
'forcedisplay[3]': '19' # users_id_editor
81+
}
82+
83+
r = requests.get(f"{GLPI_URL}/search/ITILFollowup", headers=session_headers, params=params)
84+
print(f"DEBUG search: {r.status_code} - {r.text[:200]}")
85+
86+
if r.status_code == 200:
87+
data = r.json()
88+
if 'data' in data and data['data']:
89+
return data['data']
90+
91+
# MÉTHODE 2: Si search échoue, essayer directement
92+
print("Tentative méthode directe...")
93+
r2 = requests.get(f"{GLPI_URL}/Ticket/{ticket_id}/ITILFollowup", headers=session_headers)
94+
print(f"DEBUG direct: {r2.status_code} - {r2.text[:200]}")
95+
96+
if r2.status_code == 200:
97+
return r2.json()
98+
99+
# MÉTHODE 3: Dernière tentative avec paramètres simplifiés
100+
print("Tentative méthode simplifiée...")
101+
simple_params = {'items_id': ticket_id, 'itemtype': 'Ticket'}
102+
r3 = requests.get(f"{GLPI_URL}/ITILFollowup", headers=session_headers, params=simple_params)
103+
print(f"DEBUG simple: {r3.status_code} - {r3.text[:200]}")
104+
105+
if r3.status_code == 200:
106+
return r3.json()
107+
108+
return []
109+
110+
except Exception as e:
111+
print(f"Erreur dans list_ticket_followups: {e}")
112+
return []
113+
114+
# --- Ajouter une réponse (followup) sur un ticket ---
115+
def add_ticket_followup(session_headers, ticket_id: int, content: str):
116+
"""Ajoute un followup à un ticket - VERSION CORRIGÉE"""
117+
try:
118+
# CORRECTION: Structure correcte du payload
119+
payload = {
120+
"input": {
121+
"itemtype": "Ticket",
122+
"items_id": int(ticket_id),
123+
"content": content
124+
}
125+
}
126+
127+
print(f"DEBUG payload: {json.dumps(payload, indent=2)}")
128+
129+
r = requests.post(f"{GLPI_URL}/ITILFollowup", headers=session_headers, json=payload)
130+
print(f"DEBUG response: {r.status_code} - {r.text}")
131+
132+
if r.status_code == 201: # Created
133+
return r.json().get("id")
134+
elif r.status_code == 200: # OK
135+
return r.json().get("id", 1)
136+
else:
137+
r.raise_for_status()
138+
139+
except Exception as e:
140+
print(f"Erreur dans add_ticket_followup: {e}")
141+
raise e
142+
143+
# --- Récupérer le statut d’un ticket ---
144+
def get_ticket_status(session_headers, ticket_id: int) -> int:
145+
r = requests.get(f"{GLPI_URL}/Ticket/{ticket_id}", headers=session_headers)
146+
r.raise_for_status()
147+
data = r.json()
148+
return int(data.get("status", 1)) # 1=New, 2=Assigned, 3=Planned, 4=Waiting, 5=Solved, 6=Closed
149+
150+
# --- Exemple d’utilisation ---
151+
if __name__ == "__main__":
152+
session = init_session()
153+
ticket_id = create_ticket(session, "Bug avec l’application", "Voici une capture d’écran du problème")
154+
print(f"✅ Ticket créé avec ID {ticket_id}")
155+
156+
# Joindre capture d’écran
157+
resp = upload_document(session, ticket_id, "screenshot.png")
158+
print("📎 Capture ajoutée :", resp)
159+
160+
# Historique du ticket
161+
history = list_ticket_followups(session, ticket_id)
162+
print("📜 Historique :", history)
163+
164+
# Ajouter un suivi
165+
add_ticket_followup(session, ticket_id, "Nouvelle réponse depuis l’API")
166+
print("💬 Réponse envoyée à GLPI")
167+
168+
# Vérifier statut
169+
status = get_ticket_status(session, ticket_id)
170+
print("📌 Statut actuel :", status)
171+
172+
kill_session(session)

0 commit comments

Comments
 (0)