repid 2.1.0__tar.gz → 2.1.2__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.
- {repid-2.1.0 → repid-2.1.2}/.pre-commit-config.yaml +1 -1
- {repid-2.1.0 → repid-2.1.2}/PKG-INFO +1 -1
- {repid-2.1.0 → repid-2.1.2}/docs/index.md +30 -16
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/_decode.py +85 -24
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/_encode.py +220 -43
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/amqptypes.py +4 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/message.py +9 -7
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/performatives.py +13 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/helpers.py +40 -57
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/message_broker.py +23 -6
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/connection.py +114 -21
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/links.py +221 -53
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/session.py +119 -22
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/transport.py +32 -2
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/subscriber.py +6 -9
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/message_broker.py +23 -23
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/__init__.py +5 -0
- repid-2.1.2/repid/connections/pubsub/protocol/client.py +123 -0
- repid-2.1.2/repid/connections/pubsub/protocol/control_batcher.py +225 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/received_message.py +21 -30
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/subscriber.py +42 -86
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/conftest.py +21 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_amqp_transport.py +91 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_connection.py +246 -5
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_encoding_decoding.py +239 -12
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_links.py +354 -15
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_message.py +6 -6
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_message_broker.py +222 -14
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_session.py +200 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_uamqp_types.py +52 -24
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/utils.py +41 -0
- repid-2.1.2/tests/unit/pubsub/protocol/test_client.py +103 -0
- repid-2.1.2/tests/unit/pubsub/protocol/test_control_batcher.py +284 -0
- repid-2.1.2/tests/unit/pubsub/protocol/test_received_message.py +218 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_subscriber.py +142 -133
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_subscriber_execution.py +4 -70
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/test_message_broker.py +103 -186
- {repid-2.1.0 → repid-2.1.2}/uv.lock +326 -268
- repid-2.1.0/tests/unit/pubsub/protocol/test_received_message.py +0 -157
- {repid-2.1.0 → repid-2.1.2}/.devcontainer/devcontainer.json +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/CODE_OF_CONDUCT.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/FUNDING.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/ISSUE_TEMPLATE/other.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/dependabot.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/codeql.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/dependency-review.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/docs.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/mypy.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/release.yaml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.github/workflows/tests.yaml +0 -0
- {repid-2.1.0 → repid-2.1.2}/.gitignore +0 -0
- {repid-2.1.0 → repid-2.1.2}/LICENSE +0 -0
- {repid-2.1.0 → repid-2.1.2}/Makefile +0 -0
- {repid-2.1.0 → repid-2.1.2}/README.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/SECURITY.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/advanced_user_guide/your_own_brokers.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/advanced_user_guide/your_own_converter.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/advanced_user_guide/your_own_serializer.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/benchmarks.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/benchmarks_img/.gitignore +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/benchmarks_img/chart.svg +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/contributing.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/chaining_jobs.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/large_payloads.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/middlewares.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/rabbitmq_retries.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/sentry_middleware.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/cookbook/testing.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/features.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/getting_started/glossary.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/getting_started/quickstart.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/getting_started/supported_brokers.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/integrations/asyncapi.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/integrations/fastapi_and_pydantic.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/playground.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/confirmation_and_errors.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/execution.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/index.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/parsing.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/routers.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/actors/routing.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/dependency_injection.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/message_registry.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/messages.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/raw_message_and_eager_response.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/server_registry.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/server_specific_parameters.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/workers/built_in_servers.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/workers/concurrency.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/workers/index.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/docs/user_guide/workers/lifecycle.md +0 -0
- {repid-2.1.0 → repid-2.1.2}/mkdocs.yml +0 -0
- {repid-2.1.0 → repid-2.1.2}/pyproject.toml +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_runner.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_utils/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_utils/asyncify_.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_utils/is_installed.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_utils/json_encoder.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_utils/not_set.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/_worker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/generator.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/asyncapi.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/channels.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/bindings.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/correlation_id.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/external_docs.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/message.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/reference.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/common/tag.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/components.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/info.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/operations.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi/models/servers.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/asyncapi_server.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/abc.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/LICENSE.txt +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/constants.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/endpoints.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/_uamqp/outcomes.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/events.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/managed.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/reconnect.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/amqp/protocol/states.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/in_memory/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/in_memory/message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/in_memory/utils.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/kafka/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/kafka/message.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/kafka/message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/kafka/protocols.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/kafka/subscriber.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/nats/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/nats/message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/helpers.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/_helpers.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/channel.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/credentials.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/proto.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/pubsub/protocol/resilience.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/redis/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/redis/message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/sqs/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/sqs/constants.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/sqs/message.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/sqs/message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/connections/sqs/subscriber.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/converter.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/actor.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/channel.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/contact.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/converter_input_schema.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/external_docs.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/license.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/message.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/message_schema.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/operation.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/runner_info.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/data/tag.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/_utils.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/depends.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/full_payload.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/header_dependency.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/dependencies/message_dependency.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/health_check_server.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/logger.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/main.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/message_registry.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/middlewares.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/py.typed +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/router.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/serializer.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/server_registry.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/repid/test_client.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/conftest.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/pubsub_proto_helpers.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/rabbitmq_definitions.json +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_asyncapi_compatibility.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_default_flow.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_kafka_specific.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_nats_specific.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_rabbitmq_specific.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_sqs_specific.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/integration/test_worker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_event_emitter.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_frame_buffer.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_logging.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_managed.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_managed_pools.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_metrics.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_reconnect.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/amqp/test_state_machine.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/conftest.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/in_memory/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/in_memory/test_message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/in_memory/test_utils.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_channel.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_credentials.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_helpers_internal.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_proto.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/protocol/test_resilience.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/pubsub/test_helpers.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/redis/__init__.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/redis/test_message_broker.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/redis/test_redis_keep_alive.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_asyncapi_generator.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_channel.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_converter.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_dependencies.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_health_check_server.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_main.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_middleware.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_router.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_runner.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_runner_manual_explicit.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_serializer.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_server_registry.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_test_client.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_utils.py +0 -0
- {repid-2.1.0 → repid-2.1.2}/tests/unit/test_worker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repid
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Repid is a simple, fast, and extensible async task queue framework, with built-in AsyncAPI 3.0 schema generation.
|
|
5
5
|
Project-URL: documentation, https://repid.aleksul.space
|
|
6
6
|
Project-URL: funding, https://github.com/sponsors/aleksul
|
|
@@ -65,33 +65,47 @@ if __name__ == "__main__":
|
|
|
65
65
|
|
|
66
66
|
## Install
|
|
67
67
|
|
|
68
|
-
**Repid** supports Python
|
|
68
|
+
**Repid** supports Python 3.10 and later. Install it with `pip`:
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
pip install repid
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
depending on your use case:
|
|
74
|
+
Or with `uv`:
|
|
76
75
|
|
|
77
76
|
```bash
|
|
78
|
-
|
|
77
|
+
uv add repid
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Install extras for the integrations you use:
|
|
81
|
+
|
|
82
|
+
- `pydantic` - Pydantic deserialization support
|
|
83
|
+
- `amqp` - AMQP 1.0 broker support
|
|
84
|
+
- `nats` - NATS broker support
|
|
85
|
+
- `redis` - Redis broker support
|
|
86
|
+
- `pubsub` - GCP Pub/Sub broker support
|
|
87
|
+
- `kafka` - Apache Kafka broker support
|
|
88
|
+
- `sqs` - Amazon SQS broker support
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install "repid[pydantic,amqp,nats,redis,pubsub,kafka,sqs]"
|
|
79
92
|
```
|
|
80
93
|
|
|
81
94
|
## Why Repid?
|
|
82
95
|
|
|
83
|
-
**Repid**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
**Repid** gives async Python applications a clean task queue API with type hints, schema generation,
|
|
97
|
+
and broker flexibility built in.
|
|
98
|
+
|
|
99
|
+
- **AsyncAPI native**: Repid inspects your actors and generates AsyncAPI 3.0 schemas with interactive
|
|
100
|
+
web documentation, so your task contracts stay close to the code that handles them.
|
|
101
|
+
- **Typed message handling**: With the `pydantic`, Repid can deserialize, validate, and coerce
|
|
102
|
+
message payloads and headers before an actor runs.
|
|
103
|
+
- **Async-first performance**: Repid keeps the worker path small and async-native, avoiding sync
|
|
104
|
+
compatibility layers around broker I/O and actor execution.
|
|
105
|
+
- **Dependency injection**: Actors can receive database connections, settings, clients, or other shared
|
|
106
|
+
objects directly through their function signatures, keeping task code easier to test and reuse.
|
|
107
|
+
- **Broker flexibility**: Use Repid as a producer, a consumer, or both. Broker implementations sit
|
|
108
|
+
behind the same application API, so business logic stays separate from transport code.
|
|
95
109
|
|
|
96
110
|
## LLMs
|
|
97
111
|
|
|
@@ -6,9 +6,12 @@ from collections.abc import Callable
|
|
|
6
6
|
from dataclasses import fields
|
|
7
7
|
from typing import Any, Literal, TypeVar
|
|
8
8
|
|
|
9
|
-
from . import performatives
|
|
9
|
+
from . import endpoints, outcomes, performatives
|
|
10
10
|
from .message import Header, Message, Properties
|
|
11
11
|
|
|
12
|
+
FRAME_HEADER_SIZE = 8
|
|
13
|
+
MIN_DOFF = 2
|
|
14
|
+
|
|
12
15
|
# Maps fixed-width constructor bytes to the number of data bytes to skip.
|
|
13
16
|
# Used to advance past the descriptor in a described type without allocating a Python object.
|
|
14
17
|
_DESCRIPTOR_SKIP_SIZES: dict[int, int] = {
|
|
@@ -134,6 +137,22 @@ def _decode_timestamp(buffer: memoryview) -> tuple[memoryview, int]:
|
|
|
134
137
|
return buffer[8:], c_signed_long_long.unpack(buffer[:8])[0]
|
|
135
138
|
|
|
136
139
|
|
|
140
|
+
def _decode_char(buffer: memoryview) -> tuple[memoryview, str]:
|
|
141
|
+
return buffer[4:], chr(c_unsigned_int.unpack(buffer[:4])[0])
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _decode_decimal32(buffer: memoryview) -> tuple[memoryview, bytes]:
|
|
145
|
+
return buffer[4:], buffer[:4].tobytes()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _decode_decimal64(buffer: memoryview) -> tuple[memoryview, bytes]:
|
|
149
|
+
return buffer[8:], buffer[:8].tobytes()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _decode_decimal128(buffer: memoryview) -> tuple[memoryview, bytes]:
|
|
153
|
+
return buffer[16:], buffer[:16].tobytes()
|
|
154
|
+
|
|
155
|
+
|
|
137
156
|
def _decode_uuid(buffer: memoryview) -> tuple[memoryview, uuid.UUID]:
|
|
138
157
|
return buffer[16:], uuid.UUID(bytes=buffer[:16].tobytes())
|
|
139
158
|
|
|
@@ -191,37 +210,53 @@ def _decode_map_large(buffer: memoryview) -> tuple[memoryview, dict[Any, Any]]:
|
|
|
191
210
|
def _decode_array_small(buffer: memoryview) -> tuple[memoryview, list[Any]]:
|
|
192
211
|
count = buffer[1] # Ignore first byte (size) and just rely on count
|
|
193
212
|
if count:
|
|
194
|
-
|
|
195
|
-
buffer = buffer[3:]
|
|
196
|
-
values = [None] * count
|
|
197
|
-
for i in range(count):
|
|
198
|
-
buffer, values[i] = _DECODE_MAP[subconstructor](buffer)
|
|
199
|
-
return buffer, values
|
|
213
|
+
return _decode_array_values(buffer[2], buffer[3:], count)
|
|
200
214
|
return buffer[2:], []
|
|
201
215
|
|
|
202
216
|
|
|
203
217
|
def _decode_array_large(buffer: memoryview) -> tuple[memoryview, list[Any]]:
|
|
204
218
|
count = c_unsigned_long.unpack(buffer[4:8])[0]
|
|
205
219
|
if count:
|
|
206
|
-
|
|
207
|
-
buffer = buffer[9:]
|
|
208
|
-
values = [None] * count
|
|
209
|
-
for i in range(count):
|
|
210
|
-
buffer, values[i] = _DECODE_MAP[subconstructor](buffer)
|
|
211
|
-
return buffer, values
|
|
220
|
+
return _decode_array_values(buffer[8], buffer[9:], count)
|
|
212
221
|
return buffer[8:], []
|
|
213
222
|
|
|
214
223
|
|
|
224
|
+
def _decode_array_values(
|
|
225
|
+
subconstructor: int,
|
|
226
|
+
buffer: memoryview,
|
|
227
|
+
count: int,
|
|
228
|
+
) -> tuple[memoryview, list[Any]]:
|
|
229
|
+
descriptor: Any | None = None
|
|
230
|
+
if subconstructor == 0x00:
|
|
231
|
+
descriptor_constructor = buffer[0]
|
|
232
|
+
buffer, descriptor = _DECODE_MAP[descriptor_constructor](buffer[1:])
|
|
233
|
+
subconstructor = buffer[0]
|
|
234
|
+
buffer = buffer[1:]
|
|
235
|
+
|
|
236
|
+
values = [None] * count
|
|
237
|
+
decoder = _DECODE_MAP[subconstructor]
|
|
238
|
+
for i in range(count):
|
|
239
|
+
buffer, value = decoder(buffer)
|
|
240
|
+
if descriptor is not None:
|
|
241
|
+
value = _construct_described_value(descriptor, value)
|
|
242
|
+
values[i] = value
|
|
243
|
+
return buffer, values
|
|
244
|
+
|
|
245
|
+
|
|
215
246
|
def _decode_described(buffer: memoryview) -> tuple[memoryview, object]:
|
|
216
247
|
constructor = buffer[0]
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
248
|
+
buffer, descriptor = _DECODE_MAP[constructor](buffer[1:])
|
|
249
|
+
buffer, value = _DECODE_MAP[buffer[0]](buffer[1:])
|
|
250
|
+
return buffer, _construct_described_value(descriptor, value)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _construct_described_value(descriptor: Any, value: Any) -> object:
|
|
254
|
+
cls = DESCRIBED_TYPES_MAP.get(descriptor)
|
|
255
|
+
if cls is None:
|
|
256
|
+
return (descriptor, value)
|
|
257
|
+
if isinstance(value, list):
|
|
258
|
+
return _list_to_dataclass(cls, value)
|
|
259
|
+
return value
|
|
225
260
|
|
|
226
261
|
|
|
227
262
|
def _decode_string_small(buffer: memoryview) -> tuple[memoryview, str]:
|
|
@@ -268,10 +303,14 @@ _DECODE_MAP: dict[int, Callable] = {
|
|
|
268
303
|
0x00000070: _decode_uint_large,
|
|
269
304
|
0x00000071: _decode_int_large,
|
|
270
305
|
0x00000072: _decode_float,
|
|
306
|
+
0x00000073: _decode_char,
|
|
307
|
+
0x00000074: _decode_decimal32,
|
|
271
308
|
0x00000080: _decode_ulong_large,
|
|
272
309
|
0x00000081: _decode_long_large,
|
|
273
310
|
0x00000082: _decode_double,
|
|
274
311
|
0x00000083: _decode_timestamp,
|
|
312
|
+
0x00000084: _decode_decimal64,
|
|
313
|
+
0x00000094: _decode_decimal128,
|
|
275
314
|
0x00000098: _decode_uuid,
|
|
276
315
|
0x000000A0: _decode_binary_small,
|
|
277
316
|
0x000000A1: _decode_string_small,
|
|
@@ -290,6 +329,18 @@ _DECODE_MAP: dict[int, Callable] = {
|
|
|
290
329
|
ListToDataclassT = TypeVar("ListToDataclassT")
|
|
291
330
|
|
|
292
331
|
|
|
332
|
+
DESCRIBED_TYPES_MAP: dict[int, type[Any]] = {
|
|
333
|
+
performatives.Error.CODE: performatives.Error,
|
|
334
|
+
endpoints.Source.CODE: endpoints.Source,
|
|
335
|
+
endpoints.Target.CODE: endpoints.Target,
|
|
336
|
+
outcomes.Received.CODE: outcomes.Received,
|
|
337
|
+
outcomes.Accepted.CODE: outcomes.Accepted,
|
|
338
|
+
outcomes.Rejected.CODE: outcomes.Rejected,
|
|
339
|
+
outcomes.Released.CODE: outcomes.Released,
|
|
340
|
+
outcomes.Modified.CODE: outcomes.Modified,
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
|
|
293
344
|
def _list_to_dataclass(cls: type[ListToDataclassT], fields_list: list[Any]) -> ListToDataclassT:
|
|
294
345
|
kwargs = {}
|
|
295
346
|
cls_fields = fields(cls) # type: ignore[arg-type]
|
|
@@ -311,7 +362,13 @@ def bytes_to_performative(data: bytes) -> performatives.Performative:
|
|
|
311
362
|
# channel = struct.unpack(">H", buffer[6:8])[0]
|
|
312
363
|
|
|
313
364
|
# Body
|
|
365
|
+
if size < FRAME_HEADER_SIZE:
|
|
366
|
+
raise ValueError(f"Invalid frame size: {size}")
|
|
367
|
+
if doff < MIN_DOFF:
|
|
368
|
+
raise ValueError(f"Invalid frame data offset: {doff}")
|
|
314
369
|
body_start = doff * 4
|
|
370
|
+
if size < body_start:
|
|
371
|
+
raise ValueError(f"Frame size {size} smaller than data offset {body_start}")
|
|
315
372
|
body_buffer = buffer[body_start:size]
|
|
316
373
|
|
|
317
374
|
if len(body_buffer) == 0:
|
|
@@ -395,9 +452,13 @@ def _construct_message(payload: bytes) -> Message: # noqa: C901, PLR0912
|
|
|
395
452
|
elif descriptor == 0x00000074: # Application Properties # noqa: PLR2004
|
|
396
453
|
message.application_properties = value
|
|
397
454
|
elif descriptor == 0x00000075: # Data # noqa: PLR2004
|
|
398
|
-
message.data
|
|
455
|
+
if message.data is None:
|
|
456
|
+
message.data = []
|
|
457
|
+
message.data.append(value)
|
|
399
458
|
elif descriptor == 0x00000076: # Sequence # noqa: PLR2004
|
|
400
|
-
message.sequence
|
|
459
|
+
if message.sequence is None:
|
|
460
|
+
message.sequence = []
|
|
461
|
+
message.sequence.append(value)
|
|
401
462
|
elif descriptor == 0x00000077: # Value # noqa: PLR2004
|
|
402
463
|
message.value = value
|
|
403
464
|
elif descriptor == 0x00000078: # Footer # noqa: PLR2004
|
|
@@ -411,7 +472,7 @@ def transfer_frames_to_message(frames: list[performatives.TransferFrame]) -> Mes
|
|
|
411
472
|
for frame in frames:
|
|
412
473
|
if frame.payload:
|
|
413
474
|
payload.extend(frame.payload)
|
|
414
|
-
return _construct_message(payload)
|
|
475
|
+
return _construct_message(bytes(payload))
|
|
415
476
|
|
|
416
477
|
|
|
417
478
|
def decode_frame(data: bytes) -> tuple[int, performatives.Performative]:
|