howler-api 3.4.0.dev834__tar.gz → 3.4.0.dev845__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.dev834 → howler_api-3.4.0.dev845}/PKG-INFO +1 -1
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/base.py +80 -21
- howler_api-3.4.0.dev845/howler/utils/compat.py +27 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/pyproject.toml +1 -1
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/add_label.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/change_field.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/demote.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/example_plugin.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/prioritization.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/promote.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/remove_label.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/actions/transition.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/base.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/socket.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/action.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/analytic.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/auth.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/clue.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/configs.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/dossier.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/help.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/hit.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/notebook.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/overview.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/search.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/template.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/tool.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/user.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/api/v1/view.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/app.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/classification.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/classification.yml +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/exceptions.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/loader.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/logging/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/logging/audit.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/logging/format.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/net.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/net_static.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/random_user.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/common/swagger.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/config.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/cronjobs/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/cronjobs/retention.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/cronjobs/rules.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/bulk.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/collection.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/constants.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/exceptions.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/howler_store.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/operations.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/schemas.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/store.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/support/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/support/build.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/support/schemas.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/datastore/types.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/error.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/generate_mitre.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/generate_tlds.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/reindex_data.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/external/wipe_databases.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/gunicorn_config.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/healthz.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/azure.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/discover.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/hit.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/oauth.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/search.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/workflow.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/helper/ws.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/charter.txt +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/helper.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/howler_enum.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/action.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/analytic.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/aws.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/azure.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/cbs.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/clue.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/config.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/dossier.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/gcp.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/hit.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/howler_data.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/lead.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/localized_label.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/overview.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/pivot.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/template.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/user.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/models/view.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/random_data.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/odm/randomizer.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/patched.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/plugins/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/plugins/config.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/README.md +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/events.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/set.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/security/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/security/socket.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/security/utils.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/action_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/analytic_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/auth_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/config_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/dossier_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/event_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/hit_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/jwt_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/lucene_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/notebook_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/overview_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/template_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/services/user_service.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/telemetry.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/__init__.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/annotations.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/chunk.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/constants.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/dict_utils.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/isotime.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/list_utils.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/lucene.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/path.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/socket_utils.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/str_utils.py +0 -0
- {howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/utils/uid.py +0 -0
|
@@ -19,7 +19,7 @@ from datetime import datetime
|
|
|
19
19
|
from enum import Enum as PyEnum
|
|
20
20
|
from enum import EnumMeta
|
|
21
21
|
from typing import Any as _Any
|
|
22
|
-
from typing import
|
|
22
|
+
from typing import Callable
|
|
23
23
|
from venv import logger
|
|
24
24
|
|
|
25
25
|
import arrow
|
|
@@ -29,6 +29,8 @@ from dateutil.tz import tzutc
|
|
|
29
29
|
from howler.common import loader
|
|
30
30
|
from howler.common.exceptions import HowlerKeyError, HowlerNotImplementedError, HowlerTypeError, HowlerValueError
|
|
31
31
|
from howler.common.net import is_valid_domain, is_valid_ip
|
|
32
|
+
from howler.odm.howler_enum import HowlerEnum
|
|
33
|
+
from howler.utils.compat import StrEnum as PyStrEnum
|
|
32
34
|
from howler.utils.dict_utils import flatten, recursive_update
|
|
33
35
|
from howler.utils.isotime import now_as_iso
|
|
34
36
|
from howler.utils.uid import get_random_id
|
|
@@ -549,15 +551,23 @@ class Processor(ValidatedKeyword):
|
|
|
549
551
|
|
|
550
552
|
|
|
551
553
|
class Enum(Keyword):
|
|
552
|
-
"""A field storing a short string that has predefined list of possible values
|
|
554
|
+
"""A field storing a short string that has predefined list of possible values.
|
|
553
555
|
|
|
554
|
-
|
|
556
|
+
Accepts values from lists/sets, Enum classes, and StrEnum (PyStrEnum) members.
|
|
557
|
+
"""
|
|
558
|
+
|
|
559
|
+
def __init__(
|
|
560
|
+
self,
|
|
561
|
+
values: type[HowlerEnum] | type[PyEnum] | type[PyStrEnum] | list[typing.Any] | set[typing.Any],
|
|
562
|
+
*args,
|
|
563
|
+
**kwargs,
|
|
564
|
+
):
|
|
555
565
|
super().__init__(*args, **kwargs)
|
|
556
566
|
if isinstance(values, set):
|
|
557
567
|
self.values = values
|
|
558
568
|
elif isinstance(values, (list, tuple)):
|
|
559
569
|
self.values = set(values)
|
|
560
|
-
elif isinstance(values, (PyEnum, EnumMeta)):
|
|
570
|
+
elif isinstance(values, (PyEnum, PyStrEnum, EnumMeta)):
|
|
561
571
|
self.values = set([e.value for e in values]) # type: ignore
|
|
562
572
|
else:
|
|
563
573
|
raise HowlerTypeError(f"Type unsupported for Enum odm: {type(values)}")
|
|
@@ -1063,7 +1073,7 @@ class Optional(_Field):
|
|
|
1063
1073
|
|
|
1064
1074
|
class Model:
|
|
1065
1075
|
@classmethod
|
|
1066
|
-
def fields(cls, skip_mappings=False) -> dict[str, _Field]:
|
|
1076
|
+
def fields(cls, skip_mappings=False, no_cache=False) -> dict[str, _Field]:
|
|
1067
1077
|
"""Describe the elements of the model.
|
|
1068
1078
|
|
|
1069
1079
|
For compound fields return the field object.
|
|
@@ -1071,33 +1081,42 @@ class Model:
|
|
|
1071
1081
|
Args:
|
|
1072
1082
|
skip_mappings (bool): Skip over mappings where the real subfield names are unknown.
|
|
1073
1083
|
"""
|
|
1074
|
-
if skip_mappings and
|
|
1084
|
+
if not no_cache and skip_mappings and "_odm_field_cache_skip" in cls.__dict__:
|
|
1075
1085
|
return cls._odm_field_cache_skip
|
|
1076
1086
|
|
|
1077
|
-
if not skip_mappings and
|
|
1087
|
+
if not no_cache and not skip_mappings and "_odm_field_cache" in cls.__dict__:
|
|
1078
1088
|
return cls._odm_field_cache
|
|
1079
1089
|
|
|
1080
1090
|
out = dict()
|
|
1091
|
+
# Iterate through inherited classes. If any of them are odm.Model (e.g., they expose fields())
|
|
1092
|
+
# then include their fields as well. This allows for class inheritance.
|
|
1093
|
+
for base in cls.__bases__:
|
|
1094
|
+
_fields: Callable[..., dict[str, _Field]] | None = getattr(base, "fields", None)
|
|
1095
|
+
if _fields and callable(_fields):
|
|
1096
|
+
out.update(_fields(skip_mappings=skip_mappings, no_cache=True))
|
|
1097
|
+
|
|
1081
1098
|
for name, field_data in cls.__dict__.items():
|
|
1082
1099
|
if isinstance(field_data, _Field):
|
|
1083
1100
|
if skip_mappings and isinstance(field_data, Mapping):
|
|
1084
1101
|
continue
|
|
1085
1102
|
out[name.rstrip("_")] = field_data
|
|
1086
1103
|
|
|
1087
|
-
if
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1104
|
+
if not no_cache:
|
|
1105
|
+
if skip_mappings:
|
|
1106
|
+
cls._odm_field_cache_skip = out
|
|
1107
|
+
else:
|
|
1108
|
+
cls._odm_field_cache = out
|
|
1109
|
+
|
|
1091
1110
|
return out
|
|
1092
1111
|
|
|
1093
1112
|
@classmethod
|
|
1094
1113
|
def add_namespace(cls, namespace: str, field: _Field, index=None, store=None, description=None):
|
|
1095
1114
|
recursive_set_name(field, namespace)
|
|
1096
1115
|
|
|
1097
|
-
if
|
|
1116
|
+
if "_odm_field_cache_skip" in cls.__dict__:
|
|
1098
1117
|
cls._odm_field_cache_skip[namespace.rstrip("_")] = field
|
|
1099
1118
|
|
|
1100
|
-
if
|
|
1119
|
+
if "_odm_field_cache" in cls.__dict__:
|
|
1101
1120
|
cls._odm_field_cache[namespace.rstrip("_")] = field
|
|
1102
1121
|
|
|
1103
1122
|
setattr(cls, namespace, field)
|
|
@@ -1112,10 +1131,10 @@ class Model:
|
|
|
1112
1131
|
|
|
1113
1132
|
@classmethod
|
|
1114
1133
|
def remove_namespace(cls, namespace: str):
|
|
1115
|
-
if
|
|
1134
|
+
if "_odm_field_cache_skip" in cls.__dict__:
|
|
1116
1135
|
del cls._odm_field_cache_skip[namespace.rstrip("_")]
|
|
1117
1136
|
|
|
1118
|
-
if
|
|
1137
|
+
if "_odm_field_cache" in cls.__dict__:
|
|
1119
1138
|
del cls._odm_field_cache[namespace.rstrip("_")]
|
|
1120
1139
|
|
|
1121
1140
|
delattr(cls, namespace)
|
|
@@ -1147,8 +1166,11 @@ class Model:
|
|
|
1147
1166
|
else:
|
|
1148
1167
|
out[name] = sub_field
|
|
1149
1168
|
|
|
1150
|
-
if
|
|
1151
|
-
|
|
1169
|
+
if show_compound:
|
|
1170
|
+
if isinstance(field, Compound):
|
|
1171
|
+
out[name] = field
|
|
1172
|
+
elif isinstance(field, List) and isinstance(field.child_type, Compound):
|
|
1173
|
+
out[name] = field.child_type
|
|
1152
1174
|
|
|
1153
1175
|
return out
|
|
1154
1176
|
|
|
@@ -1163,6 +1185,11 @@ class Model:
|
|
|
1163
1185
|
skip_mappings (bool): Skip over mappings where the real subfield names are unknown.
|
|
1164
1186
|
"""
|
|
1165
1187
|
out = dict()
|
|
1188
|
+
for base in cls.__bases__:
|
|
1189
|
+
_flat_fields: Callable[..., dict[str, _Field]] | None = getattr(base, "flat_fields", None)
|
|
1190
|
+
if _flat_fields and callable(_flat_fields):
|
|
1191
|
+
out.update(_flat_fields(show_compound=show_compound, skip_mappings=skip_mappings))
|
|
1192
|
+
|
|
1166
1193
|
for name, field in cls.__dict__.items():
|
|
1167
1194
|
if isinstance(field, _Field):
|
|
1168
1195
|
if skip_mappings and isinstance(field, Mapping):
|
|
@@ -1185,7 +1212,7 @@ class Model:
|
|
|
1185
1212
|
include_autogen_note=True,
|
|
1186
1213
|
defaults=None,
|
|
1187
1214
|
url_prefix="/howler/odm/class/",
|
|
1188
|
-
) ->
|
|
1215
|
+
) -> str:
|
|
1189
1216
|
markdown_content = (
|
|
1190
1217
|
(
|
|
1191
1218
|
'??? success "Auto-Generated Documentation"\n '
|
|
@@ -1476,12 +1503,44 @@ def recursive_set_name(field, name, to_parent=False):
|
|
|
1476
1503
|
recursive_set_name(field.child_type, name, to_parent=True)
|
|
1477
1504
|
|
|
1478
1505
|
|
|
1479
|
-
def model(index=None, store=None, description=None):
|
|
1480
|
-
"""Decorator
|
|
1506
|
+
def model(index=None, store=None, description=None, id_field=None):
|
|
1507
|
+
"""Decorator that finalizes a Model subclass for use with the datastore.
|
|
1508
|
+
Assigns metadata to the class (description, id field), validates that all
|
|
1509
|
+
declared field names are legal, recursively sets each field's name, and
|
|
1510
|
+
applies default index/store settings to every field.
|
|
1511
|
+
If ``id_field`` is not provided, it defaults to ``<classname_lower>_id``.
|
|
1512
|
+
Args:
|
|
1513
|
+
index: Default index setting applied to all fields on the model.
|
|
1514
|
+
store: Default store setting applied to all fields on the model.
|
|
1515
|
+
description: Human-readable description of the model.
|
|
1516
|
+
id_field: Name of the field used as the primary key. Defaults to
|
|
1517
|
+
``<classname_lower>_id`` when not specified.
|
|
1518
|
+
Returns:
|
|
1519
|
+
A class decorator that configures and returns the decorated Model subclass.
|
|
1520
|
+
Raises:
|
|
1521
|
+
HowlerValueError: If any field name fails the ``FIELD_SANITIZER`` regex
|
|
1522
|
+
or appears in ``BANNED_FIELDS``.
|
|
1523
|
+
"""
|
|
1481
1524
|
|
|
1482
1525
|
def _finish_model(cls):
|
|
1483
1526
|
cls._Model__description = description
|
|
1484
|
-
|
|
1527
|
+
fields = cls.fields()
|
|
1528
|
+
|
|
1529
|
+
if id_field is None:
|
|
1530
|
+
cls._Model__id_field = f"{cls.__name__.lower()}_id"
|
|
1531
|
+
else:
|
|
1532
|
+
if not isinstance(id_field, str):
|
|
1533
|
+
raise HowlerTypeError(f"id_field must be a str, got {type(id_field).__name__}")
|
|
1534
|
+
|
|
1535
|
+
if not FIELD_SANITIZER.match(id_field) or id_field in BANNED_FIELDS:
|
|
1536
|
+
raise HowlerValueError(f"Illegal id_field name: {id_field}")
|
|
1537
|
+
|
|
1538
|
+
if id_field not in fields:
|
|
1539
|
+
raise HowlerValueError(f"id_field must reference a declared field: {id_field}")
|
|
1540
|
+
|
|
1541
|
+
cls._Model__id_field = id_field
|
|
1542
|
+
|
|
1543
|
+
for name, field_data in fields.items():
|
|
1485
1544
|
if not FIELD_SANITIZER.match(name) or name in BANNED_FIELDS:
|
|
1486
1545
|
raise HowlerValueError(f"Illegal variable name: {name}")
|
|
1487
1546
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Compatibility shims for symbols added in Python 3.11.
|
|
2
|
+
|
|
3
|
+
Import from this module instead of using `if sys.version_info` guards inline.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
if sys.version_info >= (3, 11):
|
|
9
|
+
from enum import StrEnum
|
|
10
|
+
from typing import NotRequired, TypedDict
|
|
11
|
+
else:
|
|
12
|
+
from enum import Enum as _Enum
|
|
13
|
+
|
|
14
|
+
class StrEnum(str, _Enum): # type: ignore[no-redef]
|
|
15
|
+
"""str + Enum backport for Python < 3.11."""
|
|
16
|
+
|
|
17
|
+
def __str__(self) -> str:
|
|
18
|
+
return str.__str__(self)
|
|
19
|
+
|
|
20
|
+
def __format__(self, format_spec: str) -> str:
|
|
21
|
+
return str.__format__(self, format_spec)
|
|
22
|
+
|
|
23
|
+
# typing_extensions.TypedDict supports Generic[T] mixing on Python < 3.11;
|
|
24
|
+
# the stdlib version does not gain that until 3.11.
|
|
25
|
+
from typing_extensions import NotRequired, TypedDict # noqa: F401
|
|
26
|
+
|
|
27
|
+
__all__ = ["NotRequired", "StrEnum", "TypedDict"]
|
|
@@ -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.dev845"
|
|
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.dev834 → howler_api-3.4.0.dev845}/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
|
|
File without changes
|
{howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/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.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-3.4.0.dev834 → howler_api-3.4.0.dev845}/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
|