mq-bridge-py-basic 0.2.18__tar.gz → 0.2.20__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.
Files changed (198) hide show
  1. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/release.yml +15 -4
  2. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/Cargo.lock +31 -32
  3. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/Cargo.toml +15 -5
  4. mq_bridge_py_basic-0.2.20/PKG-INFO +191 -0
  5. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/README.md +6 -0
  6. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/benches/performance_bench.rs +1 -1
  7. mq_bridge_py_basic-0.2.20/benches/router_bench.rs +275 -0
  8. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/mq-bridge.schema.json +102 -7
  9. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/mq_bridge/__init__.py +4 -0
  10. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/mq_bridge/__init__.pyi +40 -2
  11. mq_bridge_py_basic-0.2.20/mq_bridge/config.py +98 -0
  12. mq_bridge_py_basic-0.2.20/mq_bridge/config.pyi +394 -0
  13. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/pyproject.toml +5 -3
  14. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/Cargo.toml +2 -1
  15. mq_bridge_py_basic-0.2.20/python/mq-bridge-py/README.md +167 -0
  16. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/example.py +14 -13
  17. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/examples/raw_route.py +0 -1
  18. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/pyproject-basic.toml +5 -3
  19. mq_bridge_py_basic-0.2.20/python/mq-bridge-py/scripts/gen_config_types.py +248 -0
  20. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/src/lib.rs +216 -41
  21. mq_bridge_py_basic-0.2.20/python/mq-bridge-py/tests/test_config_types.py +45 -0
  22. mq_bridge_py_basic-0.2.20/python/mq-bridge-py/tests/test_packaging.py +49 -0
  23. mq_bridge_py_basic-0.2.20/python/mq-bridge-py/tests/test_routes.py +143 -0
  24. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/uv.lock +100 -1369
  25. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/http/mq_bridge_http_profile.rs +24 -4
  26. mq_bridge_py_basic-0.2.20/scripts/analysis/http/run_http_ladder.sh +87 -0
  27. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +1 -1
  28. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/httparena/frameworks/mq-bridge-py/meta.json +7 -2
  29. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/httparena/frameworks/mq-bridge-py/server.py +191 -32
  30. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/grpc.rs +103 -32
  31. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/http.rs +329 -53
  32. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/mod.rs +113 -0
  33. mq_bridge_py_basic-0.2.20/src/endpoints/websocket.rs +783 -0
  34. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/buffer.rs +296 -2
  35. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/mod.rs +2 -5
  36. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/models.rs +77 -3
  37. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/test_utils.rs +45 -11
  38. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/websocket.rs +1 -1
  39. mq_bridge_py_basic-0.2.20/tests/websocket_test.rs +356 -0
  40. mq_bridge_py_basic-0.2.18/PKG-INFO +0 -110
  41. mq_bridge_py_basic-0.2.18/python/mq-bridge-py/README.md +0 -86
  42. mq_bridge_py_basic-0.2.18/src/endpoints/websocket.rs +0 -459
  43. mq_bridge_py_basic-0.2.18/tests/websocket_test.rs +0 -118
  44. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  45. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  46. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  47. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/benchmark.yml +0 -0
  48. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/ci.yml +0 -0
  49. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/ibm-mq.yml +0 -0
  50. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/publish-python.yml +0 -0
  51. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/python.yml +0 -0
  52. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.github/workflows/test-matrix.yml +0 -0
  53. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/.gitignore +0 -0
  54. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/ARCHITECTURE.md +0 -0
  55. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/CONFIGURATION.md +0 -0
  56. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/CONTRIBUTING.md +0 -0
  57. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/LICENSE +0 -0
  58. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/LICENSE.python +0 -0
  59. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/build.rs +0 -0
  60. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/claude.md +0 -0
  61. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/examples/ipc_worker_queue.yaml +0 -0
  62. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/mq_bridge/py.typed +0 -0
  63. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/LICENSE.python +0 -0
  64. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  65. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  66. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  67. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/examples/json_route.py +0 -0
  68. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/examples/memory.yaml +0 -0
  69. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  70. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/python/mq-bridge-py/tests/test_public_api.py +0 -0
  71. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/HTTP_STREAM_ENDPOINT_PLAN.md +0 -0
  72. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/benches/metadata_bench.rs +0 -0
  73. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  74. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  75. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/analysis/http/http_flamegraph.py +0 -0
  76. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/httparena/README.md +0 -0
  77. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  78. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  79. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  80. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  81. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/README.md +0 -0
  82. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/postgres.yml +0 -0
  83. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/seed.sql +0 -0
  84. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/techempower/verify.sh +0 -0
  85. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/the-benchmarker/README.md +0 -0
  86. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  87. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  88. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  89. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/canonical_message.rs +0 -0
  90. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/command_handler.rs +0 -0
  91. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/amqp.rs +0 -0
  92. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/aws.rs +0 -0
  93. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/fanout.rs +0 -0
  94. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/file.rs +0 -0
  95. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/grpc.proto +0 -0
  96. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/http_stream.rs +0 -0
  97. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/ibm_mq.rs +0 -0
  98. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/kafka.rs +0 -0
  99. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/endpoint.rs +0 -0
  100. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/ipc_unix.rs +0 -0
  101. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/ipc_windows.rs +0 -0
  102. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/memory_transport.rs +0 -0
  103. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/mod.rs +0 -0
  104. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/memory/transport.rs +0 -0
  105. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/mongodb.rs +0 -0
  106. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/mqtt.rs +0 -0
  107. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/nats.rs +0 -0
  108. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/null.rs +0 -0
  109. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/reader.rs +0 -0
  110. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/response.rs +0 -0
  111. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/sled.rs +0 -0
  112. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/sqlx.rs +0 -0
  113. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/static_endpoint.rs +0 -0
  114. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/stream_buffer.rs +0 -0
  115. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/switch.rs +0 -0
  116. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/endpoints/zeromq.rs +0 -0
  117. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/errors.rs +0 -0
  118. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/event_handler.rs +0 -0
  119. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/event_store.rs +0 -0
  120. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/extensions.rs +0 -0
  121. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/lib.rs +0 -0
  122. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/cookie_jar.rs +0 -0
  123. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/deduplication.rs +0 -0
  124. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/delay.rs +0 -0
  125. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/dlq.rs +0 -0
  126. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/limiter.rs +0 -0
  127. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/metrics.rs +0 -0
  128. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/random_panic.rs +0 -0
  129. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/retry.rs +0 -0
  130. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/middleware/weak_join.rs +0 -0
  131. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/outcomes.rs +0 -0
  132. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/publisher.rs +0 -0
  133. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/response.rs +0 -0
  134. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/route.rs +0 -0
  135. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/traits.rs +0 -0
  136. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/src/type_handler.rs +0 -0
  137. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/README.md +0 -0
  138. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/armature_integration.rs +0 -0
  139. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/amqp.rs +0 -0
  140. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/aws.rs +0 -0
  141. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/config.toml +0 -0
  142. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/amqp.yml +0 -0
  143. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/aws.yml +0 -0
  144. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  145. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  146. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  147. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  148. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  149. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  150. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  151. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  152. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/kafka.yml +0 -0
  153. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mariadb.yml +0 -0
  154. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  155. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  156. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mongodb.yml +0 -0
  157. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mosquitto.conf +0 -0
  158. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  159. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  160. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  161. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  162. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mqtt.yml +0 -0
  163. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  164. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/mysql.yml +0 -0
  165. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/nats.yml +0 -0
  166. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/docker-compose/postgres.yml +0 -0
  167. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/file.rs +0 -0
  168. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/grpc.rs +0 -0
  169. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/grpc_tls.rs +0 -0
  170. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/http.rs +0 -0
  171. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/http_tls.rs +0 -0
  172. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/ibm_mq.rs +0 -0
  173. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/ibm_mq_tls.rs +0 -0
  174. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/ipc.rs +0 -0
  175. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/kafka.rs +0 -0
  176. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/kafka_tls.rs +0 -0
  177. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/logic_test.rs +0 -0
  178. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mariadb.rs +0 -0
  179. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/memory.rs +0 -0
  180. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mod.rs +0 -0
  181. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mongodb.rs +0 -0
  182. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mongodb_raw.rs +0 -0
  183. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mongodb_tls.rs +0 -0
  184. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mqtt.rs +0 -0
  185. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/mysql.rs +0 -0
  186. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/nats.rs +0 -0
  187. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/performance_static.rs +0 -0
  188. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/postgres.rs +0 -0
  189. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/route.rs +0 -0
  190. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/scripts/gen_certs.sh +0 -0
  191. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/sqlite.rs +0 -0
  192. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/tls_helpers.rs +0 -0
  193. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration/zeromq.rs +0 -0
  194. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/integration_test.rs +0 -0
  195. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/ref_test.rs +0 -0
  196. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/sqlite_test.rs +0 -0
  197. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/tls_example.rs +0 -0
  198. {mq_bridge_py_basic-0.2.18 → mq_bridge_py_basic-0.2.20}/tests/unit_tests.md +0 -0
@@ -50,13 +50,24 @@ jobs:
50
50
  runs-on: ubuntu-latest
51
51
  needs: release
52
52
  environment: release
53
+ permissions:
54
+ # Required for crates.io Trusted Publishing (OIDC).
55
+ contents: read
56
+ id-token: write
53
57
  steps:
54
- - uses: actions/checkout@v4
55
-
58
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
59
+ with:
60
+ persist-credentials: false
61
+
56
62
  - name: Install Rust toolchain
57
63
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
58
-
64
+
65
+ # Exchange the GitHub OIDC token for a short-lived crates.io token.
66
+ - name: Authenticate to crates.io (Trusted Publishing)
67
+ uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
68
+ id: auth
69
+
59
70
  - name: Publish to crates.io
60
71
  run: cargo publish
61
72
  env:
62
- CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
73
+ CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
@@ -299,7 +299,7 @@ dependencies = [
299
299
  "tokio-rustls 0.26.4",
300
300
  "tokio-stream",
301
301
  "tokio-util",
302
- "tokio-websockets",
302
+ "tokio-websockets 0.10.1",
303
303
  "tracing",
304
304
  "tryhard",
305
305
  "url",
@@ -3057,9 +3057,10 @@ dependencies = [
3057
3057
 
3058
3058
  [[package]]
3059
3059
  name = "mq-bridge"
3060
- version = "0.2.18"
3060
+ version = "0.2.20"
3061
3061
  dependencies = [
3062
3062
  "anyhow",
3063
+ "arc-swap",
3063
3064
  "async-channel",
3064
3065
  "async-nats",
3065
3066
  "async-trait",
@@ -3108,7 +3109,7 @@ dependencies = [
3108
3109
  "tokio",
3109
3110
  "tokio-rustls 0.26.4",
3110
3111
  "tokio-stream",
3111
- "tokio-tungstenite",
3112
+ "tokio-websockets 0.13.2",
3112
3113
  "tonic",
3113
3114
  "tonic-prost",
3114
3115
  "tonic-prost-build",
@@ -3123,7 +3124,7 @@ dependencies = [
3123
3124
 
3124
3125
  [[package]]
3125
3126
  name = "mq-bridge-py"
3126
- version = "0.2.18"
3127
+ version = "0.2.20"
3127
3128
  dependencies = [
3128
3129
  "anyhow",
3129
3130
  "async-trait",
@@ -3131,6 +3132,7 @@ dependencies = [
3131
3132
  "fast-uuid-v7",
3132
3133
  "mq-bridge",
3133
3134
  "pyo3",
3135
+ "schemars",
3134
3136
  "serde",
3135
3137
  "serde_json",
3136
3138
  "serde_yaml_ng",
@@ -4883,6 +4885,12 @@ dependencies = [
4883
4885
  "digest 0.11.3",
4884
4886
  ]
4885
4887
 
4888
+ [[package]]
4889
+ name = "sha1_smol"
4890
+ version = "1.0.1"
4891
+ source = "registry+https://github.com/rust-lang/crates.io-index"
4892
+ checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
4893
+
4886
4894
  [[package]]
4887
4895
  name = "sha2"
4888
4896
  version = "0.10.9"
@@ -5549,18 +5557,6 @@ dependencies = [
5549
5557
  "tokio",
5550
5558
  ]
5551
5559
 
5552
- [[package]]
5553
- name = "tokio-tungstenite"
5554
- version = "0.29.0"
5555
- source = "registry+https://github.com/rust-lang/crates.io-index"
5556
- checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c"
5557
- dependencies = [
5558
- "futures-util",
5559
- "log",
5560
- "tokio",
5561
- "tungstenite",
5562
- ]
5563
-
5564
5560
  [[package]]
5565
5561
  name = "tokio-util"
5566
5562
  version = "0.7.18"
@@ -5597,6 +5593,25 @@ dependencies = [
5597
5593
  "webpki-roots 0.26.11",
5598
5594
  ]
5599
5595
 
5596
+ [[package]]
5597
+ name = "tokio-websockets"
5598
+ version = "0.13.2"
5599
+ source = "registry+https://github.com/rust-lang/crates.io-index"
5600
+ checksum = "dad543404f98bfc969aeb71994105c592acfc6c43323fddcd016bb208d1c65cb"
5601
+ dependencies = [
5602
+ "base64",
5603
+ "bytes",
5604
+ "fastrand",
5605
+ "futures-core",
5606
+ "futures-sink",
5607
+ "http 1.4.2",
5608
+ "httparse",
5609
+ "sha1_smol",
5610
+ "simdutf8",
5611
+ "tokio",
5612
+ "tokio-util",
5613
+ ]
5614
+
5600
5615
  [[package]]
5601
5616
  name = "toml"
5602
5617
  version = "1.1.2+spec-1.1.0"
@@ -5862,22 +5877,6 @@ dependencies = [
5862
5877
  "tokio",
5863
5878
  ]
5864
5879
 
5865
- [[package]]
5866
- name = "tungstenite"
5867
- version = "0.29.0"
5868
- source = "registry+https://github.com/rust-lang/crates.io-index"
5869
- checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8"
5870
- dependencies = [
5871
- "bytes",
5872
- "data-encoding",
5873
- "http 1.4.2",
5874
- "httparse",
5875
- "log",
5876
- "rand 0.9.4",
5877
- "sha1 0.10.6",
5878
- "thiserror 2.0.18",
5879
- ]
5880
-
5881
5880
  [[package]]
5882
5881
  name = "typed-builder"
5883
5882
  version = "0.22.0"
@@ -16,7 +16,7 @@ members = ["python/mq-bridge-py"]
16
16
  resolver = "2"
17
17
 
18
18
  [workspace.package]
19
- version = "0.2.18"
19
+ version = "0.2.20"
20
20
 
21
21
  [workspace.dependencies]
22
22
  anyhow = "1.0"
@@ -26,7 +26,7 @@ fast-uuid-v7 = "0.1.5"
26
26
  serde = "1.0"
27
27
  serde_json = "1.0"
28
28
  serde_yaml_ng = "0.10"
29
- tokio = "1"
29
+ tokio = "1.34" # `Receiver::recv_many` (HTTP source batch drain) needs 1.34+.
30
30
  tracing = "0.1"
31
31
 
32
32
  [profile.release]
@@ -46,6 +46,7 @@ tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync", "ti
46
46
  # Note on MSRV for optional features:
47
47
  # The base crate keeps MSRV 1.75 with default = [].
48
48
  # - "amqp" (lapin 4.10) requires Rust 1.88+; "http" (hyper-rustls 0.27) requires Rust 1.85+.
49
+ # - "websocket" (tokio-websockets 0.13) requires Rust 1.89+.
49
50
  # - "aws" (aws-sdk-*) may require a newer stable toolchain than the base MSRV.
50
51
  # Use `rustup override set stable` or a `rust-toolchain.toml` file when enabling these features.
51
52
  async-trait.workspace = true
@@ -109,6 +110,7 @@ rumqttc = { version = "0.25", default-features = false, features = ["use-rustls-
109
110
  mqi = { version = "0.3", optional = true }
110
111
 
111
112
  # HTTP
113
+ arc-swap = { version = "1", optional = true }
112
114
  hyper = { version = "1.8", optional = true, features = ["client", "server", "http1", "http2"] }
113
115
  hyper-util = { version = "0.1", optional = true, features = ["tokio", "client", "client-legacy", "server", "http1", "http2"] }
114
116
  hyper-rustls = { version = "0.27", optional = true, default-features = false, features = ["http1", "http2", "tls12", "logging", "native-tokio"] }
@@ -117,7 +119,7 @@ http-body = { version = "1.0", optional = true }
117
119
  h2 = { version = "0.4", optional = true }
118
120
  flate2 = { version = "1.0", optional = true }
119
121
  base64 = { version = "0.22", optional = true }
120
- tokio-tungstenite = { version = "0.29", optional = true }
122
+ tokio-websockets = { version = "0.13", optional = true, default-features = false, features = ["client", "server", "sha1_smol", "fastrand"] }
121
123
 
122
124
  # AWS
123
125
  aws-config = { version = "1.8", optional = true, default-features = false, features = ["behavior-version-latest", "rt-tokio", "rustls"] }
@@ -178,8 +180,8 @@ amqp = ["lapin", "rustls", "rustls-pemfile", "url"]
178
180
  nats = ["async-nats", "rustls", "rustls-pemfile"]
179
181
  mongodb = ["dep:mongodb"]
180
182
  mqtt = ["rumqttc", "rustls", "tokio-rustls", "rustls-pemfile", "url"]
181
- http = ["hyper", "hyper-util", "hyper-rustls", "http-body-util", "dep:http-body", "rustls", "tokio-rustls", "rustls-pemfile", "webpki-roots", "h2", "dep:flate2", "dep:base64"]
182
- websocket = ["dep:tokio-tungstenite"]
183
+ http = ["dep:arc-swap", "hyper", "hyper-util", "hyper-rustls", "http-body-util", "dep:http-body", "rustls", "tokio-rustls", "rustls-pemfile", "webpki-roots", "h2", "dep:flate2", "dep:base64"]
184
+ websocket = ["dep:tokio-websockets"]
183
185
  aws = ["aws-config", "aws-sdk-sqs", "aws-sdk-sns", "dep:base64"]
184
186
  ibm-mq = ["mqi"]
185
187
  zeromq = ["dep:zeromq"]
@@ -194,6 +196,8 @@ tempfile = "3.10"
194
196
  chrono = "0.4"
195
197
  metrics-util = "0.20"
196
198
  criterion = { version = "0.8", features = ["async", "async_tokio"] }
199
+ # Used by the router_bench microbench to model the proposed lock-free route table.
200
+ arc-swap = "1"
197
201
  mq-bridge = { path = ".", features = ["test-utils", "rustls-ring"] }
198
202
  reqwest = { version = "0.13", features = ["stream"] }
199
203
 
@@ -207,6 +211,12 @@ name = "performance_bench"
207
211
  harness = false
208
212
  required-features = ["test-utils"]
209
213
 
214
+ # Isolates the per-request HTTP route lookup (Mutex<HashMap> vs ArcSwap).
215
+ # No external services or features required.
216
+ [[bench]]
217
+ name = "router_bench"
218
+ harness = false
219
+
210
220
  [[test]]
211
221
  name = "integration_test"
212
222
  required-features = ["test-utils"]
@@ -0,0 +1,191 @@
1
+ Metadata-Version: 2.4
2
+ Name: mq-bridge-py-basic
3
+ Version: 0.2.20
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: License :: OSI Approved :: MIT License
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.9
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Rust
13
+ Requires-Dist: typing-extensions>=4.0
14
+ License-File: LICENSE.python
15
+ Summary: Python bindings for mq-bridge (basic: all-platform messaging set)
16
+ Keywords: messaging,tokio,pyo3,maturin,mq-bridge
17
+ License: MIT
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
20
+ Project-URL: Homepage, https://github.com/marcomq/mq-bridge
21
+ Project-URL: Issues, https://github.com/marcomq/mq-bridge/issues
22
+ Project-URL: Repository, https://github.com/marcomq/mq-bridge
23
+
24
+ # mq-bridge Python bindings
25
+
26
+ Thin Python bindings for the Rust `mq-bridge` core.
27
+
28
+ ## Install
29
+
30
+ Pick exactly one distribution. Both install the same import path: `mq_bridge`.
31
+
32
+ | Package | Install | Includes |
33
+ | :--- | :--- | :--- |
34
+ | Full | `pip install mq-bridge-py` | Basic set plus Kafka, AWS, gRPC, MongoDB, SQLx |
35
+ | Basic | `pip install mq-bridge-py-basic` | HTTP, NATS, MQTT, AMQP, WebSocket, ZeroMQ, middleware |
36
+
37
+ Memory and file endpoints are always present in both packages. Use `mq-bridge-py-basic` when you want the lean all-platform wheel set. Use `mq-bridge-py` when you need Kafka or the heavier non-messaging backends.
38
+
39
+ The public API stays close to mq-bridge itself:
40
+
41
+ - `Route.from_yaml(path, name)` loads one named route from a YAML file
42
+ - `Route.from_yaml_str(text, name)` / `Route.from_config(mapping, name)` build a route from an in-memory YAML string or a Python `dict`, no file required
43
+ - `Route.with_handler(...)` attaches a raw `Message` handler, with lazy `json()`/`text()` readers and `with_json()`/`with_payload()` response helpers
44
+ - `Route.add_handler(kind, ...)` uses mq-bridge's `kind` dispatch and delivers decoded JSON
45
+ - `RetryableError` and `NonRetryableError` let Python handlers signal retry intent
46
+ - `Publisher.from_yaml(path, name)` (plus `from_yaml_str` / `from_config`) loads one named publisher
47
+ - `Publisher.send_json(...)` and `Publisher.request_json(...)` serialize Python JSON values in Rust
48
+
49
+ The Python surface is synchronous and blocking. Tokio, broker I/O, routing, and batching all stay in Rust.
50
+
51
+ ## Config types and schema
52
+
53
+ `mq-bridge-app` can create and test route and endpoint JSON/YAML through its UI.
54
+ It does not replace your Python code or handlers, but it is useful when you want
55
+ a known-good connection and route shape before pasting the configuration into
56
+ Python. Load the generated config with `Route.from_config`, `Route.from_yaml`,
57
+ `Publisher.from_config`, or `Publisher.from_yaml`.
58
+
59
+ For the `from_config` / `from_yaml_str` mappings, `mq_bridge.config` ships
60
+ `TypedDict` definitions so editors autocomplete the config keys (`input`,
61
+ `output`, `batch_size`, every transport config, middleware, …):
62
+
63
+ ```python
64
+ from mq_bridge import Route
65
+ from mq_bridge.config import ConfigDocument
66
+
67
+ config: ConfigDocument = {
68
+ "routes": {
69
+ "orders": {
70
+ "input": {"memory": {"topic": "orders.in", "capacity": 1600}},
71
+ "output": {"response": {}},
72
+ "batch_size": 128,
73
+ }
74
+ }
75
+ }
76
+ route = Route.from_config(config, "orders")
77
+ ```
78
+
79
+ These types are generated from the JSON Schema, which the extension produces on
80
+ demand from the Rust models — there is no checked-in schema copy to drift:
81
+
82
+ ```python
83
+ from mq_bridge import config_schema
84
+
85
+ schema = config_schema() # the JSON Schema as a dict
86
+ ```
87
+
88
+ `config_schema()` is handy for editor validation of YAML configs too — dump it
89
+ to a file and point your `# yaml-language-server: $schema=` line at it. The types
90
+ are regenerated with `uv run python scripts/gen_config_types.py` (a test fails if
91
+ they drift from the schema).
92
+
93
+ ## Running a route
94
+
95
+ `Route.run()` **blocks the calling thread** until another thread calls `stop()` —
96
+ it deploys the route and then parks. This is convenient for a process whose only
97
+ job is the route, but it is a common trap: nothing after `route.run()` executes
98
+ until the route stops.
99
+
100
+ To keep running Python code after the route is up, use `start()` (non-blocking)
101
+ or the context-manager form:
102
+
103
+ ```python
104
+ route = Route.from_config(config, "orders_route").with_handler(handle)
105
+
106
+ # Non-blocking: deploys, returns, and runs on a background thread.
107
+ route.start()
108
+ publisher.send_json({"order_id": 42}, {"kind": "order.created"})
109
+ route.stop()
110
+ route.join() # optional: wait for a clean shutdown
111
+
112
+ # Or scope it to a block — starts on enter, stops + joins on exit:
113
+ with Route.from_config(config, "orders_route").with_handler(handle):
114
+ publisher.send_json({"order_id": 42}, {"kind": "order.created"})
115
+ ```
116
+
117
+ Configuration/connection errors surface from `start()` itself, not from a
118
+ background thread. `run()` remains available for the blocking single-route case.
119
+
120
+ ## Tuning (environment variables)
121
+
122
+ These knobs are read from the environment at startup:
123
+
124
+ | Variable | Default | Effect |
125
+ | :--- | :--- | :--- |
126
+ | `MQ_BRIDGE_PY_HANDLER_EXECUTOR` | `worker` | `worker` runs handlers on a dedicated interpreter thread that coalesces queued batches under one GIL acquisition (best under load); `direct` calls the handler inline. |
127
+ | `MQ_BRIDGE_PY_HANDLER_CONCURRENCY` | CPU count | Max in-flight handler batches. `0` disables the limit. |
128
+ | `MQ_BRIDGE_PY_GC_MODE` | `default` | `default` leaves CPython's cyclic GC alone; `count` disables it and runs `gc.collect()` every N messages; `off` disables it entirely (pure refcounting). |
129
+ | `MQ_BRIDGE_PY_GC_THRESHOLD` | `100000` | Messages between collections when `MQ_BRIDGE_PY_GC_MODE=count`. |
130
+
131
+ ## Local development
132
+
133
+ `uv` is a good fit here for the Python-side developer workflow, while `maturin` stays the build backend:
134
+
135
+ ```bash
136
+ cd python/mq-bridge-py
137
+ uv sync --group dev --no-install-project
138
+ uv run maturin develop
139
+ uv run pytest -q
140
+ ```
141
+
142
+ Performance smoke tests are skipped by default because they start routes and measure
143
+ local throughput:
144
+
145
+ ```bash
146
+ cd python/mq-bridge-py
147
+ MQ_BRIDGE_RUN_PERF_TESTS=1 uv run pytest -q -m performance
148
+ ```
149
+
150
+ ## Examples
151
+
152
+ Raw message handler:
153
+
154
+ ```bash
155
+ cd python/mq-bridge-py
156
+ uv run python examples/raw_route.py
157
+ ```
158
+
159
+ Kind-based JSON handler:
160
+
161
+ ```bash
162
+ cd python/mq-bridge-py
163
+ uv run python examples/json_route.py
164
+ ```
165
+
166
+ Memory benchmark:
167
+
168
+ ```bash
169
+ cd python/mq-bridge-py
170
+ uv run maturin develop --release
171
+ uv run python examples/bench_memory.py --messages 100000
172
+ ```
173
+
174
+ ## Analysis
175
+
176
+ HTTP comparison benchmark, driven by a native load generator (`wrk`) so the
177
+ client is never the bottleneck. It boots each server itself (mq-bridge in worker
178
+ and direct executor modes, plus FastAPI, Starlette, Sanic, aiohttp, and
179
+ FastStream when installed) and drives each with `wrk`:
180
+
181
+ ```bash
182
+ cd python/mq-bridge-py
183
+ uv run maturin develop --release
184
+ uv sync --group bench # optional Python HTTP peers
185
+ uv run python analysis/bench_http_native.py --connections 1,8,32 --duration 8
186
+ ```
187
+
188
+ Requires `wrk` on `PATH` (`brew install wrk`). The FastStream target compares its
189
+ ASGI custom-route path over Uvicorn; it is not a broker-backed subscriber/publisher
190
+ benchmark. The examples use included sample configs or create temporary configs.
191
+
@@ -157,6 +157,12 @@ The `response` output endpoint sends a reply back to the original requester. Thi
157
157
  There is a separate repository for running mq-bridge as a standalone app, for example as a Docker container configured via YAML or environment variables:
158
158
  https://github.com/marcomq/mq-bridge-app
159
159
 
160
+ ### Configuration-first workflow
161
+
162
+ `mq-bridge-app` can be used to create and test route and endpoint configurations through a UI. The generated JSON/YAML can then be copied into an application and loaded by the Rust library or the Python bindings.
163
+
164
+ This does not replace application code or handlers, but it is useful when you want a known-good connection and route shape before pasting the configuration into code. For Python projects, routes and publishers are commonly loaded from JSON/YAML with `Route.from_config`, `Route.from_yaml`, `Publisher.from_config`, or `Publisher.from_yaml`.
165
+
160
166
  ### Programmatic Handlers
161
167
 
162
168
  For business logic, `mq-bridge` provides a handler layer separate from transport-level middleware. This is where message-specific code usually belongs.
@@ -648,7 +648,7 @@ pub mod websocket_helper {
648
648
  let websocket_config = WebSocketConfig {
649
649
  url: "127.0.0.1:0".to_string(),
650
650
  path: Some("/bench".to_string()),
651
- internal_buffer_size: Some(super::PERF_TEST_MESSAGE_COUNT * 2),
651
+ routed_queue_capacity: Some(super::PERF_TEST_MESSAGE_COUNT * 2),
652
652
  ..Default::default()
653
653
  };
654
654