howler-api 4.0.0.dev669__tar.gz → 4.0.0.dev679__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-4.0.0.dev669 → howler_api-4.0.0.dev679}/PKG-INFO +1 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/view.py +1 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/collection.py +33 -22
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/store.py +0 -4
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/base.py +22 -2
- howler_api-4.0.0.dev679/howler/odm/mixins.py +97 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/case.py +2 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/hit.py +3 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/observable.py +3 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/__init__.py +2 -2
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/pyproject.toml +1 -1
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/README.md +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/add_label.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/change_field.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/demote.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/example_plugin.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/prioritization.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/promote.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/remove_label.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/actions/transition.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/base.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/socket.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/action.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/analytic.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/auth.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/clue.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/configs.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/dossier.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/help.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/hit.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/notebook.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/overview.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/search.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/template.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/tool.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/user.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v2/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v2/case.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v2/ingest.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/api/v2/search.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/app.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/README.md +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/classification.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/classification.yml +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/exceptions.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/loader.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/logging/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/logging/audit.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/logging/format.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/net.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/net_static.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/random_user.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/common/swagger.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/config.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/cronjobs/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/cronjobs/retention.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/README.md +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/bulk.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/constants.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/exceptions.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/howler_store.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/operations.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/schemas.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/support/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/support/build.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/support/schemas.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/datastore/types.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/error.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/generate_mitre.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/generate_tlds.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/reindex_data.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/external/wipe_databases.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/gunicorn_config.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/healthz.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/azure.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/discover.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/hit.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/oauth.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/search.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/workflow.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/helper/ws.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/README.md +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/charter.txt +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/constants.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/helper.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/howler_enum.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/action.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/analytic.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/aws.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/azure.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/cbs.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/clue.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/config.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/dossier.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/gcp.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/howler_data.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/lead.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/localized_label.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/overview.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/pivot.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/record.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/template.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/user.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/models/view.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/random_data.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/odm/randomizer.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/patched.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/plugins/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/plugins/config.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/README.md +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/events.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/set.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/security/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/security/socket.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/security/utils.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/action_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/analytic_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/auth_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/case_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/config_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/docs_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/dossier_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/event_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/hit_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/jwt_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/lucene_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/notebook_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/observable_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/overview_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/search_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/template_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/services/user_service.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/annotations.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/chunk.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/compat.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/dict_utils.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/isotime.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/list_utils.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/lucene.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/path.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/socket_utils.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/str_utils.py +0 -0
- {howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/utils/uid.py +0 -0
|
@@ -261,7 +261,7 @@ def remove_as_favourite(view_id: str, **kwargs):
|
|
|
261
261
|
"""Remove a view from a list of the user's favourites
|
|
262
262
|
|
|
263
263
|
Variables:
|
|
264
|
-
|
|
264
|
+
view_id => The id of the view to remove as a favourite
|
|
265
265
|
|
|
266
266
|
Optional Arguments:
|
|
267
267
|
None
|
|
@@ -270,14 +270,17 @@ class ESCollection(Generic[ModelType]):
|
|
|
270
270
|
if index is None:
|
|
271
271
|
index = self.index_name
|
|
272
272
|
|
|
273
|
+
client = self.datastore.client
|
|
274
|
+
if request_timeout is not None:
|
|
275
|
+
client = client.options(request_timeout=request_timeout)
|
|
276
|
+
|
|
273
277
|
# initial search
|
|
274
278
|
resp = self.with_retries(
|
|
275
|
-
|
|
279
|
+
client.search,
|
|
276
280
|
index=index,
|
|
277
281
|
query=query,
|
|
278
282
|
scroll=scroll,
|
|
279
283
|
size=size,
|
|
280
|
-
request_timeout=request_timeout,
|
|
281
284
|
sort=sort,
|
|
282
285
|
_source=source,
|
|
283
286
|
)
|
|
@@ -305,16 +308,18 @@ class ESCollection(Generic[ModelType]):
|
|
|
305
308
|
|
|
306
309
|
finally:
|
|
307
310
|
if scroll_id:
|
|
308
|
-
|
|
309
|
-
self.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
)
|
|
313
|
-
if not resp.get("succeeded", False):
|
|
314
|
-
logger.warning(
|
|
315
|
-
f"Could not clear scroll ID {scroll_id}, there is potential "
|
|
316
|
-
"memory leak in you Elastic cluster..."
|
|
311
|
+
try:
|
|
312
|
+
resp = self.with_retries(
|
|
313
|
+
self.datastore.client.clear_scroll,
|
|
314
|
+
scroll_id=[scroll_id],
|
|
317
315
|
)
|
|
316
|
+
if not resp.get("succeeded", False):
|
|
317
|
+
logger.warning(
|
|
318
|
+
f"Could not clear scroll ID {scroll_id}, there is potential "
|
|
319
|
+
"memory leak in your Elastic cluster..."
|
|
320
|
+
)
|
|
321
|
+
except elasticsearch.exceptions.NotFoundError:
|
|
322
|
+
pass
|
|
318
323
|
|
|
319
324
|
def with_retries(self, func, *args, raise_conflicts=False, **kwargs):
|
|
320
325
|
"""This function performs the passed function with the given args and kwargs and reconnect if it fails
|
|
@@ -470,7 +475,9 @@ class ESCollection(Generic[ModelType]):
|
|
|
470
475
|
raise
|
|
471
476
|
|
|
472
477
|
def _safe_index_copy(self, copy_function, src, target, settings=None, min_status="yellow"):
|
|
473
|
-
|
|
478
|
+
options_client = self.datastore.client.options(request_timeout=60)
|
|
479
|
+
timed_function = getattr(options_client.indices, copy_function.__name__)
|
|
480
|
+
ret = timed_function(index=src, target=target, settings=settings)
|
|
474
481
|
if not ret["acknowledged"]:
|
|
475
482
|
raise DataStoreException(f"Failed to create index {target} from {src}.")
|
|
476
483
|
|
|
@@ -1657,19 +1664,23 @@ class ESCollection(Generic[ModelType]):
|
|
|
1657
1664
|
|
|
1658
1665
|
# Check if the scroll is finished and close it
|
|
1659
1666
|
if deep_paging_id is not None and new_deep_paging_id is None:
|
|
1660
|
-
|
|
1661
|
-
self.
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1667
|
+
try:
|
|
1668
|
+
self.with_retries(
|
|
1669
|
+
self.datastore.client.clear_scroll,
|
|
1670
|
+
scroll_id=[deep_paging_id],
|
|
1671
|
+
)
|
|
1672
|
+
except elasticsearch.exceptions.NotFoundError:
|
|
1673
|
+
pass
|
|
1665
1674
|
|
|
1666
1675
|
# Check if we can tell from inspection that we have finished the scroll
|
|
1667
1676
|
if new_deep_paging_id is not None and len(ret_data["items"]) < ret_data["rows"]:
|
|
1668
|
-
|
|
1669
|
-
self.
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1677
|
+
try:
|
|
1678
|
+
self.with_retries(
|
|
1679
|
+
self.datastore.client.clear_scroll,
|
|
1680
|
+
scroll_id=[new_deep_paging_id],
|
|
1681
|
+
)
|
|
1682
|
+
except elasticsearch.exceptions.NotFoundError:
|
|
1683
|
+
pass
|
|
1673
1684
|
new_deep_paging_id = None
|
|
1674
1685
|
|
|
1675
1686
|
if new_deep_paging_id is not None:
|
|
@@ -9,7 +9,6 @@ from typing import Any, Optional, cast
|
|
|
9
9
|
from urllib.parse import urlparse
|
|
10
10
|
|
|
11
11
|
import elasticsearch
|
|
12
|
-
import elasticsearch.client
|
|
13
12
|
|
|
14
13
|
from howler.common.logging.format import HWL_DATE_FORMAT, HWL_LOG_FORMAT
|
|
15
14
|
from howler.datastore.collection import ESCollection
|
|
@@ -138,7 +137,6 @@ class ESStore(object):
|
|
|
138
137
|
max_retries=0,
|
|
139
138
|
request_timeout=TRANSPORT_TIMEOUT,
|
|
140
139
|
)
|
|
141
|
-
self.eql = elasticsearch.client.EqlClient(self.client)
|
|
142
140
|
self.archive_access = archive_access
|
|
143
141
|
self.url_path = "elastic"
|
|
144
142
|
|
|
@@ -218,14 +216,12 @@ class ESStore(object):
|
|
|
218
216
|
max_retries=0,
|
|
219
217
|
request_timeout=TRANSPORT_TIMEOUT,
|
|
220
218
|
)
|
|
221
|
-
self.eql = elasticsearch.client.EqlClient(self.client)
|
|
222
219
|
|
|
223
220
|
def close(self):
|
|
224
221
|
self._closed = True
|
|
225
222
|
# Flatten the client object so that attempts to access without reconnecting errors hard
|
|
226
223
|
# But 'cast' it so that mypy and other linters don't think that its normal for client to be None
|
|
227
224
|
self.client = cast(elasticsearch.Elasticsearch, None)
|
|
228
|
-
self.eql = cast(elasticsearch.client.EqlClient, None)
|
|
229
225
|
|
|
230
226
|
def get_hosts(self, safe=False):
|
|
231
227
|
if not safe:
|
|
@@ -1503,11 +1503,31 @@ def recursive_set_name(field, name, to_parent=False):
|
|
|
1503
1503
|
recursive_set_name(field.child_type, name, to_parent=True)
|
|
1504
1504
|
|
|
1505
1505
|
|
|
1506
|
-
def model(index=None, store=None, description=None):
|
|
1507
|
-
"""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
|
+
"""
|
|
1508
1524
|
|
|
1509
1525
|
def _finish_model(cls):
|
|
1510
1526
|
cls._Model__description = description
|
|
1527
|
+
cls._Model__id_field = id_field
|
|
1528
|
+
|
|
1529
|
+
if cls._Model__id_field is None:
|
|
1530
|
+
cls._Model__id_field = f"{cls.__name__.lower()}_id"
|
|
1511
1531
|
|
|
1512
1532
|
for name, field_data in cls.fields().items():
|
|
1513
1533
|
if not FIELD_SANITIZER.match(name) or name in BANNED_FIELDS:
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Datastore convenience mixins for Howler ODM Model classes.
|
|
2
|
+
|
|
3
|
+
Provides :class:`DatastoreMixin`, a generic mixin that adds a class-level
|
|
4
|
+
``store`` property (returning a typed :class:`ESCollection`) and instance-level
|
|
5
|
+
``ds`` / ``save`` helpers so that Model subclasses can interact with the
|
|
6
|
+
Elasticsearch datastore without boilerplate.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from operator import attrgetter
|
|
12
|
+
from typing import Generic, TypeVar, overload
|
|
13
|
+
|
|
14
|
+
from howler.common.exceptions import HowlerRuntimeError
|
|
15
|
+
from howler.common.loader import datastore
|
|
16
|
+
from howler.datastore.collection import ESCollection
|
|
17
|
+
from howler.odm.base import Model
|
|
18
|
+
|
|
19
|
+
ModelType = TypeVar("ModelType", bound=Model)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class _ObjectsDescriptor(Generic[ModelType]):
|
|
23
|
+
"""Descriptor that provides class-level-only access to the model's ESCollection.
|
|
24
|
+
|
|
25
|
+
Intended to be accessed exclusively via the class (e.g. ``Case.store``).
|
|
26
|
+
Raises ``AttributeError`` if accessed from an instance to enforce
|
|
27
|
+
cla # noqa: D205
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
@overload
|
|
31
|
+
def __get__(self, obj: None, objtype: type[ModelType]) -> ESCollection[ModelType]: ...
|
|
32
|
+
|
|
33
|
+
@overload
|
|
34
|
+
def __get__(self, obj: ModelType, objtype: type[ModelType]) -> ESCollection[ModelType]: ...
|
|
35
|
+
|
|
36
|
+
def __get__(self, obj: ModelType | None, objtype: type[ModelType] | None = None) -> ESCollection[ModelType]:
|
|
37
|
+
"""Return the ESCollection for the owner class.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
obj: The instance the descriptor was accessed from, or ``None``
|
|
41
|
+
when accessed via the class.
|
|
42
|
+
objtype: The owner class (e.g. ``Case``, ``Hit``).
|
|
43
|
+
Returns:
|
|
44
|
+
ESCollection[ModelType]: The datastore collection for *objtype*.
|
|
45
|
+
Raises:
|
|
46
|
+
AttributeError: If accessed from an instance (*obj* is not ``None``)
|
|
47
|
+
or if *objtype* cannot be determined.
|
|
48
|
+
"""
|
|
49
|
+
if obj is not None:
|
|
50
|
+
raise HowlerRuntimeError(
|
|
51
|
+
f"'{type(obj).__name__}.store' is a class-level property and cannot be accessed from an instance. "
|
|
52
|
+
f"Use '{type(obj).__name__}.store' instead."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if objtype is None:
|
|
56
|
+
raise HowlerRuntimeError("Cannot resolve owner class for 'store' descriptor.")
|
|
57
|
+
|
|
58
|
+
index_name = objtype.__name__.lower()
|
|
59
|
+
return datastore()[index_name]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class DatastoreMixin(Generic[ModelType]):
|
|
63
|
+
"""Mixin that provides convenience datastore access to Model instances.
|
|
64
|
+
|
|
65
|
+
Generic over ``ModelType`` so that the ``store`` class property returns a
|
|
66
|
+
correctly-typed ``ESCollection[ModelType]``. Adds a ``ds`` property for
|
|
67
|
+
retrieving the shared datastore connection, a ``store`` class-only property
|
|
68
|
+
for retrieving the model's ESCollection (raises ``AttributeError`` if accessed
|
|
69
|
+
from an instance), and a ``save`` method that persists the current model
|
|
70
|
+
instance using its class name as the index and its configured ID field as the
|
|
71
|
+
document key.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
store: _ObjectsDescriptor = _ObjectsDescriptor()
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def ds(self):
|
|
78
|
+
"""Return the shared datastore instance.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
The singleton datastore connection used for all persistence operations.
|
|
82
|
+
"""
|
|
83
|
+
return datastore()
|
|
84
|
+
|
|
85
|
+
def save(self) -> bool:
|
|
86
|
+
"""Persist the current model instance to the datastore.
|
|
87
|
+
|
|
88
|
+
Determines the target index from the lowercase class name, extracts the
|
|
89
|
+
model's ID from the configured ID field, and saves the instance.
|
|
90
|
+
Returns:
|
|
91
|
+
bool: True if the save operation succeeded, False otherwise.
|
|
92
|
+
"""
|
|
93
|
+
index_name = self.__class__.__name__.lower()
|
|
94
|
+
id_field = self.__class__._Model__id_field # type: ignore[attr-defined]
|
|
95
|
+
current_id = attrgetter(id_field)(self)
|
|
96
|
+
|
|
97
|
+
return self.ds[index_name].save(current_id, self)
|
|
@@ -3,6 +3,7 @@ from typing import Any, Optional
|
|
|
3
3
|
from howler import odm
|
|
4
4
|
from howler.common.exceptions import HowlerValueError
|
|
5
5
|
from howler.odm.constants import Status
|
|
6
|
+
from howler.odm.mixins import DatastoreMixin
|
|
6
7
|
from howler.utils.compat import StrEnum
|
|
7
8
|
|
|
8
9
|
CASE_ITEM_TYPES = {"observable", "hit", "case", "lead", "reference"}
|
|
@@ -92,7 +93,7 @@ class CaseEnrichment(odm.Model):
|
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
@odm.model(index=True, store=True, description="Case model with path-based items, enrichments, rules, and tasks.")
|
|
95
|
-
class Case(odm.Model):
|
|
96
|
+
class Case(DatastoreMixin["Case"], odm.Model):
|
|
96
97
|
case_id: str = odm.UUID(description="A unique identifier for this case.")
|
|
97
98
|
title: str = odm.Keyword(description="Case title.")
|
|
98
99
|
summary: str = odm.Text(description="Short case summary.")
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from howler import odm
|
|
4
4
|
from howler.common.logging import get_logger
|
|
5
|
+
from howler.odm.mixins import DatastoreMixin
|
|
5
6
|
from howler.odm.models.howler_data import HowlerData
|
|
6
7
|
from howler.odm.models.record import Record
|
|
7
8
|
|
|
@@ -12,8 +13,9 @@ logger = get_logger(__file__)
|
|
|
12
13
|
index=True,
|
|
13
14
|
store=True,
|
|
14
15
|
description="Howler Outline schema which is an extended version of Elastic Common Schema (ECS)",
|
|
16
|
+
id_field="howler.id",
|
|
15
17
|
)
|
|
16
|
-
class Hit(Record):
|
|
18
|
+
class Hit(DatastoreMixin["Hit"], Record):
|
|
17
19
|
# Howler extended fields. Deviates from ECS
|
|
18
20
|
howler: HowlerData = odm.Compound(
|
|
19
21
|
HowlerData,
|
|
@@ -4,6 +4,7 @@ from howler import odm
|
|
|
4
4
|
from howler.common.exceptions import HowlerValueError
|
|
5
5
|
from howler.common.logging import get_logger
|
|
6
6
|
from howler.odm.howler_enum import HowlerEnum
|
|
7
|
+
from howler.odm.mixins import DatastoreMixin
|
|
7
8
|
from howler.odm.models.record import Record
|
|
8
9
|
|
|
9
10
|
logger = get_logger(__file__)
|
|
@@ -110,8 +111,9 @@ class ObservableData(odm.Model):
|
|
|
110
111
|
index=True,
|
|
111
112
|
store=True,
|
|
112
113
|
description="Observable schema which is an extended version of Elastic Common Schema (ECS)",
|
|
114
|
+
id_field="howler.id",
|
|
113
115
|
)
|
|
114
|
-
class Observable(Record):
|
|
116
|
+
class Observable(DatastoreMixin["Observable"], Record):
|
|
115
117
|
# Howler extended fields. Deviates from ECS
|
|
116
118
|
howler: ObservableData = odm.Compound(
|
|
117
119
|
ObservableData,
|
|
@@ -4,7 +4,7 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
6
|
import time
|
|
7
|
-
from datetime import datetime
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
import redis
|
|
@@ -30,7 +30,7 @@ pool: dict[tuple[str, str, bool], redis.BlockingConnectionPool] = {}
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def now_as_iso():
|
|
33
|
-
s = datetime.
|
|
33
|
+
s = datetime.now(timezone.utc).replace(tzinfo=None).isoformat()
|
|
34
34
|
return f"{s}Z"
|
|
35
35
|
|
|
36
36
|
|
|
@@ -152,7 +152,7 @@ suppress-none-returning = true
|
|
|
152
152
|
[tool.poetry]
|
|
153
153
|
package-mode = true
|
|
154
154
|
name = "howler-api"
|
|
155
|
-
version = "4.0.0.
|
|
155
|
+
version = "4.0.0.dev679"
|
|
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
|
{howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/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-4.0.0.dev669 → howler_api-4.0.0.dev679}/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
|
{howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev669 → howler_api-4.0.0.dev679}/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
|
|
File without changes
|
|
File without changes
|