taegis-sdk-python 1.2.4__tar.gz → 1.2.6__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 (230) hide show
  1. {taegis-sdk-python-1.2.4/taegis_sdk_python.egg-info → taegis_sdk_python-1.2.6}/PKG-INFO +2 -1
  2. taegis-sdk-python-1.2.4/taegis_sdk_python.egg-info/requires.txt → taegis_sdk_python-1.2.6/requirements.txt +1 -0
  3. taegis_sdk_python-1.2.6/taegis_sdk_python/_version.py +1 -0
  4. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/authentication.py +29 -18
  5. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/config.py +12 -2
  6. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/service_core.py +125 -66
  7. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/__init__.py +41 -10
  8. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/alerts/types.py +42 -0
  9. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets2/types.py +90 -18
  10. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/authz/types.py +4 -0
  11. taegis_sdk_python-1.2.6/taegis_sdk_python/services/contracted_endpoint/__init__.py +34 -0
  12. taegis_sdk_python-1.2.6/taegis_sdk_python/services/contracted_endpoint/mutations.py +31 -0
  13. taegis_sdk_python-1.2.6/taegis_sdk_python/services/contracted_endpoint/queries.py +79 -0
  14. taegis_sdk_python-1.2.6/taegis_sdk_python/services/contracted_endpoint/subscriptions.py +31 -0
  15. taegis_sdk_python-1.2.6/taegis_sdk_python/services/contracted_endpoint/types.py +66 -0
  16. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_command_manager/types.py +2 -0
  17. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/events/types.py +0 -1
  18. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/exports/mutations.py +16 -0
  19. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/exports/queries.py +12 -0
  20. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/exports/types.py +6 -1
  21. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/file_info/queries.py +12 -6
  22. taegis_sdk_python-1.2.6/taegis_sdk_python/services/ingest_stats/__init__.py +32 -0
  23. taegis_sdk_python-1.2.6/taegis_sdk_python/services/ingest_stats/mutations.py +31 -0
  24. taegis_sdk_python-1.2.6/taegis_sdk_python/services/ingest_stats/queries.py +118 -0
  25. taegis_sdk_python-1.2.6/taegis_sdk_python/services/ingest_stats/subscriptions.py +31 -0
  26. taegis_sdk_python-1.2.6/taegis_sdk_python/services/ingest_stats/types.py +123 -0
  27. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations/mutations.py +112 -0
  28. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations/queries.py +124 -2
  29. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations2/types.py +53 -16
  30. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/preferences/types.py +30 -3
  31. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/rules/types.py +31 -0
  32. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat/mutations.py +0 -57
  33. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat/queries.py +40 -123
  34. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat/types.py +39 -260
  35. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/trip/queries.py +0 -15
  36. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/trip/types.py +6 -71
  37. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/users/types.py +28 -3
  38. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6/taegis_sdk_python.egg-info}/PKG-INFO +2 -1
  39. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python.egg-info/SOURCES.txt +10 -0
  40. taegis-sdk-python-1.2.4/requirements.txt → taegis_sdk_python-1.2.6/taegis_sdk_python.egg-info/requires.txt +2 -1
  41. taegis-sdk-python-1.2.4/taegis_sdk_python/_version.py +0 -1
  42. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/LICENSE +0 -0
  43. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/MANIFEST.in +0 -0
  44. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/README.md +0 -0
  45. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/requirements-dev.txt +0 -0
  46. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/requirements-test.txt +0 -0
  47. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/setup.cfg +0 -0
  48. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/setup.py +0 -0
  49. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/__init__.py +0 -0
  50. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/_consts.py +0 -0
  51. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/errors.py +0 -0
  52. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/access_points/__init__.py +0 -0
  53. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/access_points/mutations.py +0 -0
  54. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/access_points/queries.py +0 -0
  55. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/access_points/subscriptions.py +0 -0
  56. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/access_points/types.py +0 -0
  57. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/agent/__init__.py +0 -0
  58. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/agent/mutations.py +0 -0
  59. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/agent/queries.py +0 -0
  60. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/agent/subscriptions.py +0 -0
  61. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/agent/types.py +0 -0
  62. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/alerts/__init__.py +0 -0
  63. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/alerts/mutations.py +0 -0
  64. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/alerts/queries.py +0 -0
  65. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/alerts/subscriptions.py +0 -0
  66. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets/__init__.py +0 -0
  67. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets/mutations.py +0 -0
  68. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets/queries.py +0 -0
  69. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets/subscriptions.py +0 -0
  70. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets/types.py +0 -0
  71. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets2/__init__.py +0 -0
  72. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets2/mutations.py +0 -0
  73. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets2/queries.py +0 -0
  74. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/assets2/subscriptions.py +0 -0
  75. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/audits/__init__.py +0 -0
  76. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/audits/mutations.py +0 -0
  77. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/audits/queries.py +0 -0
  78. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/audits/subscriptions.py +0 -0
  79. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/audits/types.py +0 -0
  80. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/authz/__init__.py +0 -0
  81. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/authz/mutations.py +0 -0
  82. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/authz/queries.py +0 -0
  83. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/authz/subscriptions.py +0 -0
  84. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/byoti/__init__.py +0 -0
  85. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/byoti/mutations.py +0 -0
  86. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/byoti/queries.py +0 -0
  87. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/byoti/subscriptions.py +0 -0
  88. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/byoti/types.py +0 -0
  89. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/clients/__init__.py +0 -0
  90. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/clients/mutations.py +0 -0
  91. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/clients/queries.py +0 -0
  92. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/clients/subscriptions.py +0 -0
  93. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/clients/types.py +0 -0
  94. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/collector/__init__.py +0 -0
  95. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/collector/mutations.py +0 -0
  96. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/collector/queries.py +0 -0
  97. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/collector/subscriptions.py +0 -0
  98. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/collector/types.py +0 -0
  99. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/comments/__init__.py +0 -0
  100. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/comments/mutations.py +0 -0
  101. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/comments/queries.py +0 -0
  102. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/comments/subscriptions.py +0 -0
  103. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/comments/types.py +0 -0
  104. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/datasources/__init__.py +0 -0
  105. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/datasources/mutations.py +0 -0
  106. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/datasources/queries.py +0 -0
  107. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/datasources/subscriptions.py +0 -0
  108. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/datasources/types.py +0 -0
  109. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/detector_registry/__init__.py +0 -0
  110. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/detector_registry/mutations.py +0 -0
  111. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/detector_registry/queries.py +0 -0
  112. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/detector_registry/subscriptions.py +0 -0
  113. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/detector_registry/types.py +0 -0
  114. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_command_manager/__init__.py +0 -0
  115. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_command_manager/mutations.py +0 -0
  116. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_command_manager/queries.py +0 -0
  117. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_command_manager/subscriptions.py +0 -0
  118. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_management_service/__init__.py +0 -0
  119. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_management_service/mutations.py +0 -0
  120. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_management_service/queries.py +0 -0
  121. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_management_service/subscriptions.py +0 -0
  122. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/endpoint_management_service/types.py +0 -0
  123. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/event_search/__init__.py +0 -0
  124. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/event_search/mutations.py +0 -0
  125. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/event_search/queries.py +0 -0
  126. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/event_search/subscriptions.py +0 -0
  127. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/event_search/types.py +0 -0
  128. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/events/__init__.py +0 -0
  129. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/events/mutations.py +0 -0
  130. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/events/queries.py +0 -0
  131. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/events/subscriptions.py +0 -0
  132. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/exports/__init__.py +0 -0
  133. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/exports/subscriptions.py +0 -0
  134. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/fast_ioc/__init__.py +0 -0
  135. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/fast_ioc/mutations.py +0 -0
  136. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/fast_ioc/queries.py +0 -0
  137. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/fast_ioc/subscriptions.py +0 -0
  138. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/fast_ioc/types.py +0 -0
  139. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/file_info/__init__.py +0 -0
  140. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/file_info/mutations.py +0 -0
  141. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/file_info/subscriptions.py +0 -0
  142. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/file_info/types.py +0 -0
  143. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations/__init__.py +0 -0
  144. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations/subscriptions.py +0 -0
  145. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations/types.py +0 -0
  146. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations2/__init__.py +0 -0
  147. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations2/mutations.py +0 -0
  148. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations2/queries.py +0 -0
  149. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/investigations2/subscriptions.py +0 -0
  150. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/mitre_attack_info/__init__.py +0 -0
  151. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/mitre_attack_info/mutations.py +0 -0
  152. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/mitre_attack_info/queries.py +0 -0
  153. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/mitre_attack_info/subscriptions.py +0 -0
  154. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/mitre_attack_info/types.py +0 -0
  155. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_context/__init__.py +0 -0
  156. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_context/mutations.py +0 -0
  157. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_context/queries.py +0 -0
  158. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_context/subscriptions.py +0 -0
  159. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_context/types.py +0 -0
  160. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_ioc/__init__.py +0 -0
  161. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_ioc/mutations.py +0 -0
  162. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_ioc/queries.py +0 -0
  163. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_ioc/subscriptions.py +0 -0
  164. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/multi_tenant_ioc/types.py +0 -0
  165. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notebooks/__init__.py +0 -0
  166. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notebooks/mutations.py +0 -0
  167. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notebooks/queries.py +0 -0
  168. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notebooks/subscriptions.py +0 -0
  169. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notebooks/types.py +0 -0
  170. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notifications/__init__.py +0 -0
  171. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notifications/mutations.py +0 -0
  172. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notifications/queries.py +0 -0
  173. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notifications/subscriptions.py +0 -0
  174. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/notifications/types.py +0 -0
  175. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/preferences/__init__.py +0 -0
  176. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/preferences/mutations.py +0 -0
  177. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/preferences/queries.py +0 -0
  178. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/preferences/subscriptions.py +0 -0
  179. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/queries/__init__.py +0 -0
  180. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/queries/mutations.py +0 -0
  181. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/queries/queries.py +0 -0
  182. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/queries/subscriptions.py +0 -0
  183. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/queries/types.py +0 -0
  184. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/roadrunner/__init__.py +0 -0
  185. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/roadrunner/mutations.py +0 -0
  186. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/roadrunner/queries.py +0 -0
  187. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/roadrunner/subscriptions.py +0 -0
  188. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/roadrunner/types.py +0 -0
  189. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/rules/__init__.py +0 -0
  190. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/rules/mutations.py +0 -0
  191. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/rules/queries.py +0 -0
  192. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/rules/subscriptions.py +0 -0
  193. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/sharelinks/__init__.py +0 -0
  194. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/sharelinks/mutations.py +0 -0
  195. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/sharelinks/queries.py +0 -0
  196. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/sharelinks/subscriptions.py +0 -0
  197. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/sharelinks/types.py +0 -0
  198. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/subjects/__init__.py +0 -0
  199. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/subjects/mutations.py +0 -0
  200. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/subjects/queries.py +0 -0
  201. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/subjects/subscriptions.py +0 -0
  202. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/subjects/types.py +0 -0
  203. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenant_profiles/__init__.py +0 -0
  204. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenant_profiles/mutations.py +0 -0
  205. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenant_profiles/queries.py +0 -0
  206. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenant_profiles/subscriptions.py +0 -0
  207. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenant_profiles/types.py +0 -0
  208. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenants/__init__.py +0 -0
  209. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenants/mutations.py +0 -0
  210. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenants/queries.py +0 -0
  211. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenants/subscriptions.py +0 -0
  212. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/tenants/types.py +0 -0
  213. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat/__init__.py +0 -0
  214. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat/subscriptions.py +0 -0
  215. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat_score/__init__.py +0 -0
  216. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat_score/mutations.py +0 -0
  217. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat_score/queries.py +0 -0
  218. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat_score/subscriptions.py +0 -0
  219. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/threat_score/types.py +0 -0
  220. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/trip/__init__.py +0 -0
  221. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/trip/mutations.py +0 -0
  222. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/trip/subscriptions.py +0 -0
  223. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/users/__init__.py +0 -0
  224. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/users/mutations.py +0 -0
  225. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/users/queries.py +0 -0
  226. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/services/users/subscriptions.py +0 -0
  227. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/tokens.py +0 -0
  228. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python/utils.py +0 -0
  229. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python.egg-info/dependency_links.txt +0 -0
  230. {taegis-sdk-python-1.2.4 → taegis_sdk_python-1.2.6}/taegis_sdk_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: taegis-sdk-python
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: Taegis Python SDK
5
5
  Home-page: https://github.com/secureworks/taegis-sdk-python
6
6
  Author: Secureworks
@@ -21,6 +21,7 @@ Requires-Dist: dataclasses-json
21
21
  Requires-Dist: pyjwt>=2.8.0
22
22
  Requires-Dist: requests-toolbelt
23
23
  Requires-Dist: websockets
24
+ Requires-Dist: filelock>=3.12.4
24
25
 
25
26
  # Taegis SDK for Python
26
27
 
@@ -8,3 +8,4 @@ dataclasses-json
8
8
  pyjwt>=2.8.0
9
9
  requests-toolbelt
10
10
  websockets
11
+ filelock>=3.12.4
@@ -0,0 +1 @@
1
+ __version__ = "v1.2.6"
@@ -8,6 +8,7 @@ import os
8
8
  from getpass import getpass
9
9
  from time import time
10
10
  from typing import Any, Dict, Tuple, Union, Optional
11
+ import threading
11
12
 
12
13
  from oauthlib.oauth2 import BackendApplicationClient
13
14
  from requests import HTTPError, post
@@ -26,6 +27,8 @@ except ImportError: # pragma: no cover
26
27
 
27
28
  logger = logging.getLogger(__name__)
28
29
 
30
+ LOCK = threading.RLock()
31
+
29
32
 
30
33
  def check_username(
31
34
  request_url: str, username: str
@@ -103,23 +106,31 @@ def get_token(environment: str, request_url: str) -> str: # pragma: no cover
103
106
  access_token = get_cached_token(environment)
104
107
 
105
108
  if not access_token:
106
- client_id, client_secret = get_oauth_from_env(environment)
107
- if client_id and client_secret:
108
- access_token = get_token_by_oauth(request_url, client_id, client_secret)
109
- else:
110
- username = input("Username: ")
111
- response = check_username(request_url, username)
112
-
113
- if response.get("login_type") == "username-password":
114
- access_token = get_token_by_password_grant(request_url, username)
115
- elif response.get("login_type") == "sso":
116
- access_token = get_token_by_sso_device_code(request_url)
117
- else:
118
- raise InvalidAuthenticationMethod(
119
- message="No known authenticition method for user"
120
- )
121
-
122
- write_to_config(environment, "access_token", access_token)
109
+ with LOCK:
110
+ access_token = get_cached_token(environment)
111
+
112
+ if not access_token:
113
+ client_id, client_secret = get_oauth_from_env(environment)
114
+ if client_id and client_secret:
115
+ access_token = get_token_by_oauth(
116
+ request_url, client_id, client_secret
117
+ )
118
+ else:
119
+ username = input("Username: ")
120
+ response = check_username(request_url, username)
121
+
122
+ if response.get("login_type") == "username-password":
123
+ access_token = get_token_by_password_grant(
124
+ request_url, username
125
+ )
126
+ elif response.get("login_type") == "sso":
127
+ access_token = get_token_by_sso_device_code(request_url)
128
+ else:
129
+ raise InvalidAuthenticationMethod(
130
+ message="No known authentication method for user"
131
+ )
132
+
133
+ write_to_config(environment, "access_token", access_token)
123
134
 
124
135
  return access_token
125
136
 
@@ -130,7 +141,7 @@ def get_cached_token(env: str) -> Union[str, None]: # pragma: no cover
130
141
 
131
142
  # check for token and expiry in config
132
143
  token = str(config.get(env, "access_token", fallback=""))
133
- if token and get_token_exp(token) >= int(time()):
144
+ if token and get_token_exp(token) >= int(time()) + 15:
134
145
  return token
135
146
 
136
147
  return None
@@ -2,8 +2,13 @@
2
2
 
3
3
  Taegis SDK Configuration management.
4
4
  """
5
+
5
6
  from configparser import ConfigParser
6
7
  from pathlib import Path
8
+ import threading
9
+ from filelock import FileLock
10
+
11
+ LOCK = threading.RLock()
7
12
 
8
13
 
9
14
  def get_config_file() -> Path:
@@ -44,9 +49,14 @@ def write_config(config: ConfigParser):
44
49
  Config object
45
50
  """
46
51
  config_fp = get_config_file()
52
+ lock_file = config_fp.with_suffix(".lock")
53
+ file_lock = FileLock(lock_file)
54
+
55
+ with file_lock:
56
+ with config_fp.open(mode="w") as f: # pylint: disable=invalid-name
57
+ config.write(f)
47
58
 
48
- with config_fp.open(mode="w") as f: # pylint: disable=invalid-name
49
- config.write(f)
59
+ lock_file.unlink(missing_ok=True)
50
60
 
51
61
 
52
62
  def write_to_config(section: str, key: str, value: str):
@@ -8,8 +8,10 @@ from __future__ import annotations
8
8
  import logging
9
9
  from datetime import datetime, timedelta
10
10
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
11
+ import threading
11
12
 
12
13
  from gql import Client, gql
14
+ from gql.transport import Transport
13
15
  from gql.transport.requests import RequestsHTTPTransport
14
16
  from gql.transport.websockets import WebsocketsTransport
15
17
  from graphql import GraphQLError, GraphQLField, GraphQLSchema
@@ -25,57 +27,135 @@ log = logging.getLogger(__name__)
25
27
 
26
28
 
27
29
  class SchemaCache:
28
- """GraphQL Schema Cache."""
30
+ """Taegis GraphQL Schema Cache."""
29
31
 
30
- def __init__(self, schema: Optional[GraphQLSchema] = None, expires: int = 5):
31
- """Initialize SchemaCache.
32
+ _lock = threading.RLock()
32
33
 
33
- Parameters
34
- ----------
35
- schema : Optional[GraphQLSchema], optional
36
- GraphQL schema object, by default None
37
- expires : int, optional
38
- Schema expires in minutes, by default 5
39
- """
34
+ def __init__(self, expires: int, schema: Optional[GraphQLSchema] = None):
35
+ self._expires = expires
40
36
  self._schema = schema
41
37
  self._inserted_at = datetime.now()
42
- self.expires = expires
38
+
39
+ def is_expired(self) -> bool:
40
+ """Returns if the schema is expired.
41
+
42
+ Returns
43
+ -------
44
+ bool
45
+ Is schema expired?
46
+ """
47
+ return self._inserted_at + timedelta(minutes=self._expires) <= datetime.now()
43
48
 
44
49
  @property
45
- def schema(self) -> Union[GraphQLSchema, None]:
46
- """Return GraphQLSchema if it exists and is not expired.
50
+ def schema(self) -> Optional[GraphQLSchema]:
51
+ """Get the schema.
47
52
 
48
53
  Returns
49
54
  -------
50
- Union[GraphQLSchema, None]
51
- GraphQL Schema
55
+ Optional[GraphQLSchema]
52
56
  """
53
- if self._inserted_at + timedelta(minutes=self.expires) < datetime.now():
54
- self.schema = None
57
+ log.debug(f"Schema is expired: {self.is_expired()}")
58
+
55
59
  return self._schema
56
60
 
57
- @schema.setter
58
- def schema(self, schema: Optional[GraphQLSchema]):
59
- """Set schema and update inserted_at.
61
+
62
+ class SchemaCacheMap:
63
+ """Taegis Schema Cache Map.
64
+
65
+ This is a singleton class that will cache the introspection schema for a given
66
+ GraphQL server. The schema will be cached for a given amount of time and will
67
+ be retrieved from the transport if expired.
68
+ """
69
+
70
+ _instance = None
71
+ _lock = threading.RLock()
72
+
73
+ def __new__(cls, *args, **kwargs):
74
+ if cls._instance is None:
75
+ with cls._lock:
76
+ if cls._instance is None:
77
+ cls._instance = super(SchemaCacheMap, cls).__new__(cls)
78
+ cls._instance.__post_init__(*args, **kwargs)
79
+ return cls._instance
80
+
81
+ def __post_init__(self, expires: int = 5):
82
+ self._map = {}
83
+ self._expires = expires
84
+
85
+ def get(
86
+ self, transport: Transport, introspection_args: Dict[str, Any]
87
+ ) -> GraphQLSchema:
88
+ """Get the schema from the map.
89
+
90
+ Retrieves new schema if expired, thread locks to prevent another service
91
+ from retrieving the schema at the same time.
92
+
93
+ Parameters
94
+ ----------
95
+ transport : Transport
96
+ gql Transport
97
+ introspection_args : Dict[str, Any]
98
+ Introspection Query arguments
99
+
100
+ Returns
101
+ -------
102
+ GraphQLSchema
103
+ """
104
+ if transport.url not in self._map or self._map[transport.url].is_expired():
105
+ log.debug("Schema not in map or expired...")
106
+ with self._lock:
107
+ if (
108
+ transport.url not in self._map
109
+ or self._map[transport.url].is_expired()
110
+ ):
111
+ self._map[transport.url] = SchemaCache(
112
+ expires=self._expires,
113
+ schema=self.retrieve_schema(transport, introspection_args),
114
+ )
115
+
116
+ return self._map.get(transport.url).schema
117
+
118
+ def clear(self, transport: Transport):
119
+ """Clear the schema from the map.
60
120
 
61
121
  Parameters
62
122
  ----------
63
- schema :
64
- _description_
123
+ transport : Transport
124
+ gql Transport
65
125
  """
66
- if self._schema is not schema:
67
- self._schema = schema
68
- self._inserted_at = datetime.now()
126
+ if transport.url in self._map:
127
+ with self._lock:
128
+ if transport.url in self._map:
129
+ del self._map[transport.url]
130
+
131
+ @staticmethod
132
+ def retrieve_schema(
133
+ transport: Transport, introspection_args: Dict[str, Any]
134
+ ) -> GraphQLSchema:
135
+ """Retrieve the schema from a gql Client with the provided transport and
136
+ introspection query arguments.
69
137
 
70
- def should_fetch_schema(self) -> bool:
71
- """Return True if schema is should be fetched in transport.
138
+ Parameters
139
+ ----------
140
+ transport : Transport
141
+ introspection_args : Dict[str, Any]
72
142
 
73
143
  Returns
74
144
  -------
75
- bool
76
- True if schema is should be fetched in transport.
145
+ GraphQLSchema
77
146
  """
78
- return not self.schema
147
+ log.debug(f"Retrieving schema for {transport.url}...")
148
+
149
+ client = Client(
150
+ transport=transport,
151
+ fetch_schema_from_transport=True,
152
+ introspection_args=introspection_args,
153
+ )
154
+
155
+ with client:
156
+ schema = client.schema
157
+
158
+ return schema
79
159
 
80
160
 
81
161
  class ServiceCore:
@@ -88,7 +168,7 @@ class ServiceCore:
88
168
  self._gateway = self.service._gateway
89
169
  self._input_value_deprecation = True
90
170
 
91
- self._schema = SchemaCache(schema=None, expires=self.service.schema_expiry)
171
+ self._cache_map = SchemaCacheMap(expires=self.service.schema_expiry)
92
172
 
93
173
  self._queries = None
94
174
  self._mutations = None
@@ -134,20 +214,18 @@ class ServiceCore:
134
214
 
135
215
  client = Client(
136
216
  transport=transport,
137
- schema=self._schema.schema,
138
- fetch_schema_from_transport=self._schema.should_fetch_schema(),
139
- introspection_args={
140
- "input_value_deprecation": (
141
- bool(self.service.input_value_deprecation)
142
- if self.service.input_value_deprecation is not None
143
- else self._input_value_deprecation
144
- )
145
- },
217
+ schema=self._cache_map.get(
218
+ transport,
219
+ introspection_args={
220
+ "input_value_deprecation": (
221
+ bool(self.service.input_value_deprecation)
222
+ if self.service.input_value_deprecation is not None
223
+ else self._input_value_deprecation
224
+ )
225
+ },
226
+ ),
146
227
  )
147
228
 
148
- with client:
149
- self._schema.schema = client.schema
150
-
151
229
  return client
152
230
 
153
231
  @property
@@ -158,12 +236,6 @@ class ServiceCore:
158
236
  f"access-token-{self.service.access_token}",
159
237
  ]
160
238
 
161
- # we cannot build the async client and use it to fetch the schema
162
- # due to async issues with the transport. This will grab the schema
163
- # from a sync client and use it to build the async client.
164
- if not self._schema.schema:
165
- self.sync_client # pylint: disable=pointless-statement
166
-
167
239
  if self.service.tenant_id:
168
240
  subprotocols.append(f"x-tenant-context-{self.service.tenant_id}")
169
241
 
@@ -176,15 +248,7 @@ class ServiceCore:
176
248
 
177
249
  client = Client(
178
250
  transport=transport,
179
- schema=self._schema.schema,
180
- fetch_schema_from_transport=self._schema.should_fetch_schema(),
181
- introspection_args={
182
- "input_value_deprecation": (
183
- bool(self.service.input_value_deprecation)
184
- if self.service.input_value_deprecation is not None
185
- else self._input_value_deprecation
186
- )
187
- },
251
+ schema=self.schema,
188
252
  )
189
253
 
190
254
  return client
@@ -197,13 +261,11 @@ class ServiceCore:
197
261
  -------
198
262
  GraphQLSchema
199
263
  """
200
- if not self._schema.schema:
201
- self.sync_client # pylint: disable=pointless-statement
202
- return self._schema.schema
264
+ return self.sync_client.schema
203
265
 
204
266
  def clear_schema(self):
205
267
  """Clears the introspection schema."""
206
- self._schema.schema = None
268
+ self._cache_map.clear(self.sync_client.transport)
207
269
 
208
270
  def get_sync_schema(self) -> Union[GraphQLSchema, None]:
209
271
  """Retrieves introspection schema from Synchronous endpoint.
@@ -212,10 +274,7 @@ class ServiceCore:
212
274
  -------
213
275
  GraphQLSchema
214
276
  """
215
- client = self.sync_client
216
- with client:
217
- schema = client.schema
218
- return schema
277
+ return self.schema
219
278
 
220
279
  @async_block
221
280
  async def get_ws_schema(self) -> Union[GraphQLSchema, None]:
@@ -3,6 +3,7 @@ This needs to be a generated file. Need to make jinja template.
3
3
  """
4
4
 
5
5
  from typing import Dict, Optional, Any
6
+ import threading
6
7
 
7
8
  from taegis_sdk_python._consts import TAEGIS_ENVIRONMENT_URLS
8
9
  from taegis_sdk_python._version import __version__
@@ -20,6 +21,7 @@ from taegis_sdk_python.services.byoti import ByotiService
20
21
  from taegis_sdk_python.services.clients import ClientsService
21
22
  from taegis_sdk_python.services.collector import CollectorService
22
23
  from taegis_sdk_python.services.comments import CommentsService
24
+ from taegis_sdk_python.services.contracted_endpoint import ContractedEndpointService
23
25
  from taegis_sdk_python.services.datasources import DatasourcesService
24
26
  from taegis_sdk_python.services.detector_registry import DetectorRegistryService
25
27
  from taegis_sdk_python.services.endpoint_command_manager import (
@@ -33,6 +35,7 @@ from taegis_sdk_python.services.events import EventsService
33
35
  from taegis_sdk_python.services.exports import ExportsService
34
36
  from taegis_sdk_python.services.fast_ioc import FastIocService
35
37
  from taegis_sdk_python.services.file_info import FileInfoService
38
+ from taegis_sdk_python.services.ingest_stats import IngestStatsService
36
39
  from taegis_sdk_python.services.investigations import InvestigationsService
37
40
  from taegis_sdk_python.services.investigations2 import Investigations2Service
38
41
  from taegis_sdk_python.services.mitre_attack_info import MitreAttackInfoService
@@ -100,8 +103,8 @@ class GraphQLService:
100
103
 
101
104
  self._tenant_id = tenant_id
102
105
  self._gateway = gateway or "/graphql"
103
- self._context_manager = {}
104
- self._context_kwargs = []
106
+ self._thread_id = threading.get_ident()
107
+ self._context_kwargs = {}
105
108
  if not extra_headers:
106
109
  self._extra_headers = {}
107
110
  else:
@@ -120,6 +123,7 @@ class GraphQLService:
120
123
  self._clients = None
121
124
  self._collector = None
122
125
  self._comments = None
126
+ self._contracted_endpoint = None
123
127
  self._datasources = None
124
128
  self._detector_registry = None
125
129
  self._endpoint_command_manager = None
@@ -129,6 +133,7 @@ class GraphQLService:
129
133
  self._exports = None
130
134
  self._fast_ioc = None
131
135
  self._file_info = None
136
+ self._ingest_stats = None
132
137
  self._investigations = None
133
138
  self._investigations2 = None
134
139
  self._mitre_attack_info = None
@@ -151,22 +156,34 @@ class GraphQLService:
151
156
  self._users = None
152
157
 
153
158
  def __call__(self, **kwargs):
154
- self._context_kwargs.append(kwargs)
159
+ if threading.get_ident() not in self._context_kwargs:
160
+ self._context_kwargs[threading.get_ident()] = []
161
+
162
+ self._context_kwargs[threading.get_ident()].append(kwargs)
155
163
  return self
156
164
 
157
165
  def __enter__(self):
158
- for kwarg in self._context_kwargs:
159
- self._context_manager.update(kwarg)
160
166
  return self
161
167
 
162
168
  def __exit__(self, exc_type, exc_val, exc_tb):
163
- self._context_manager.clear()
169
+ if self._context_kwargs[threading.get_ident()]:
170
+ self._context_kwargs[threading.get_ident()].pop()
171
+
172
+ else:
173
+ del self._context_kwargs[threading.get_ident()]
174
+
175
+ @property
176
+ def _context_manager(self):
177
+ """Internal Context Manager property."""
178
+ temp_context = {}
164
179
 
165
- if self._context_kwargs:
166
- self._context_kwargs.pop()
180
+ for kwarg in self._context_kwargs.get(self._thread_id, []):
181
+ temp_context.update(kwarg)
182
+ if self._thread_id != threading.get_ident():
183
+ for kwarg in self._context_kwargs.get(threading.get_ident(), []):
184
+ temp_context.update(kwarg)
167
185
 
168
- for kwarg in self._context_kwargs:
169
- self._context_manager.update(kwarg)
186
+ return temp_context
170
187
 
171
188
  @property
172
189
  def environment(self):
@@ -325,6 +342,13 @@ class GraphQLService:
325
342
  self._comments = CommentsService(self)
326
343
  return self._comments
327
344
 
345
+ @property
346
+ def contracted_endpoint(self):
347
+ """ContractedEndpoint Service Endpoint."""
348
+ if not self._contracted_endpoint:
349
+ self._contracted_endpoint = ContractedEndpointService(self)
350
+ return self._contracted_endpoint
351
+
328
352
  @property
329
353
  def datasources(self):
330
354
  """Datasources Service Endpoint."""
@@ -388,6 +412,13 @@ class GraphQLService:
388
412
  self._file_info = FileInfoService(self)
389
413
  return self._file_info
390
414
 
415
+ @property
416
+ def ingest_stats(self):
417
+ """IngestStats Service Endpoint."""
418
+ if not self._ingest_stats:
419
+ self._ingest_stats = IngestStatsService(self)
420
+ return self._ingest_stats
421
+
391
422
  @property
392
423
  def investigations(self):
393
424
  """Investigations Service Endpoint."""
@@ -1350,6 +1350,35 @@ class UpdateThreatScoreResponse:
1350
1350
  )
1351
1351
 
1352
1352
 
1353
+ @dataclass_json
1354
+ @dataclass(order=True, eq=True, frozen=True)
1355
+ class MatchedYaraRule:
1356
+ """MatchedYaraRule."""
1357
+
1358
+ rule_name: Optional[str] = field(
1359
+ default=None, metadata=config(field_name="rule_name")
1360
+ )
1361
+ rule_description: Optional[str] = field(
1362
+ default=None, metadata=config(field_name="rule_description")
1363
+ )
1364
+ classification: Optional[str] = field(
1365
+ default=None, metadata=config(field_name="classification")
1366
+ )
1367
+ confidence: Optional[float] = field(
1368
+ default=None, metadata=config(field_name="confidence")
1369
+ )
1370
+ severity: Optional[float] = field(
1371
+ default=None, metadata=config(field_name="severity")
1372
+ )
1373
+ attack_technique_ids: Optional[List[str]] = field(
1374
+ default=None, metadata=config(field_name="attack_technique_ids")
1375
+ )
1376
+ vid: Optional[str] = field(default=None, metadata=config(field_name="vid"))
1377
+ rule_created_date: Optional[Timestamp] = field(
1378
+ default=None, metadata=config(field_name="rule_created_date")
1379
+ )
1380
+
1381
+
1353
1382
  @dataclass_json
1354
1383
  @dataclass(order=True, eq=True, frozen=True)
1355
1384
  class DDosIpCount:
@@ -2008,6 +2037,16 @@ class AlertsInvestigationInfo:
2008
2037
  )
2009
2038
 
2010
2039
 
2040
+ @dataclass_json
2041
+ @dataclass(order=True, eq=True, frozen=True)
2042
+ class FileAnalysisDetail:
2043
+ """FileAnalysisDetail."""
2044
+
2045
+ matched_yara_rule: Optional[List[MatchedYaraRule]] = field(
2046
+ default=None, metadata=config(field_name="matched_yara_rule")
2047
+ )
2048
+
2049
+
2011
2050
  @dataclass_json
2012
2051
  @dataclass(order=True, eq=True, frozen=True)
2013
2052
  class HandsOnKeyboardDetails:
@@ -2178,6 +2217,9 @@ class EnrichmentDetail:
2178
2217
  ] = field(
2179
2218
  default=None, metadata=config(field_name="account_compromise_detector_detail")
2180
2219
  )
2220
+ file_analysis_detail: Optional[FileAnalysisDetail] = field(
2221
+ default=None, metadata=config(field_name="file_analysis_detail")
2222
+ )
2181
2223
  generic: Optional[GenericDetail] = field(
2182
2224
  default=None, metadata=config(field_name="generic")
2183
2225
  )