Metadata-Version: 2.4
Name: glpi-python-client
Version: 0.3.0
Summary: A typed Python client for GLPI ITSM APIs.
Project-URL: Homepage, https://github.com/baraline/glpi_python_client
Project-URL: Documentation, https://glpi-python-client.readthedocs.io/en/latest/
Project-URL: Issues, https://github.com/baraline/glpi_python_client/issues
Project-URL: Source, https://github.com/baraline/glpi_python_client
Author: glpi-python-client contributors
License: MIT
License-File: LICENSE
Keywords: api,client,glpi,itsm
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: lxml>=4.9
Requires-Dist: markdown>=3.6
Requires-Dist: markdownify>=0.13
Requires-Dist: pydantic>=2.8
Requires-Dist: requests>=2.31
Requires-Dist: tenacity>=8.2
Requires-Dist: typing-extensions>=4.7; python_version < '3.11'
Requires-Dist: urllib3>=2.0
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: numpydoc>=1.8; extra == 'dev'
Requires-Dist: pre-commit>=4.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'dev'
Requires-Dist: sphinx<8.2,>=7.2; extra == 'dev'
Requires-Dist: tomli>=2.0; (python_version < '3.11') and extra == 'dev'
Requires-Dist: twine>=5.1; extra == 'dev'
Requires-Dist: types-requests>=2.32; extra == 'dev'
Requires-Dist: vulture>=2.11; extra == 'dev'
Provides-Extra: docs
Requires-Dist: numpydoc>=1.8; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'docs'
Requires-Dist: sphinx<8.2,>=7.2; extra == 'docs'
Requires-Dist: tomli>=2.0; (python_version < '3.11') and extra == 'docs'
Description-Content-Type: text/markdown

# glpi-python-client

[![CI](https://github.com/baraline/glpi_python_client/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/baraline/glpi_python_client/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/baraline/glpi_python_client/branch/main/graph/badge.svg)](https://codecov.io/gh/baraline/glpi_python_client)
[![License](https://img.shields.io/github/license/baraline/glpi_python_client)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://github.com/baraline/glpi_python_client)
[![Docs](https://readthedocs.org/projects/glpi-python-client/badge/?version=latest)](https://glpi-python-client.readthedocs.io/en/latest/)

`glpi-python-client` is a typed Python client for the GLPI REST API.

The goal is to let GLPI integrations work with domain objects instead of raw
JSON payloads. The package exposes Pydantic models for tickets, users,
followups, documents, locations, and related records, while converting GLPI
HTML content into Markdown for Python-side workflows and rendering Markdown
back to HTML for outgoing payloads.

It currently focuses on ticket-centric workflows and exposes two high-level
clients built on top of the GLPI v2 REST API:

- `GlpiClient` — synchronous, blocking client (single source of truth for
  endpoint behaviour).
- `AsyncGlpiClient` — asynchronous facade that wraps every synchronous
  method into a coroutine and dispatches it to a worker thread.

Note that all integration tests using this package are made on GLPI 11.
I cannot make any guarantee of the behaviour on previous versions.

While the package is preparing for 1.0, alot of potential breaking change might happen between versions. A deprecation policy will be put in place once 1.0 is out and the package have been stabilized.

## Installation

```bash
pip install glpi-python-client
```

For local development:

```bash
python -m pip install -e .[dev]
python -m pytest
```

## Quick Start

Create a client with your GLPI v2 API URL and at least one complete auth pair:

- `client_id` and `client_secret`
- `username` and `password`
- both pairs together

### Synchronous client

```python
from glpi_python_client import GlpiClient, PostTicket

with GlpiClient(
    glpi_api_url="https://glpi.example.com/api.php/v2",
    client_id="oauth-client-id",
    client_secret="oauth-client-secret",
    username="api-user",
    password="api-password",
) as glpi:
    ticket_id = glpi.create_ticket(
        PostTicket(
            name="Printer issue",
            content="The printer is not reachable from the office network.",
        )
    )
    ticket = glpi.get_ticket(ticket_id)
    print(ticket.id, ticket.name)
```

### Asynchronous client

```python
import asyncio

from glpi_python_client import AsyncGlpiClient, PostTicket


async def main() -> None:
    async with AsyncGlpiClient(
        glpi_api_url="https://glpi.example.com/api.php/v2",
        client_id="oauth-client-id",
        client_secret="oauth-client-secret",
        username="api-user",
        password="api-password",
    ) as glpi:
        ticket_id = await glpi.create_ticket(
            PostTicket(
                name="Printer issue",
                content="The printer is not reachable from the office network.",
            )
        )
        ticket = await glpi.get_ticket(ticket_id)
        print(ticket.id, ticket.name)


asyncio.run(main())
```

`GlpiClient.from_env()` and `AsyncGlpiClient.from_env()` are also available
when the credentials are already exposed as `GLPI_`-prefixed environment
variables.

### Sync or async?

Both clients expose the exact same endpoint surface and accept the same
constructor arguments. The async client is a thin facade that wraps each
synchronous method into a coroutine dispatched to a worker thread via
`asyncio.to_thread` (or a caller-supplied `concurrent.futures.Executor`).
A shared `threading.Lock` serialises OAuth token acquisition so concurrent
`asyncio.gather(...)` fan-outs cannot race. Pick `GlpiClient` for plain
scripts, CLI tools, and synchronous services; pick `AsyncGlpiClient` when
your application already runs an event loop or when you need concurrent
fan-out (the aggregated `get_ticket_context` and per-ticket
`get_task_statistics` helpers use `asyncio.gather` on the async client).

## Documentation

- [Hosted documentation](https://glpi-python-client.readthedocs.io/en/latest/)
- [API reference](https://glpi-python-client.readthedocs.io/en/latest/api_reference.html)
- [Installation guide](https://glpi-python-client.readthedocs.io/en/latest/installation.html)
- [Development guide](https://glpi-python-client.readthedocs.io/en/latest/development_rtd.html)

To build the Sphinx documentation locally:

```bash
python -m pip install -e .[docs]
python -m sphinx -b html docs docs/_build/html
```

## Sponsoring & Professional services
The development of this package is indirectly supported by [Novahé](https://www.novahe.fr/) & [Constellation](https://www.constellation.fr/).

If you need professional help or services around GLPI, we offer consulting and engineering services to install, maintain or upgarde GLPI instance, as an [official GLPI partner](https://www.glpi-project.org/fr/new-glpi-silver-partner-in-france-novahe/).

