glpi-python-client 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.gitignore +3 -2
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/PKG-INFO +1 -1
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/api_reference.rst +30 -0
- glpi_python_client-0.3.4/docs/development_rtd.rst +162 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/user_guide.rst +71 -7
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/__init__.py +9 -1
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/_v1_session.py +173 -49
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/tests/test_v1_session.py +184 -21
- glpi_python_client-0.3.2/glpi_python_client/clients/sync_client.py → glpi_python_client-0.3.4/glpi_python_client/clients/_base_client.py +21 -106
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/__init__.py +2 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_document.py +21 -20
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/management/_document.py +1 -7
- glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/__init__.py +10 -0
- glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/_fields.py +411 -0
- glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/tests/test_fields_mixin.py +377 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/async_client.py +14 -90
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_config.py +1 -1
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_http.py +14 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_transport.py +29 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_statistics.py +21 -16
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_statistics_async.py +19 -14
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_statistics.py +2 -2
- glpi_python_client-0.3.4/glpi_python_client/clients/sync_client.py +129 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_api_coverage.py +2 -2
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/__init__.py +10 -0
- glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/__init__.py +19 -0
- glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/_fields.py +177 -0
- glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/tests/__init__.py +0 -0
- glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/tests/test_fields_schemas.py +82 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/_ticket_context.py +12 -9
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/tests/test_ticket_context.py +7 -7
- glpi_python_client-0.3.4/glpi_python_client/py.typed +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/utils.py +2 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/pyproject.toml +1 -1
- glpi_python_client-0.3.2/docs/development_rtd.rst +0 -84
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.pre-commit-config.yaml +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.readthedocs.yaml +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/CONTRIBUTING.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/LICENSE +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/README.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/_static/.gitkeep +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/conf.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/development.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/glpi_api_contract.json +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/index.rst +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/installation.rst +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/publishing.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/publishing_rtd.rst +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/sponsoring.rst +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/auth.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/tests/test_auth.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/_entity.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/_user.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/_team.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/_ticket.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_followup.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_solution.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_task.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/dropdowns/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/dropdowns/_location.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/management/__init__.py +0 -0
- /glpi_python_client-0.3.2/glpi_python_client/py.typed → /glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_async_bridge.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_constants.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_errors.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_filters.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_payloads.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_errors.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_filters.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_http.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_payloads.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_transport.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_pagination_async.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_ticket_context.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_ticket_context_async.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_statistics_async.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_ticket_context.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_async_branches.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_async_smoke.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_glpi_client.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_parity.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_smoke.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/conversion.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/tests/test_conversion.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/_base.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/_common.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/_content.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/_entity.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/_user.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/tests/test_administration_schemas.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/_team.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/_ticket.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/tests/test_assistance_schemas.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/tests/test_content_roundtrip.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_document.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_followup.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_solution.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_task.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/tests/test_timeline_schemas.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/_location.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/tests/test_dropdowns_schemas.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/enums.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/_document.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/tests/test_management_schemas.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/tests/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/__init__.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/fixtures.py +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/README.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-client-setup/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-document-workflow/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-reporting-and-context/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-team-members/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-ticket-timeline/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-ticket-workflow/SKILL.md +0 -0
- {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-user-location-provisioning/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: glpi-python-client
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: A typed Python client for GLPI ITSM APIs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/baraline/glpi_python_client
|
|
6
6
|
Project-URL: Documentation, https://glpi-python-client.readthedocs.io/en/latest/
|
|
@@ -289,6 +289,36 @@ Entities
|
|
|
289
289
|
:undoc-members:
|
|
290
290
|
:show-inheritance:
|
|
291
291
|
|
|
292
|
+
Plugin: Fields (custom fields)
|
|
293
|
+
------------------------------
|
|
294
|
+
|
|
295
|
+
Schemas returned by the GLPI ``Fields`` plugin (legacy v1 REST endpoints).
|
|
296
|
+
The companion mixin methods are exposed on :class:`GlpiClient` /
|
|
297
|
+
:class:`AsyncGlpiClient` as ``list_plugin_fields_containers``,
|
|
298
|
+
``list_plugin_fields_fields``, ``list_item_plugin_field_rows``,
|
|
299
|
+
``create_item_plugin_field_row``, ``update_item_plugin_field_row``,
|
|
300
|
+
``get_ticket_custom_fields`` and ``set_ticket_custom_fields``.
|
|
301
|
+
|
|
302
|
+
.. autoclass:: GetPluginFieldsContainer
|
|
303
|
+
:members:
|
|
304
|
+
:undoc-members:
|
|
305
|
+
:show-inheritance:
|
|
306
|
+
|
|
307
|
+
.. autoclass:: GetPluginFieldsField
|
|
308
|
+
:members:
|
|
309
|
+
:undoc-members:
|
|
310
|
+
:show-inheritance:
|
|
311
|
+
|
|
312
|
+
.. autoclass:: GetPluginFieldsValueRow
|
|
313
|
+
:members:
|
|
314
|
+
:undoc-members:
|
|
315
|
+
:show-inheritance:
|
|
316
|
+
|
|
317
|
+
.. autoclass:: PostPluginFieldsValueRow
|
|
318
|
+
:members:
|
|
319
|
+
:undoc-members:
|
|
320
|
+
:show-inheritance:
|
|
321
|
+
|
|
292
322
|
Enums
|
|
293
323
|
-----
|
|
294
324
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Development
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
Local Setup
|
|
5
|
+
-----------
|
|
6
|
+
|
|
7
|
+
Create a virtual environment and install the development dependencies:
|
|
8
|
+
|
|
9
|
+
.. code-block:: console
|
|
10
|
+
|
|
11
|
+
python -m venv .venv
|
|
12
|
+
.venv\Scripts\activate
|
|
13
|
+
python -m pip install --upgrade pip
|
|
14
|
+
python -m pip install -e .[dev]
|
|
15
|
+
python -m pre_commit install
|
|
16
|
+
|
|
17
|
+
The repository ships a root ``.pre-commit-config.yaml`` that runs Ruff on each
|
|
18
|
+
commit. The lint hook applies safe fixes first, then Ruff formats the touched
|
|
19
|
+
files.
|
|
20
|
+
|
|
21
|
+
Quality Checks
|
|
22
|
+
--------------
|
|
23
|
+
|
|
24
|
+
Run the focused checks before opening a pull request:
|
|
25
|
+
|
|
26
|
+
.. code-block:: console
|
|
27
|
+
|
|
28
|
+
python -m pre_commit run --all-files
|
|
29
|
+
python -m pytest
|
|
30
|
+
python -m ruff check .
|
|
31
|
+
python -m mypy glpi_python_client
|
|
32
|
+
python -m sphinx -b html docs docs/_build/html
|
|
33
|
+
|
|
34
|
+
Integration Tests
|
|
35
|
+
-----------------
|
|
36
|
+
|
|
37
|
+
The ``integration_tests/`` directory holds end-to-end tests that drive a live
|
|
38
|
+
GLPI instance through the synchronous and asynchronous clients. They are
|
|
39
|
+
collected only when secrets resolve to a reachable instance; otherwise each
|
|
40
|
+
test self-skips via ``pytest.skip``. Every test cleans up the records it
|
|
41
|
+
creates in a ``finally`` block, but it is still recommended to point them at
|
|
42
|
+
a non-production GLPI.
|
|
43
|
+
|
|
44
|
+
Markers and CI behaviour
|
|
45
|
+
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
46
|
+
|
|
47
|
+
All integration tests are tagged with the ``integration`` pytest marker
|
|
48
|
+
declared in ``pyproject.toml``. The ``ci.yml`` workflow runs
|
|
49
|
+
``pytest -m "not integration"`` for both the test matrix and the coverage
|
|
50
|
+
job, so the public CI never reaches a live GLPI. The default local
|
|
51
|
+
``python -m pytest`` invocation *does* attempt to collect them, but they
|
|
52
|
+
skip automatically when no secrets are configured.
|
|
53
|
+
|
|
54
|
+
To explicitly opt in or out locally:
|
|
55
|
+
|
|
56
|
+
.. code-block:: console
|
|
57
|
+
|
|
58
|
+
python -m pytest -m integration # run only the live suite
|
|
59
|
+
python -m pytest -m "not integration" # mirror the CI behaviour
|
|
60
|
+
|
|
61
|
+
Configuration
|
|
62
|
+
~~~~~~~~~~~~~
|
|
63
|
+
|
|
64
|
+
The suite reads each value from a file named after the secret under
|
|
65
|
+
``secrets/`` at the repository root, falling back to the matching
|
|
66
|
+
environment variable when the file is absent. The ``secrets/`` directory is
|
|
67
|
+
gitignored. Each file contains a single trimmed value.
|
|
68
|
+
|
|
69
|
+
Required:
|
|
70
|
+
|
|
71
|
+
============================== ========================= ===========================================
|
|
72
|
+
Secret file Environment variable Purpose
|
|
73
|
+
============================== ========================= ===========================================
|
|
74
|
+
``glpi_api_url`` ``GLPI_API_URL`` Base URL of the GLPI v2 API.
|
|
75
|
+
``glpi_client_id_test`` ``GLPI_CLIENT_ID`` OAuth2 client identifier.
|
|
76
|
+
``glpi_client_secret_test`` ``GLPI_CLIENT_SECRET`` OAuth2 client secret.
|
|
77
|
+
``glpi_username`` ``GLPI_USERNAME`` GLPI user for the password grant.
|
|
78
|
+
``glpi_password`` ``GLPI_PASSWORD`` Password for the GLPI user above.
|
|
79
|
+
============================== ========================= ===========================================
|
|
80
|
+
|
|
81
|
+
Optional:
|
|
82
|
+
|
|
83
|
+
============================== ============================= ============================================
|
|
84
|
+
Secret file Environment variable Purpose
|
|
85
|
+
============================== ============================= ============================================
|
|
86
|
+
``glpi_verify_ssl`` ``GLPI_VERIFY_SSL`` Toggle TLS verification (default ``false``).
|
|
87
|
+
``glpi_entity`` ``GLPI_ENTITY`` Active entity id sent on every request.
|
|
88
|
+
``glpi_profile`` ``GLPI_PROFILE`` Active profile id sent on every request.
|
|
89
|
+
``glpi_entity_recursive`` ``GLPI_ENTITY_RECURSIVE`` Include sub-entities (default ``false``).
|
|
90
|
+
``glpi_api_v1_url`` ``GLPI_API_V1_URL`` Base URL of the legacy v1 API.
|
|
91
|
+
``glpi_api_v1_token_user`` ``GLPI_V1_USER_TOKEN`` v1 user token (enables document uploads).
|
|
92
|
+
``glpi_api_v1_app_token`` ``GLPI_V1_APP_TOKEN`` v1 application token paired with the above.
|
|
93
|
+
``glpi_team_member_role`` ``GLPI_TEAM_MEMBER_ROLE`` Role used to add the test user to a ticket.
|
|
94
|
+
============================== ============================= ============================================
|
|
95
|
+
|
|
96
|
+
The v1 secrets are only required for the document-upload test; when they
|
|
97
|
+
are missing that single test skips while the rest of the suite runs.
|
|
98
|
+
|
|
99
|
+
Running the suite
|
|
100
|
+
~~~~~~~~~~~~~~~~~
|
|
101
|
+
|
|
102
|
+
Once secrets are in place:
|
|
103
|
+
|
|
104
|
+
.. code-block:: console
|
|
105
|
+
|
|
106
|
+
python -m pytest integration_tests -m integration
|
|
107
|
+
|
|
108
|
+
Use a disposable GLPI instance or one whose entity is dedicated to
|
|
109
|
+
automated tests. The suite creates and deletes users, locations, tickets,
|
|
110
|
+
followups, tasks, and solutions on every run.
|
|
111
|
+
|
|
112
|
+
Package Layout
|
|
113
|
+
--------------
|
|
114
|
+
|
|
115
|
+
``glpi_python_client.__init__``
|
|
116
|
+
Public import surface (``GlpiClient``, ``GlpiTicketContext``, public Pydantic
|
|
117
|
+
models, enums, and ``__version__``).
|
|
118
|
+
|
|
119
|
+
``glpi_python_client.clients.glpi_client``
|
|
120
|
+
Composition root. ``GlpiClient`` mixes the per-resource async API mixins,
|
|
121
|
+
the OAuth2 token manager, the asynchronous v2 transport, and the optional
|
|
122
|
+
internal v1 session used for document uploads.
|
|
123
|
+
|
|
124
|
+
``glpi_python_client.clients.api``
|
|
125
|
+
Async API mixins generated from the GLPI v2 OpenAPI contract: tickets,
|
|
126
|
+
ticket timeline (followups, tasks, solutions, documents), team members,
|
|
127
|
+
documents, users, locations, entities, ...
|
|
128
|
+
|
|
129
|
+
``glpi_python_client.clients.custom``
|
|
130
|
+
Higher-level helpers built on top of the contract mixins:
|
|
131
|
+
``get_ticket_context``, ``get_ticket_statistics``, ``get_task_statistics``.
|
|
132
|
+
|
|
133
|
+
``glpi_python_client.clients.commons``
|
|
134
|
+
Shared HTTP transport pieces, including the timeline envelope unwrap that
|
|
135
|
+
reconciles live server behaviour with the OpenAPI contract.
|
|
136
|
+
|
|
137
|
+
``glpi_python_client.models.api_schema``
|
|
138
|
+
Contract-aligned Pydantic v2 models (``Get``/``Post``/``Patch``/``Delete``)
|
|
139
|
+
for each GLPI v2 resource.
|
|
140
|
+
|
|
141
|
+
``glpi_python_client.models.custom_schema``
|
|
142
|
+
Composite models such as ``GlpiTicketContext`` returned by the custom
|
|
143
|
+
helpers.
|
|
144
|
+
|
|
145
|
+
Adding Endpoints
|
|
146
|
+
----------------
|
|
147
|
+
|
|
148
|
+
#. Add or extend the contract-aligned models in
|
|
149
|
+
``glpi_python_client.models.api_schema``.
|
|
150
|
+
#. Add the async mixin and method under ``glpi_python_client.clients.api``,
|
|
151
|
+
mirroring the OpenAPI path and HTTP verb.
|
|
152
|
+
#. When the live server diverges from the contract, document the choice in the
|
|
153
|
+
module docstring and (when needed) wire an unwrap helper from
|
|
154
|
+
``glpi_python_client.clients.commons``.
|
|
155
|
+
#. Re-export new public symbols from ``glpi_python_client.__init__``.
|
|
156
|
+
#. Add tests for payload serialization, response parsing, and client behaviour.
|
|
157
|
+
#. Document the workflow in :doc:`user_guide` and the matching skill in
|
|
158
|
+
``skills/``.
|
|
159
|
+
|
|
160
|
+
Keep organization-specific entity, profile, and category defaults outside the
|
|
161
|
+
library core. Applications can apply their own mapping before calling the
|
|
162
|
+
client.
|
|
@@ -11,8 +11,10 @@ whose surface is built from contract-aligned per-endpoint mixins:
|
|
|
11
11
|
it to a worker thread via :func:`asyncio.to_thread`.
|
|
12
12
|
|
|
13
13
|
Both clients speak the GLPI **v2** high-level API and fall back to the
|
|
14
|
-
legacy v1
|
|
15
|
-
|
|
14
|
+
legacy v1 API for features that are not exposed by v2, currently
|
|
15
|
+
binary document uploads and the ``Fields`` plugin custom-field
|
|
16
|
+
helpers. They expose the exact same endpoint methods and accept the
|
|
17
|
+
same constructor arguments.
|
|
16
18
|
Public methods always return Pydantic models (or simple Python types)
|
|
17
19
|
and never raw dictionaries.
|
|
18
20
|
|
|
@@ -36,7 +38,8 @@ The guide is split into the following sections:
|
|
|
36
38
|
one-to-one to GLPI v2 endpoints (tickets, timeline, team members,
|
|
37
39
|
users, locations, entities, documents).
|
|
38
40
|
5. **Added functionalities** — helpers built on top of the API mixins:
|
|
39
|
-
|
|
41
|
+
the ``Fields`` plugin custom-field helpers, the aggregated ticket
|
|
42
|
+
context view, and the reporting helpers.
|
|
40
43
|
6. **End-to-end examples** — full workflows that combine the previous
|
|
41
44
|
building blocks.
|
|
42
45
|
|
|
@@ -111,7 +114,9 @@ Optional constructor arguments
|
|
|
111
114
|
* ``auth_token_refresh`` — number of seconds before token expiry at
|
|
112
115
|
which the auth manager proactively refreshes the OAuth access token.
|
|
113
116
|
* ``v1_base_url`` and ``v1_user_token`` — together enable the legacy v1
|
|
114
|
-
|
|
117
|
+
fallback used by :meth:`GlpiClient.upload_document` and the
|
|
118
|
+
``Fields`` plugin helpers such as
|
|
119
|
+
:meth:`GlpiClient.get_ticket_custom_fields`.
|
|
115
120
|
* ``executor`` (:class:`AsyncGlpiClient` only) — an explicit
|
|
116
121
|
:class:`concurrent.futures.Executor` used to dispatch the wrapped
|
|
117
122
|
synchronous calls. Defaults to the standard library thread pool
|
|
@@ -616,6 +621,55 @@ Example output::
|
|
|
616
621
|
The helpers in this section are not part of the GLPI contract. They are
|
|
617
622
|
small utilities the client builds on top of the API mixins.
|
|
618
623
|
|
|
624
|
+
Ticket custom fields via the Fields plugin
|
|
625
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
626
|
+
|
|
627
|
+
The `Fields plugin <https://github.com/pluginsGLPI/fields>`_ exposes
|
|
628
|
+
ticket custom fields through the legacy v1 API rather than the GLPI v2
|
|
629
|
+
contract. Configure the client with ``v1_base_url`` and
|
|
630
|
+
``v1_user_token`` (or the matching ``GLPI_V1_*`` environment
|
|
631
|
+
variables), then use the discovery helpers when you need the plugin's
|
|
632
|
+
internal container and field names:
|
|
633
|
+
|
|
634
|
+
.. code-block:: python
|
|
635
|
+
|
|
636
|
+
from glpi_python_client import GlpiClient
|
|
637
|
+
|
|
638
|
+
with GlpiClient(
|
|
639
|
+
glpi_api_url="https://glpi.example.com/api.php/v2",
|
|
640
|
+
client_id="oauth-client-id",
|
|
641
|
+
client_secret="oauth-client-secret",
|
|
642
|
+
username="api-user",
|
|
643
|
+
password="api-password",
|
|
644
|
+
v1_base_url="https://glpi.example.com/apirest.php",
|
|
645
|
+
v1_user_token="legacy-user-token",
|
|
646
|
+
) as client:
|
|
647
|
+
containers = client.list_plugin_fields_containers(itemtype="Ticket")
|
|
648
|
+
for container in containers:
|
|
649
|
+
print(container.id, container.name)
|
|
650
|
+
fields = client.list_plugin_fields_fields(container_id=container.id)
|
|
651
|
+
print([field.name for field in fields])
|
|
652
|
+
|
|
653
|
+
custom_fields = client.get_ticket_custom_fields(ticket_id)
|
|
654
|
+
print(custom_fields)
|
|
655
|
+
|
|
656
|
+
client.set_ticket_custom_fields(
|
|
657
|
+
ticket_id,
|
|
658
|
+
{
|
|
659
|
+
"aidelarsolution": {
|
|
660
|
+
"aidelarsolutionfield": "<p>Handled by the NOC shift</p>",
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
)
|
|
664
|
+
|
|
665
|
+
The high-level ``get_ticket_custom_fields`` /
|
|
666
|
+
``set_ticket_custom_fields`` pair uses the mapping
|
|
667
|
+
``{container_name: {field_name: value}}`` and automatically decides
|
|
668
|
+
whether the v1 plugin needs a row creation or an in-place update. Drop
|
|
669
|
+
to ``list_item_plugin_field_rows``, ``create_item_plugin_field_row``,
|
|
670
|
+
or ``update_item_plugin_field_row`` only when you need the raw v1 row
|
|
671
|
+
shape.
|
|
672
|
+
|
|
619
673
|
Aggregated ticket context
|
|
620
674
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
621
675
|
|
|
@@ -776,6 +830,12 @@ batches until the API returns fewer rows than the requested
|
|
|
776
830
|
print(ticket.id, ticket.name)
|
|
777
831
|
print(f"processed {total} tickets")
|
|
778
832
|
|
|
833
|
+
.. note::
|
|
834
|
+
|
|
835
|
+
Always pass an RSQL filter to ``iter_search_tickets``. Querying
|
|
836
|
+
without any filter can return very large result sets and may cause
|
|
837
|
+
the GLPI server to return a 500 errors.
|
|
838
|
+
|
|
779
839
|
On the asynchronous client the same helpers are exposed as **async
|
|
780
840
|
generators** through the bridge, so each ``next()`` call runs off the
|
|
781
841
|
event loop and the consumer uses ``async for``:
|
|
@@ -790,8 +850,10 @@ event loop and the consumer uses ``async for``:
|
|
|
790
850
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
791
851
|
|
|
792
852
|
Counts tickets created within an ISO date window and groups them by
|
|
793
|
-
entity, status, priority, and type.
|
|
794
|
-
|
|
853
|
+
entity, status, priority, and type. The ``start_date`` is inclusive
|
|
854
|
+
from 00:00:00 and the ``end_date`` is inclusive through 23:59:59, so
|
|
855
|
+
tickets created at any time on those days are counted. Optional
|
|
856
|
+
filters restrict the result set on the server side:
|
|
795
857
|
|
|
796
858
|
* ``entity_id`` — restrict to a single entity by numeric identifier.
|
|
797
859
|
* ``entity_name`` — substring match against the entity ``name`` column;
|
|
@@ -893,7 +955,9 @@ then computes per-user and per-entity totals.
|
|
|
893
955
|
Available filters:
|
|
894
956
|
|
|
895
957
|
* ``start_date`` / ``end_date`` / ``default_days`` — ISO ``YYYY-MM-DD``
|
|
896
|
-
date window; ``
|
|
958
|
+
date window; ``start_date`` is inclusive from 00:00:00,
|
|
959
|
+
``end_date`` is inclusive through 23:59:59, and ``default_days``
|
|
960
|
+
is used when ``start_date`` is omitted.
|
|
897
961
|
* ``entity_id`` — restrict to a single entity by identifier.
|
|
898
962
|
* ``entity_name`` — substring match resolved through ``search_entities``;
|
|
899
963
|
ignored when ``entity_id`` is given.
|
|
@@ -30,6 +30,9 @@ from glpi_python_client.models import (
|
|
|
30
30
|
GetEntity,
|
|
31
31
|
GetFollowup,
|
|
32
32
|
GetLocation,
|
|
33
|
+
GetPluginFieldsContainer,
|
|
34
|
+
GetPluginFieldsField,
|
|
35
|
+
GetPluginFieldsValueRow,
|
|
33
36
|
GetSolution,
|
|
34
37
|
GetTeamMember,
|
|
35
38
|
GetTicket,
|
|
@@ -63,6 +66,7 @@ from glpi_python_client.models import (
|
|
|
63
66
|
PostEntity,
|
|
64
67
|
PostFollowup,
|
|
65
68
|
PostLocation,
|
|
69
|
+
PostPluginFieldsValueRow,
|
|
66
70
|
PostSolution,
|
|
67
71
|
PostTeamMember,
|
|
68
72
|
PostTicket,
|
|
@@ -72,7 +76,7 @@ from glpi_python_client.models import (
|
|
|
72
76
|
TicketMarkdownOptions,
|
|
73
77
|
)
|
|
74
78
|
|
|
75
|
-
__version__ = "0.3.
|
|
79
|
+
__version__ = "0.3.4"
|
|
76
80
|
|
|
77
81
|
__all__ = [
|
|
78
82
|
"AsyncGlpiClient",
|
|
@@ -90,6 +94,9 @@ __all__ = [
|
|
|
90
94
|
"GetEntity",
|
|
91
95
|
"GetFollowup",
|
|
92
96
|
"GetLocation",
|
|
97
|
+
"GetPluginFieldsContainer",
|
|
98
|
+
"GetPluginFieldsField",
|
|
99
|
+
"GetPluginFieldsValueRow",
|
|
93
100
|
"GetSolution",
|
|
94
101
|
"GetTeamMember",
|
|
95
102
|
"GetTicket",
|
|
@@ -124,6 +131,7 @@ __all__ = [
|
|
|
124
131
|
"PostEntity",
|
|
125
132
|
"PostFollowup",
|
|
126
133
|
"PostLocation",
|
|
134
|
+
"PostPluginFieldsValueRow",
|
|
127
135
|
"PostSolution",
|
|
128
136
|
"PostTeamMember",
|
|
129
137
|
"PostTicket",
|