Skip to main content

glpi-testkit

Generate realistic ITIL tickets for GLPI — in French, Arabic and Darija — without touching a single real ticket.

CI PyPI Python License Typed

Seeded and reproducible. No dependencies.


Why

You need ticket data — to demo a plugin, load-test an instance, or train a classifier. Real tickets are full of personal data and usually cannot leave the building, which stops the project before it starts.

The usual workaround is a loop that writes "Test ticket 1, Test ticket 2". That tells you nothing: no priority distribution, no escalations, no language mix, nothing a model or a dashboard could learn from.

This package generates tickets that behave like real ones, and that contain no personal data by construction — there is no source dataset to leak from.

Installation

pip install glpi-testkit

Use it

# 1000 tickets, reproducible, with a distribution summary
glpi-testkit -n 1000 --seed 42 --stats -o tickets.json

# Darija only, VPN incidents only
glpi-testkit -n 200 -l ary -c network.vpn -o darija-vpn.json

# Ready to POST to the GLPI API
glpi-testkit -n 50 --glpi-input -o payload.json

# See the catalogue
glpi-testkit --list-categories
from glpi_testkit import TicketGenerator, Language

generator = TicketGenerator(seed=42, languages=[Language.FRENCH, Language.DARIJA])
tickets = generator.generate(1000)

print(tickets[0].name, tickets[0].priority.name, tickets[0].language)
print(tickets[0].to_glpi_input())  # ready for the GLPI REST API

What makes the data usable

It follows GLPI's own priority rules

GLPI does not average urgency and impact — it looks the pair up in a configurable 5×5 matrix. The default below was read out of a stock GLPI 11 install, and the arithmetic fallback in CommonITILObject::computePriority is reproduced too, so a ticket generated here carries the priority a real GLPI would have computed.

         impact:  1  2  3  4  5
urgency 1:        1  1  2  2  2
urgency 2:        1  2  2  3  3
urgency 3:        2  2  3  4  4
urgency 4:        2  3  4  4  5
urgency 5:        2  3  4  5  5
from glpi_testkit import compute_priority

compute_priority(urgency=4, impact=5)  # Level.VERY_HIGH

Pass your own matrix if you have customised yours: TicketGenerator(priority_matrix=my_matrix).

The lifecycle holds together

Every ticket carries a coherent history, which is what makes the data worth training on: timestamps are ordered, only assigned tickets have an assignee, only solved ones have a solve date, delay statistics match their dates, and high-priority tickets get escalated and bounce between groups.

stateDiagram-v2
    [*] --> NEW
    NEW --> ASSIGNED: picked up
    ASSIGNED --> ASSIGNED: escalated / reassigned
    ASSIGNED --> WAITING: awaiting requester
    ASSIGNED --> PLANNED: scheduled
    WAITING --> ASSIGNED
    ASSIGNED --> SOLVED: solution provided
    SOLVED --> CLOSED: validated
    CLOSED --> [*]

    note right of NEW
        4% stay here
    end note
    note right of CLOSED
        55% end here,
        as in a real export
    end note

SLA pressure is a dial, not an accident

sla_pressure scales resolution time against each category's target. Measured over 3000 tickets across five seeds:

sla_pressure tickets breaching SLA
0.2 (default) 13–14% — a desk meeting its targets
0.35 23%
0.5 32%
1.0 49% — a team in crisis

The three languages are written properly

French, Modern Standard Arabic, and Darija in both Arabic script and Latin letters (arabizi) — because that is what a Moroccan service desk actually receives.

fr   Le scanner de l'agence de Rabat est hors service depuis deux semaines.
ar   تظهر الطابعة رسالة انحشار الورق رغم أن الدرج فارغ.
ary  l vpn kat9ta3 kol chi 10 d daqayq, tan7iyed men SAP kol mrra.

Slot substitution is the easy way to get variety and the easy way to produce broken grammar — "un imprimante", "du agence", "de le CRM", or an Arabic feminine verb against a masculine noun. Every slot therefore carries its own article, preposition and gender, and a dedicated test suite scans thousands of generated sentences for each fault class.

Darija written in Latin letters is deliberately left lowercase: users really do type it that way, and that is what a classifier will meet in production.

Native review welcome. The Arabic and Darija phrasings are written to be idiomatic, but a native reviewer will always improve them — corrections are the single most useful pull request this project can receive.

Load it into GLPI

With glpi-rest:

from glpi_rest import GLPIClient
from glpi_testkit import TicketGenerator

tickets = TicketGenerator(seed=42).generate(200)

with GLPIClient(url, app_token=..., user_token=...) as glpi:
    for ticket in tickets:
        glpi.add_item("Ticket", ticket.to_glpi_input())

to_glpi_input() emits only the fields the API accepts on creation, with GLPI's integer enums and Y-m-d H:i:s timestamps. to_dict() gives you everything instead — events, delay statistics, requester and assignee — for offline work.

The catalogue

Key Type SLA Covers
network.vpn incident 4 h VPN drops, connection failures
hardware.printer incident 24 h paper jams, dead devices
account.password request 2 h resets, locked accounts
software.crash incident 8 h application crashes
email.mailbox incident 8 h full mailboxes, attachments
request.equipment request 72 h new starters, replacements
security.phishing incident 2 h suspicious mail reports

Urgency and impact ranges are set per category, so a jammed printer never outranks a security incident by chance.

Privacy

There is no source dataset. Every name, phrase and reference in this package was invented, and a test asserts the output contains nothing shaped like a Moroccan phone number, RIB or ICE.

That is the point: it lets you build and publish on ticket data without ever processing a customer's. If you also need to clean a real export, see glpi-anonymizer.

Limitations

  • Seven categories today. Real service desks have dozens — new catalogue entries are the most useful contribution.
  • Text is template-based, so lexical variety is bounded by the catalogue. It is built for structure, volume and language mix, not for fooling a human reader into thinking a person wrote it.
  • Timestamps ignore business hours and public holidays.

Contributing

See CONTRIBUTING.md.

git clone https://github.com/novagiosAI/glpi-testkit.git
cd glpi-testkit
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pytest

License

Apache License 2.0 — free for commercial use.


Built and maintained by Novagios — IT services, AI and ITSM.

Metadata

Release files for glpi-testkit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for glpi-testkit 0.1.0
File Size Uploaded
glpi_testkit-0.1.0.tar.gz 31.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glpi-testkit 0.1.0
File Interpreter ABI Platform
glpi_testkit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 57.9 kB

Release files / glpi_testkit-0.1.0.tar.gz

Download URL glpi_testkit-0.1.0.tar.gz
Size 31.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d71f05eb24a31a68e5f6c8e81db20c585a0fb1f6f3e4a18a814c3fa0045acadc
BLAKE2b-256 checksum
How to use checksums
2cfaa23142775ad91ce301e4294f27734e8b9219a9a42294dc4660a57e0b7738
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / glpi_testkit-0.1.0-py3-none-any.whl

Download URL glpi_testkit-0.1.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eee1717e7a8a1c10188de52de16a3cdb80c154836760fc6396ce2dfc295e510b
BLAKE2b-256 checksum
How to use checksums
bdcfdfec2c3a5dc910feb5eed732911f3159685683cdfb351c29c0b1ff7175a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page