agentscore-commerce 2.0.0__tar.gz → 2.0.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.
Files changed (176) hide show
  1. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/PKG-INFO +1 -1
  2. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/checkout.py +87 -1
  3. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/checkout_hooks.py +4 -0
  4. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/pyproject.toml +1 -1
  5. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_checkout.py +172 -0
  6. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_seamless_helpers.py +75 -0
  7. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/uv.lock +31 -31
  8. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  11. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/dependabot.yml +0 -0
  12. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/workflows/ci.yml +0 -0
  13. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/workflows/publish.yml +0 -0
  14. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.github/workflows/security.yml +0 -0
  15. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/.gitignore +0 -0
  16. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/CLAUDE.md +0 -0
  17. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/CODE_OF_CONDUCT.md +0 -0
  18. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/CONTRIBUTING.md +0 -0
  19. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/LICENSE +0 -0
  20. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/README.md +0 -0
  21. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/SECURITY.md +0 -0
  22. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/__init__.py +0 -0
  23. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/api/__init__.py +0 -0
  24. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/__init__.py +0 -0
  25. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/accepted_methods.py +0 -0
  26. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/agent_instructions.py +0 -0
  27. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/agent_memory.py +0 -0
  28. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/body.py +0 -0
  29. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/how_to_pay.py +0 -0
  30. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/identity.py +0 -0
  31. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/pricing.py +0 -0
  32. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/receipt.py +0 -0
  33. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/respond_402.py +0 -0
  34. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/challenge/validation_error.py +0 -0
  35. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/__init__.py +0 -0
  36. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/agentscore_content.py +0 -0
  37. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/bazaar.py +0 -0
  38. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/llms_txt.py +0 -0
  39. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/openapi.py +0 -0
  40. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/probe.py +0 -0
  41. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/redemption_md.py +0 -0
  42. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/robots_tag.py +0 -0
  43. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/skill_md.py +0 -0
  44. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/well_known.py +0 -0
  45. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/well_known_mpp.py +0 -0
  46. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/discovery/well_known_x402.py +0 -0
  47. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/__init__.py +0 -0
  48. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/_denial.py +0 -0
  49. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/_response.py +0 -0
  50. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/a2a.py +0 -0
  51. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/address.py +0 -0
  52. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/aiohttp.py +0 -0
  53. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/cache.py +0 -0
  54. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/core.py +0 -0
  55. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/django.py +0 -0
  56. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/fastapi.py +0 -0
  57. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/flask.py +0 -0
  58. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/middleware.py +0 -0
  59. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/policy.py +0 -0
  60. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/py.typed +0 -0
  61. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/sanic.py +0 -0
  62. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/sessions.py +0 -0
  63. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/signer.py +0 -0
  64. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/tokens.py +0 -0
  65. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/types.py +0 -0
  66. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/ucp.py +0 -0
  67. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/identity/ucp_jwks.py +0 -0
  68. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/__init__.py +0 -0
  69. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/amounts.py +0 -0
  70. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/directive.py +0 -0
  71. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/dispatch.py +0 -0
  72. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/headers.py +0 -0
  73. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/idempotency.py +0 -0
  74. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/lazy.py +0 -0
  75. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/mppx_server.py +0 -0
  76. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/networks.py +0 -0
  77. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/rail_spec.py +0 -0
  78. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/rails.py +0 -0
  79. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/settlement_override.py +0 -0
  80. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/signer.py +0 -0
  81. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/solana.py +0 -0
  82. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/usdc.py +0 -0
  83. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/wwwauthenticate.py +0 -0
  84. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/x402.py +0 -0
  85. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/x402_server.py +0 -0
  86. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/x402_settle.py +0 -0
  87. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/x402_validation.py +0 -0
  88. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/payment/zero_settle.py +0 -0
  89. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/stripe_multichain/__init__.py +0 -0
  90. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/stripe_multichain/mppx_stripe.py +0 -0
  91. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/stripe_multichain/payment_intent.py +0 -0
  92. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/stripe_multichain/pi_cache.py +0 -0
  93. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/agentscore_commerce/stripe_multichain/simulate_deposit.py +0 -0
  94. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/README.md +0 -0
  95. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/api_provider.py +0 -0
  96. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/compliance_merchant.py +0 -0
  97. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/identity_only.py +0 -0
  98. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/multi_rail_merchant.py +0 -0
  99. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/per_product_policy_merchant.py +0 -0
  100. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/signed_ucp_merchant.py +0 -0
  101. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/stripe_multichain_merchant.py +0 -0
  102. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/examples/variable_cost_merchant.py +0 -0
  103. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/lefthook.yml +0 -0
  104. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/ruff.toml +0 -0
  105. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/scripts/regenerate_cross_lang_fixtures.py +0 -0
  106. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/__init__.py +0 -0
  107. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/conftest.py +0 -0
  108. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-agentscore-gate-blocked.json +0 -0
  109. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-agentscore-gate-full.json +0 -0
  110. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-capability.json +0 -0
  111. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-emoji-keys.json +0 -0
  112. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-es256-rails.json +0 -0
  113. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-extras-int.json +0 -0
  114. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-int-boundary.json +0 -0
  115. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-minimal.json +0 -0
  116. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-multikey.json +0 -0
  117. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/node-unicode.json +0 -0
  118. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-agentscore-gate-blocked.json +0 -0
  119. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-agentscore-gate-full.json +0 -0
  120. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-capability.json +0 -0
  121. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-emoji-keys.json +0 -0
  122. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-es256-rails.json +0 -0
  123. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-extras-int.json +0 -0
  124. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-int-boundary.json +0 -0
  125. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-minimal.json +0 -0
  126. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-multikey.json +0 -0
  127. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/fixtures/cross-lang/py-unicode.json +0 -0
  128. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_a2a.py +0 -0
  129. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_address.py +0 -0
  130. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_agent_memory_emitter.py +0 -0
  131. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_aiohttp.py +0 -0
  132. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_amounts.py +0 -0
  133. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_api_reexport.py +0 -0
  134. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_cache.py +0 -0
  135. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_challenge.py +0 -0
  136. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_classify_orchestration_error.py +0 -0
  137. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_core.py +0 -0
  138. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_coverage_fillers.py +0 -0
  139. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_denial.py +0 -0
  140. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_discovery.py +0 -0
  141. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_dispatch.py +0 -0
  142. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_django.py +0 -0
  143. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_fastapi.py +0 -0
  144. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_flask.py +0 -0
  145. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_gate_quota_info.py +0 -0
  146. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_get_signer_verdict.py +0 -0
  147. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_idempotency_helper.py +0 -0
  148. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_integration.py +0 -0
  149. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_lifted_helpers.py +0 -0
  150. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_load_ucp_signing_key_from_env.py +0 -0
  151. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_middleware.py +0 -0
  152. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_directive.py +0 -0
  153. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_dispatch.py +0 -0
  154. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_handlers.py +0 -0
  155. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_headers.py +0 -0
  156. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_misc.py +0 -0
  157. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_servers.py +0 -0
  158. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_payment_signer.py +0 -0
  159. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_policy.py +0 -0
  160. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_pricing.py +0 -0
  161. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_public_surface.py +0 -0
  162. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_rail_spec.py +0 -0
  163. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_response.py +0 -0
  164. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_robots_tag.py +0 -0
  165. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_sanic.py +0 -0
  166. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_sessions.py +0 -0
  167. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_signer_match.py +0 -0
  168. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_skill_md.py +0 -0
  169. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_stripe_multichain.py +0 -0
  170. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_tokens.py +0 -0
  171. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_ucp.py +0 -0
  172. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_ucp_cross_lang.py +0 -0
  173. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_ucp_jwks.py +0 -0
  174. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_validation_error.py +0 -0
  175. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/tests/test_zero_settle.py +0 -0
  176. {agentscore_commerce-2.0.0 → agentscore_commerce-2.0.2}/vulture_whitelist.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentscore-commerce
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Agent commerce SDK for Python — identity middleware (FastAPI, Flask, Django, AIOHTTP, Sanic, ASGI) + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for AgentScore-powered agent commerce.
5
5
  Project-URL: Homepage, https://agentscore.sh
6
6
  Project-URL: Repository, https://github.com/agentscore/python-commerce
@@ -450,6 +450,9 @@ class SettleOutcome:
450
450
  """``"evm"`` / ``"solana"`` for chain signers; ``None`` otherwise."""
451
451
  payment_response_header: str | None = None
452
452
  """The ``PAYMENT-RESPONSE`` header to echo (x402 success path). ``None`` for MPP."""
453
+ payment_receipt_header: str | None = None
454
+ """The ``Payment-Receipt`` header to echo (MPP success path, paymentauth.org §5).
455
+ ``None`` for x402 and for the MPP zero-settle carve-out (no receipt minted)."""
453
456
  raw: Any = None
454
457
  """The underlying settle result. Inspect for power-user fields (facilitator
455
458
  diagnostics, raw receipt blobs); prefer the normalized fields above for the
@@ -490,6 +493,11 @@ class MppxComposeOutcome:
490
493
  """For ``status=200``: ``"evm"`` / ``"solana"`` depending on the rail."""
491
494
  payment_response_header: str | None = None
492
495
  """For ``status=200``: optional PAYMENT-RESPONSE header echoed to the agent."""
496
+ payment_receipt_header: str | None = None
497
+ """For ``status=200``: serialized ``Payment-Receipt`` header (base64url-encoded
498
+ receipt struct per pympp's ``Receipt.to_payment_receipt``). Echoed to the agent
499
+ so spec-strict MPP clients (tempo CLI, etc.) can lift tx_hash + source from
500
+ headers without parsing the JSON body."""
493
501
  raw: Any = None
494
502
  """The underlying pympp compose result for ``on_settled`` introspection."""
495
503
 
@@ -540,6 +548,41 @@ async def _maybe_await(value: Any) -> Any:
540
548
  return value
541
549
 
542
550
 
551
+ def _extract_mppx_receipt_header_from_raw(raw: Any) -> str | None:
552
+ """Best-effort ``Payment-Receipt`` extraction from a custom hook's ``raw``.
553
+
554
+ Handles the three shapes hand-rolled hooks commonly return on a 200:
555
+
556
+ * The raw object itself exposes ``to_payment_receipt()`` (pympp Receipt
557
+ handed back directly).
558
+ * ``raw`` is a tuple ``(credential, receipt)`` (the pympp ``Mpp.charge``
559
+ return shape, unpacked but not re-wrapped).
560
+ * ``raw`` is a dict with ``receipt`` key, or an object with ``.receipt``
561
+ attribute (the auto-built hook's ``{"credential", "receipt"}`` dict).
562
+
563
+ Returns ``None`` when none of the shapes match, or the receipt's
564
+ ``to_payment_receipt`` raises: the response then omits the header rather
565
+ than emitting a malformed value.
566
+ """
567
+ candidates: list[Any] = [raw]
568
+ if isinstance(raw, tuple | list) and len(raw) >= 2:
569
+ candidates.append(raw[1])
570
+ if isinstance(raw, dict) and "receipt" in raw:
571
+ candidates.append(raw["receipt"])
572
+ if hasattr(raw, "receipt"):
573
+ candidates.append(raw.receipt)
574
+ for candidate in candidates:
575
+ to_header = getattr(candidate, "to_payment_receipt", None)
576
+ if callable(to_header):
577
+ try:
578
+ value = to_header()
579
+ except Exception: # noqa: S112
580
+ continue
581
+ if isinstance(value, str) and value:
582
+ return value
583
+ return None
584
+
585
+
543
586
  def _resolve_identity_metadata(ctx: CheckoutContext) -> dict[str, Any] | None:
544
587
  """Compose the identity_metadata block from request + assess state.
545
588
 
@@ -791,6 +834,31 @@ class Checkout:
791
834
  return key
792
835
  return "tempo"
793
836
 
837
+ def _rails_key_for_mppx_method(self, method: str) -> str | None:
838
+ """Map an mppx credential ``method`` to the merchant's rails-dict key.
839
+
840
+ Used in ``_handle_mppx`` so the settle outcome distinguishes Solana
841
+ from Tempo (both fall under ``rail="mpp"``) and from Stripe SPT.
842
+ ``method`` is one of ``tempo`` / ``solana`` / ``stripe``. Returns
843
+ ``None`` when the merchant has no rail registered for that method.
844
+ """
845
+ if method == "stripe":
846
+ for key, spec in self.rails.items():
847
+ if isinstance(spec, StripeRailSpec):
848
+ return key
849
+ return None
850
+ if method == "solana":
851
+ for key, spec in self.rails.items():
852
+ if isinstance(spec, SolanaMppRailSpec):
853
+ return key
854
+ return None
855
+ if method == "tempo":
856
+ for key, spec in self.rails.items():
857
+ if isinstance(spec, (TempoRailSpec, TempoSessionRailSpec)):
858
+ return key
859
+ return None
860
+ return None
861
+
794
862
  @property
795
863
  def _x402_base_network(self) -> str | None:
796
864
  """CAIP-2 read from ``rails['x402_base'].network`` (or its default).
@@ -1574,6 +1642,7 @@ class Checkout:
1574
1642
  signer_address=carve.signer_address,
1575
1643
  signer_network="evm" if carve.signer_address else None,
1576
1644
  payment_response_header=None,
1645
+ payment_receipt_header=None,
1577
1646
  raw=verified,
1578
1647
  )
1579
1648
  return await self._build_success(ctx, outcome)
@@ -1589,6 +1658,7 @@ class Checkout:
1589
1658
  signer_address=carve.signer_address,
1590
1659
  signer_network="evm" if carve.signer_address else None,
1591
1660
  payment_response_header=None,
1661
+ payment_receipt_header=None,
1592
1662
  raw=None,
1593
1663
  )
1594
1664
  return await self._build_success(ctx, outcome)
@@ -1705,6 +1775,7 @@ class Checkout:
1705
1775
  signer_address=x402_signer.address if x402_signer else None,
1706
1776
  signer_network=x402_signer.network if x402_signer else None,
1707
1777
  payment_response_header=settle.payment_response_header,
1778
+ payment_receipt_header=None,
1708
1779
  raw=settle,
1709
1780
  )
1710
1781
  return await self._build_success(ctx, outcome)
@@ -1715,13 +1786,26 @@ class Checkout:
1715
1786
  raise RuntimeError(msg)
1716
1787
  composed: MppxComposeOutcome = await _maybe_await(self.compose_mppx(ctx))
1717
1788
  if composed.status == 200:
1789
+ receipt_method: str | None = None
1790
+ raw_receipt = composed.raw.get("receipt") if isinstance(composed.raw, dict) else None
1791
+ if isinstance(raw_receipt, dict):
1792
+ m = raw_receipt.get("method")
1793
+ if isinstance(m, str):
1794
+ receipt_method = m
1795
+ elif raw_receipt is not None:
1796
+ m = getattr(raw_receipt, "method", None)
1797
+ if isinstance(m, str):
1798
+ receipt_method = m
1799
+ derived_key = self._rails_key_for_mppx_method(receipt_method) if receipt_method is not None else None
1718
1800
  outcome = SettleOutcome(
1719
1801
  rail="mpp",
1720
- rail_key=composed.rail_key,
1802
+ rail_key=derived_key or composed.rail_key or self._mpp_rail_key(),
1721
1803
  tx_hash=composed.tx_hash,
1722
1804
  signer_address=composed.signer_address,
1723
1805
  signer_network=composed.signer_network,
1724
1806
  payment_response_header=composed.payment_response_header,
1807
+ payment_receipt_header=composed.payment_receipt_header
1808
+ or _extract_mppx_receipt_header_from_raw(composed.raw),
1725
1809
  raw=composed.raw,
1726
1810
  )
1727
1811
  return await self._build_success(ctx, outcome)
@@ -1862,6 +1946,8 @@ class Checkout:
1862
1946
  headers: dict[str, str] = {}
1863
1947
  if outcome.payment_response_header:
1864
1948
  headers["payment-response"] = outcome.payment_response_header
1949
+ if outcome.payment_receipt_header:
1950
+ headers["payment-receipt"] = outcome.payment_receipt_header
1865
1951
  return CheckoutResult(
1866
1952
  status=200,
1867
1953
  body=body,
@@ -93,11 +93,15 @@ def make_mppx_compose_hook(
93
93
  signer_address = signer.address
94
94
  signer_network = signer.network
95
95
 
96
+ to_header = getattr(receipt, "to_payment_receipt", None)
97
+ payment_receipt_header = to_header() if callable(to_header) else None
98
+
96
99
  return MppxComposeOutcome(
97
100
  status=200,
98
101
  tx_hash=tx_hash,
99
102
  signer_address=signer_address,
100
103
  signer_network=signer_network,
104
+ payment_receipt_header=payment_receipt_header,
101
105
  raw={"credential": credential, "receipt": receipt},
102
106
  )
103
107
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentscore-commerce"
7
- version = "2.0.0"
7
+ version = "2.0.2"
8
8
  description = "Agent commerce SDK for Python — identity middleware (FastAPI, Flask, Django, AIOHTTP, Sanic, ASGI) + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for AgentScore-powered agent commerce."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -300,6 +300,142 @@ async def test_compose_mppx_returns_200_runs_on_settled() -> None:
300
300
  on_settled.assert_awaited_once()
301
301
 
302
302
 
303
+ @pytest.mark.asyncio
304
+ async def test_compose_mppx_payment_receipt_header_surfaces_on_response() -> None:
305
+ """When ``compose_mppx`` populates ``payment_receipt_header``, Checkout echoes
306
+ it as a ``payment-receipt`` HTTP header on the success response — symmetric
307
+ to the existing ``payment_response_header`` (x402) behavior."""
308
+ receipt_header = "eyJzdGF0dXMiOiJzdWNjZXNzIn0"
309
+ compose_mppx = AsyncMock(
310
+ return_value=MppxComposeOutcome(status=200, payment_receipt_header=receipt_header),
311
+ )
312
+ checkout = Checkout(
313
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
314
+ url="https://api.example/purchase",
315
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
316
+ compose_mppx=compose_mppx,
317
+ )
318
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
319
+ assert result.status == 200
320
+ assert result.headers["payment-receipt"] == receipt_header
321
+
322
+
323
+ @pytest.mark.asyncio
324
+ async def test_compose_mppx_omitted_payment_receipt_header_emits_no_header() -> None:
325
+ """Default ``payment_receipt_header=None`` on the compose outcome must NOT
326
+ emit an empty ``payment-receipt`` header on the response."""
327
+ compose_mppx = AsyncMock(return_value=MppxComposeOutcome(status=200))
328
+ checkout = Checkout(
329
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
330
+ url="https://api.example/purchase",
331
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
332
+ compose_mppx=compose_mppx,
333
+ )
334
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
335
+ assert result.status == 200
336
+ assert "payment-receipt" not in result.headers
337
+
338
+
339
+ @pytest.mark.asyncio
340
+ async def test_compose_mppx_auto_extracts_receipt_header_from_raw_dict() -> None:
341
+ """When a custom compose_mppx returns ``raw={'credential': c, 'receipt': r}``
342
+ (the auto-built hook's shape) without explicitly setting
343
+ ``payment_receipt_header``, Checkout lifts the header from ``r.to_payment_receipt()``."""
344
+
345
+ class _Receipt:
346
+ @staticmethod
347
+ def to_payment_receipt() -> str:
348
+ return "auto-from-raw-dict"
349
+
350
+ compose_mppx = AsyncMock(
351
+ return_value=MppxComposeOutcome(status=200, raw={"credential": object(), "receipt": _Receipt()}),
352
+ )
353
+ checkout = Checkout(
354
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
355
+ url="https://api.example/purchase",
356
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
357
+ compose_mppx=compose_mppx,
358
+ )
359
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
360
+ assert result.status == 200
361
+ assert result.headers["payment-receipt"] == "auto-from-raw-dict"
362
+
363
+
364
+ @pytest.mark.asyncio
365
+ async def test_compose_mppx_auto_extracts_receipt_header_from_raw_tuple() -> None:
366
+ """``raw=(credential, receipt)`` (the pympp Mpp.charge return) is also a
367
+ recognized shape — the second element's ``to_payment_receipt()`` is lifted."""
368
+
369
+ class _Receipt:
370
+ @staticmethod
371
+ def to_payment_receipt() -> str:
372
+ return "auto-from-raw-tuple"
373
+
374
+ compose_mppx = AsyncMock(
375
+ return_value=MppxComposeOutcome(status=200, raw=(object(), _Receipt())),
376
+ )
377
+ checkout = Checkout(
378
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
379
+ url="https://api.example/purchase",
380
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
381
+ compose_mppx=compose_mppx,
382
+ )
383
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
384
+ assert result.status == 200
385
+ assert result.headers["payment-receipt"] == "auto-from-raw-tuple"
386
+
387
+
388
+ @pytest.mark.asyncio
389
+ async def test_compose_mppx_explicit_payment_receipt_header_wins_over_raw() -> None:
390
+ """When the hook sets ``payment_receipt_header`` explicitly, the auto-extract
391
+ from ``raw`` is NOT consulted."""
392
+
393
+ class _Receipt:
394
+ @staticmethod
395
+ def to_payment_receipt() -> str:
396
+ return "auto-IGNORED"
397
+
398
+ compose_mppx = AsyncMock(
399
+ return_value=MppxComposeOutcome(
400
+ status=200,
401
+ payment_receipt_header="explicit-value",
402
+ raw={"receipt": _Receipt()},
403
+ ),
404
+ )
405
+ checkout = Checkout(
406
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
407
+ url="https://api.example/purchase",
408
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
409
+ compose_mppx=compose_mppx,
410
+ )
411
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
412
+ assert result.status == 200
413
+ assert result.headers["payment-receipt"] == "explicit-value"
414
+
415
+
416
+ @pytest.mark.asyncio
417
+ async def test_compose_mppx_receipt_to_header_that_throws_falls_through() -> None:
418
+ """If ``to_payment_receipt()`` raises (unsupported pympp version, malformed
419
+ receipt), the SDK omits the header rather than emitting a malformed value."""
420
+
421
+ class _BadReceipt:
422
+ def to_payment_receipt(self) -> str:
423
+ raise RuntimeError("malformed receipt")
424
+
425
+ compose_mppx = AsyncMock(
426
+ return_value=MppxComposeOutcome(status=200, raw={"receipt": _BadReceipt()}),
427
+ )
428
+ checkout = Checkout(
429
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
430
+ url="https://api.example/purchase",
431
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=10.0),
432
+ compose_mppx=compose_mppx,
433
+ )
434
+ result = await checkout.handle(_req(headers={"authorization": "Payment id=abc"}))
435
+ assert result.status == 200
436
+ assert "payment-receipt" not in result.headers
437
+
438
+
303
439
  @pytest.mark.asyncio
304
440
  async def test_compose_mppx_returns_402_on_settle_leg_rejects_credential() -> None:
305
441
  """When the agent sends Authorization: Payment and mppx returns 402 (credential
@@ -437,3 +573,39 @@ def test_init_requires_x402_base_railspec_when_x402_server_provided() -> None:
437
573
  compute_pricing=lambda _ctx: PricingResult(amount_usd=1.0),
438
574
  x402_server=object(),
439
575
  )
576
+
577
+
578
+ def test_rails_key_for_mppx_method_picks_the_matching_spec() -> None:
579
+ """``_rails_key_for_mppx_method`` maps mppx credential methods (``tempo`` /
580
+ ``solana`` / ``stripe``) to the merchant's actual rails-dict key, so MPP
581
+ settlements distinguish Solana from Tempo (both fall under
582
+ ``SettleOutcome.rail="mpp"``) and from Stripe SPT.
583
+ """
584
+ checkout = Checkout(
585
+ rails={
586
+ "tempo_charge": TempoRailSpec(recipient="0xtempo"),
587
+ "x402_base": X402BaseRailSpec(recipient="0xbase"),
588
+ "sol_rail": SolanaMppRailSpec(recipient="solanaaddr"),
589
+ "stripe_spt": StripeRailSpec(profile_id="profile_x"),
590
+ },
591
+ url="https://api.example/purchase",
592
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=1.0),
593
+ )
594
+ assert checkout._rails_key_for_mppx_method("tempo") == "tempo_charge"
595
+ assert checkout._rails_key_for_mppx_method("solana") == "sol_rail"
596
+ assert checkout._rails_key_for_mppx_method("stripe") == "stripe_spt"
597
+ assert checkout._rails_key_for_mppx_method("unknown") is None
598
+
599
+
600
+ def test_rails_key_for_mppx_method_returns_none_when_rail_absent() -> None:
601
+ """When the merchant hasn't registered a rail for the credential method,
602
+ the helper returns ``None`` so the caller can fall back to
603
+ ``_mpp_rail_key()`` or a hard-coded default."""
604
+ checkout = Checkout(
605
+ rails={"tempo": TempoRailSpec(recipient="0xtempo")},
606
+ url="https://api.example/purchase",
607
+ compute_pricing=lambda _ctx: PricingResult(amount_usd=1.0),
608
+ )
609
+ assert checkout._rails_key_for_mppx_method("solana") is None
610
+ assert checkout._rails_key_for_mppx_method("stripe") is None
611
+ assert checkout._rails_key_for_mppx_method("tempo") == "tempo"
@@ -274,6 +274,81 @@ async def test_make_mppx_compose_hook_lifts_signer_from_did_pkh_eip155() -> None
274
274
  assert out.signer_network == "evm"
275
275
 
276
276
 
277
+ @pytest.mark.asyncio
278
+ async def test_make_mppx_compose_hook_serializes_receipt_to_payment_receipt_header() -> None:
279
+ """When the pympp ``Receipt`` exposes ``to_payment_receipt()``, the compose
280
+ hook lifts the serialized header onto ``MppxComposeOutcome.payment_receipt_header``
281
+ so Checkout can echo it as the response's ``Payment-Receipt`` header."""
282
+
283
+ class _Credential:
284
+ source = "did:pkh:eip155:8453:0xABCD000000000000000000000000000000000003"
285
+
286
+ class _Receipt:
287
+ reference = "0xtx_hash"
288
+ transaction = None
289
+
290
+ @staticmethod
291
+ def to_payment_receipt() -> str:
292
+ return "eyJzdGF0dXMiOiJzdWNjZXNzIn0"
293
+
294
+ class _Mpp:
295
+ realm = "r"
296
+
297
+ async def charge(self, *, authorization: str | None, amount: str) -> tuple:
298
+ return (_Credential(), _Receipt())
299
+
300
+ async def _getter() -> _Mpp:
301
+ return _Mpp()
302
+
303
+ hook = make_mppx_compose_hook(server_getter=_getter)
304
+
305
+ class _Pricing:
306
+ amount_usd = 0.1
307
+
308
+ class _Ctx:
309
+ request = _req({"authorization": "Payment somevalidcred"})
310
+ pricing = _Pricing()
311
+
312
+ out = await hook(_Ctx())
313
+ assert out.status == 200
314
+ assert out.payment_receipt_header == "eyJzdGF0dXMiOiJzdWNjZXNzIn0"
315
+
316
+
317
+ @pytest.mark.asyncio
318
+ async def test_make_mppx_compose_hook_omits_receipt_header_when_unavailable() -> None:
319
+ """Older pympp Receipts without ``to_payment_receipt()`` leave the header
320
+ field None rather than raising or fabricating."""
321
+
322
+ class _Credential:
323
+ source = "did:pkh:eip155:8453:0xABCD000000000000000000000000000000000003"
324
+
325
+ class _Receipt:
326
+ reference = "0xtx_hash"
327
+ transaction = None
328
+
329
+ class _Mpp:
330
+ realm = "r"
331
+
332
+ async def charge(self, *, authorization: str | None, amount: str) -> tuple:
333
+ return (_Credential(), _Receipt())
334
+
335
+ async def _getter() -> _Mpp:
336
+ return _Mpp()
337
+
338
+ hook = make_mppx_compose_hook(server_getter=_getter)
339
+
340
+ class _Pricing:
341
+ amount_usd = 0.1
342
+
343
+ class _Ctx:
344
+ request = _req({"authorization": "Payment somevalidcred"})
345
+ pricing = _Pricing()
346
+
347
+ out = await hook(_Ctx())
348
+ assert out.status == 200
349
+ assert out.payment_receipt_header is None
350
+
351
+
277
352
  @pytest.mark.asyncio
278
353
  async def test_make_mppx_compose_hook_returns_402_when_charge_raises() -> None:
279
354
  class _Mpp:
@@ -10,7 +10,7 @@ resolution-markers = [
10
10
 
11
11
  [[package]]
12
12
  name = "agentscore-commerce"
13
- version = "2.0.0"
13
+ version = "2.0.2"
14
14
  source = { editable = "." }
15
15
  dependencies = [
16
16
  { name = "agentscore-py" },
@@ -662,14 +662,14 @@ wheels = [
662
662
 
663
663
  [[package]]
664
664
  name = "click"
665
- version = "8.3.3"
665
+ version = "8.4.0"
666
666
  source = { registry = "https://pypi.org/simple" }
667
667
  dependencies = [
668
668
  { name = "colorama", marker = "sys_platform == 'win32'" },
669
669
  ]
670
- sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" }
670
+ sdist = { url = "https://files.pythonhosted.org/packages/23/e4/796662cd90cf80e3a363c99db2b88e0e394b988a575f60a17e16440cd011/click-8.4.0.tar.gz", hash = "sha256:638f1338fe1235c8f4e008e4a8a254fb5c5fbdcbb40ece3c9142ebb78e792973", size = 350843, upload-time = "2026-05-17T00:47:58.425Z" }
671
671
  wheels = [
672
- { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" },
672
+ { url = "https://files.pythonhosted.org/packages/ee/ae/8e92f8058baf87f6c7d86ee7e457668690195cc77efedb8d3797a06e3940/click-8.4.0-py3-none-any.whl", hash = "sha256:40c50b7c6c6adac2823d411041ec84f3f103f1b280d5e9ce0d7f998995832f81", size = 116147, upload-time = "2026-05-17T00:47:56.842Z" },
673
673
  ]
674
674
 
675
675
  [[package]]
@@ -2222,14 +2222,14 @@ wheels = [
2222
2222
 
2223
2223
  [[package]]
2224
2224
  name = "pympp"
2225
- version = "0.7.0"
2225
+ version = "0.8.0"
2226
2226
  source = { registry = "https://pypi.org/simple" }
2227
2227
  dependencies = [
2228
2228
  { name = "httpx" },
2229
2229
  ]
2230
- sdist = { url = "https://files.pythonhosted.org/packages/65/3b/81be4aba4e44f7122a78a182d7112b02ba0b91c7f76c65a44c8811b969af/pympp-0.7.0.tar.gz", hash = "sha256:0689c3b54986b5860650596548320de6026add6409ed08ab84b45444c70d0b08", size = 141144, upload-time = "2026-05-02T19:31:56.545Z" }
2230
+ sdist = { url = "https://files.pythonhosted.org/packages/2d/c0/b7c18c939086564ee4dab503a353bd1d843d8881c0db9e150fe8a6bddaf7/pympp-0.8.0.tar.gz", hash = "sha256:8afe5e9a2ebd5898d6687f98dd8ee8533c64bf49ce04e36244383c461b1898fe", size = 146377, upload-time = "2026-05-16T17:24:15.529Z" }
2231
2231
  wheels = [
2232
- { url = "https://files.pythonhosted.org/packages/d4/c4/fd283dc0b3c176fe5b56d509b52b8852c0d0bd6ae335818cbc80a605c6e2/pympp-0.7.0-py3-none-any.whl", hash = "sha256:914014caffb925adab2cd99064254d1ab48bbd23648f1385b6c724ff01903a36", size = 83155, upload-time = "2026-05-02T19:31:55.391Z" },
2232
+ { url = "https://files.pythonhosted.org/packages/3e/79/2a0b6f0a789a22c32c949a2fc039f5fea4e3fb781de08e6cb565aaa78522/pympp-0.8.0-py3-none-any.whl", hash = "sha256:2a377ad746efa6fe8e269794f4e3bea53520170347356abd44e424ad111207c9", size = 86851, upload-time = "2026-05-16T17:24:13.967Z" },
2233
2233
  ]
2234
2234
 
2235
2235
  [package.optional-dependencies]
@@ -2330,11 +2330,11 @@ wheels = [
2330
2330
 
2331
2331
  [[package]]
2332
2332
  name = "python-multipart"
2333
- version = "0.0.28"
2333
+ version = "0.0.29"
2334
2334
  source = { registry = "https://pypi.org/simple" }
2335
- sdist = { url = "https://files.pythonhosted.org/packages/82/54/a85eb421fbdd5007bc5af39d0f4ed9fa609e0fedbfdc2adcf0b34526870e/python_multipart-0.0.28.tar.gz", hash = "sha256:8550da197eac0f7ab748961fc9509b999fa2662ea25cef857f05249f6893c0f8", size = 45314, upload-time = "2026-05-10T11:05:16.596Z" }
2335
+ sdist = { url = "https://files.pythonhosted.org/packages/4e/fe/70bd71a6738b09a0bdf6480ca6436b167469ca4578b2a0efbe390b4b0e70/python_multipart-0.0.29.tar.gz", hash = "sha256:643e93849196645e2dbdd81a0f8829a23123ad7f797a84a364c6fb3563f18904", size = 45678, upload-time = "2026-05-17T17:29:47.654Z" }
2336
2336
  wheels = [
2337
- { url = "https://files.pythonhosted.org/packages/f3/a2/43bbc5860b5034e2af4ef99a0e04d726ff329c43e192ef3abaa8d7ecfce5/python_multipart-0.0.28-py3-none-any.whl", hash = "sha256:10faac07eb966c3f48dc415f9dee46c04cb10d58d30a35677db8027c825ed9b6", size = 29438, upload-time = "2026-05-10T11:05:15.052Z" },
2337
+ { url = "https://files.pythonhosted.org/packages/8f/cb/769cfc37177252872a45a71f3fbdde9d51b471a3f3c14bfe95dde3407386/python_multipart-0.0.29-py3-none-any.whl", hash = "sha256:2ddcc971cef266225f54f552d8fa10bcfbb1f14446caec199060daac59ff2d69", size = 29640, upload-time = "2026-05-17T17:29:45.69Z" },
2338
2338
  ]
2339
2339
 
2340
2340
  [[package]]
@@ -2976,27 +2976,27 @@ wheels = [
2976
2976
 
2977
2977
  [[package]]
2978
2978
  name = "ty"
2979
- version = "0.0.36"
2980
- source = { registry = "https://pypi.org/simple" }
2981
- sdist = { url = "https://files.pythonhosted.org/packages/14/bf/4baa1533937246861afcf27a84a3bbf1a536729fc40fdbbf6c99c4218dac/ty-0.0.36.tar.gz", hash = "sha256:0350a4edc956f165ab1d1c92db3b74526fcaae16921095b63c3c6a8be313b2ff", size = 5643311, upload-time = "2026-05-15T10:19:37.359Z" }
2982
- wheels = [
2983
- { url = "https://files.pythonhosted.org/packages/bf/08/83e6f1a8aad5fef237373c020628e3703b2a79cae134df7ae74a074b23ca/ty-0.0.36-py3-none-linux_armv6l.whl", hash = "sha256:c70fae86e68717969101ee4da11e2077efd55ea3ac4e1478b9dccf600d561086", size = 11236491, upload-time = "2026-05-15T10:19:51.863Z" },
2984
- { url = "https://files.pythonhosted.org/packages/05/08/39fc4f4acf4430a1a2bd5f1698ac28a6d39e4c93b0e363b6ee19b5e0f5f4/ty-0.0.36-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:543410bc78f38d351a388c29c6e7e0a646decdf0e8fb6b47496056030efab76f", size = 10984361, upload-time = "2026-05-15T10:19:20.755Z" },
2985
- { url = "https://files.pythonhosted.org/packages/87/f3/92d2bc59922c0ae6baa7476a815dbfe216f7a7f8ff3a801012a330acdbe3/ty-0.0.36-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a9f568ca71245f198278be8a73c30b87194277e3c8f328bb053e68399dd8dc91", size = 10423126, upload-time = "2026-05-15T10:19:45.722Z" },
2986
- { url = "https://files.pythonhosted.org/packages/be/b2/f03701dbb5513b833680d7fd845e7e521bf8ae290eae465175049263b989/ty-0.0.36-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f951b2845f39a12624f3beececc3063a12ce1212c11916d3557e7e78998c9d2", size = 10943043, upload-time = "2026-05-15T10:19:23.708Z" },
2987
- { url = "https://files.pythonhosted.org/packages/7f/32/5a186144fa4fbdace1f263047d58e2c89ac828cee4b5dda2b7dbb3496ad3/ty-0.0.36-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:45952006bf810deb25e1c4dfe9977a3cb8e9e675b2b491a6fd46717210a4a970", size = 11020866, upload-time = "2026-05-15T10:19:39.882Z" },
2988
- { url = "https://files.pythonhosted.org/packages/a1/0f/a8f6e63eaf0c3445b076f2bf07f97440ac548db06bb892097b22351e26df/ty-0.0.36-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e0d7d7c14f789e66fb0296c6c1facf07e519ff5d6d0250ffc3d54479f50cf88", size = 11507375, upload-time = "2026-05-15T10:19:54.95Z" },
2989
- { url = "https://files.pythonhosted.org/packages/c4/e2/0556e4253c285d2166037e009f50f82799f93c56ceb1c574a40da851333c/ty-0.0.36-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4873e1ae8d99c67296d7908c1be70da0f6a644746751c619b49cebeff0816509", size = 12043426, upload-time = "2026-05-15T10:19:26.254Z" },
2990
- { url = "https://files.pythonhosted.org/packages/37/0b/915d9c41ac95ab753b78b96779b94a7fe846d5715182b96d4b06c14e5910/ty-0.0.36-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e376cb976e9a8a4a5900f6e322ea4c8ac1dad0a6a8c9a10d5b15e87b8cf3f88", size = 11676680, upload-time = "2026-05-15T10:19:57.711Z" },
2991
- { url = "https://files.pythonhosted.org/packages/b9/ee/c356541929121004aeecc2e72d4e53185d59413d78a37f27eff83292369e/ty-0.0.36-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a002bbcc8ea6dd34b79463ae147f36e5c46ed9676767c0bc307a48e92e5e5dac", size = 11594362, upload-time = "2026-05-15T10:19:18.184Z" },
2992
- { url = "https://files.pythonhosted.org/packages/4c/6b/aba45733431791fb7dadbb44550bbb3bdc909f7c551538d8a804639c5f4c/ty-0.0.36-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a489fe80d42cd23c06ac8304bcbf07712f976655ca1a0e6b05040b53ccdc252b", size = 11749166, upload-time = "2026-05-15T10:19:34.969Z" },
2993
- { url = "https://files.pythonhosted.org/packages/28/32/9a5bd2d6512ee0b4496df36521162c142f0fec8f6c33889a0bbbfe8b91f7/ty-0.0.36-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a19d1ca362c8c2ea85dccb39d314aaa560cec77f618fcfc6d2e056253ca552b", size = 10923862, upload-time = "2026-05-15T10:19:31.9Z" },
2994
- { url = "https://files.pythonhosted.org/packages/36/f1/cbaf5a560c13d25842685d32afecedc193f8c9e6f7f8f03974616eb3361f/ty-0.0.36-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea83a24b4a5cf1c0421c436569e70648073a20eb9d31af3ae434dde28070cb2", size = 11057070, upload-time = "2026-05-15T10:20:00.293Z" },
2995
- { url = "https://files.pythonhosted.org/packages/59/5e/6c40145836825144600d3378cd6d6d2287ad3c079c86ceeedc4c35093394/ty-0.0.36-py3-none-musllinux_1_2_i686.whl", hash = "sha256:642421a4c56ea1a403e706dc22d0206bd5a76b08fca702ed7c7f43664b586569", size = 11184165, upload-time = "2026-05-15T10:19:29.036Z" },
2996
- { url = "https://files.pythonhosted.org/packages/0e/5f/e9ea4193c9b01da05691064f38bcb107460c92055266dd43f8d457e82305/ty-0.0.36-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:248f933e58d3295a54438c08e8289ae782aa12c96c2d10adcaef77f973ab536d", size = 11688416, upload-time = "2026-05-15T10:19:12.083Z" },
2997
- { url = "https://files.pythonhosted.org/packages/b5/13/576a6ec0226388d457e2ffd677485d8f532d8c852f2d8b6278c4d82813d7/ty-0.0.36-py3-none-win32.whl", hash = "sha256:0c5c806444904bb66506ea6811a751caa93860838d01210fad7f9100370c4ce9", size = 10503333, upload-time = "2026-05-15T10:19:48.825Z" },
2998
- { url = "https://files.pythonhosted.org/packages/8a/ba/e0b42be5920f56f49b1d6b5f77fd0668e4a5c94f63402bcdc3ee53511a11/ty-0.0.36-py3-none-win_amd64.whl", hash = "sha256:79d4adf8e4ffe12b3adc822874bce963993f0de904ddb5daa9599f38e53d602a", size = 11574185, upload-time = "2026-05-15T10:19:15.177Z" },
2999
- { url = "https://files.pythonhosted.org/packages/f8/77/42de5de13d5e473c5fb4667cb2cc1efa5d3c07df4a43d11ca4a6d6c62223/ty-0.0.36-py3-none-win_arm64.whl", hash = "sha256:a392731f68a5eff66346fdcb831d370d5e3c49aabae805081b4b70c0b6a3093b", size = 10939643, upload-time = "2026-05-15T10:19:42.593Z" },
2979
+ version = "0.0.37"
2980
+ source = { registry = "https://pypi.org/simple" }
2981
+ sdist = { url = "https://files.pythonhosted.org/packages/c7/c3/60bc4829e0c1a8ff80b592067e1185a7b5ea64608acb0c676c44d5137d52/ty-0.0.37.tar.gz", hash = "sha256:f873f69627bd7f4ef8d57f716c63e5c63d7d1b7327ab3de185c7287a75223011", size = 5655422, upload-time = "2026-05-16T05:57:21.315Z" }
2982
+ wheels = [
2983
+ { url = "https://files.pythonhosted.org/packages/b8/fe/180dd6914f9db33ad0200fbeaa429dd1fb0a4e6d98320dc1775f100a91af/ty-0.0.37-py3-none-linux_armv6l.whl", hash = "sha256:66cf7310189856e15f690559ddf37735476d2644db917d92f7cef13e5c834adf", size = 11246028, upload-time = "2026-05-16T05:57:41.744Z" },
2984
+ { url = "https://files.pythonhosted.org/packages/ef/a2/fa0cfd31467ad99b2db8c81ee9e2b4574589974a3eb9723be825e15b300c/ty-0.0.37-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2048f3c44ee6c7dde6e0ca064f99c6cada8f6de8ccdcfad2d856a429f8a4ac82", size = 11001460, upload-time = "2026-05-16T05:57:35.27Z" },
2985
+ { url = "https://files.pythonhosted.org/packages/10/3f/db60ba9be8b95a464ece0ba103e534047c34b49fee12f5e101f83f8d66db/ty-0.0.37-py3-none-macosx_11_0_arm64.whl", hash = "sha256:32c7b9b5b626aacdec334b44a2698e5f7b80df55bf7338267084d00d4b9546b3", size = 10446549, upload-time = "2026-05-16T05:57:37.252Z" },
2986
+ { url = "https://files.pythonhosted.org/packages/56/6f/11dd7174b20ebcb37a3d3b68f60b3940e37e4356e0accd03e2d7f9f70690/ty-0.0.37-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9fba1bebccf1e656bc5e3787acc5a191c491041ee4d12fe8fe2eff64e7b190d", size = 10961016, upload-time = "2026-05-16T05:57:16.394Z" },
2987
+ { url = "https://files.pythonhosted.org/packages/65/dd/3c17ce2860c525817c42c82d7075391b1f5615d36c03aa2d26647a224e8a/ty-0.0.37-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f987c5fb59aa5017ee8e8c5b57a07390f584e58e572255acd0fa44b3e0b238df", size = 11022093, upload-time = "2026-05-16T05:57:32.741Z" },
2988
+ { url = "https://files.pythonhosted.org/packages/d0/a8/e7a40b0b57660921dd3482d219add963973b52ae8507abd88f48439704b5/ty-0.0.37-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4168f53146e7a3f52560ff433f238352591c9b1a9ed09397fbb776ddef4f89c", size = 11486333, upload-time = "2026-05-16T05:57:18.839Z" },
2989
+ { url = "https://files.pythonhosted.org/packages/da/5f/2c406b98244bc1ad42afdd35f466bcef88664210957dcbb5172254ff2462/ty-0.0.37-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e487eafdb80a48223ce68a01f9287528216ffe0126d1629ff11e4f7c1dd3cf", size = 12093526, upload-time = "2026-05-16T05:57:04.456Z" },
2990
+ { url = "https://files.pythonhosted.org/packages/d3/3c/5c492a38e1b21a26370727dd4b77a53f05262e53e3be232047f22e7fa1b3/ty-0.0.37-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b49f388d063668676daaa7eef57385089d1b844279c0185bd84d4dbc3bcede6", size = 11725957, upload-time = "2026-05-16T05:57:23.356Z" },
2991
+ { url = "https://files.pythonhosted.org/packages/b2/00/8a3d9ba265cd0582342c14e4980cc0351aaaa45c6305712d398c9e2446c7/ty-0.0.37-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b96bfc1cc725d9d859abef4e3aa32a6da0f7472eaaafae2d9a6cffd729c7c61", size = 11610336, upload-time = "2026-05-16T05:57:27.888Z" },
2992
+ { url = "https://files.pythonhosted.org/packages/91/4b/6ee172935cb842f5c1553b0d37215b45e9dde05a4c74fdb47fd271907122/ty-0.0.37-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c55f39b519107cf234b794718793e11793c055e89028a282a309f690def48117", size = 11797856, upload-time = "2026-05-16T05:57:11.109Z" },
2993
+ { url = "https://files.pythonhosted.org/packages/34/ef/75a7425bf9fe74483404ff11a8cbe3aa307354e0801697d6063384157776/ty-0.0.37-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c79204350de060a077bff7f027a1d53e216cad147d826ec9862be0af2f9c3c1e", size = 10941848, upload-time = "2026-05-16T05:57:30.653Z" },
2994
+ { url = "https://files.pythonhosted.org/packages/e0/2c/7ea9dccd55961375067f99ed00fb8eabb491f6a06d0e5f09c797d2b900a6/ty-0.0.37-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:49a21b4dcb2cd94cd0298c96dfb71a2dd25f08bf7e6eefd0c33c519d058908c6", size = 11058248, upload-time = "2026-05-16T05:57:01.785Z" },
2995
+ { url = "https://files.pythonhosted.org/packages/98/d7/848fde96c6610b2b1fd75823d44d8977a4525c4397f27332f054ccd6cf9c/ty-0.0.37-py3-none-musllinux_1_2_i686.whl", hash = "sha256:119332095c5974fe1dabfe4fd00c6759eeec5b99f7d7a80b2833feee5a58abdb", size = 11168423, upload-time = "2026-05-16T05:57:39.297Z" },
2996
+ { url = "https://files.pythonhosted.org/packages/29/11/c1613ac4b64357b9067df68bac97bcb458cc426cd468a2782847238c539b/ty-0.0.37-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ac5dc593675414f68862c2f71cc04912b0e5ec5520a9c49fc71ed79205b95c33", size = 11698565, upload-time = "2026-05-16T05:57:14.206Z" },
2997
+ { url = "https://files.pythonhosted.org/packages/5f/ac/961205863903881996adb5a6f9cfe570c132882922ac226540346f15df20/ty-0.0.37-py3-none-win32.whl", hash = "sha256:33b57e4095179f06c2ae01c334833645cad94bf7d7467e073cdc3aaabea565d3", size = 10518308, upload-time = "2026-05-16T05:57:25.824Z" },
2998
+ { url = "https://files.pythonhosted.org/packages/39/cd/f308edd0cd86e402fe3a1b5c54e0a0dfa0177d80c1557c4849510bb2a147/ty-0.0.37-py3-none-win_amd64.whl", hash = "sha256:3b159351e99cf6eed7aacfb69ae8437725d15599ac4f21c8b2e909b300498b6c", size = 11607159, upload-time = "2026-05-16T05:57:06.76Z" },
2999
+ { url = "https://files.pythonhosted.org/packages/1a/ed/5ec4b501479bc5dad55467e2fe72e797cb9c178468c0d1a514536872ebc5/ty-0.0.37-py3-none-win_arm64.whl", hash = "sha256:6c3c2b997f68c71e14242b96d48cba3c086439556af02bb4613aa458950d5c23", size = 10958817, upload-time = "2026-05-16T05:57:08.907Z" },
3000
3000
  ]
3001
3001
 
3002
3002
  [[package]]