howler-api 3.4.0.dev845__tar.gz → 3.4.0.dev870__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.
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/PKG-INFO +1 -1
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/store.py +123 -34
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/base.py +2 -2
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/pyproject.toml +1 -1
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/add_label.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/change_field.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/demote.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/example_plugin.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/prioritization.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/promote.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/remove_label.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/actions/transition.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/base.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/socket.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/action.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/analytic.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/auth.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/clue.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/configs.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/dossier.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/help.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/hit.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/notebook.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/overview.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/search.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/template.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/tool.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/user.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/api/v1/view.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/app.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/classification.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/classification.yml +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/exceptions.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/loader.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/logging/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/logging/audit.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/logging/format.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/net.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/net_static.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/random_user.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/common/swagger.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/config.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/cronjobs/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/cronjobs/retention.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/cronjobs/rules.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/bulk.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/collection.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/constants.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/exceptions.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/howler_store.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/operations.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/schemas.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/support/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/support/build.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/support/schemas.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/types.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/error.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/generate_mitre.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/generate_tlds.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/reindex_data.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/external/wipe_databases.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/gunicorn_config.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/healthz.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/azure.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/discover.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/hit.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/oauth.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/search.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/workflow.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/helper/ws.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/charter.txt +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/helper.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/howler_enum.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/action.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/analytic.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/aws.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/azure.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/cbs.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/clue.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/config.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/dossier.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/gcp.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/hit.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/howler_data.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/lead.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/localized_label.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/overview.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/pivot.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/template.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/user.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/view.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/random_data.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/randomizer.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/patched.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/plugins/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/plugins/config.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/README.md +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/events.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/set.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/security/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/security/socket.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/security/utils.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/action_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/analytic_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/auth_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/config_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/dossier_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/event_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/hit_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/jwt_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/lucene_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/notebook_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/overview_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/template_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/services/user_service.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/telemetry.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/__init__.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/annotations.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/chunk.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/compat.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/constants.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/dict_utils.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/isotime.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/list_utils.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/lucene.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/path.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/socket_utils.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/str_utils.py +0 -0
- {howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/utils/uid.py +0 -0
|
@@ -28,7 +28,18 @@ logger.addHandler(console)
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class ESStore(object):
|
|
31
|
-
"""Elasticsearch multi-index
|
|
31
|
+
"""Elasticsearch multi-index datastore backed by one or more ES hosts.
|
|
32
|
+
|
|
33
|
+
Manages connections, collection caching, model registration, and date-math
|
|
34
|
+
helpers for Howler's Elasticsearch indices.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
DEFAULT_SORT: Default sort order for queries.
|
|
38
|
+
DATE_FORMAT: Mapping of abstract time-unit names to ES date-math tokens.
|
|
39
|
+
DATEMATH_MAP: Mapping used by ``to_pydatemath`` to convert internal
|
|
40
|
+
date-math expressions into ES-compatible strings.
|
|
41
|
+
ID: Name of the document identifier field.
|
|
42
|
+
"""
|
|
32
43
|
|
|
33
44
|
DEFAULT_SORT = "id asc"
|
|
34
45
|
DATE_FORMAT = {
|
|
@@ -60,6 +71,18 @@ class ESStore(object):
|
|
|
60
71
|
ID = "id"
|
|
61
72
|
|
|
62
73
|
def __init__(self, config: Optional[Config] = None, archive_access=True):
|
|
74
|
+
"""Initialise the store and open an Elasticsearch connection.
|
|
75
|
+
|
|
76
|
+
Host addresses, TLS certificates, API keys, and basic-auth credentials
|
|
77
|
+
are resolved from the supplied ``config`` and from environment variables
|
|
78
|
+
named ``<HOST>_HOST_APIKEY_ID`` / ``<HOST>_HOST_APIKEY_SECRET`` or
|
|
79
|
+
``<HOST>_HOST_USERNAME`` / ``<HOST>_HOST_PASSWORD``.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
config: Application configuration. Falls back to the global
|
|
83
|
+
``howler.odm.models.config.config`` singleton when ``None``.
|
|
84
|
+
archive_access: Whether archive indices should be accessible.
|
|
85
|
+
"""
|
|
63
86
|
if not config:
|
|
64
87
|
config = _config
|
|
65
88
|
|
|
@@ -111,32 +134,7 @@ class ESStore(object):
|
|
|
111
134
|
tracer = logging.getLogger("elasticsearch")
|
|
112
135
|
tracer.setLevel(logging.CRITICAL)
|
|
113
136
|
|
|
114
|
-
|
|
115
|
-
self.client = elasticsearch.Elasticsearch(
|
|
116
|
-
hosts=self._hosts, # type: ignore
|
|
117
|
-
ca_certs=self._cert, # type: ignore
|
|
118
|
-
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
119
|
-
api_key=self._apikey,
|
|
120
|
-
max_retries=0,
|
|
121
|
-
request_timeout=TRANSPORT_TIMEOUT,
|
|
122
|
-
)
|
|
123
|
-
elif self._username is not None and self._password is not None:
|
|
124
|
-
self.client = elasticsearch.Elasticsearch(
|
|
125
|
-
hosts=self._hosts, # type: ignore
|
|
126
|
-
ca_certs=self._cert, # type: ignore
|
|
127
|
-
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
128
|
-
basic_auth=(self._username, self._password),
|
|
129
|
-
max_retries=0,
|
|
130
|
-
request_timeout=TRANSPORT_TIMEOUT,
|
|
131
|
-
)
|
|
132
|
-
else:
|
|
133
|
-
self.client = elasticsearch.Elasticsearch(
|
|
134
|
-
hosts=self._hosts, # type: ignore
|
|
135
|
-
ca_certs=self._cert, # type: ignore
|
|
136
|
-
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
137
|
-
max_retries=0,
|
|
138
|
-
request_timeout=TRANSPORT_TIMEOUT,
|
|
139
|
-
)
|
|
137
|
+
self.client = self.__build_connection()
|
|
140
138
|
self.archive_access = archive_access
|
|
141
139
|
self.url_path = "elastic"
|
|
142
140
|
|
|
@@ -149,7 +147,24 @@ class ESStore(object):
|
|
|
149
147
|
def __str__(self):
|
|
150
148
|
return "{0} - {1}".format(self.__class__.__name__, self._hosts)
|
|
151
149
|
|
|
152
|
-
def
|
|
150
|
+
def __getitem__(self, name: str) -> ESCollection:
|
|
151
|
+
return self.__getattr__(name)
|
|
152
|
+
|
|
153
|
+
def __getattr__(self, name: str) -> ESCollection:
|
|
154
|
+
"""Return the ``ESCollection`` registered under *name*.
|
|
155
|
+
|
|
156
|
+
Collections are cached after the first access when validation is
|
|
157
|
+
enabled.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
name: Registered collection (index) name.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
The ``ESCollection`` instance for *name*.
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
KeyError: If *name* has not been registered via ``register``.
|
|
167
|
+
"""
|
|
153
168
|
if not self.validate:
|
|
154
169
|
return ESCollection(self, name, model_class=self._models[name], validate=self.validate)
|
|
155
170
|
|
|
@@ -206,21 +221,67 @@ class ESStore(object):
|
|
|
206
221
|
def date_separator(self):
|
|
207
222
|
return self.DATE_FORMAT["SEPARATOR"]
|
|
208
223
|
|
|
224
|
+
def __build_connection(self) -> elasticsearch.Elasticsearch:
|
|
225
|
+
"""Create a new ``Elasticsearch`` client from stored credentials.
|
|
226
|
+
|
|
227
|
+
Authentication is selected automatically: API-key auth is preferred,
|
|
228
|
+
then basic auth, then anonymous.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
A freshly constructed ``Elasticsearch`` client.
|
|
232
|
+
"""
|
|
233
|
+
if self._apikey is not None:
|
|
234
|
+
return elasticsearch.Elasticsearch(
|
|
235
|
+
hosts=self._hosts, # type: ignore
|
|
236
|
+
ca_certs=self._cert, # type: ignore
|
|
237
|
+
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
238
|
+
api_key=self._apikey,
|
|
239
|
+
max_retries=0,
|
|
240
|
+
request_timeout=TRANSPORT_TIMEOUT,
|
|
241
|
+
)
|
|
242
|
+
elif self._username is not None and self._password is not None:
|
|
243
|
+
return elasticsearch.Elasticsearch(
|
|
244
|
+
hosts=self._hosts, # type: ignore
|
|
245
|
+
ca_certs=self._cert, # type: ignore
|
|
246
|
+
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
247
|
+
basic_auth=(self._username, self._password),
|
|
248
|
+
max_retries=0,
|
|
249
|
+
request_timeout=TRANSPORT_TIMEOUT,
|
|
250
|
+
)
|
|
251
|
+
else:
|
|
252
|
+
return elasticsearch.Elasticsearch(
|
|
253
|
+
hosts=self._hosts, # type: ignore
|
|
254
|
+
ca_certs=self._cert, # type: ignore
|
|
255
|
+
ssl_assert_fingerprint=self._fingerprint, # type: ignore
|
|
256
|
+
max_retries=0,
|
|
257
|
+
request_timeout=TRANSPORT_TIMEOUT,
|
|
258
|
+
)
|
|
259
|
+
|
|
209
260
|
def connection_reset(self):
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
api_key=self._apikey,
|
|
213
|
-
max_retries=0,
|
|
214
|
-
request_timeout=TRANSPORT_TIMEOUT,
|
|
215
|
-
)
|
|
261
|
+
"""Replace the current ES client with a fresh connection."""
|
|
262
|
+
self.client = self.__build_connection()
|
|
216
263
|
|
|
217
264
|
def close(self):
|
|
265
|
+
"""Mark the store as closed and release the ES client.
|
|
266
|
+
|
|
267
|
+
After calling this method any attempt to use the client will raise
|
|
268
|
+
an ``AttributeError``.
|
|
269
|
+
"""
|
|
218
270
|
self._closed = True
|
|
219
271
|
# Flatten the client object so that attempts to access without reconnecting errors hard
|
|
220
272
|
# But 'cast' it so that mypy and other linters don't think that its normal for client to be None
|
|
221
273
|
self.client = cast(elasticsearch.Elasticsearch, None)
|
|
222
274
|
|
|
223
275
|
def get_hosts(self, safe=False):
|
|
276
|
+
"""Return the list of configured ES host addresses.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
safe: When ``True``, strip the scheme and port from each URL and
|
|
280
|
+
return only hostnames.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
A list of host strings.
|
|
284
|
+
"""
|
|
224
285
|
if not safe:
|
|
225
286
|
return self._hosts
|
|
226
287
|
else:
|
|
@@ -231,15 +292,33 @@ class ESStore(object):
|
|
|
231
292
|
return out
|
|
232
293
|
|
|
233
294
|
def get_models(self):
|
|
295
|
+
"""Return the mapping of registered collection names to model classes."""
|
|
234
296
|
return self._models
|
|
235
297
|
|
|
236
298
|
def is_closed(self):
|
|
299
|
+
"""Return ``True`` if the store has been closed."""
|
|
237
300
|
return self._closed
|
|
238
301
|
|
|
239
302
|
def ping(self):
|
|
303
|
+
"""Ping the Elasticsearch cluster.
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
``True`` if the cluster responded successfully.
|
|
307
|
+
"""
|
|
240
308
|
return self.client.ping()
|
|
241
309
|
|
|
242
310
|
def register(self, name: str, model_class=None):
|
|
311
|
+
"""Register a collection (index) name and its optional ODM model class.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
name: Collection name. Must contain only lowercase letters, digits,
|
|
315
|
+
and underscores.
|
|
316
|
+
model_class: ODM model class used for validation and serialisation.
|
|
317
|
+
``None`` disables model-level validation for this collection.
|
|
318
|
+
|
|
319
|
+
Raises:
|
|
320
|
+
DataStoreException: If *name* contains invalid characters.
|
|
321
|
+
"""
|
|
243
322
|
name_match = re.match(r"[a-z0-9_]*", name)
|
|
244
323
|
if not name_match or name_match.string != name:
|
|
245
324
|
raise DataStoreException(
|
|
@@ -249,6 +328,16 @@ class ESStore(object):
|
|
|
249
328
|
self._models[name] = model_class
|
|
250
329
|
|
|
251
330
|
def to_pydatemath(self, value):
|
|
331
|
+
"""Convert an internal date-math expression to ES date-math syntax.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
value: String containing abstract date-math tokens (e.g.
|
|
335
|
+
``"NOW-1DAY"``).
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
The equivalent Elasticsearch date-math string (e.g.
|
|
339
|
+
``"now-1d"``).
|
|
340
|
+
"""
|
|
252
341
|
replace_list = [
|
|
253
342
|
(self.now, self.DATEMATH_MAP["NOW"]),
|
|
254
343
|
(self.year, self.DATEMATH_MAP["YEAR"]),
|
|
@@ -1532,10 +1532,10 @@ def model(index=None, store=None, description=None, id_field=None):
|
|
|
1532
1532
|
if not isinstance(id_field, str):
|
|
1533
1533
|
raise HowlerTypeError(f"id_field must be a str, got {type(id_field).__name__}")
|
|
1534
1534
|
|
|
1535
|
-
if not
|
|
1535
|
+
if not FLATTENED_OBJECT_SANITIZER.match(id_field) or id_field in BANNED_FIELDS:
|
|
1536
1536
|
raise HowlerValueError(f"Illegal id_field name: {id_field}")
|
|
1537
1537
|
|
|
1538
|
-
if id_field not in fields:
|
|
1538
|
+
if id_field not in fields and id_field not in cls.flat_fields():
|
|
1539
1539
|
raise HowlerValueError(f"id_field must reference a declared field: {id_field}")
|
|
1540
1540
|
|
|
1541
1541
|
cls._Model__id_field = id_field
|
|
@@ -152,7 +152,7 @@ suppress-none-returning = true
|
|
|
152
152
|
[tool.poetry]
|
|
153
153
|
package-mode = true
|
|
154
154
|
name = "howler-api"
|
|
155
|
-
version = "3.4.0.
|
|
155
|
+
version = "3.4.0.dev870"
|
|
156
156
|
description = "Howler - API server"
|
|
157
157
|
authors = [
|
|
158
158
|
"Canadian Centre for Cyber Security <howler@cyber.gc.ca>",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/datastore/migrations/fix_process.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/odm/models/ecs/autonomous_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev845 → howler_api-3.4.0.dev870}/howler/remote/datatypes/user_quota_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|