Python library for working with the GLPI REST API (9.1+, 10.x, 11.x)
Project description
python-glpi-utils
python-glpi-utils is a Python library for working with the GLPI REST API.
It provides:
- A synchronous client (
GlpiAPI) powered byrequests. - An asynchronous client (
AsyncGlpiAPI) powered byaiohttp. - OAuth2 clients (
GlpiOAuthClient/AsyncGlpiOAuthClient) for the GLPI 11+ high-level API (/api.php) with automatic token refresh. - Auto-pagination (
get_all_pages/iter_pages) — fetch every item across all pages with one call. - Fluent item-type accessors (
api.ticket,api.computer,api.user, …) so you writeapi.ticket.get_all_pages()instead of building raw HTTP calls. - A
SensitiveFilterthat masks passwords and tokens in debug logs automatically. - A
GLPIVersionhelper for comparing GLPI versions. - A clean exception hierarchy so you can catch exactly what you need.
Compatibility:
- Legacy REST API (
/apirest.php): GLPI 9.1 and above (tested on 10.x and 11.x)- High-level OAuth2 API (
/api.php): GLPI 11+ only
Requirements
| Dependency | Version |
|---|---|
| Python | ≥ 3.9 |
| GLPI | ≥ 9.1 |
| requests | ≥ 2.28 |
| aiohttp | ≥ 3.9 (async only) |
Installation
From PyPI
pip install glpi-utils
With async support:
pip install glpi-utils[async]
From source
git clone https://github.com/giovanny07/python-glpi-utils
cd python-glpi-utils
pip install -e .[async]
Quick start
Synchronous
from glpi_utils import GlpiAPI
api = GlpiAPI(url="https://glpi.example.com", app_token="YOUR_APP_TOKEN")
api.login(username="glpi", password="glpi")
print("GLPI version:", api.version) # GLPIVersion('10.0.19')
print(api.version > 10.0) # True
tickets = api.ticket.get_all(range="0-9", expand_dropdowns=True)
for t in tickets:
print(f"[{t['id']}] {t['name']}")
api.logout()
Asynchronous
import asyncio
from glpi_utils import AsyncGlpiAPI
async def main():
api = AsyncGlpiAPI(url="https://glpi.example.com")
await api.login(username="glpi", password="glpi")
version = await api.get_version()
print("GLPI version:", version)
tickets = await api.ticket.get_all(range="0-9")
for t in tickets:
print(f"[{t['id']}] {t['name']}")
await api.logout()
asyncio.run(main())
Context manager (auto-logout)
# Sync
with GlpiAPI(url="https://glpi.example.com") as api:
api.login(username="glpi", password="glpi")
print(api.version)
# Async
async with AsyncGlpiAPI(url="https://glpi.example.com") as api:
await api.login(username="glpi", password="glpi")
version = await api.get_version()
Authentication
Three methods are supported (sync and async):
# 1. Username + password (Basic Auth)
api.login(username="glpi", password="glpi")
# 2. Personal API token (from user profile → Remote access key)
api.login(user_token="q56hqkniwot8wntb3z1qarka5atf365taaa2uyjrn")
# 3. Environment variables (no arguments needed)
# GLPI_URL, GLPI_USER, GLPI_PASSWORD, GLPI_USER_TOKEN, GLPI_APP_TOKEN
api = GlpiAPI() # reads GLPI_URL
api.login() # reads GLPI_USER + GLPI_PASSWORD or GLPI_USER_TOKEN
Item-type accessors
All standard GLPI item types are available as attributes:
| Attribute | GLPI itemtype |
|---|---|
api.ticket |
Ticket |
api.computer |
Computer |
api.monitor |
Monitor |
api.printer |
Printer |
api.networkequipment |
NetworkEquipment |
api.software |
Software |
api.user |
User |
api.group |
Group |
api.entity |
Entity |
api.location |
Location |
api.category |
ITILCategory |
api.problem |
Problem |
api.change |
Change |
api.project |
Project |
api.projecttask |
ProjectTask |
api.document |
Document |
api.contract |
Contract |
api.knowledgebase |
KnowbaseItem |
api.followup |
ITILFollowup |
api.solution |
ITILSolution |
api.task |
TicketTask |
For any other item type use api.item("YourItemtype"):
proxy = api.item("KnowbaseItem")
articles = proxy.get_all(range="0-4")
Auto-pagination
By default get_all() returns a single page (50 items). Use get_all_pages() to retrieve everything automatically:
# All tickets — pagination handled transparently
all_tickets = api.ticket.get_all_pages()
# With filters
open_tickets = api.ticket.get_all_pages(
sort="date_mod",
order="DESC",
is_deleted=False,
)
# Custom page size (fewer round-trips on fast networks)
computers = api.computer.get_all_pages(page_size=100, expand_dropdowns=True)
print(f"Total: {len(all_tickets)} tickets")
For large datasets, use iter_pages() to process items batch by batch without loading everything into RAM:
total = 0
for page in api.ticket.iter_pages(page_size=100):
for ticket in page:
process(ticket)
total += 1
print(f"Processed {total} tickets")
# Async version
async for page in api.ticket.iter_pages(page_size=100):
for ticket in page:
await process(ticket)
OAuth2 (High-level API — GLPI 11+ only)
For the GLPI 11+ high-level API (/api.php), use the OAuth2 clients:
from glpi_utils.oauth import GlpiOAuthClient
# Client credentials grant (service accounts, scripts)
with GlpiOAuthClient(
url="https://glpi.example.com",
client_id="my-app",
client_secret="my-secret",
) as api:
api.authenticate()
tickets = api.ticket.get_all_pages()
# Password grant (user-delegated)
api = GlpiOAuthClient(url="https://glpi.example.com", client_id="my-app")
api.authenticate(username="glpi", password="glpi")
computers = api.computer.get_all_pages()
api.close()
# Async
from glpi_utils.oauth import AsyncGlpiOAuthClient
async with AsyncGlpiOAuthClient(
url="https://glpi.example.com",
client_id="my-app",
client_secret="my-secret",
) as api:
await api.authenticate()
tickets = await api.ticket.get_all_pages()
The OAuth2 clients support all the same CRUD, sub-item, search and pagination methods as GlpiAPI.
Environment variables: GLPI_OAUTH_CLIENT_ID, GLPI_OAUTH_CLIENT_SECRET, GLPI_OAUTH_USERNAME, GLPI_OAUTH_PASSWORD.
CRUD operations
Every item-type accessor exposes the same set of methods:
# Read
ticket = api.ticket.get(1, expand_dropdowns=True)
tickets = api.ticket.get_all(range="0-49", sort="date_mod", order="DESC")
# Search engine
results = api.ticket.search(
criteria=[{"field": 12, "searchtype": "equals", "value": 1}],
forcedisplay=[1, 3, 12],
range="0-49",
)
# Create
new = api.ticket.create({
"name": "Service degraded",
"content": "Users report slow response times.",
"type": 1,
"status": 1,
"urgency": 3,
"impact": 3,
"priority": 3,
})
# Update (id required)
api.ticket.update({"id": new["id"], "status": 2}) # Assigned
# Delete
api.ticket.delete({"id": new["id"]}) # to trash
api.ticket.delete({"id": new["id"]}, force_purge=True) # permanent
Sub-items (followups, tasks, solutions)
# Read followups
followups = api.ticket.get_sub_items(1, "ITILFollowup")
# Add a followup
api.ticket.add_sub_item(1, "ITILFollowup", {
"content": "Confirmed issue on node 3.",
"is_private": 0,
})
GLPIVersion
ver = api.version
print(type(ver).__name__, ver) # GLPIVersion 10.0.19
print(ver > 10.0) # True
print(ver == "10.0.19") # True
print(ver.major) # 10
print(ver.minor) # 0
print(ver.patch) # 19
Error handling
from glpi_utils import (
GlpiError,
GlpiAPIError,
GlpiAuthError,
GlpiNotFoundError,
GlpiPermissionError,
)
try:
ticket = api.ticket.get(99999)
except GlpiNotFoundError:
print("Ticket does not exist")
except GlpiPermissionError:
print("Insufficient rights")
except GlpiAuthError:
print("Session expired – re-login")
except GlpiAPIError as e:
print(f"API error {e.error_code}: {e.message}")
except GlpiError:
print("Generic library error")
Enabling debug logging
The library is silent by default. Enable with standard logging:
import logging
logging.basicConfig(level=logging.DEBUG)
from glpi_utils import GlpiAPI
api = GlpiAPI(url="https://glpi.example.com")
api.login(username="glpi", password="glpi")
Passwords, tokens and session IDs are masked automatically by SensitiveFilter. To add your own handler with masking:
from glpi_utils import SensitiveFilter
handler = logging.StreamHandler()
handler.addFilter(SensitiveFilter())
logging.getLogger("glpi_utils").addHandler(handler)
logging.getLogger("glpi_utils").setLevel(logging.DEBUG)
Running the tests
pip install -e ".[async,dev]"
pytest
License
python-glpi-utils is distributed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file glpi_utils-1.4.2.tar.gz.
File metadata
- Download URL: glpi_utils-1.4.2.tar.gz
- Upload date:
- Size: 40.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1a5f55eb92eaa81968f3890ecd6fc83b8ef7345afbed3640e9d9e3e930590d3
|
|
| MD5 |
48b6d0f293604026f31b9ef0f66a2cfe
|
|
| BLAKE2b-256 |
86f615a6a49a211fc1f26807acb6a754424562a323095bd9f5353899c9b9192a
|
File details
Details for the file glpi_utils-1.4.2-py3-none-any.whl.
File metadata
- Download URL: glpi_utils-1.4.2-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
642368c16c727c481905cbc1aee61dcbf65ce8dfd55f7567549282e7c5534bde
|
|
| MD5 |
c0f7705a8b1891d00c93c9dc83cee87e
|
|
| BLAKE2b-256 |
6340100b62778a9ab7bdeb52f49f823d544d8b69c90c21a0c2d574c2b1de840d
|