howler-api 2.12.0.dev307__tar.gz → 2.12.0.dev316__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 (199) hide show
  1. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/PKG-INFO +1 -1
  2. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/view.py +22 -20
  3. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/config.py +145 -1
  4. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/random_data.py +2 -2
  5. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/pyproject.toml +1 -1
  6. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/README.md +0 -0
  7. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/__init__.py +0 -0
  8. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/__init__.py +0 -0
  9. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/add_label.py +0 -0
  10. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/add_to_bundle.py +0 -0
  11. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/change_field.py +0 -0
  12. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/demote.py +0 -0
  13. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/example_plugin.py +0 -0
  14. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/prioritization.py +0 -0
  15. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/promote.py +0 -0
  16. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/remove_from_bundle.py +0 -0
  17. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/remove_label.py +0 -0
  18. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/actions/transition.py +0 -0
  19. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/__init__.py +0 -0
  20. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/base.py +0 -0
  21. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/socket.py +0 -0
  22. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/__init__.py +0 -0
  23. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/action.py +0 -0
  24. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/analytic.py +0 -0
  25. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/auth.py +0 -0
  26. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/borealis.py +0 -0
  27. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/configs.py +0 -0
  28. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/dossier.py +0 -0
  29. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/help.py +0 -0
  30. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/hit.py +0 -0
  31. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/notebook.py +0 -0
  32. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/overview.py +0 -0
  33. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/search.py +0 -0
  34. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/template.py +0 -0
  35. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/tool.py +0 -0
  36. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/user.py +0 -0
  37. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/utils/__init__.py +0 -0
  38. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/api/v1/utils/etag.py +0 -0
  39. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/app.py +0 -0
  40. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/README.md +0 -0
  41. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/__init__.py +0 -0
  42. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/classification.py +0 -0
  43. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/classification.yml +0 -0
  44. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/exceptions.py +0 -0
  45. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/hexdump.py +0 -0
  46. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/iprange.py +0 -0
  47. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/loader.py +0 -0
  48. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/logging/__init__.py +0 -0
  49. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/logging/audit.py +0 -0
  50. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/logging/format.py +0 -0
  51. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/net.py +0 -0
  52. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/net_static.py +0 -0
  53. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/random_user.py +0 -0
  54. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/common/swagger.py +0 -0
  55. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/config.py +0 -0
  56. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/cronjobs/__init__.py +0 -0
  57. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/cronjobs/retention.py +0 -0
  58. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/cronjobs/rules.py +0 -0
  59. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/cronjobs/view_cleanup.py +0 -0
  60. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/README.md +0 -0
  61. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/__init__.py +0 -0
  62. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/bulk.py +0 -0
  63. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/collection.py +0 -0
  64. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/constants.py +0 -0
  65. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/exceptions.py +0 -0
  66. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/howler_store.py +0 -0
  67. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/migrations/fix_process.py +0 -0
  68. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/operations.py +0 -0
  69. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/schemas.py +0 -0
  70. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/store.py +0 -0
  71. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/support/__init__.py +0 -0
  72. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/support/build.py +0 -0
  73. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/support/schemas.py +0 -0
  74. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/datastore/types.py +0 -0
  75. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/error.py +0 -0
  76. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/__init__.py +0 -0
  77. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/generate_mitre.py +0 -0
  78. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/generate_sigma_rules.py +0 -0
  79. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/generate_tlds.py +0 -0
  80. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/reindex_data.py +0 -0
  81. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/external/wipe_databases.py +0 -0
  82. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/gunicorn_config.py +0 -0
  83. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/healthz.py +0 -0
  84. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/__init__.py +0 -0
  85. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/azure.py +0 -0
  86. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/discover.py +0 -0
  87. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/hit.py +0 -0
  88. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/oauth.py +0 -0
  89. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/search.py +0 -0
  90. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/workflow.py +0 -0
  91. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/helper/ws.py +0 -0
  92. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/README.md +0 -0
  93. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/__init__.py +0 -0
  94. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/base.py +0 -0
  95. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/charter.txt +0 -0
  96. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/helper.py +0 -0
  97. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/howler_enum.py +0 -0
  98. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/__init__.py +0 -0
  99. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/action.py +0 -0
  100. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/analytic.py +0 -0
  101. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/assemblyline.py +0 -0
  102. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/aws.py +0 -0
  103. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/azure.py +0 -0
  104. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/cbs.py +0 -0
  105. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/dossier.py +0 -0
  106. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/__init__.py +0 -0
  107. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/agent.py +0 -0
  108. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/autonomous_system.py +0 -0
  109. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/client.py +0 -0
  110. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/cloud.py +0 -0
  111. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/code_signature.py +0 -0
  112. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/container.py +0 -0
  113. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/dns.py +0 -0
  114. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/egress.py +0 -0
  115. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/elf.py +0 -0
  116. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/email.py +0 -0
  117. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/error.py +0 -0
  118. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/event.py +0 -0
  119. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/faas.py +0 -0
  120. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/file.py +0 -0
  121. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/geo.py +0 -0
  122. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/group.py +0 -0
  123. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/hash.py +0 -0
  124. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/host.py +0 -0
  125. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/http.py +0 -0
  126. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/ingress.py +0 -0
  127. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/interface.py +0 -0
  128. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/network.py +0 -0
  129. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/observer.py +0 -0
  130. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/organization.py +0 -0
  131. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/os.py +0 -0
  132. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/pe.py +0 -0
  133. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/process.py +0 -0
  134. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/registry.py +0 -0
  135. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/related.py +0 -0
  136. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/rule.py +0 -0
  137. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/server.py +0 -0
  138. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/threat.py +0 -0
  139. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/tls.py +0 -0
  140. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/url.py +0 -0
  141. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/user.py +0 -0
  142. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/user_agent.py +0 -0
  143. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/ecs/vulnerability.py +0 -0
  144. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/gcp.py +0 -0
  145. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/hit.py +0 -0
  146. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/howler_data.py +0 -0
  147. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/lead.py +0 -0
  148. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/localized_label.py +0 -0
  149. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/overview.py +0 -0
  150. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/pivot.py +0 -0
  151. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/template.py +0 -0
  152. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/user.py +0 -0
  153. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/models/view.py +0 -0
  154. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/odm/randomizer.py +0 -0
  155. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/patched.py +0 -0
  156. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/plugins/__init__.py +0 -0
  157. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/plugins/config.py +0 -0
  158. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/__init__.py +0 -0
  159. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/README.md +0 -0
  160. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/__init__.py +0 -0
  161. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/counters.py +0 -0
  162. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/events.py +0 -0
  163. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/hash.py +0 -0
  164. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/lock.py +0 -0
  165. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/queues/__init__.py +0 -0
  166. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/queues/comms.py +0 -0
  167. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/queues/multi.py +0 -0
  168. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/queues/named.py +0 -0
  169. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/queues/priority.py +0 -0
  170. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/set.py +0 -0
  171. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/remote/datatypes/user_quota_tracker.py +0 -0
  172. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/security/__init__.py +0 -0
  173. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/security/socket.py +0 -0
  174. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/security/utils.py +0 -0
  175. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/__init__.py +0 -0
  176. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/action_service.py +0 -0
  177. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/analytic_service.py +0 -0
  178. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/auth_service.py +0 -0
  179. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/config_service.py +0 -0
  180. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/dossier_service.py +0 -0
  181. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/event_service.py +0 -0
  182. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/hit_service.py +0 -0
  183. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/jwt_service.py +0 -0
  184. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/lucene_service.py +0 -0
  185. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/notebook_service.py +0 -0
  186. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/overview_service.py +0 -0
  187. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/template_service.py +0 -0
  188. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/services/user_service.py +0 -0
  189. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/__init__.py +0 -0
  190. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/annotations.py +0 -0
  191. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/chunk.py +0 -0
  192. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/dict_utils.py +0 -0
  193. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/isotime.py +0 -0
  194. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/list_utils.py +0 -0
  195. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/lucene.py +0 -0
  196. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/path.py +0 -0
  197. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/socket_utils.py +0 -0
  198. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/str_utils.py +0 -0
  199. {howler_api-2.12.0.dev307 → howler_api-2.12.0.dev316}/howler/utils/uid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: howler-api
3
- Version: 2.12.0.dev307
3
+ Version: 2.12.0.dev316
4
4
  Summary: Howler - API server
5
5
  License: MIT
6
6
  Keywords: howler,alerting,gc,canada,cse-cst,cse,cst,cyber,cccs
@@ -108,13 +108,13 @@ def create_view(**kwargs):
108
108
 
109
109
 
110
110
  @generate_swagger_docs()
111
- @view_api.route("/<id>", methods=["DELETE"])
111
+ @view_api.route("/<view_id>", methods=["DELETE"])
112
112
  @api_login(required_priv=["W"])
113
- def delete_view(id: str, user: User, **kwargs):
113
+ def delete_view(view_id: str, user: User, **kwargs):
114
114
  """Delete a view
115
115
 
116
116
  Variables:
117
- id => The id of the view to delete
117
+ view_id => The id of the view to delete
118
118
 
119
119
  Optional Arguments:
120
120
  None
@@ -129,7 +129,7 @@ def delete_view(id: str, user: User, **kwargs):
129
129
  """
130
130
  storage = datastore()
131
131
 
132
- existing_view: View = storage.view.get_if_exists(id)
132
+ existing_view: View = storage.view.get_if_exists(view_id)
133
133
  if not existing_view:
134
134
  return not_found(err="This view does not exist")
135
135
 
@@ -139,7 +139,7 @@ def delete_view(id: str, user: User, **kwargs):
139
139
  if existing_view.type == "readonly":
140
140
  return forbidden(err="You cannot delete built-in views.")
141
141
 
142
- success = storage.view.delete(id)
142
+ success = storage.view.delete(view_id)
143
143
 
144
144
  storage.view.commit()
145
145
 
@@ -147,13 +147,13 @@ def delete_view(id: str, user: User, **kwargs):
147
147
 
148
148
 
149
149
  @generate_swagger_docs()
150
- @view_api.route("/<id>", methods=["PUT"])
150
+ @view_api.route("/<view_id>", methods=["PUT"])
151
151
  @api_login(required_priv=["R", "W"])
152
- def update_view(id: str, user: User, **kwargs):
152
+ def update_view(view_id: str, user: User, **kwargs):
153
153
  """Update a view
154
154
 
155
155
  Variables:
156
- id => The id of the view to modify
156
+ view_id => The view_id of the view to modify
157
157
 
158
158
  Optional Arguments:
159
159
  None
@@ -178,7 +178,7 @@ def update_view(id: str, user: User, **kwargs):
178
178
  if set(new_data.keys()) & {"view_id", "owner"}:
179
179
  return bad_request(err="You cannot change the owner or id of a view.")
180
180
 
181
- existing_view: View = storage.view.get_if_exists(id)
181
+ existing_view: View = storage.view.get_if_exists(view_id)
182
182
  if not existing_view:
183
183
  return not_found(err="This view does not exist")
184
184
 
@@ -210,13 +210,13 @@ def update_view(id: str, user: User, **kwargs):
210
210
 
211
211
 
212
212
  @generate_swagger_docs()
213
- @view_api.route("/<id>/favourite", methods=["POST"])
213
+ @view_api.route("/<view_id>/favourite", methods=["POST"])
214
214
  @api_login(required_priv=["R", "W"])
215
- def set_as_favourite(id: str, **kwargs):
215
+ def set_as_favourite(view_id: str, **kwargs):
216
216
  """Add a view to a list of the user's favourites
217
217
 
218
218
  Variables:
219
- id => The id of the view to add as a favourite
219
+ view_id => The id of the view to add as a favourite
220
220
 
221
221
  Optional Arguments:
222
222
  None
@@ -231,7 +231,7 @@ def set_as_favourite(id: str, **kwargs):
231
231
  """
232
232
  storage = datastore()
233
233
 
234
- existing_view: View = storage.view.get_if_exists(id)
234
+ existing_view: View = storage.view.get_if_exists(view_id)
235
235
  if not existing_view:
236
236
  return not_found(err="This view does not exist")
237
237
 
@@ -243,7 +243,7 @@ def set_as_favourite(id: str, **kwargs):
243
243
  try:
244
244
  current_user = storage.user.get_if_exists(kwargs["user"]["uname"])
245
245
 
246
- current_user["favourite_views"] = list(set(current_user.get("favourite_views", []) + [id]))
246
+ current_user["favourite_views"] = list(set(current_user.get("favourite_views", []) + [view_id]))
247
247
 
248
248
  storage.user.save(current_user["uname"], current_user)
249
249
 
@@ -253,9 +253,9 @@ def set_as_favourite(id: str, **kwargs):
253
253
 
254
254
 
255
255
  @generate_swagger_docs()
256
- @view_api.route("/<id>/favourite", methods=["DELETE"])
256
+ @view_api.route("/<view_id>/favourite", methods=["DELETE"])
257
257
  @api_login(required_priv=["R", "W"])
258
- def remove_as_favourite(id, **kwargs):
258
+ def remove_as_favourite(view_id: str, **kwargs):
259
259
  """Remove a view from a list of the user's favourites
260
260
 
261
261
  Variables:
@@ -271,13 +271,15 @@ def remove_as_favourite(id, **kwargs):
271
271
  """
272
272
  storage = datastore()
273
273
 
274
- if not storage.view.exists(id):
275
- return not_found(err="This view does not exist")
276
-
277
274
  try:
278
275
  current_user = storage.user.get_if_exists(kwargs["user"]["uname"])
279
276
 
280
- current_user["favourite_views"] = list(filter(lambda f: f != id, current_user.get("favourite_views", [])))
277
+ current_favourites: list[str] = current_user.get("favourite_views", [])
278
+
279
+ if view_id not in current_favourites:
280
+ return not_found(err="View is not favourited.")
281
+
282
+ current_user["favourite_views"] = [favourite for favourite in current_favourites if favourite != view_id]
281
283
 
282
284
  storage.user.save(current_user["uname"], current_user)
283
285
 
@@ -20,11 +20,24 @@ logger.addHandler(console)
20
20
 
21
21
 
22
22
  class RedisServer(BaseModel):
23
+ """Configuration for a single Redis server instance.
24
+
25
+ Defines the connection parameters for a Redis server, including
26
+ the hostname and port number.
27
+ """
28
+
23
29
  host: str = Field(description="Hostname of Redis instance")
24
30
  port: int = Field(description="Port of Redis instance")
25
31
 
26
32
 
27
33
  class Redis(BaseModel):
34
+ """Redis configuration for Howler.
35
+
36
+ Defines connections to both persistent and non-persistent Redis instances.
37
+ The non-persistent instance is used for volatile data like caches, while
38
+ the persistent instance is used for data that needs to survive restarts.
39
+ """
40
+
28
41
  nonpersistent: RedisServer = Field(
29
42
  default=RedisServer(host="127.0.0.1", port=6379), description="A volatile Redis instance"
30
43
  )
@@ -35,6 +48,14 @@ class Redis(BaseModel):
35
48
 
36
49
 
37
50
  class Host(BaseModel):
51
+ """Configuration for a remote host connection.
52
+
53
+ Defines connection parameters for external services, including authentication
54
+ credentials (username/password or API key) and connection details.
55
+ Environment variables can override username and password using the pattern
56
+ {NAME}_HOST_USERNAME and {NAME}_HOST_PASSWORD.
57
+ """
58
+
38
59
  name: str = Field(description="Name of the host")
39
60
  username: Optional[str] = Field(description="Username to login with", default=None)
40
61
  password: Optional[str] = Field(description="Password to login with", default=None)
@@ -64,6 +85,12 @@ class Host(BaseModel):
64
85
 
65
86
 
66
87
  class Datastore(BaseModel):
88
+ """Datastore configuration for Howler.
89
+
90
+ Defines the backend datastore used by Howler for storing hits and metadata.
91
+ Currently supports Elasticsearch as the datastore type.
92
+ """
93
+
67
94
  hosts: list[Host] = Field(
68
95
  default=[Host(name="elastic", username="elastic", password="devpass", scheme="http", host="localhost:9200")], # noqa: S106
69
96
  description="List of hosts used for the datastore",
@@ -74,6 +101,13 @@ class Datastore(BaseModel):
74
101
 
75
102
 
76
103
  class Logging(BaseModel):
104
+ """Logging configuration for Howler.
105
+
106
+ Defines how and where Howler logs should be output, including console,
107
+ file, and syslog destinations. Also controls log level, format, and
108
+ metric export intervals.
109
+ """
110
+
77
111
  log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "DISABLED"] = Field(
78
112
  default="INFO",
79
113
  description="What level of logging should we have?",
@@ -94,6 +128,12 @@ class Logging(BaseModel):
94
128
 
95
129
 
96
130
  class PasswordRequirement(BaseModel):
131
+ """Password complexity requirements for internal authentication.
132
+
133
+ Defines the rules for password creation and validation, including
134
+ character type requirements and minimum length.
135
+ """
136
+
97
137
  lower: bool = Field(default=False, description="Password must contain lowercase letters")
98
138
  number: bool = Field(default=False, description="Password must contain numbers")
99
139
  special: bool = Field(default=False, description="Password must contain special characters")
@@ -102,6 +142,13 @@ class PasswordRequirement(BaseModel):
102
142
 
103
143
 
104
144
  class Internal(BaseModel):
145
+ """Internal authentication configuration.
146
+
147
+ Defines settings for Howler's built-in username/password authentication,
148
+ including password requirements and brute-force protection via login
149
+ failure tracking.
150
+ """
151
+
105
152
  enabled: bool = Field(default=True, description="Internal authentication allowed?")
106
153
  failure_ttl: int = Field(
107
154
  default=60, description="How long to wait after `max_failures` before re-attempting login?"
@@ -111,6 +158,13 @@ class Internal(BaseModel):
111
158
 
112
159
 
113
160
  class OAuthAutoProperty(BaseModel):
161
+ """Automatic property assignment based on OAuth attributes.
162
+
163
+ Defines rules for automatically assigning user properties (roles,
164
+ classifications, or access levels) based on pattern matching against
165
+ OAuth provider data.
166
+ """
167
+
114
168
  field: str = Field(description="Field to apply `pattern` to")
115
169
  pattern: str = Field(description="Regex pattern for auto-prop assignment")
116
170
  type: Literal["access", "classification", "role"] = Field(
@@ -120,6 +174,13 @@ class OAuthAutoProperty(BaseModel):
120
174
 
121
175
 
122
176
  class OAuthProvider(BaseModel):
177
+ """OAuth provider configuration.
178
+
179
+ Defines the connection and authentication settings for an OAuth 2.0 provider.
180
+ Includes user auto-creation, group mapping, JWT validation, and various
181
+ OAuth endpoints required for the authentication flow.
182
+ """
183
+
123
184
  auto_create: bool = Field(default=True, description="Auto-create users if they are missing")
124
185
  auto_sync: bool = Field(default=False, description="Should we automatically sync with OAuth provider?")
125
186
  auto_properties: list[OAuthAutoProperty] = Field(
@@ -191,6 +252,13 @@ class OAuthProvider(BaseModel):
191
252
 
192
253
 
193
254
  class OAuth(BaseModel):
255
+ """OAuth authentication configuration.
256
+
257
+ Top-level OAuth settings including enabling/disabling OAuth authentication,
258
+ Gravatar integration, and a dictionary of configured OAuth providers.
259
+ Also controls API key lifetime restrictions for OAuth-authenticated users.
260
+ """
261
+
194
262
  enabled: bool = Field(default=False, description="Enable use of OAuth?")
195
263
  gravatar_enabled: bool = Field(default=True, description="Enable gravatar?")
196
264
  providers: dict[str, OAuthProvider] = Field(
@@ -204,6 +272,13 @@ class OAuth(BaseModel):
204
272
 
205
273
 
206
274
  class Auth(BaseModel):
275
+ """Authentication configuration for Howler.
276
+
277
+ Configures all authentication methods supported by Howler, including
278
+ internal username/password authentication and OAuth providers. Also
279
+ controls API key settings and restrictions.
280
+ """
281
+
207
282
  allow_apikeys: bool = Field(default=True, description="Allow API keys?")
208
283
  allow_extended_apikeys: bool = Field(default=True, description="Allow extended API keys?")
209
284
  max_apikey_duration_amount: Optional[int] = Field(
@@ -218,17 +293,34 @@ class Auth(BaseModel):
218
293
 
219
294
 
220
295
  class APMServer(BaseModel):
221
- "APM server configuration"
296
+ """Application Performance Monitoring (APM) server configuration.
297
+
298
+ Defines the connection details for an external APM server used to
299
+ collect and analyze application performance metrics.
300
+ """
222
301
 
223
302
  server_url: Optional[str] = Field(default=None, description="URL to API server")
224
303
  token: Optional[str] = Field(default=None, description="Authentication token for server")
225
304
 
226
305
 
227
306
  class Metrics(BaseModel):
307
+ """Metrics collection configuration.
308
+
309
+ Configures how Howler collects and exports application metrics,
310
+ including integration with external APM servers.
311
+ """
312
+
228
313
  apm_server: APMServer = APMServer()
229
314
 
230
315
 
231
316
  class Retention(BaseModel):
317
+ """Hit retention policy configuration.
318
+
319
+ Defines the automatic data retention policy for hits, including
320
+ the maximum age of hits before they are purged and the schedule
321
+ for running the retention cleanup job.
322
+ """
323
+
232
324
  enabled: bool = Field(
233
325
  default=True,
234
326
  description=(
@@ -251,6 +343,12 @@ class Retention(BaseModel):
251
343
 
252
344
 
253
345
  class ViewCleanup(BaseModel):
346
+ """View cleanup job configuration.
347
+
348
+ Defines the schedule and behavior for cleaning up stale dashboard views
349
+ that reference non-existent backend data.
350
+ """
351
+
254
352
  enabled: bool = Field(
255
353
  default=True,
256
354
  description=(
@@ -265,6 +363,13 @@ class ViewCleanup(BaseModel):
265
363
 
266
364
 
267
365
  class System(BaseModel):
366
+ """System-level configuration for Howler.
367
+
368
+ Defines global system settings including deployment type (production,
369
+ staging, or development) and configuration for automated maintenance
370
+ jobs like data retention and view cleanup.
371
+ """
372
+
268
373
  type: Literal["production", "staging", "development"] = Field(default="development", description="Type of system")
269
374
  retention: Retention = Retention()
270
375
  "Retention Configuration"
@@ -273,6 +378,13 @@ class System(BaseModel):
273
378
 
274
379
 
275
380
  class UI(BaseModel):
381
+ """User interface and web server configuration.
382
+
383
+ Defines settings for the Howler web UI including Flask configuration,
384
+ session validation, API auditing, static file locations, and WebSocket
385
+ integration for real-time updates.
386
+ """
387
+
276
388
  audit: bool = Field(description="Should API calls be audited and saved to a separate log file?", default=True)
277
389
  debug: bool = Field(default=False, description="Enable debugging?")
278
390
  static_folder: Optional[str] = Field(
@@ -298,6 +410,13 @@ class UI(BaseModel):
298
410
 
299
411
 
300
412
  class Borealis(BaseModel):
413
+ """Borealis enrichment service integration configuration.
414
+
415
+ Defines settings for integrating with Borealis, an external enrichment
416
+ service that can provide additional context and status information for
417
+ hits displayed in the Howler UI.
418
+ """
419
+
301
420
  enabled: bool = Field(default=False, description="Should borealis integration be enabled?")
302
421
 
303
422
  url: str = Field(
@@ -312,6 +431,13 @@ class Borealis(BaseModel):
312
431
 
313
432
 
314
433
  class Notebook(BaseModel):
434
+ """Jupyter notebook integration configuration.
435
+
436
+ Defines settings for integrating with nbgallery, a collaborative
437
+ Jupyter notebook platform, allowing users to access and share
438
+ notebooks related to their Howler analysis work.
439
+ """
440
+
315
441
  enabled: bool = Field(default=False, description="Should nbgallery notebook integration be enabled?")
316
442
 
317
443
  scope: Optional[str] = Field(default=None, description="The scope expected by nbgallery for JWTs")
@@ -322,6 +448,13 @@ class Notebook(BaseModel):
322
448
 
323
449
 
324
450
  class Core(BaseModel):
451
+ """Core application configuration for Howler.
452
+
453
+ Aggregates all core service configurations including Redis, metrics,
454
+ and external integrations like Borealis and nbgallery notebooks.
455
+ Also manages the loading of external plugins.
456
+ """
457
+
325
458
  plugins: set[str] = Field(description="A list of external plugins to load", default=set())
326
459
 
327
460
  metrics: Metrics = Metrics()
@@ -379,6 +512,17 @@ logger.info("Fetching configuration files from %s", ":".join(str(c) for c in con
379
512
 
380
513
 
381
514
  class Config(BaseSettings):
515
+ """Main Howler configuration model.
516
+
517
+ The root configuration object that aggregates all configuration sections
518
+ including authentication, datastore, logging, system settings, UI, and core
519
+ services. Configuration can be loaded from YAML files or environment variables
520
+ with the HWL_ prefix.
521
+
522
+ Environment variables use double underscores (__) for nested properties.
523
+ For example: HWL_DATASTORE__TYPE=elasticsearch
524
+ """
525
+
382
526
  auth: Auth = Auth()
383
527
  core: Core = Core()
384
528
  datastore: Datastore = Datastore()
@@ -821,14 +821,14 @@ def wipe_dossiers(ds: HowlerDatastore):
821
821
  def setup_hits(ds):
822
822
  "Set up hits index"
823
823
  os.environ["ELASTIC_HIT_SHARDS"] = "1"
824
- os.environ["ELASTIC_HIT_REPLICAS"] = "0"
824
+ os.environ["ELASTIC_HIT_REPLICAS"] = "1"
825
825
  ds.hit.fix_shards()
826
826
  ds.hit.fix_replicas()
827
827
 
828
828
 
829
829
  def setup_users(ds):
830
830
  "Set up users index"
831
- os.environ["ELASTIC_USER_REPLICAS"] = "12"
831
+ os.environ["ELASTIC_USER_REPLICAS"] = "1"
832
832
  os.environ["ELASTIC_USER_AVATAR_REPLICAS"] = "1"
833
833
  ds.user.fix_replicas()
834
834
  ds.user_avatar.fix_replicas()
@@ -148,7 +148,7 @@ suppress-none-returning = true
148
148
  [tool.poetry]
149
149
  package-mode = true
150
150
  name = "howler-api"
151
- version = "2.12.0.dev307"
151
+ version = "2.12.0.dev316"
152
152
  description = "Howler - API server"
153
153
  authors = [
154
154
  "Canadian Centre for Cyber Security <howler@cyber.gc.ca>",