meteroid 0.27.0__py3-none-any.whl

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 (384) hide show
  1. meteroid/__init__.py +56 -0
  2. meteroid/_exceptions.py +93 -0
  3. meteroid/_version.py +6 -0
  4. meteroid/api/__init__.py +188 -0
  5. meteroid/api/_auth.py +231 -0
  6. meteroid/api/_errors.py +125 -0
  7. meteroid/api/_pagination.py +258 -0
  8. meteroid/api/_response.py +132 -0
  9. meteroid/api/_streaming.py +353 -0
  10. meteroid/api/add_ons.py +665 -0
  11. meteroid/api/batch_jobs.py +293 -0
  12. meteroid/api/checkout_sessions.py +421 -0
  13. meteroid/api/client.py +967 -0
  14. meteroid/api/common.py +826 -0
  15. meteroid/api/connect.py +436 -0
  16. meteroid/api/coupons.py +631 -0
  17. meteroid/api/credit_notes.py +450 -0
  18. meteroid/api/custom_properties.py +495 -0
  19. meteroid/api/customers.py +1032 -0
  20. meteroid/api/entitlements.py +254 -0
  21. meteroid/api/events.py +150 -0
  22. meteroid/api/features.py +521 -0
  23. meteroid/api/invoices.py +521 -0
  24. meteroid/api/metrics.py +554 -0
  25. meteroid/api/middleware.py +40 -0
  26. meteroid/api/oauth.py +361 -0
  27. meteroid/api/oauth_apps.py +393 -0
  28. meteroid/api/plans.py +1181 -0
  29. meteroid/api/product_families.py +273 -0
  30. meteroid/api/products.py +663 -0
  31. meteroid/api/subscriptions.py +728 -0
  32. meteroid/api/usage.py +311 -0
  33. meteroid/errors.py +46 -0
  34. meteroid/models/__init__.py +1212 -0
  35. meteroid/models/add_on.py +42 -0
  36. meteroid/models/add_on_event.py +28 -0
  37. meteroid/models/add_on_event_data.py +37 -0
  38. meteroid/models/add_on_id.py +4 -0
  39. meteroid/models/add_on_list_response.py +20 -0
  40. meteroid/models/address.py +27 -0
  41. meteroid/models/all_components_scope.py +11 -0
  42. meteroid/models/applied_coupon.py +32 -0
  43. meteroid/models/applied_coupon_detailed.py +20 -0
  44. meteroid/models/applied_coupon_id.py +4 -0
  45. meteroid/models/available_parameters.py +24 -0
  46. meteroid/models/bank_account_id.py +4 -0
  47. meteroid/models/bank_transfer_payment_method_config.py +17 -0
  48. meteroid/models/batch_job_chunk_id.py +4 -0
  49. meteroid/models/batch_job_detail_response.py +51 -0
  50. meteroid/models/batch_job_failures_response.py +19 -0
  51. meteroid/models/batch_job_id.py +4 -0
  52. meteroid/models/batch_job_item_failure_response.py +26 -0
  53. meteroid/models/batch_job_list_response.py +20 -0
  54. meteroid/models/batch_job_response.py +39 -0
  55. meteroid/models/batch_job_status.py +28 -0
  56. meteroid/models/batch_job_type.py +24 -0
  57. meteroid/models/billable_metric_id.py +4 -0
  58. meteroid/models/billing_config.py +17 -0
  59. meteroid/models/billing_cycle_reset_period.py +11 -0
  60. meteroid/models/billing_metric_aggregate_enum.py +22 -0
  61. meteroid/models/billing_period_enum.py +19 -0
  62. meteroid/models/billing_type.py +15 -0
  63. meteroid/models/billing_type_enum.py +15 -0
  64. meteroid/models/boolean_config_value.py +13 -0
  65. meteroid/models/boolean_effective_entitlement_value.py +13 -0
  66. meteroid/models/boolean_entitlement_value.py +13 -0
  67. meteroid/models/boolean_feature_type.py +11 -0
  68. meteroid/models/boolean_resolved_entitlement_value.py +13 -0
  69. meteroid/models/calendar_reset_period.py +19 -0
  70. meteroid/models/calendar_unit.py +18 -0
  71. meteroid/models/cancel_checkout_session_response.py +17 -0
  72. meteroid/models/cancel_subscription_request.py +17 -0
  73. meteroid/models/cancel_subscription_response.py +17 -0
  74. meteroid/models/capacity_fee.py +24 -0
  75. meteroid/models/capacity_fee_structure.py +17 -0
  76. meteroid/models/capacity_plan_fee.py +23 -0
  77. meteroid/models/capacity_pricing.py +18 -0
  78. meteroid/models/capacity_threshold.py +18 -0
  79. meteroid/models/checkout_session.py +59 -0
  80. meteroid/models/checkout_session_id.py +4 -0
  81. meteroid/models/checkout_session_status.py +20 -0
  82. meteroid/models/checkout_type.py +19 -0
  83. meteroid/models/component_override.py +22 -0
  84. meteroid/models/component_parameterization.py +20 -0
  85. meteroid/models/component_parameters.py +21 -0
  86. meteroid/models/components_scope.py +13 -0
  87. meteroid/models/config_effective_entitlement_value.py +17 -0
  88. meteroid/models/config_entitlement_value.py +17 -0
  89. meteroid/models/config_feature_type.py +21 -0
  90. meteroid/models/config_resolved_entitlement_value.py +17 -0
  91. meteroid/models/config_value.py +31 -0
  92. meteroid/models/config_value_type.py +21 -0
  93. meteroid/models/connected_account.py +55 -0
  94. meteroid/models/connected_account_id.py +4 -0
  95. meteroid/models/connected_accounts_response.py +17 -0
  96. meteroid/models/connection_status.py +19 -0
  97. meteroid/models/connection_type.py +15 -0
  98. meteroid/models/country_code.py +4 -0
  99. meteroid/models/coupon.py +44 -0
  100. meteroid/models/coupon_discount.py +20 -0
  101. meteroid/models/coupon_event.py +28 -0
  102. meteroid/models/coupon_event_data.py +37 -0
  103. meteroid/models/coupon_filter.py +17 -0
  104. meteroid/models/coupon_id.py +4 -0
  105. meteroid/models/coupon_line_item.py +17 -0
  106. meteroid/models/coupon_list_response.py +20 -0
  107. meteroid/models/create_add_on_request.py +28 -0
  108. meteroid/models/create_checkout_session_request.py +71 -0
  109. meteroid/models/create_checkout_session_response.py +17 -0
  110. meteroid/models/create_connected_account_request.py +25 -0
  111. meteroid/models/create_coupon_request.py +33 -0
  112. meteroid/models/create_entitlements_request.py +17 -0
  113. meteroid/models/create_feature_request.py +31 -0
  114. meteroid/models/create_metric_request.py +43 -0
  115. meteroid/models/create_o_auth_app_request.py +17 -0
  116. meteroid/models/create_onboarding_link_request.py +13 -0
  117. meteroid/models/create_plan_request.py +55 -0
  118. meteroid/models/create_product_request.py +26 -0
  119. meteroid/models/create_subscription_add_on.py +22 -0
  120. meteroid/models/create_subscription_components.py +26 -0
  121. meteroid/models/credit_note.py +74 -0
  122. meteroid/models/credit_note_custom_properties_request.py +15 -0
  123. meteroid/models/credit_note_event.py +28 -0
  124. meteroid/models/credit_note_event_data.py +62 -0
  125. meteroid/models/credit_note_id.py +4 -0
  126. meteroid/models/credit_note_list_response.py +20 -0
  127. meteroid/models/credit_note_status.py +16 -0
  128. meteroid/models/credit_type.py +18 -0
  129. meteroid/models/currency.py +332 -0
  130. meteroid/models/custom_property_definition.py +40 -0
  131. meteroid/models/custom_property_definition_create_request.py +36 -0
  132. meteroid/models/custom_property_definition_id.py +4 -0
  133. meteroid/models/custom_property_definition_list_response.py +20 -0
  134. meteroid/models/custom_property_definition_update_request.py +28 -0
  135. meteroid/models/custom_property_entity_type.py +20 -0
  136. meteroid/models/custom_property_type.py +34 -0
  137. meteroid/models/custom_tax_rate.py +17 -0
  138. meteroid/models/customer.py +72 -0
  139. meteroid/models/customer_create_request.py +79 -0
  140. meteroid/models/customer_details.py +31 -0
  141. meteroid/models/customer_event.py +28 -0
  142. meteroid/models/customer_event_data.py +32 -0
  143. meteroid/models/customer_id.py +4 -0
  144. meteroid/models/customer_list_response.py +20 -0
  145. meteroid/models/customer_patch_request.py +74 -0
  146. meteroid/models/customer_payment_method_id.py +4 -0
  147. meteroid/models/customer_portal_scope.py +15 -0
  148. meteroid/models/customer_portal_token_request.py +23 -0
  149. meteroid/models/customer_portal_token_response.py +27 -0
  150. meteroid/models/customer_type.py +15 -0
  151. meteroid/models/customer_update_request.py +75 -0
  152. meteroid/models/decline_kind.py +30 -0
  153. meteroid/models/double_segmentation_matrix.py +19 -0
  154. meteroid/models/e_invoicing_finding.py +21 -0
  155. meteroid/models/e_invoicing_status.py +16 -0
  156. meteroid/models/effective_entitlement.py +20 -0
  157. meteroid/models/effective_entitlement_list_response.py +17 -0
  158. meteroid/models/effective_entitlement_value.py +25 -0
  159. meteroid/models/entitlement.py +28 -0
  160. meteroid/models/entitlement_id.py +4 -0
  161. meteroid/models/entitlement_list_response.py +17 -0
  162. meteroid/models/entitlement_product_ref.py +19 -0
  163. meteroid/models/entitlement_spec_request.py +20 -0
  164. meteroid/models/entitlement_value.py +25 -0
  165. meteroid/models/error_code.py +30 -0
  166. meteroid/models/event.py +27 -0
  167. meteroid/models/event_id.py +4 -0
  168. meteroid/models/event_type.py +90 -0
  169. meteroid/models/existing_price_ref.py +17 -0
  170. meteroid/models/existing_product_ref.py +17 -0
  171. meteroid/models/external_payment_method_config.py +11 -0
  172. meteroid/models/extra_component.py +22 -0
  173. meteroid/models/extra_recurring_billing_type_enum.py +15 -0
  174. meteroid/models/extra_recurring_fee_structure.py +17 -0
  175. meteroid/models/extra_recurring_plan_fee.py +25 -0
  176. meteroid/models/extra_recurring_pricing.py +16 -0
  177. meteroid/models/feature.py +39 -0
  178. meteroid/models/feature_id.py +4 -0
  179. meteroid/models/feature_list_response.py +20 -0
  180. meteroid/models/feature_ref.py +25 -0
  181. meteroid/models/feature_status.py +16 -0
  182. meteroid/models/feature_type.py +22 -0
  183. meteroid/models/fee.py +34 -0
  184. meteroid/models/fixed_discount.py +15 -0
  185. meteroid/models/fixed_window_reset_period.py +19 -0
  186. meteroid/models/get_checkout_session_response.py +17 -0
  187. meteroid/models/grouped_usage.py +16 -0
  188. meteroid/models/ingest_events_request.py +26 -0
  189. meteroid/models/ingest_events_response.py +18 -0
  190. meteroid/models/ingest_failure.py +15 -0
  191. meteroid/models/introspection_request.py +14 -0
  192. meteroid/models/invoice.py +108 -0
  193. meteroid/models/invoice_custom_properties_request.py +15 -0
  194. meteroid/models/invoice_documents_event.py +28 -0
  195. meteroid/models/invoice_documents_event_data.py +39 -0
  196. meteroid/models/invoice_event.py +28 -0
  197. meteroid/models/invoice_event_data.py +42 -0
  198. meteroid/models/invoice_id.py +4 -0
  199. meteroid/models/invoice_line_item.py +39 -0
  200. meteroid/models/invoice_list_response.py +20 -0
  201. meteroid/models/invoice_payment_status.py +20 -0
  202. meteroid/models/invoice_status.py +20 -0
  203. meteroid/models/invoice_type.py +19 -0
  204. meteroid/models/invoicing_entity_id.py +4 -0
  205. meteroid/models/json_config_value.py +14 -0
  206. meteroid/models/linked_segmentation_matrix.py +17 -0
  207. meteroid/models/list_checkout_sessions_response.py +17 -0
  208. meteroid/models/matrix_dimension.py +15 -0
  209. meteroid/models/matrix_plan_pricing.py +17 -0
  210. meteroid/models/matrix_pricing.py +17 -0
  211. meteroid/models/matrix_row.py +22 -0
  212. meteroid/models/metered_effective_entitlement_value.py +20 -0
  213. meteroid/models/metered_entitlement_spec.py +25 -0
  214. meteroid/models/metered_entitlement_usage.py +19 -0
  215. meteroid/models/metered_entitlement_value.py +24 -0
  216. meteroid/models/metered_feature_type.py +17 -0
  217. meteroid/models/metered_resolved_entitlement_value.py +25 -0
  218. meteroid/models/metric.py +50 -0
  219. meteroid/models/metric_dimension.py +15 -0
  220. meteroid/models/metric_event.py +28 -0
  221. meteroid/models/metric_event_data.py +47 -0
  222. meteroid/models/metric_filter.py +23 -0
  223. meteroid/models/metric_filter_operator.py +21 -0
  224. meteroid/models/metric_list_response.py +20 -0
  225. meteroid/models/metric_segmentation_matrix.py +25 -0
  226. meteroid/models/metric_summary.py +33 -0
  227. meteroid/models/metric_usage.py +27 -0
  228. meteroid/models/minimum_commitment.py +20 -0
  229. meteroid/models/minimum_commitment_input.py +20 -0
  230. meteroid/models/minimum_commitment_input_scope.py +20 -0
  231. meteroid/models/minimum_commitment_scope.py +20 -0
  232. meteroid/models/never_reset_period.py +11 -0
  233. meteroid/models/new_product_ref.py +22 -0
  234. meteroid/models/number_config_value.py +14 -0
  235. meteroid/models/o_auth_app.py +37 -0
  236. meteroid/models/o_auth_app_id.py +4 -0
  237. meteroid/models/o_auth_app_with_secret.py +19 -0
  238. meteroid/models/o_auth_apps_response.py +17 -0
  239. meteroid/models/o_auth_error_code.py +34 -0
  240. meteroid/models/o_auth_error_response.py +21 -0
  241. meteroid/models/onboarding_link_response.py +16 -0
  242. meteroid/models/onboarding_mode.py +15 -0
  243. meteroid/models/one_time_fee.py +16 -0
  244. meteroid/models/one_time_fee_structure.py +11 -0
  245. meteroid/models/one_time_plan_fee.py +16 -0
  246. meteroid/models/one_time_pricing.py +16 -0
  247. meteroid/models/online_method_config.py +13 -0
  248. meteroid/models/online_methods_config.py +19 -0
  249. meteroid/models/online_payment_method_config.py +17 -0
  250. meteroid/models/organization_id.py +4 -0
  251. meteroid/models/package_plan_pricing.py +16 -0
  252. meteroid/models/package_pricing.py +16 -0
  253. meteroid/models/pagination_response.py +19 -0
  254. meteroid/models/patch_plan_request.py +17 -0
  255. meteroid/models/payment_event.py +28 -0
  256. meteroid/models/payment_method_info.py +23 -0
  257. meteroid/models/payment_method_type_enum.py +19 -0
  258. meteroid/models/payment_methods_config.py +27 -0
  259. meteroid/models/payment_status_enum.py +21 -0
  260. meteroid/models/payment_transaction_id.py +4 -0
  261. meteroid/models/payment_type_enum.py +15 -0
  262. meteroid/models/per_unit_plan_pricing.py +14 -0
  263. meteroid/models/per_unit_pricing.py +14 -0
  264. meteroid/models/percentage_discount.py +13 -0
  265. meteroid/models/plan.py +69 -0
  266. meteroid/models/plan_add_on_input.py +24 -0
  267. meteroid/models/plan_event.py +28 -0
  268. meteroid/models/plan_event_data.py +34 -0
  269. meteroid/models/plan_id.py +4 -0
  270. meteroid/models/plan_list_response.py +20 -0
  271. meteroid/models/plan_status_enum.py +19 -0
  272. meteroid/models/plan_type_enum.py +16 -0
  273. meteroid/models/plan_usage_pricing_model.py +31 -0
  274. meteroid/models/plan_version_id.py +4 -0
  275. meteroid/models/plan_version_list_response.py +20 -0
  276. meteroid/models/plan_version_summary.py +26 -0
  277. meteroid/models/price_component.py +25 -0
  278. meteroid/models/price_component_id.py +4 -0
  279. meteroid/models/price_component_input.py +22 -0
  280. meteroid/models/price_entry.py +20 -0
  281. meteroid/models/price_id.py +4 -0
  282. meteroid/models/price_input.py +22 -0
  283. meteroid/models/pricing.py +34 -0
  284. meteroid/models/product.py +37 -0
  285. meteroid/models/product_event.py +28 -0
  286. meteroid/models/product_event_data.py +30 -0
  287. meteroid/models/product_family.py +19 -0
  288. meteroid/models/product_family_create_request.py +13 -0
  289. meteroid/models/product_family_id.py +4 -0
  290. meteroid/models/product_family_list_response.py +20 -0
  291. meteroid/models/product_fee_structure.py +34 -0
  292. meteroid/models/product_fee_type_enum.py +21 -0
  293. meteroid/models/product_id.py +4 -0
  294. meteroid/models/product_list_response.py +20 -0
  295. meteroid/models/product_ref.py +20 -0
  296. meteroid/models/products_scope.py +14 -0
  297. meteroid/models/property_config.py +26 -0
  298. meteroid/models/quote_event.py +28 -0
  299. meteroid/models/quote_event_data.py +23 -0
  300. meteroid/models/quote_id.py +4 -0
  301. meteroid/models/rate_fee.py +14 -0
  302. meteroid/models/rate_fee_structure.py +11 -0
  303. meteroid/models/rate_plan_fee.py +17 -0
  304. meteroid/models/rate_pricing.py +14 -0
  305. meteroid/models/recurring_fee.py +22 -0
  306. meteroid/models/refund_event_data.py +57 -0
  307. meteroid/models/refund_mode.py +16 -0
  308. meteroid/models/replace_plan_request.py +50 -0
  309. meteroid/models/reset_period.py +31 -0
  310. meteroid/models/resolved_entitlement.py +20 -0
  311. meteroid/models/resolved_entitlement_list_response.py +17 -0
  312. meteroid/models/resolved_entitlement_value.py +25 -0
  313. meteroid/models/rest_error_response.py +19 -0
  314. meteroid/models/reversal_kind.py +30 -0
  315. meteroid/models/revocation_request.py +17 -0
  316. meteroid/models/rotated_secret.py +15 -0
  317. meteroid/models/select_option.py +15 -0
  318. meteroid/models/shipping_address.py +19 -0
  319. meteroid/models/sliding_window_reset_period.py +19 -0
  320. meteroid/models/slot_downgrade_policy_enum.py +14 -0
  321. meteroid/models/slot_fee.py +22 -0
  322. meteroid/models/slot_fee_structure.py +22 -0
  323. meteroid/models/slot_plan_fee.py +23 -0
  324. meteroid/models/slot_pricing.py +18 -0
  325. meteroid/models/slot_upgrade_policy_enum.py +14 -0
  326. meteroid/models/sub_line_item.py +22 -0
  327. meteroid/models/subscription.py +99 -0
  328. meteroid/models/subscription_activation_condition_enum.py +18 -0
  329. meteroid/models/subscription_add_on.py +30 -0
  330. meteroid/models/subscription_add_on_customization.py +20 -0
  331. meteroid/models/subscription_add_on_id.py +4 -0
  332. meteroid/models/subscription_add_on_parameterization.py +21 -0
  333. meteroid/models/subscription_add_on_price_override.py +19 -0
  334. meteroid/models/subscription_component.py +28 -0
  335. meteroid/models/subscription_coupon.py +36 -0
  336. meteroid/models/subscription_create_request.py +69 -0
  337. meteroid/models/subscription_details.py +112 -0
  338. meteroid/models/subscription_event.py +28 -0
  339. meteroid/models/subscription_event_data.py +74 -0
  340. meteroid/models/subscription_fee.py +34 -0
  341. meteroid/models/subscription_fee_billing_period_enum.py +20 -0
  342. meteroid/models/subscription_id.py +4 -0
  343. meteroid/models/subscription_list_response.py +20 -0
  344. meteroid/models/subscription_status_enum.py +38 -0
  345. meteroid/models/subscription_update_request.py +36 -0
  346. meteroid/models/subscription_update_response.py +17 -0
  347. meteroid/models/subscription_update_type.py +30 -0
  348. meteroid/models/tax_breakdown_item.py +32 -0
  349. meteroid/models/tax_exemption_type.py +20 -0
  350. meteroid/models/tenant_id.py +4 -0
  351. meteroid/models/term_rate.py +20 -0
  352. meteroid/models/text_config_value.py +13 -0
  353. meteroid/models/tier_row.py +20 -0
  354. meteroid/models/tiered_plan_pricing.py +19 -0
  355. meteroid/models/tiered_pricing.py +19 -0
  356. meteroid/models/token_introspection_response.py +25 -0
  357. meteroid/models/token_request.py +32 -0
  358. meteroid/models/token_response.py +21 -0
  359. meteroid/models/transaction.py +62 -0
  360. meteroid/models/trial_config.py +21 -0
  361. meteroid/models/unit_conversion.py +19 -0
  362. meteroid/models/unit_conversion_rounding_enum.py +21 -0
  363. meteroid/models/update_add_on_request.py +25 -0
  364. meteroid/models/update_coupon_request.py +22 -0
  365. meteroid/models/update_entitlement_request.py +17 -0
  366. meteroid/models/update_feature_request.py +16 -0
  367. meteroid/models/update_metric_request.py +28 -0
  368. meteroid/models/update_product_request.py +21 -0
  369. meteroid/models/usage_fee.py +20 -0
  370. meteroid/models/usage_fee_structure.py +20 -0
  371. meteroid/models/usage_model_enum.py +20 -0
  372. meteroid/models/usage_plan_fee.py +23 -0
  373. meteroid/models/usage_pricing.py +17 -0
  374. meteroid/models/usage_pricing_model.py +31 -0
  375. meteroid/models/usage_response.py +22 -0
  376. meteroid/models/volume_plan_pricing.py +19 -0
  377. meteroid/models/volume_pricing.py +19 -0
  378. meteroid/py.typed +0 -0
  379. meteroid/serialization.py +907 -0
  380. meteroid/unions.py +102 -0
  381. meteroid-0.27.0.dist-info/METADATA +148 -0
  382. meteroid-0.27.0.dist-info/RECORD +384 -0
  383. meteroid-0.27.0.dist-info/WHEEL +4 -0
  384. meteroid-0.27.0.dist-info/licenses/LICENSE +201 -0
meteroid/__init__.py ADDED
@@ -0,0 +1,56 @@
1
+ # ruff: noqa: I001 (the import order depends on the client name)
2
+ from ._version import __version__
3
+ from .api import (
4
+ APIResponse,
5
+ AsyncMeteroid,
6
+ AsyncPage,
7
+ AsyncPaginator,
8
+ AsyncStream,
9
+ Meteroid,
10
+ Stream,
11
+ SyncPage,
12
+ )
13
+ from .errors import (
14
+ MeteroidError,
15
+ APIConnectionError,
16
+ APIError,
17
+ APIResponseValidationError,
18
+ APIStatusError,
19
+ APITimeoutError,
20
+ AuthenticationError,
21
+ BadRequestError,
22
+ ConflictError,
23
+ InternalServerError,
24
+ ModelParseError,
25
+ NotFoundError,
26
+ PermissionDeniedError,
27
+ RateLimitError,
28
+ UnprocessableEntityError,
29
+ )
30
+
31
+ __all__ = [
32
+ "Meteroid",
33
+ "MeteroidError",
34
+ "APIConnectionError",
35
+ "APIError",
36
+ "APIResponse",
37
+ "APIResponseValidationError",
38
+ "APIStatusError",
39
+ "APITimeoutError",
40
+ "AsyncMeteroid",
41
+ "AsyncPage",
42
+ "AsyncPaginator",
43
+ "AsyncStream",
44
+ "AuthenticationError",
45
+ "BadRequestError",
46
+ "ConflictError",
47
+ "InternalServerError",
48
+ "ModelParseError",
49
+ "NotFoundError",
50
+ "PermissionDeniedError",
51
+ "RateLimitError",
52
+ "Stream",
53
+ "SyncPage",
54
+ "UnprocessableEntityError",
55
+ "__version__",
56
+ ]
@@ -0,0 +1,93 @@
1
+ # this file is @generated by Perseid; edit the shared runtime template.
2
+ """The errors of a request that got no usable response.
3
+
4
+ Errors carrying an HTTP status are in :mod:`meteroid.api`, as
5
+ :class:`~meteroid.api.APIStatusError` subclasses. Every error derives
6
+ from :class:`MeteroidError`.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import httpx
12
+
13
+ from .serialization import MeteroidError, ModelParseError
14
+
15
+ __all__ = [
16
+ "APIConnectionError",
17
+ "APIError",
18
+ "APIResponseValidationError",
19
+ "APITimeoutError",
20
+ "MeteroidError",
21
+ "ModelParseError",
22
+ ]
23
+
24
+
25
+ class APIError(MeteroidError):
26
+ """An error of a request to the API."""
27
+
28
+ message: str
29
+ request: httpx.Request | None
30
+ """The request that failed, when it was built."""
31
+
32
+ def __init__(self, message: str, request: httpx.Request | None) -> None:
33
+ super().__init__(message)
34
+ self.message = message
35
+ self.request = request
36
+
37
+
38
+ class APIConnectionError(APIError):
39
+ """The request got no response, after retries: connection failure, reset or timeout."""
40
+
41
+ def __init__(
42
+ self, request: httpx.Request | None, message: str = "Connection error."
43
+ ) -> None:
44
+ super().__init__(message, request)
45
+
46
+
47
+ class APITimeoutError(APIConnectionError):
48
+ """The request timed out, after retries."""
49
+
50
+ def __init__(self, request: httpx.Request | None) -> None:
51
+ super().__init__(request, "Request timed out.")
52
+
53
+
54
+ class APIResponseValidationError(APIError):
55
+ """A successful response was not valid JSON, or did not match its model."""
56
+
57
+ response: httpx.Response
58
+ status_code: int
59
+
60
+ def __init__(self, response: httpx.Response, reason: str) -> None:
61
+ super().__init__(
62
+ f"Could not decode response ({response.status_code}): {reason}",
63
+ request_of(response),
64
+ )
65
+ self.response = response
66
+ self.status_code = response.status_code
67
+
68
+ @property
69
+ def raw_body(self) -> bytes:
70
+ """The response body, empty when it was streamed."""
71
+ try:
72
+ return self.response.content
73
+ except httpx.ResponseNotRead:
74
+ return b""
75
+
76
+
77
+ def request_of(response: httpx.Response) -> httpx.Request | None:
78
+ """The request of a response, which a middleware may have built without one."""
79
+ try:
80
+ return response.request
81
+ except RuntimeError:
82
+ return None
83
+
84
+
85
+ def connection_error(error: httpx.RequestError) -> APIConnectionError:
86
+ """The SDK error for a transport error of ``httpx``."""
87
+ try:
88
+ request: httpx.Request | None = error.request
89
+ except RuntimeError:
90
+ request = None
91
+ if isinstance(error, httpx.TimeoutException):
92
+ return APITimeoutError(request)
93
+ return APIConnectionError(request, str(error) or "Connection error.")
meteroid/_version.py ADDED
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("meteroid")
5
+ except PackageNotFoundError:
6
+ __version__ = "0+uninstalled"
@@ -0,0 +1,188 @@
1
+ # this file is @generated
2
+ """Meteroid API resources."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import importlib
7
+ import typing as t
8
+
9
+ from .._exceptions import (
10
+ APIConnectionError,
11
+ APIError,
12
+ APIResponseValidationError,
13
+ APITimeoutError,
14
+ )
15
+ from ..serialization import MeteroidError
16
+ from ._errors import (
17
+ APIStatusError,
18
+ AuthenticationError,
19
+ BadRequestError,
20
+ ConflictError,
21
+ ErrorBody,
22
+ InternalServerError,
23
+ NotFoundError,
24
+ PermissionDeniedError,
25
+ RateLimitError,
26
+ UnprocessableEntityError,
27
+ )
28
+ from ._pagination import AsyncPage, AsyncPaginator, SyncPage
29
+ from ._response import APIResponse
30
+ from ._streaming import (
31
+ AsyncEventStream,
32
+ AsyncStream,
33
+ EventStream,
34
+ SseEvent,
35
+ Stream,
36
+ Upload,
37
+ )
38
+ from .client import AsyncMeteroid, Meteroid
39
+
40
+ if t.TYPE_CHECKING:
41
+ from .add_ons import AddOns, AsyncAddOns
42
+ from .batch_jobs import AsyncBatchJobs, BatchJobs
43
+ from .checkout_sessions import AsyncCheckoutSessions, CheckoutSessions
44
+ from .connect import AsyncConnect, Connect
45
+ from .coupons import AsyncCoupons, Coupons
46
+ from .credit_notes import AsyncCreditNotes, CreditNotes
47
+ from .custom_properties import AsyncCustomProperties, CustomProperties
48
+ from .customers import AsyncCustomers, Customers
49
+ from .entitlements import AsyncEntitlements, Entitlements
50
+ from .events import AsyncEvents, Events
51
+ from .features import AsyncFeatures, Features
52
+ from .invoices import AsyncInvoices, Invoices
53
+ from .metrics import AsyncMetrics, Metrics
54
+ from .oauth import AsyncOauth, Oauth
55
+ from .oauth_apps import AsyncOauthApps, OauthApps
56
+ from .plans import AsyncPlans, Plans
57
+ from .product_families import AsyncProductFamilies, ProductFamilies
58
+ from .products import AsyncProducts, Products
59
+ from .subscriptions import AsyncSubscriptions, Subscriptions
60
+ from .usage import AsyncUsage, Usage
61
+
62
+ # Each resource's module is imported the first time it is used.
63
+ _MODULES: dict[str, str] = {
64
+ "AsyncAddOns": "add_ons",
65
+ "AddOns": "add_ons",
66
+ "AsyncBatchJobs": "batch_jobs",
67
+ "BatchJobs": "batch_jobs",
68
+ "AsyncCheckoutSessions": "checkout_sessions",
69
+ "CheckoutSessions": "checkout_sessions",
70
+ "AsyncConnect": "connect",
71
+ "Connect": "connect",
72
+ "AsyncCoupons": "coupons",
73
+ "Coupons": "coupons",
74
+ "AsyncCreditNotes": "credit_notes",
75
+ "CreditNotes": "credit_notes",
76
+ "AsyncCustomProperties": "custom_properties",
77
+ "CustomProperties": "custom_properties",
78
+ "AsyncCustomers": "customers",
79
+ "Customers": "customers",
80
+ "AsyncEntitlements": "entitlements",
81
+ "Entitlements": "entitlements",
82
+ "AsyncEvents": "events",
83
+ "Events": "events",
84
+ "AsyncFeatures": "features",
85
+ "Features": "features",
86
+ "AsyncInvoices": "invoices",
87
+ "Invoices": "invoices",
88
+ "AsyncMetrics": "metrics",
89
+ "Metrics": "metrics",
90
+ "AsyncOauth": "oauth",
91
+ "Oauth": "oauth",
92
+ "AsyncOauthApps": "oauth_apps",
93
+ "OauthApps": "oauth_apps",
94
+ "AsyncPlans": "plans",
95
+ "Plans": "plans",
96
+ "AsyncProductFamilies": "product_families",
97
+ "ProductFamilies": "product_families",
98
+ "AsyncProducts": "products",
99
+ "Products": "products",
100
+ "AsyncSubscriptions": "subscriptions",
101
+ "Subscriptions": "subscriptions",
102
+ "AsyncUsage": "usage",
103
+ "Usage": "usage",
104
+ }
105
+
106
+
107
+ def __getattr__(name: str) -> t.Any:
108
+ module = _MODULES.get(name)
109
+ if module is None:
110
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
111
+ value = getattr(importlib.import_module(f".{module}", __name__), name)
112
+ globals()[name] = value
113
+ return value
114
+
115
+
116
+ def __dir__() -> list[str]:
117
+ return sorted({*globals(), *_MODULES})
118
+
119
+
120
+ __all__ = [
121
+ "APIConnectionError",
122
+ "APIError",
123
+ "APIResponse",
124
+ "APIResponseValidationError",
125
+ "APITimeoutError",
126
+ "AsyncMeteroid",
127
+ "AsyncEventStream",
128
+ "AsyncPage",
129
+ "AsyncPaginator",
130
+ "AsyncStream",
131
+ "EventStream",
132
+ "Meteroid",
133
+ "MeteroidError",
134
+ "SseEvent",
135
+ "Stream",
136
+ "SyncPage",
137
+ "Upload",
138
+ "APIStatusError",
139
+ "AuthenticationError",
140
+ "BadRequestError",
141
+ "ConflictError",
142
+ "ErrorBody",
143
+ "InternalServerError",
144
+ "NotFoundError",
145
+ "PermissionDeniedError",
146
+ "RateLimitError",
147
+ "UnprocessableEntityError",
148
+ "AsyncAddOns",
149
+ "AddOns",
150
+ "AsyncBatchJobs",
151
+ "BatchJobs",
152
+ "AsyncCheckoutSessions",
153
+ "CheckoutSessions",
154
+ "AsyncConnect",
155
+ "Connect",
156
+ "AsyncCoupons",
157
+ "Coupons",
158
+ "AsyncCreditNotes",
159
+ "CreditNotes",
160
+ "AsyncCustomProperties",
161
+ "CustomProperties",
162
+ "AsyncCustomers",
163
+ "Customers",
164
+ "AsyncEntitlements",
165
+ "Entitlements",
166
+ "AsyncEvents",
167
+ "Events",
168
+ "AsyncFeatures",
169
+ "Features",
170
+ "AsyncInvoices",
171
+ "Invoices",
172
+ "AsyncMetrics",
173
+ "Metrics",
174
+ "AsyncOauth",
175
+ "Oauth",
176
+ "AsyncOauthApps",
177
+ "OauthApps",
178
+ "AsyncPlans",
179
+ "Plans",
180
+ "AsyncProductFamilies",
181
+ "ProductFamilies",
182
+ "AsyncProducts",
183
+ "Products",
184
+ "AsyncSubscriptions",
185
+ "Subscriptions",
186
+ "AsyncUsage",
187
+ "Usage",
188
+ ]
meteroid/api/_auth.py ADDED
@@ -0,0 +1,231 @@
1
+ # this file is @generated by Perseid; edit the shared runtime template.
2
+ """Security schemes: bearer tokens, HTTP basic credentials and API keys."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import asyncio
7
+ import base64
8
+ import threading
9
+ import time
10
+ import typing as t
11
+ import urllib.parse
12
+
13
+ import httpx
14
+
15
+ __all__ = [
16
+ "OAuthTokens",
17
+ "Security",
18
+ "SecurityScheme",
19
+ "TokenProvider",
20
+ "apply_auth",
21
+ "async_token",
22
+ "chosen_schemes",
23
+ "needs_token_provider",
24
+ "oauth_scheme",
25
+ "sync_token",
26
+ "token_url",
27
+ ]
28
+
29
+ TokenProvider = t.Callable[[], str | t.Awaitable[str]]
30
+ """Returns a fresh bearer token; the async client also accepts coroutine functions."""
31
+
32
+ Security = t.Sequence[t.Sequence[str]]
33
+ """Alternatives of scheme names: the first one whose credentials are all configured is sent."""
34
+
35
+
36
+ class SecurityScheme(t.NamedTuple):
37
+ """How the API reads one kind of credentials."""
38
+
39
+ kind: str
40
+ """``bearer``, ``basic`` or ``api_key``."""
41
+ location: str = ""
42
+ param: str = ""
43
+ token_url: str = ""
44
+ """OAuth2 token endpoint of the client credentials flow, absolute or relative to the base URL."""
45
+ scope: str = ""
46
+ """Space-separated scopes asked for with the access token."""
47
+
48
+
49
+ _EXPIRY_MARGIN = 60.0
50
+ """Seconds before its expiry that an access token is renewed, or half its life when shorter."""
51
+
52
+ _COOKIE_OCTETS = "!#$%&'()*+-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
53
+ """Every RFC 6265 cookie-octet, so that an opaque API key is sent as is."""
54
+
55
+
56
+ class OAuthTokens:
57
+ """OAuth2 client credentials: an access token per token URL and scope, kept until it is about to expire.
58
+
59
+ The client fetches a token on first use with :attr:`client_id` and :attr:`client_secret`,
60
+ sending them in an HTTP basic header (``client_auth="basic"``) or as form fields (``"body"``).
61
+ The lock makes concurrent callers share one token request.
62
+ """
63
+
64
+ def __init__(
65
+ self, client_id: str, client_secret: str, client_auth: str = "basic"
66
+ ) -> None:
67
+ if client_auth not in ("basic", "body"):
68
+ raise ValueError("oauth_client_auth must be 'basic' or 'body'")
69
+ self.client_id = client_id
70
+ self.client_secret = client_secret
71
+ self.client_auth = client_auth
72
+ self.lock = threading.Lock()
73
+ self._async_lock: asyncio.Lock | None = None
74
+ self._tokens: dict[str, tuple[str, float]] = {}
75
+
76
+ def async_lock(self) -> asyncio.Lock:
77
+ if self._async_lock is None:
78
+ self._async_lock = asyncio.Lock()
79
+ return self._async_lock
80
+
81
+ def cached(self, url: str) -> str | None:
82
+ """The access token kept under ``url``, unless it is about to expire."""
83
+ entry = self._tokens.get(url)
84
+ return entry[0] if entry is not None and entry[1] > time.monotonic() else None
85
+
86
+ def store(self, url: str, token: str, expires_in: float | None) -> str:
87
+ """Keeps ``token``, which lives ``expires_in`` seconds, forever when ``None``."""
88
+ life = float("inf") if expires_in is None else max(expires_in, 0.0)
89
+ self._tokens[url] = (
90
+ token,
91
+ time.monotonic() + life - min(_EXPIRY_MARGIN, life / 2),
92
+ )
93
+ return token
94
+
95
+ def invalidate(self, url: str, token: str) -> None:
96
+ """Forgets ``token`` after the API rejected it, unless a newer one replaced it."""
97
+ entry = self._tokens.get(url)
98
+ if entry is not None and entry[0] == token:
99
+ del self._tokens[url]
100
+
101
+ def request_parts(self, scope: str) -> tuple[list[tuple[str, str]], dict[str, str]]:
102
+ """The form fields and headers of a token request."""
103
+ form = [("grant_type", "client_credentials")]
104
+ if scope:
105
+ form.append(("scope", scope))
106
+ if self.client_auth == "body":
107
+ form += [
108
+ ("client_id", self.client_id),
109
+ ("client_secret", self.client_secret),
110
+ ]
111
+ return form, {}
112
+ # RFC 6749 2.3.1: both are form-encoded before the base64.
113
+ raw = f"{urllib.parse.quote_plus(self.client_id)}:{urllib.parse.quote_plus(self.client_secret)}"
114
+ return form, {
115
+ "authorization": f"Basic {base64.b64encode(raw.encode()).decode()}"
116
+ }
117
+
118
+
119
+ def token_url(base_path: str, url: str) -> str:
120
+ """``url`` as an absolute URL: an absolute-path reference is resolved against the origin of
121
+ the base URL, any other relative one is joined under it."""
122
+ if "://" in url:
123
+ return url
124
+ if url.startswith("/"):
125
+ parts = urllib.parse.urlsplit(base_path)
126
+ return f"{parts.scheme}://{parts.netloc}{url}"
127
+ return f"{base_path}/{url}"
128
+
129
+
130
+ class _Credentials(t.Protocol):
131
+ bearer_access_token: str | None
132
+ token_provider: TokenProvider | None
133
+ basic_auth: tuple[str, str] | None
134
+ api_keys: t.Mapping[str, str]
135
+ security_schemes: t.Mapping[str, SecurityScheme]
136
+ oauth: OAuthTokens | None
137
+
138
+
139
+ def _configured(cfg: _Credentials, name: str) -> bool:
140
+ scheme = cfg.security_schemes.get(name)
141
+ if scheme is None:
142
+ return False
143
+ if scheme.kind == "bearer":
144
+ return (
145
+ cfg.token_provider is not None
146
+ or bool(cfg.bearer_access_token)
147
+ or (bool(scheme.token_url) and cfg.oauth is not None)
148
+ )
149
+ if scheme.kind == "basic":
150
+ return cfg.basic_auth is not None
151
+ return bool(cfg.api_keys.get(name) or cfg.bearer_access_token)
152
+
153
+
154
+ def chosen_schemes(cfg: _Credentials, security: Security) -> list[str]:
155
+ """The schemes of the first alternative of ``security`` whose credentials are all set."""
156
+ for names in security:
157
+ if names and all(_configured(cfg, name) for name in names):
158
+ return list(names)
159
+ return []
160
+
161
+
162
+ def needs_token_provider(cfg: _Credentials, names: t.Sequence[str]) -> bool:
163
+ """Whether the token provider must be called for the schemes ``names``."""
164
+ return cfg.token_provider is not None and any(
165
+ cfg.security_schemes[name].kind == "bearer" for name in names
166
+ )
167
+
168
+
169
+ def oauth_scheme(cfg: _Credentials, names: t.Sequence[str]) -> SecurityScheme | None:
170
+ """The OAuth2 scheme among ``names`` whose token the client fetches, when neither a token
171
+ provider nor a token is set."""
172
+ if cfg.oauth is None or cfg.token_provider is not None or cfg.bearer_access_token:
173
+ return None
174
+ for name in names:
175
+ scheme = cfg.security_schemes[name]
176
+ if scheme.kind == "bearer" and scheme.token_url:
177
+ return scheme
178
+ return None
179
+
180
+
181
+ def sync_token(cfg: _Credentials) -> str:
182
+ """A token from the provider, which must not be a coroutine function."""
183
+ assert cfg.token_provider is not None
184
+ token = cfg.token_provider()
185
+ if not isinstance(token, str):
186
+ raise TypeError("an async token_provider needs the async client")
187
+ return token
188
+
189
+
190
+ async def async_token(cfg: _Credentials) -> str:
191
+ """A token from the provider, awaited when it returns an awaitable."""
192
+ assert cfg.token_provider is not None
193
+ token = cfg.token_provider()
194
+ return token if isinstance(token, str) else await token
195
+
196
+
197
+ def apply_auth(
198
+ cfg: _Credentials,
199
+ names: t.Sequence[str],
200
+ provided_token: str | None,
201
+ headers: httpx.Headers,
202
+ params: list[tuple[str, str]],
203
+ ) -> None:
204
+ """Sets the credentials of the schemes ``names`` on a request's headers and query."""
205
+ for name in names:
206
+ scheme = cfg.security_schemes[name]
207
+ if scheme.kind == "bearer":
208
+ token = (
209
+ provided_token
210
+ if provided_token is not None
211
+ else cfg.bearer_access_token
212
+ )
213
+ headers["authorization"] = f"Bearer {token}"
214
+ elif scheme.kind == "basic":
215
+ assert cfg.basic_auth is not None
216
+ raw = ":".join(cfg.basic_auth).encode()
217
+ headers["authorization"] = f"Basic {base64.b64encode(raw).decode()}"
218
+ else:
219
+ key = cfg.api_keys.get(name) or cfg.bearer_access_token or ""
220
+ if scheme.location == "query":
221
+ params.append((scheme.param, key))
222
+ elif scheme.location == "cookie":
223
+ cookie = (
224
+ f"{scheme.param}={urllib.parse.quote(key, safe=_COOKIE_OCTETS)}"
225
+ )
226
+ previous = headers.get("cookie")
227
+ headers["cookie"] = (
228
+ cookie if previous is None else f"{previous}; {cookie}"
229
+ )
230
+ else:
231
+ headers[scheme.param.lower()] = key
@@ -0,0 +1,125 @@
1
+ # this file is @generated
2
+ """API errors by status, carrying the decoded error body."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import typing as t
7
+
8
+ import httpx
9
+
10
+ from .. import models as _models
11
+ from .._exceptions import APIError, request_of
12
+ from ..serialization import JSONValue
13
+ from ._response import request_id
14
+
15
+ __all__ = [
16
+ "APIStatusError",
17
+ "AuthenticationError",
18
+ "BadRequestError",
19
+ "ConflictError",
20
+ "ErrorBody",
21
+ "InternalServerError",
22
+ "NotFoundError",
23
+ "PermissionDeniedError",
24
+ "RateLimitError",
25
+ "UnprocessableEntityError",
26
+ "error_class",
27
+ ]
28
+
29
+ _MAX_DETAIL = 500
30
+
31
+ ErrorBody: t.TypeAlias = _models.OAuthErrorResponse | _models.RestErrorResponse
32
+ """The error responses the API declares."""
33
+
34
+
35
+ class APIStatusError(APIError):
36
+ """The API answered with a non-2xx status. Subclasses tell the common ones apart."""
37
+
38
+ response: httpx.Response
39
+ status_code: int
40
+ body: ErrorBody | JSONValue
41
+ """The error response decoded into the schema the operation declares for its
42
+ status; its JSON when it declares none or it does not match; else `None`."""
43
+
44
+ def __init__(self, response: httpx.Response, body: object) -> None:
45
+ detail = _body_text(response) or response.reason_phrase or "error"
46
+ super().__init__(
47
+ f"Error code: {response.status_code} - {detail}", request_of(response)
48
+ )
49
+ self.response = response
50
+ self.status_code = response.status_code
51
+ self.body = t.cast("ErrorBody | JSONValue", body)
52
+
53
+ @property
54
+ def headers(self) -> httpx.Headers:
55
+ """The response headers."""
56
+ return self.response.headers
57
+
58
+ @property
59
+ def request_id(self) -> str | None:
60
+ """The request id to quote to support, when the API sends one."""
61
+ return request_id(self.response.headers)
62
+
63
+ @property
64
+ def raw_body(self) -> bytes:
65
+ """The response body."""
66
+ return self.response.content
67
+
68
+
69
+ def _body_text(response: httpx.Response) -> str:
70
+ """The start of the response body, for the error message."""
71
+ try:
72
+ text = response.text.strip()
73
+ except httpx.ResponseNotRead:
74
+ return ""
75
+ return text if len(text) <= _MAX_DETAIL else f"{text[:_MAX_DETAIL]}..."
76
+
77
+
78
+ class BadRequestError(APIStatusError):
79
+ """400 Bad Request."""
80
+
81
+
82
+ class AuthenticationError(APIStatusError):
83
+ """401 Unauthorized."""
84
+
85
+
86
+ class PermissionDeniedError(APIStatusError):
87
+ """403 Forbidden."""
88
+
89
+
90
+ class NotFoundError(APIStatusError):
91
+ """404 Not Found."""
92
+
93
+
94
+ class ConflictError(APIStatusError):
95
+ """409 Conflict."""
96
+
97
+
98
+ class UnprocessableEntityError(APIStatusError):
99
+ """422 Unprocessable Entity."""
100
+
101
+
102
+ class RateLimitError(APIStatusError):
103
+ """429 Too Many Requests, once retries are exhausted."""
104
+
105
+
106
+ class InternalServerError(APIStatusError):
107
+ """Any 5xx status, once retries are exhausted."""
108
+
109
+
110
+ _BY_STATUS: dict[int, type[APIStatusError]] = {
111
+ 400: BadRequestError,
112
+ 401: AuthenticationError,
113
+ 403: PermissionDeniedError,
114
+ 404: NotFoundError,
115
+ 409: ConflictError,
116
+ 422: UnprocessableEntityError,
117
+ 429: RateLimitError,
118
+ }
119
+
120
+
121
+ def error_class(status_code: int) -> type[APIStatusError]:
122
+ """The error raised for a response with this status."""
123
+ if status_code >= 500:
124
+ return InternalServerError
125
+ return _BY_STATUS.get(status_code, APIStatusError)