howler-api 3.2.0.dev561__tar.gz → 3.2.0.dev576__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.2.0.dev561 → howler_api-3.2.0.dev576}/PKG-INFO +1 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/types.py +7 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/config.py +6 -0
- howler_api-3.2.0.dev576/howler/remote/datatypes/__init__.py +157 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/events.py +8 -8
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/hash.py +5 -3
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/lock.py +3 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/multi.py +2 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/named.py +2 -2
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/priority.py +2 -2
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/set.py +2 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/user_quota_tracker.py +3 -1
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/pyproject.toml +2 -2
- howler_api-3.2.0.dev561/howler/remote/datatypes/__init__.py +0 -98
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/README.md +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/add_label.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/change_field.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/demote.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/example_plugin.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/prioritization.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/promote.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/remove_label.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/actions/transition.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/base.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/socket.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/action.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/analytic.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/auth.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/clue.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/configs.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/dossier.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/help.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/hit.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/notebook.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/overview.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/search.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/template.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/tool.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/user.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/api/v1/view.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/app.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/README.md +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/classification.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/classification.yml +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/exceptions.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/loader.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/logging/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/logging/audit.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/logging/format.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/net.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/net_static.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/random_user.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/common/swagger.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/config.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/cronjobs/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/cronjobs/retention.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/cronjobs/rules.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/README.md +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/bulk.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/collection.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/constants.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/exceptions.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/howler_store.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/operations.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/schemas.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/store.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/support/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/support/build.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/datastore/support/schemas.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/error.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/generate_mitre.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/generate_tlds.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/reindex_data.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/external/wipe_databases.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/gunicorn_config.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/healthz.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/azure.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/discover.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/hit.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/oauth.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/search.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/workflow.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/helper/ws.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/README.md +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/base.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/charter.txt +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/helper.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/howler_enum.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/action.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/analytic.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/aws.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/azure.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/cbs.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/clue.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/dossier.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/gcp.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/hit.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/howler_data.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/lead.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/localized_label.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/overview.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/pivot.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/template.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/user.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/models/view.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/random_data.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/odm/randomizer.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/patched.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/plugins/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/plugins/config.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/README.md +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/security/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/security/socket.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/security/utils.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/action_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/analytic_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/auth_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/config_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/dossier_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/event_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/hit_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/jwt_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/lucene_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/notebook_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/overview_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/template_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/services/user_service.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/__init__.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/annotations.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/chunk.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/dict_utils.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/isotime.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/list_utils.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/lucene.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/path.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/socket_utils.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/str_utils.py +0 -0
- {howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/utils/uid.py +0 -0
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Generic, TypedDict, TypeVar
|
|
3
|
+
|
|
4
|
+
if sys.version_info >= (3, 11):
|
|
5
|
+
from typing import NotRequired
|
|
6
|
+
else:
|
|
7
|
+
from typing_extensions import NotRequired
|
|
2
8
|
|
|
3
9
|
SearchResultType = TypeVar("SearchResultType")
|
|
4
10
|
|
|
@@ -28,6 +28,12 @@ class RedisServer(BaseModel):
|
|
|
28
28
|
|
|
29
29
|
host: str = Field(description="Hostname of Redis instance")
|
|
30
30
|
port: int = Field(description="Port of Redis instance")
|
|
31
|
+
password: Optional[str] = Field(description="Password for Redis instance", default=None)
|
|
32
|
+
tls_enabled: bool = Field(default=False, description="Enable TLS for Redis connection")
|
|
33
|
+
tls_ca_cert: Optional[str] = Field(
|
|
34
|
+
description="Path to CA Certificate (PEM) to validate Redis instance certificate when using TLS", default=None
|
|
35
|
+
)
|
|
36
|
+
is_cluster: bool = Field(default=False, description="Is this Redis instance a cluster?")
|
|
31
37
|
|
|
32
38
|
|
|
33
39
|
class Redis(BaseModel):
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import time
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import redis
|
|
10
|
+
from packaging.version import parse
|
|
11
|
+
|
|
12
|
+
from howler.common import loader
|
|
13
|
+
from howler.odm.models.config import config
|
|
14
|
+
from howler.utils.uid import get_random_id
|
|
15
|
+
|
|
16
|
+
# Add a version warning if redis python client is < 2.10.0. Older versions
|
|
17
|
+
# have a connection bug that can manifest with the dispatcher.
|
|
18
|
+
if parse(redis.__version__) <= parse("2.10.0"):
|
|
19
|
+
import warnings
|
|
20
|
+
|
|
21
|
+
warnings.warn(
|
|
22
|
+
"%s works best with redis > 2.10.0. You're running"
|
|
23
|
+
" redis %s. You should upgrade." % (__name__, redis.__version__)
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
log = logging.getLogger(f"{loader.APP_NAME}.queue")
|
|
28
|
+
pool: dict[tuple[str, str, bool], redis.BlockingConnectionPool] = {}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def now_as_iso():
|
|
32
|
+
s = datetime.utcfromtimestamp(time.time()).isoformat()
|
|
33
|
+
return f"{s}Z"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def reply_queue_name(prefix=None, suffix=None):
|
|
37
|
+
if prefix:
|
|
38
|
+
components = [prefix]
|
|
39
|
+
else:
|
|
40
|
+
components = []
|
|
41
|
+
|
|
42
|
+
components.append(get_random_id())
|
|
43
|
+
|
|
44
|
+
if suffix:
|
|
45
|
+
components.append(str(suffix))
|
|
46
|
+
|
|
47
|
+
return "-".join(components)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def retry_call(func, *args, **kw):
|
|
51
|
+
maximum = 2
|
|
52
|
+
exponent = -7
|
|
53
|
+
|
|
54
|
+
while True:
|
|
55
|
+
try:
|
|
56
|
+
ret_val = func(*args, **kw)
|
|
57
|
+
|
|
58
|
+
if exponent != -7:
|
|
59
|
+
log.info("Reconnected to Redis!")
|
|
60
|
+
|
|
61
|
+
return ret_val
|
|
62
|
+
except (redis.ConnectionError, ConnectionResetError) as ce:
|
|
63
|
+
log.warning(f"No connection to Redis, reconnecting... [{ce}]")
|
|
64
|
+
time.sleep(2**exponent)
|
|
65
|
+
exponent = exponent + 1 if exponent < maximum else exponent
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_client(
|
|
69
|
+
host: str | redis.Redis | redis.StrictRedis | redis.RedisCluster | None, port: int | None, private: bool = False
|
|
70
|
+
):
|
|
71
|
+
"""
|
|
72
|
+
Get Redis instance.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
host: Redis host, defaults to nonpersistent host
|
|
76
|
+
port: Redis port, defaults to nonpersistent port
|
|
77
|
+
private: If true then use standard connection, otherwise use a Pool
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Redis instance
|
|
81
|
+
"""
|
|
82
|
+
# In case a structure is passed a client as host
|
|
83
|
+
if isinstance(host, (redis.Redis, redis.StrictRedis, redis.RedisCluster)):
|
|
84
|
+
return host
|
|
85
|
+
|
|
86
|
+
if not host or not port:
|
|
87
|
+
host = host or config.core.redis.nonpersistent.host
|
|
88
|
+
port = int(port or config.core.redis.nonpersistent.port)
|
|
89
|
+
|
|
90
|
+
extra_conn_config: dict[str, str | bool | int] = {}
|
|
91
|
+
host_config = None
|
|
92
|
+
|
|
93
|
+
if host == config.core.redis.nonpersistent.host and port == config.core.redis.nonpersistent.port:
|
|
94
|
+
host_config = config.core.redis.nonpersistent
|
|
95
|
+
else:
|
|
96
|
+
host_config = config.core.redis.persistent
|
|
97
|
+
|
|
98
|
+
if host_config.password:
|
|
99
|
+
extra_conn_config["username"] = "default"
|
|
100
|
+
extra_conn_config["password"] = host_config.password
|
|
101
|
+
|
|
102
|
+
if host_config.tls_enabled:
|
|
103
|
+
extra_conn_config["ssl"] = True
|
|
104
|
+
extra_conn_config["ssl_cert_reqs"] = "required"
|
|
105
|
+
|
|
106
|
+
if host_config.tls_ca_cert:
|
|
107
|
+
if not Path(host_config.tls_ca_cert).exists():
|
|
108
|
+
raise FileNotFoundError(f"Redis TLS CA cert or path '{host_config.tls_ca_cert}' not found.")
|
|
109
|
+
|
|
110
|
+
if Path(host_config.tls_ca_cert).is_file():
|
|
111
|
+
extra_conn_config["ssl_ca_certs"] = host_config.tls_ca_cert
|
|
112
|
+
else:
|
|
113
|
+
extra_conn_config["ssl_ca_path"] = host_config.tls_ca_cert
|
|
114
|
+
|
|
115
|
+
if host_config.is_cluster is True:
|
|
116
|
+
return redis.RedisCluster(host=host, port=port, **extra_conn_config) # type: ignore
|
|
117
|
+
|
|
118
|
+
if private:
|
|
119
|
+
return redis.StrictRedis(host=host, port=port, **extra_conn_config) # type: ignore
|
|
120
|
+
else:
|
|
121
|
+
return redis.StrictRedis(connection_pool=get_pool(host, port, **extra_conn_config))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_pool(host, port, **kwargs):
|
|
125
|
+
"""
|
|
126
|
+
Get Redis connection pool
|
|
127
|
+
Args:
|
|
128
|
+
host: Redis host
|
|
129
|
+
port: Redis port
|
|
130
|
+
**kwargs: Extra parameters to pass to pool connection class
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Redis BlockingConnectionPool
|
|
134
|
+
"""
|
|
135
|
+
key = (host, str(port), kwargs.get("ssl", False))
|
|
136
|
+
connection_pool = pool.get(key, None)
|
|
137
|
+
|
|
138
|
+
if not connection_pool:
|
|
139
|
+
if "ssl" in kwargs and kwargs["ssl"]:
|
|
140
|
+
# SSLConnection class doesn't accept 'ssl' parameter as it implicitly uses SSL
|
|
141
|
+
kwargs.pop("ssl")
|
|
142
|
+
connection_pool = redis.BlockingConnectionPool(
|
|
143
|
+
host=host, port=port, max_connections=200, connection_class=redis.SSLConnection, **kwargs
|
|
144
|
+
)
|
|
145
|
+
else:
|
|
146
|
+
connection_pool = redis.BlockingConnectionPool(host=host, port=port, max_connections=200, **kwargs)
|
|
147
|
+
pool[key] = connection_pool
|
|
148
|
+
|
|
149
|
+
return connection_pool
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def decode(data):
|
|
153
|
+
try:
|
|
154
|
+
return json.loads(data)
|
|
155
|
+
except ValueError:
|
|
156
|
+
log.warning("Invalid data on queue: %s", str(data))
|
|
157
|
+
return None
|
|
@@ -8,7 +8,7 @@ from howler.common.logging import get_logger
|
|
|
8
8
|
from howler.remote.datatypes import get_client, retry_call
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
-
|
|
11
|
+
pass
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
logger = get_logger(__name__)
|
|
@@ -21,12 +21,12 @@ class EventSender(Generic[MessageType]):
|
|
|
21
21
|
def __init__(
|
|
22
22
|
self,
|
|
23
23
|
prefix: str,
|
|
24
|
-
host=None,
|
|
25
|
-
port=None,
|
|
26
|
-
private=None,
|
|
24
|
+
host: str | None = None,
|
|
25
|
+
port: int | None = None,
|
|
26
|
+
private: bool | None = None,
|
|
27
27
|
serializer: Callable[[MessageType], str] = json.dumps,
|
|
28
28
|
):
|
|
29
|
-
self.client
|
|
29
|
+
self.client = get_client(host, port, bool(private))
|
|
30
30
|
self.prefix = prefix.lower()
|
|
31
31
|
if not self.prefix.endswith("."):
|
|
32
32
|
self.prefix += "."
|
|
@@ -40,12 +40,12 @@ class EventSender(Generic[MessageType]):
|
|
|
40
40
|
class EventWatcher(Generic[MessageType]):
|
|
41
41
|
def __init__(
|
|
42
42
|
self,
|
|
43
|
-
host=None,
|
|
44
|
-
port=None,
|
|
43
|
+
host: str | None = None,
|
|
44
|
+
port: int | None = None,
|
|
45
45
|
private=None,
|
|
46
46
|
deserializer: Callable[[str], MessageType] = json.loads,
|
|
47
47
|
):
|
|
48
|
-
client
|
|
48
|
+
client = get_client(host, port, bool(private))
|
|
49
49
|
self.pubsub = retry_call(client.pubsub)
|
|
50
50
|
self.worker: Optional[threading.Thread] = None
|
|
51
51
|
self.deserializer = deserializer
|
|
@@ -2,7 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import time
|
|
5
|
-
from typing import TYPE_CHECKING, Generic, Optional, TypeVar
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar
|
|
6
|
+
|
|
7
|
+
from redis import RedisCluster
|
|
6
8
|
|
|
7
9
|
from howler.common.exceptions import HowlerValueError
|
|
8
10
|
from howler.remote.datatypes import get_client, retry_call
|
|
@@ -71,10 +73,10 @@ class Hash(Generic[T]):
|
|
|
71
73
|
def __init__(
|
|
72
74
|
self,
|
|
73
75
|
name: str,
|
|
74
|
-
host:
|
|
76
|
+
host: str | Redis[Any] | RedisCluster[Any] | None = None,
|
|
75
77
|
port: Optional[int] = None,
|
|
76
78
|
):
|
|
77
|
-
self.c = get_client(host, port, False)
|
|
79
|
+
self.c: Any = get_client(host, port, False)
|
|
78
80
|
self.name = name
|
|
79
81
|
self._pop = self.c.register_script(h_pop_script)
|
|
80
82
|
self._limited_add = self.c.register_script(_limited_add)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from howler.remote.datatypes import get_client, retry_call
|
|
2
4
|
from howler.utils.uid import get_random_id
|
|
3
5
|
|
|
@@ -27,7 +29,7 @@ end
|
|
|
27
29
|
class Lock(object):
|
|
28
30
|
def __init__(self, name, timeout, host=None, port=None):
|
|
29
31
|
self.uuid = get_random_id()
|
|
30
|
-
self.c = get_client(host, port, False)
|
|
32
|
+
self.c: Any = get_client(host, port, False)
|
|
31
33
|
self.lock_release = "-".join(("lock", str(timeout), name, "released"))
|
|
32
34
|
self.lock_holder = "-".join(("lock", str(timeout), name, "holder"))
|
|
33
35
|
self.timeout = timeout
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
from howler.remote.datatypes import get_client, retry_call
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class MultiQueue(object):
|
|
7
8
|
def __init__(self, host=None, port=None, private=False):
|
|
8
|
-
self.c = get_client(host, port, private)
|
|
9
|
+
self.c: Any = get_client(host, port, private)
|
|
9
10
|
|
|
10
11
|
def delete(self, name):
|
|
11
12
|
retry_call(self.c.delete, name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import time
|
|
3
|
-
from typing import Generic, Optional, TypeVar
|
|
3
|
+
from typing import Any, Generic, Optional, TypeVar
|
|
4
4
|
|
|
5
5
|
from howler.common.exceptions import HowlerTypeError
|
|
6
6
|
from howler.remote.datatypes import get_client, retry_call
|
|
@@ -10,7 +10,7 @@ T = TypeVar("T")
|
|
|
10
10
|
|
|
11
11
|
class NamedQueue(Generic[T]):
|
|
12
12
|
def __init__(self, name: str, host=None, port=None, private: bool = False, ttl: int = 0):
|
|
13
|
-
self.c = get_client(host, port, private)
|
|
13
|
+
self.c: Any = get_client(host, port, private)
|
|
14
14
|
self.name: str = name
|
|
15
15
|
self.ttl: int = ttl
|
|
16
16
|
self.last_expire_time: float = 0
|
{howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/queues/priority.py
RENAMED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import time
|
|
5
|
-
from typing import Generic, Optional, TypeVar, Union
|
|
5
|
+
from typing import Any, Generic, Optional, TypeVar, Union
|
|
6
6
|
|
|
7
7
|
from howler.common.exceptions import HowlerTypeError
|
|
8
8
|
from howler.remote.datatypes import decode, get_client, retry_call
|
|
@@ -36,7 +36,7 @@ T = TypeVar("T")
|
|
|
36
36
|
|
|
37
37
|
class PriorityQueue(Generic[T]):
|
|
38
38
|
def __init__(self, name, host=None, port=None, private=False):
|
|
39
|
-
self.c = get_client(host, port, private)
|
|
39
|
+
self.c: Any = get_client(host, port, private)
|
|
40
40
|
self._deque_range = self.c.register_script(pq_dequeue_range_script)
|
|
41
41
|
self.name = name
|
|
42
42
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import time
|
|
3
|
+
from typing import Any
|
|
3
4
|
|
|
4
5
|
from howler.remote.datatypes import get_client, retry_call
|
|
5
6
|
|
|
@@ -26,7 +27,7 @@ return false
|
|
|
26
27
|
|
|
27
28
|
class Set(object):
|
|
28
29
|
def __init__(self, name, host=None, port=None):
|
|
29
|
-
self.c = get_client(host, port, False)
|
|
30
|
+
self.c: Any = get_client(host, port, False)
|
|
30
31
|
self.name = name
|
|
31
32
|
self._drop_card = self.c.register_script(_drop_card_script)
|
|
32
33
|
self._limited_add = self.c.register_script(_limited_add)
|
{howler_api-3.2.0.dev561 → howler_api-3.2.0.dev576}/howler/remote/datatypes/user_quota_tracker.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
import redis
|
|
2
4
|
|
|
3
5
|
from howler.remote.datatypes import get_client, retry_call
|
|
@@ -22,7 +24,7 @@ end
|
|
|
22
24
|
|
|
23
25
|
class UserQuotaTracker(object):
|
|
24
26
|
def __init__(self, prefix, timeout=120, redis=None, host=None, port=None, private=False):
|
|
25
|
-
self.c = redis or get_client(host, port, private)
|
|
27
|
+
self.c: Any = redis or get_client(host, port, private)
|
|
26
28
|
self.bs = self.c.register_script(begin_script)
|
|
27
29
|
self.prefix = prefix
|
|
28
30
|
self.timeout = timeout
|
|
@@ -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.2.0.
|
|
155
|
+
version = "3.2.0.dev576"
|
|
156
156
|
description = "Howler - API server"
|
|
157
157
|
authors = [
|
|
158
158
|
"Canadian Centre for Cyber Security <howler@cyber.gc.ca>",
|
|
@@ -240,7 +240,7 @@ mypy = "^1.6.1"
|
|
|
240
240
|
pytest = "^8.1.1"
|
|
241
241
|
retrying = "^1.3.4"
|
|
242
242
|
pyftpdlib = "^1.5.9"
|
|
243
|
-
pyopenssl = "
|
|
243
|
+
pyopenssl = ">=24.1,<27.0"
|
|
244
244
|
diff-cover = "^9.2.4"
|
|
245
245
|
pytest-cov = "^4.1.0"
|
|
246
246
|
mock = "^5.1.0"
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
import logging
|
|
5
|
-
import time
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
|
|
8
|
-
import redis
|
|
9
|
-
from packaging.version import parse
|
|
10
|
-
|
|
11
|
-
from howler.common import loader
|
|
12
|
-
from howler.odm.models.config import config
|
|
13
|
-
from howler.utils.uid import get_random_id
|
|
14
|
-
|
|
15
|
-
# Add a version warning if redis python client is < 2.10.0. Older versions
|
|
16
|
-
# have a connection bug that can manifest with the dispatcher.
|
|
17
|
-
if parse(redis.__version__) <= parse("2.10.0"):
|
|
18
|
-
import warnings
|
|
19
|
-
|
|
20
|
-
warnings.warn(
|
|
21
|
-
"%s works best with redis > 2.10.0. You're running"
|
|
22
|
-
" redis %s. You should upgrade." % (__name__, redis.__version__)
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
log = logging.getLogger(f"{loader.APP_NAME}.queue")
|
|
27
|
-
pool: dict[tuple[str, str], redis.BlockingConnectionPool] = {}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def now_as_iso():
|
|
31
|
-
s = datetime.utcfromtimestamp(time.time()).isoformat()
|
|
32
|
-
return f"{s}Z"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def reply_queue_name(prefix=None, suffix=None):
|
|
36
|
-
if prefix:
|
|
37
|
-
components = [prefix]
|
|
38
|
-
else:
|
|
39
|
-
components = []
|
|
40
|
-
|
|
41
|
-
components.append(get_random_id())
|
|
42
|
-
|
|
43
|
-
if suffix:
|
|
44
|
-
components.append(str(suffix))
|
|
45
|
-
|
|
46
|
-
return "-".join(components)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def retry_call(func, *args, **kw):
|
|
50
|
-
maximum = 2
|
|
51
|
-
exponent = -7
|
|
52
|
-
|
|
53
|
-
while True:
|
|
54
|
-
try:
|
|
55
|
-
ret_val = func(*args, **kw)
|
|
56
|
-
|
|
57
|
-
if exponent != -7:
|
|
58
|
-
log.info("Reconnected to Redis!")
|
|
59
|
-
|
|
60
|
-
return ret_val
|
|
61
|
-
except (redis.ConnectionError, ConnectionResetError) as ce:
|
|
62
|
-
log.warning(f"No connection to Redis, reconnecting... [{ce}]")
|
|
63
|
-
time.sleep(2**exponent)
|
|
64
|
-
exponent = exponent + 1 if exponent < maximum else exponent
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def get_client(host, port, private):
|
|
68
|
-
# In case a structure is passed a client as host
|
|
69
|
-
if isinstance(host, (redis.Redis, redis.StrictRedis)):
|
|
70
|
-
return host
|
|
71
|
-
|
|
72
|
-
if not host or not port:
|
|
73
|
-
host = host or config.core.redis.nonpersistent.host
|
|
74
|
-
port = int(port or config.core.redis.nonpersistent.port)
|
|
75
|
-
|
|
76
|
-
if private:
|
|
77
|
-
return redis.StrictRedis(host=host, port=port)
|
|
78
|
-
else:
|
|
79
|
-
return redis.StrictRedis(connection_pool=get_pool(host, port))
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def get_pool(host, port):
|
|
83
|
-
key = (host, port)
|
|
84
|
-
|
|
85
|
-
connection_pool = pool.get(key, None)
|
|
86
|
-
if not connection_pool:
|
|
87
|
-
connection_pool = redis.BlockingConnectionPool(host=host, port=port, max_connections=200)
|
|
88
|
-
pool[key] = connection_pool
|
|
89
|
-
|
|
90
|
-
return connection_pool
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def decode(data):
|
|
94
|
-
try:
|
|
95
|
-
return json.loads(data)
|
|
96
|
-
except ValueError:
|
|
97
|
-
log.warning("Invalid data on queue: %s", str(data))
|
|
98
|
-
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.2.0.dev561 → howler_api-3.2.0.dev576}/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
|