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.
Files changed (138) hide show
  1. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.gitignore +3 -2
  2. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/PKG-INFO +1 -1
  3. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/api_reference.rst +30 -0
  4. glpi_python_client-0.3.4/docs/development_rtd.rst +162 -0
  5. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/user_guide.rst +71 -7
  6. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/__init__.py +9 -1
  7. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/_v1_session.py +173 -49
  8. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/tests/test_v1_session.py +184 -21
  9. 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
  10. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/__init__.py +2 -0
  11. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_document.py +21 -20
  12. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/management/_document.py +1 -7
  13. glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/__init__.py +10 -0
  14. glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/_fields.py +411 -0
  15. glpi_python_client-0.3.4/glpi_python_client/clients/api/plugins/tests/test_fields_mixin.py +377 -0
  16. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/async_client.py +14 -90
  17. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_config.py +1 -1
  18. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_http.py +14 -0
  19. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_transport.py +29 -0
  20. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_statistics.py +21 -16
  21. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_statistics_async.py +19 -14
  22. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_statistics.py +2 -2
  23. glpi_python_client-0.3.4/glpi_python_client/clients/sync_client.py +129 -0
  24. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_api_coverage.py +2 -2
  25. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/__init__.py +10 -0
  26. glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/__init__.py +19 -0
  27. glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/_fields.py +177 -0
  28. glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/tests/__init__.py +0 -0
  29. glpi_python_client-0.3.4/glpi_python_client/models/api_schema/plugins/tests/test_fields_schemas.py +82 -0
  30. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/_ticket_context.py +12 -9
  31. {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
  32. glpi_python_client-0.3.4/glpi_python_client/py.typed +0 -0
  33. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/utils.py +2 -0
  34. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/pyproject.toml +1 -1
  35. glpi_python_client-0.3.2/docs/development_rtd.rst +0 -84
  36. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.pre-commit-config.yaml +0 -0
  37. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/.readthedocs.yaml +0 -0
  38. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/CONTRIBUTING.md +0 -0
  39. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/LICENSE +0 -0
  40. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/README.md +0 -0
  41. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/_static/.gitkeep +0 -0
  42. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/conf.py +0 -0
  43. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/development.md +0 -0
  44. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/glpi_api_contract.json +0 -0
  45. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/index.rst +0 -0
  46. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/installation.rst +0 -0
  47. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/publishing.md +0 -0
  48. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/publishing_rtd.rst +0 -0
  49. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/docs/sponsoring.rst +0 -0
  50. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/__init__.py +0 -0
  51. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/auth.py +0 -0
  52. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/auth/tests/test_auth.py +0 -0
  53. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/__init__.py +0 -0
  54. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/__init__.py +0 -0
  55. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/_entity.py +0 -0
  56. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/administration/_user.py +0 -0
  57. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/__init__.py +0 -0
  58. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/_team.py +0 -0
  59. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/_ticket.py +0 -0
  60. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/__init__.py +0 -0
  61. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_followup.py +0 -0
  62. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_solution.py +0 -0
  63. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/assistance/timeline/_task.py +0 -0
  64. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/dropdowns/__init__.py +0 -0
  65. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/dropdowns/_location.py +0 -0
  66. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/api/management/__init__.py +0 -0
  67. /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
  68. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/__init__.py +0 -0
  69. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_async_bridge.py +0 -0
  70. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_constants.py +0 -0
  71. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_errors.py +0 -0
  72. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_filters.py +0 -0
  73. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/_payloads.py +0 -0
  74. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/__init__.py +0 -0
  75. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_errors.py +0 -0
  76. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_filters.py +0 -0
  77. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_http.py +0 -0
  78. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_payloads.py +0 -0
  79. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/commons/tests/test_transport.py +0 -0
  80. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/__init__.py +0 -0
  81. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_pagination_async.py +0 -0
  82. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_ticket_context.py +0 -0
  83. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/_ticket_context_async.py +0 -0
  84. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_statistics_async.py +0 -0
  85. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/custom/tests/test_ticket_context.py +0 -0
  86. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/__init__.py +0 -0
  87. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_async_branches.py +0 -0
  88. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_async_smoke.py +0 -0
  89. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_glpi_client.py +0 -0
  90. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_parity.py +0 -0
  91. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/clients/tests/test_smoke.py +0 -0
  92. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/__init__.py +0 -0
  93. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/conversion.py +0 -0
  94. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/tests/__init__.py +0 -0
  95. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/content/tests/test_conversion.py +0 -0
  96. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/_base.py +0 -0
  97. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/__init__.py +0 -0
  98. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/_common.py +0 -0
  99. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/_content.py +0 -0
  100. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/__init__.py +0 -0
  101. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/_entity.py +0 -0
  102. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/_user.py +0 -0
  103. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/administration/tests/__init__.py +0 -0
  104. {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
  105. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/__init__.py +0 -0
  106. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/_team.py +0 -0
  107. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/_ticket.py +0 -0
  108. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/tests/__init__.py +0 -0
  109. {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
  110. {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
  111. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/__init__.py +0 -0
  112. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_document.py +0 -0
  113. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_followup.py +0 -0
  114. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_solution.py +0 -0
  115. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/assistance/timeline/_task.py +0 -0
  116. {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
  117. {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
  118. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/__init__.py +0 -0
  119. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/_location.py +0 -0
  120. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/dropdowns/tests/__init__.py +0 -0
  121. {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
  122. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/enums.py +0 -0
  123. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/__init__.py +0 -0
  124. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/_document.py +0 -0
  125. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/api_schema/management/tests/__init__.py +0 -0
  126. {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
  127. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/__init__.py +0 -0
  128. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/models/custom_schema/tests/__init__.py +0 -0
  129. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/__init__.py +0 -0
  130. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/glpi_python_client/testing/fixtures.py +0 -0
  131. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/README.md +0 -0
  132. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-client-setup/SKILL.md +0 -0
  133. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-document-workflow/SKILL.md +0 -0
  134. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-reporting-and-context/SKILL.md +0 -0
  135. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-team-members/SKILL.md +0 -0
  136. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-ticket-timeline/SKILL.md +0 -0
  137. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-ticket-workflow/SKILL.md +0 -0
  138. {glpi_python_client-0.3.2 → glpi_python_client-0.3.4}/skills/glpi-user-location-provisioning/SKILL.md +0 -0
@@ -26,5 +26,6 @@ dist/
26
26
  secrets/
27
27
  secrets/*
28
28
 
29
- integration_tests/
30
- integration_tests/*
29
+ .claude/
30
+
31
+ CLAUDE.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: glpi-python-client
3
- Version: 0.3.2
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 endpoint only for binary document uploads. They expose the
15
- exact same endpoint methods and accept the same constructor arguments.
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
- the aggregated ticket context view and the reporting helpers.
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
- fallback used by :meth:`GlpiClient.upload_document`.
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. Optional filters restrict the
794
- result set on the server side:
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; ``default_days`` is used when ``start_date`` is omitted.
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.2"
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",