payi 0.1.0a26__tar.gz → 0.1.0a28__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.

Potentially problematic release.


This version of payi might be problematic. Click here for more details.

Files changed (147) hide show
  1. payi-0.1.0a28/.release-please-manifest.json +3 -0
  2. {payi-0.1.0a26 → payi-0.1.0a28}/CHANGELOG.md +24 -0
  3. {payi-0.1.0a26 → payi-0.1.0a28}/CONTRIBUTING.md +24 -20
  4. {payi-0.1.0a26 → payi-0.1.0a28}/PKG-INFO +11 -11
  5. {payi-0.1.0a26 → payi-0.1.0a28}/README.md +8 -6
  6. {payi-0.1.0a26 → payi-0.1.0a28}/api.md +30 -6
  7. {payi-0.1.0a26 → payi-0.1.0a28}/pyproject.toml +5 -10
  8. {payi-0.1.0a26 → payi-0.1.0a28}/requirements-dev.lock +11 -14
  9. {payi-0.1.0a26 → payi-0.1.0a28}/requirements.lock +4 -4
  10. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_base_client.py +9 -2
  11. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_client.py +16 -0
  12. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_compat.py +5 -3
  13. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_models.py +11 -8
  14. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_response.py +3 -0
  15. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_types.py +4 -2
  16. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/__init__.py +1 -0
  17. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_transform.py +12 -2
  18. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_utils.py +17 -0
  19. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_version.py +1 -1
  20. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/__init__.py +28 -0
  21. payi-0.1.0a28/src/payi/resources/billing_models.py +492 -0
  22. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/budgets/budgets.py +4 -4
  23. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/categories/resources.py +5 -9
  24. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/ingest.py +19 -10
  25. payi-0.1.0a28/src/payi/resources/price_modifiers.py +353 -0
  26. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/__init__.py +8 -0
  27. payi-0.1.0a28/src/payi/types/billing_model.py +29 -0
  28. payi-0.1.0a28/src/payi/types/billing_model_create_params.py +20 -0
  29. payi-0.1.0a28/src/payi/types/billing_model_list_response.py +10 -0
  30. payi-0.1.0a28/src/payi/types/billing_model_update_params.py +20 -0
  31. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budget_create_params.py +2 -2
  32. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budget_response.py +2 -2
  33. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/categories/resource_create_params.py +9 -5
  34. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_resource_response.py +9 -5
  35. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/cost_data.py +0 -1
  36. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/csat.py +0 -1
  37. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experience_instance.py +0 -1
  38. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/experience_type.py +0 -1
  39. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/ingest_event_param.py +12 -6
  40. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/ingest_response.py +7 -1
  41. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/ingest_units_params.py +11 -6
  42. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/paged_budget_list.py +2 -2
  43. payi-0.1.0a28/src/payi/types/price_modifier.py +26 -0
  44. payi-0.1.0a28/src/payi/types/price_modifier_create_params.py +17 -0
  45. payi-0.1.0a28/src/payi/types/price_modifier_retrieve_response.py +10 -0
  46. payi-0.1.0a28/src/payi/types/price_modifier_update_params.py +17 -0
  47. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/requests_data.py +2 -1
  48. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/total_cost_data.py +0 -1
  49. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/categories/test_resources.py +72 -4
  50. payi-0.1.0a28/tests/api_resources/test_billing_models.py +422 -0
  51. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/test_budgets.py +2 -2
  52. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/test_ingest.py +38 -52
  53. payi-0.1.0a28/tests/api_resources/test_price_modifiers.py +261 -0
  54. {payi-0.1.0a26 → payi-0.1.0a28}/tests/conftest.py +8 -6
  55. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_client.py +21 -2
  56. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_models.py +8 -15
  57. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_response.py +50 -0
  58. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_transform.py +15 -0
  59. payi-0.1.0a26/.release-please-manifest.json +0 -3
  60. payi-0.1.0a26/src/payi/types/evaluations/__init__.py +0 -6
  61. payi-0.1.0a26/src/payi/types/evaluations/experience_create_params.py +0 -14
  62. payi-0.1.0a26/src/payi/types/evaluations/request_create_params.py +0 -14
  63. payi-0.1.0a26/src/payi/types/shared/__init__.py +0 -2
  64. payi-0.1.0a26/tests/api_resources/experiences/__init__.py +0 -1
  65. {payi-0.1.0a26 → payi-0.1.0a28}/.gitignore +0 -0
  66. {payi-0.1.0a26 → payi-0.1.0a28}/LICENSE +0 -0
  67. {payi-0.1.0a26 → payi-0.1.0a28}/SECURITY.md +0 -0
  68. {payi-0.1.0a26 → payi-0.1.0a28}/bin/check-release-environment +0 -0
  69. {payi-0.1.0a26 → payi-0.1.0a28}/bin/publish-pypi +0 -0
  70. {payi-0.1.0a26 → payi-0.1.0a28}/examples/.keep +0 -0
  71. {payi-0.1.0a26 → payi-0.1.0a28}/mypy.ini +0 -0
  72. {payi-0.1.0a26 → payi-0.1.0a28}/noxfile.py +0 -0
  73. {payi-0.1.0a26 → payi-0.1.0a28}/release-please-config.json +0 -0
  74. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/__init__.py +0 -0
  75. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_constants.py +0 -0
  76. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_exceptions.py +0 -0
  77. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_files.py +0 -0
  78. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_qs.py +0 -0
  79. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_resource.py +0 -0
  80. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_streaming.py +0 -0
  81. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_logs.py +0 -0
  82. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_proxy.py +0 -0
  83. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_reflection.py +0 -0
  84. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_streams.py +0 -0
  85. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_sync.py +0 -0
  86. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/_utils/_typing.py +0 -0
  87. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/lib/.keep +0 -0
  88. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/lib/helpers.py +0 -0
  89. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/py.typed +0 -0
  90. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/budgets/__init__.py +0 -0
  91. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/budgets/tags.py +0 -0
  92. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/categories/__init__.py +0 -0
  93. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/categories/categories.py +0 -0
  94. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/csat.py +0 -0
  95. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/experiences/__init__.py +0 -0
  96. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/experiences/experiences.py +0 -0
  97. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/resources/experiences/types.py +0 -0
  98. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budget_history_response.py +0 -0
  99. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budget_list_params.py +0 -0
  100. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budget_update_params.py +0 -0
  101. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/__init__.py +0 -0
  102. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/budget_tags.py +0 -0
  103. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_create_params.py +0 -0
  104. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_create_response.py +0 -0
  105. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_delete_response.py +0 -0
  106. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_list_response.py +0 -0
  107. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_remove_params.py +0 -0
  108. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_remove_response.py +0 -0
  109. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_update_params.py +0 -0
  110. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/budgets/tag_update_response.py +0 -0
  111. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/bulk_ingest_response.py +0 -0
  112. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/categories/__init__.py +0 -0
  113. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/categories/resource_list_response.py +0 -0
  114. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_delete_resource_response.py +0 -0
  115. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_delete_response.py +0 -0
  116. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_list_resources_response.py +0 -0
  117. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_list_response.py +0 -0
  118. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/category_response.py +0 -0
  119. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/cost_details.py +0 -0
  120. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/csat_create_params.py +0 -0
  121. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/default_response.py +0 -0
  122. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/__init__.py +0 -0
  123. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/type_create_params.py +0 -0
  124. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/type_list_params.py +0 -0
  125. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/type_list_response.py +0 -0
  126. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/experiences/type_update_params.py +0 -0
  127. {payi-0.1.0a26 → payi-0.1.0a28}/src/payi/types/ingest_bulk_params.py +0 -0
  128. {payi-0.1.0a26 → payi-0.1.0a28}/tests/__init__.py +0 -0
  129. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/__init__.py +0 -0
  130. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/budgets/__init__.py +0 -0
  131. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/budgets/test_tags.py +0 -0
  132. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/categories/__init__.py +0 -0
  133. {payi-0.1.0a26/tests/api_resources/evaluations → payi-0.1.0a28/tests/api_resources/experiences}/__init__.py +0 -0
  134. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/experiences/test_types.py +0 -0
  135. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/test_categories.py +0 -0
  136. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/test_csat.py +0 -0
  137. {payi-0.1.0a26 → payi-0.1.0a28}/tests/api_resources/test_experiences.py +0 -0
  138. {payi-0.1.0a26 → payi-0.1.0a28}/tests/sample_file.txt +0 -0
  139. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_deepcopy.py +0 -0
  140. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_extract_files.py +0 -0
  141. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_files.py +0 -0
  142. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_qs.py +0 -0
  143. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_required_args.py +0 -0
  144. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_streaming.py +0 -0
  145. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_utils/test_proxy.py +0 -0
  146. {payi-0.1.0a26 → payi-0.1.0a28}/tests/test_utils/test_typing.py +0 -0
  147. {payi-0.1.0a26 → payi-0.1.0a28}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.28"
3
+ }
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.28 (2024-11-15)
4
+
5
+ Full Changelog: [v0.1.0-alpha.27...v0.1.0-alpha.28](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.27...v0.1.0-alpha.28)
6
+
7
+ ### Features
8
+
9
+ * **api:** api update ([#127](https://github.com/Pay-i/pay-i-python/issues/127)) ([f9f8665](https://github.com/Pay-i/pay-i-python/commit/f9f8665278eec1f3b4d081076047460004230a97))
10
+
11
+
12
+ ### Chores
13
+
14
+ * rebuild project due to codegen change ([#128](https://github.com/Pay-i/pay-i-python/issues/128)) ([31ab0f5](https://github.com/Pay-i/pay-i-python/commit/31ab0f57ca4d1c073c7d1996af9df94db792cf9f))
15
+ * rebuild project due to codegen change ([#130](https://github.com/Pay-i/pay-i-python/issues/130)) ([e98d9ce](https://github.com/Pay-i/pay-i-python/commit/e98d9cead371ef5e3e9f3b68116dc81975fbd471))
16
+ * rebuild project due to codegen change ([#131](https://github.com/Pay-i/pay-i-python/issues/131)) ([e197c4b](https://github.com/Pay-i/pay-i-python/commit/e197c4b0199f417b550ee4c852ffcaef4888c82c))
17
+
18
+ ## 0.1.0-alpha.27 (2024-10-22)
19
+
20
+ Full Changelog: [v0.1.0-alpha.26...v0.1.0-alpha.27](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.26...v0.1.0-alpha.27)
21
+
22
+ ### Features
23
+
24
+ * **api:** api update ([#121](https://github.com/Pay-i/pay-i-python/issues/121)) ([5d4aa28](https://github.com/Pay-i/pay-i-python/commit/5d4aa28bde2fa653fb5c99081758d8c06de572ea))
25
+ * **api:** api update ([#125](https://github.com/Pay-i/pay-i-python/issues/125)) ([64e1ac8](https://github.com/Pay-i/pay-i-python/commit/64e1ac8e641917f23998c95fc9ce717484dc826f))
26
+
3
27
  ## 0.1.0-alpha.26 (2024-10-01)
4
28
 
5
29
  Full Changelog: [v0.1.0-alpha.25...v0.1.0-alpha.26](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.25...v0.1.0-alpha.26)
@@ -2,9 +2,13 @@
2
2
 
3
3
  ### With Rye
4
4
 
5
- We use [Rye](https://rye.astral.sh/) to manage dependencies so we highly recommend [installing it](https://rye.astral.sh/guide/installation/) as it will automatically provision a Python environment with the expected Python version.
5
+ We use [Rye](https://rye.astral.sh/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run:
6
6
 
7
- After installing Rye, you'll just have to run this command:
7
+ ```sh
8
+ $ ./scripts/bootstrap
9
+ ```
10
+
11
+ Or [install Rye manually](https://rye.astral.sh/guide/installation/) and run:
8
12
 
9
13
  ```sh
10
14
  $ rye sync --all-features
@@ -39,17 +43,17 @@ modify the contents of the `src/payi/lib/` and `examples/` directories.
39
43
 
40
44
  All files in the `examples/` directory are not modified by the generator and can be freely edited or added to.
41
45
 
42
- ```bash
46
+ ```py
43
47
  # add an example to examples/<your-example>.py
44
48
 
45
49
  #!/usr/bin/env -S rye run python
46
50
 
47
51
  ```
48
52
 
49
- ```
50
- chmod +x examples/<your-example>.py
53
+ ```sh
54
+ $ chmod +x examples/<your-example>.py
51
55
  # run the example against your api
52
- ./examples/<your-example>.py
56
+ $ ./examples/<your-example>.py
53
57
  ```
54
58
 
55
59
  ## Using the repository from source
@@ -58,8 +62,8 @@ If you’d like to use the repository from source, you can either install from g
58
62
 
59
63
  To install via git:
60
64
 
61
- ```bash
62
- pip install git+ssh://git@github.com/Pay-i/pay-i-python.git
65
+ ```sh
66
+ $ pip install git+ssh://git@github.com/Pay-i/pay-i-python.git
63
67
  ```
64
68
 
65
69
  Alternatively, you can build from source and install the wheel file:
@@ -68,29 +72,29 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz
68
72
 
69
73
  To create a distributable version of the library, all you have to do is run this command:
70
74
 
71
- ```bash
72
- rye build
75
+ ```sh
76
+ $ rye build
73
77
  # or
74
- python -m build
78
+ $ python -m build
75
79
  ```
76
80
 
77
81
  Then to install:
78
82
 
79
83
  ```sh
80
- pip install ./path-to-wheel-file.whl
84
+ $ pip install ./path-to-wheel-file.whl
81
85
  ```
82
86
 
83
87
  ## Running tests
84
88
 
85
89
  Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
86
90
 
87
- ```bash
91
+ ```sh
88
92
  # you will need npm installed
89
- npx prism mock path/to/your/openapi.yml
93
+ $ npx prism mock path/to/your/openapi.yml
90
94
  ```
91
95
 
92
- ```bash
93
- rye run pytest
96
+ ```sh
97
+ $ ./scripts/test
94
98
  ```
95
99
 
96
100
  ## Linting and formatting
@@ -100,14 +104,14 @@ This repository uses [ruff](https://github.com/astral-sh/ruff) and
100
104
 
101
105
  To lint:
102
106
 
103
- ```bash
104
- rye run lint
107
+ ```sh
108
+ $ ./scripts/lint
105
109
  ```
106
110
 
107
111
  To format and fix all ruff issues automatically:
108
112
 
109
- ```bash
110
- rye run format
113
+ ```sh
114
+ $ ./scripts/format
111
115
  ```
112
116
 
113
117
  ## Publishing and releases
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: payi
3
- Version: 0.1.0a26
3
+ Version: 0.1.0a28
4
4
  Summary: The official Python library for the payi API
5
5
  Project-URL: Homepage, https://github.com/Pay-i/pay-i-python
6
6
  Project-URL: Repository, https://github.com/Pay-i/pay-i-python
7
7
  Author-email: Payi <support@payi.com>
8
- License-Expression: Apache-2.0
9
- License-File: LICENSE
8
+ License: Apache-2.0
10
9
  Classifier: Intended Audience :: Developers
11
10
  Classifier: License :: OSI Approved :: Apache Software License
12
11
  Classifier: Operating System :: MacOS
@@ -14,7 +13,6 @@ Classifier: Operating System :: Microsoft :: Windows
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Operating System :: POSIX
16
15
  Classifier: Operating System :: POSIX :: Linux
17
- Classifier: Programming Language :: Python :: 3.7
18
16
  Classifier: Programming Language :: Python :: 3.8
19
17
  Classifier: Programming Language :: Python :: 3.9
20
18
  Classifier: Programming Language :: Python :: 3.10
@@ -22,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.11
22
20
  Classifier: Programming Language :: Python :: 3.12
23
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
22
  Classifier: Typing :: Typed
25
- Requires-Python: >=3.7
23
+ Requires-Python: >=3.8
26
24
  Requires-Dist: anyio<5,>=3.5.0
27
25
  Requires-Dist: cached-property; python_version < '3.8'
28
26
  Requires-Dist: distro<2,>=1.7.0
@@ -36,7 +34,7 @@ Description-Content-Type: text/markdown
36
34
 
37
35
  [![PyPI version](https://img.shields.io/pypi/v/payi.svg)](https://pypi.org/project/payi/)
38
36
 
39
- The Payi Python library provides convenient access to the Payi REST API from any Python 3.7+
37
+ The Payi Python library provides convenient access to the Payi REST API from any Python 3.8+
40
38
  application. The library includes type definitions for all request params and response fields,
41
39
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
42
40
 
@@ -62,8 +60,7 @@ import os
62
60
  from payi import Payi
63
61
 
64
62
  client = Payi(
65
- # This is the default and can be omitted
66
- api_key=os.environ.get("PAYI_API_KEY"),
63
+ api_key=os.environ.get("PAYI_API_KEY"), # This is the default and can be omitted
67
64
  )
68
65
 
69
66
  budget_response = client.budgets.create(
@@ -88,8 +85,7 @@ import asyncio
88
85
  from payi import AsyncPayi
89
86
 
90
87
  client = AsyncPayi(
91
- # This is the default and can be omitted
92
- api_key=os.environ.get("PAYI_API_KEY"),
88
+ api_key=os.environ.get("PAYI_API_KEY"), # This is the default and can be omitted
93
89
  )
94
90
 
95
91
 
@@ -369,4 +365,8 @@ print(payi.__version__)
369
365
 
370
366
  ## Requirements
371
367
 
372
- Python 3.7 or higher.
368
+ Python 3.8 or higher.
369
+
370
+ ## Contributing
371
+
372
+ See [the contributing documentation](https://github.com/Pay-i/pay-i-python/tree/main/./CONTRIBUTING.md).
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![PyPI version](https://img.shields.io/pypi/v/payi.svg)](https://pypi.org/project/payi/)
4
4
 
5
- The Payi Python library provides convenient access to the Payi REST API from any Python 3.7+
5
+ The Payi Python library provides convenient access to the Payi REST API from any Python 3.8+
6
6
  application. The library includes type definitions for all request params and response fields,
7
7
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
8
8
 
@@ -28,8 +28,7 @@ import os
28
28
  from payi import Payi
29
29
 
30
30
  client = Payi(
31
- # This is the default and can be omitted
32
- api_key=os.environ.get("PAYI_API_KEY"),
31
+ api_key=os.environ.get("PAYI_API_KEY"), # This is the default and can be omitted
33
32
  )
34
33
 
35
34
  budget_response = client.budgets.create(
@@ -54,8 +53,7 @@ import asyncio
54
53
  from payi import AsyncPayi
55
54
 
56
55
  client = AsyncPayi(
57
- # This is the default and can be omitted
58
- api_key=os.environ.get("PAYI_API_KEY"),
56
+ api_key=os.environ.get("PAYI_API_KEY"), # This is the default and can be omitted
59
57
  )
60
58
 
61
59
 
@@ -335,4 +333,8 @@ print(payi.__version__)
335
333
 
336
334
  ## Requirements
337
335
 
338
- Python 3.7 or higher.
336
+ Python 3.8 or higher.
337
+
338
+ ## Contributing
339
+
340
+ See [the contributing documentation](./CONTRIBUTING.md).
@@ -1,9 +1,3 @@
1
- # Shared Types
2
-
3
- ```python
4
- from payi.types import EvaluationResponse
5
- ```
6
-
7
1
  # Budgets
8
2
 
9
3
  Types:
@@ -144,3 +138,33 @@ from payi.types import Csat
144
138
  Methods:
145
139
 
146
140
  - <code title="post /api/v1/csat/experiences/{experience_id}">client.csat.<a href="./src/payi/resources/csat.py">create</a>(experience_id, \*\*<a href="src/payi/types/csat_create_params.py">params</a>) -> <a href="./src/payi/types/csat.py">Csat</a></code>
141
+
142
+ # BillingModels
143
+
144
+ Types:
145
+
146
+ ```python
147
+ from payi.types import BillingModel, BillingModelListResponse
148
+ ```
149
+
150
+ Methods:
151
+
152
+ - <code title="post /api/v1/billing-model">client.billing_models.<a href="./src/payi/resources/billing_models.py">create</a>(\*\*<a href="src/payi/types/billing_model_create_params.py">params</a>) -> <a href="./src/payi/types/billing_model.py">BillingModel</a></code>
153
+ - <code title="get /api/v1/billing-model/{billing_model_id}">client.billing_models.<a href="./src/payi/resources/billing_models.py">retrieve</a>(billing_model_id) -> <a href="./src/payi/types/billing_model.py">BillingModel</a></code>
154
+ - <code title="put /api/v1/billing-model/{billing_model_id}">client.billing_models.<a href="./src/payi/resources/billing_models.py">update</a>(billing_model_id, \*\*<a href="src/payi/types/billing_model_update_params.py">params</a>) -> <a href="./src/payi/types/billing_model.py">BillingModel</a></code>
155
+ - <code title="get /api/v1/billing-model">client.billing_models.<a href="./src/payi/resources/billing_models.py">list</a>() -> <a href="./src/payi/types/billing_model_list_response.py">BillingModelListResponse</a></code>
156
+ - <code title="put /api/v1/billing-model/{billing_model_id}/default">client.billing_models.<a href="./src/payi/resources/billing_models.py">set_default</a>(billing_model_id) -> <a href="./src/payi/types/billing_model.py">BillingModel</a></code>
157
+
158
+ # PriceModifiers
159
+
160
+ Types:
161
+
162
+ ```python
163
+ from payi.types import PriceModifier, PriceModifierRetrieveResponse
164
+ ```
165
+
166
+ Methods:
167
+
168
+ - <code title="post /api/v1/price-modifier">client.price_modifiers.<a href="./src/payi/resources/price_modifiers.py">create</a>(\*\*<a href="src/payi/types/price_modifier_create_params.py">params</a>) -> <a href="./src/payi/types/price_modifier.py">PriceModifier</a></code>
169
+ - <code title="get /api/v1/price-modifier/{billing_model_id}">client.price_modifiers.<a href="./src/payi/resources/price_modifiers.py">retrieve</a>(billing_model_id) -> <a href="./src/payi/types/price_modifier_retrieve_response.py">PriceModifierRetrieveResponse</a></code>
170
+ - <code title="put /api/v1/price-modifier">client.price_modifiers.<a href="./src/payi/resources/price_modifiers.py">update</a>(\*\*<a href="src/payi/types/price_modifier_update_params.py">params</a>) -> <a href="./src/payi/types/price_modifier.py">PriceModifier</a></code>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "payi"
3
- version = "0.1.0-alpha.26"
3
+ version = "0.1.0-alpha.28"
4
4
  description = "The official Python library for the payi API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -16,11 +16,10 @@ dependencies = [
16
16
  "sniffio",
17
17
  "cached-property; python_version < '3.8'",
18
18
  ]
19
- requires-python = ">= 3.7"
19
+ requires-python = ">= 3.8"
20
20
  classifiers = [
21
21
  "Typing :: Typed",
22
22
  "Intended Audience :: Developers",
23
- "Programming Language :: Python :: 3.7",
24
23
  "Programming Language :: Python :: 3.8",
25
24
  "Programming Language :: Python :: 3.9",
26
25
  "Programming Language :: Python :: 3.10",
@@ -63,11 +62,11 @@ format = { chain = [
63
62
  "format:ruff",
64
63
  "format:docs",
65
64
  "fix:ruff",
65
+ # run formatting again to fix any inconsistencies when imports are stripped
66
+ "format:ruff",
66
67
  ]}
67
- "format:black" = "black ."
68
68
  "format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md"
69
69
  "format:ruff" = "ruff format"
70
- "format:isort" = "isort ."
71
70
 
72
71
  "lint" = { chain = [
73
72
  "check:ruff",
@@ -125,10 +124,6 @@ path = "README.md"
125
124
  pattern = '\[(.+?)\]\(((?!https?://)\S+?)\)'
126
125
  replacement = '[\1](https://github.com/Pay-i/pay-i-python/tree/main/\g<2>)'
127
126
 
128
- [tool.black]
129
- line-length = 120
130
- target-version = ["py37"]
131
-
132
127
  [tool.pytest.ini_options]
133
128
  testpaths = ["tests"]
134
129
  addopts = "--tb=short"
@@ -143,7 +138,7 @@ filterwarnings = [
143
138
  # there are a couple of flags that are still disabled by
144
139
  # default in strict mode as they are experimental and niche.
145
140
  typeCheckingMode = "strict"
146
- pythonVersion = "3.7"
141
+ pythonVersion = "3.8"
147
142
 
148
143
  exclude = [
149
144
  "_dev",
@@ -16,8 +16,6 @@ anyio==4.4.0
16
16
  # via payi
17
17
  argcomplete==3.1.2
18
18
  # via nox
19
- attrs==23.1.0
20
- # via pytest
21
19
  certifi==2023.7.22
22
20
  # via httpcore
23
21
  # via httpx
@@ -28,8 +26,9 @@ distlib==0.3.7
28
26
  # via virtualenv
29
27
  distro==1.8.0
30
28
  # via payi
31
- exceptiongroup==1.1.3
29
+ exceptiongroup==1.2.2
32
30
  # via anyio
31
+ # via pytest
33
32
  filelock==3.12.4
34
33
  # via virtualenv
35
34
  h11==0.14.0
@@ -49,7 +48,7 @@ markdown-it-py==3.0.0
49
48
  # via rich
50
49
  mdurl==0.1.2
51
50
  # via markdown-it-py
52
- mypy==1.11.2
51
+ mypy==1.13.0
53
52
  mypy-extensions==1.0.0
54
53
  # via mypy
55
54
  nodeenv==1.8.0
@@ -60,27 +59,25 @@ packaging==23.2
60
59
  # via pytest
61
60
  platformdirs==3.11.0
62
61
  # via virtualenv
63
- pluggy==1.3.0
64
- # via pytest
65
- py==1.11.0
62
+ pluggy==1.5.0
66
63
  # via pytest
67
- pydantic==2.7.1
64
+ pydantic==2.9.2
68
65
  # via payi
69
- pydantic-core==2.18.2
66
+ pydantic-core==2.23.4
70
67
  # via pydantic
71
68
  pygments==2.18.0
72
69
  # via rich
73
70
  pyright==1.1.380
74
- pytest==7.1.1
71
+ pytest==8.3.3
75
72
  # via pytest-asyncio
76
- pytest-asyncio==0.21.1
73
+ pytest-asyncio==0.24.0
77
74
  python-dateutil==2.8.2
78
75
  # via time-machine
79
76
  pytz==2023.3.post1
80
77
  # via dirty-equals
81
78
  respx==0.20.2
82
79
  rich==13.7.1
83
- ruff==0.6.5
80
+ ruff==0.6.9
84
81
  setuptools==68.2.2
85
82
  # via nodeenv
86
83
  six==1.16.0
@@ -90,10 +87,10 @@ sniffio==1.3.0
90
87
  # via httpx
91
88
  # via payi
92
89
  time-machine==2.9.0
93
- tomli==2.0.1
90
+ tomli==2.0.2
94
91
  # via mypy
95
92
  # via pytest
96
- typing-extensions==4.8.0
93
+ typing-extensions==4.12.2
97
94
  # via anyio
98
95
  # via mypy
99
96
  # via payi
@@ -19,7 +19,7 @@ certifi==2023.7.22
19
19
  # via httpx
20
20
  distro==1.8.0
21
21
  # via payi
22
- exceptiongroup==1.1.3
22
+ exceptiongroup==1.2.2
23
23
  # via anyio
24
24
  h11==0.14.0
25
25
  # via httpcore
@@ -30,15 +30,15 @@ httpx==0.25.2
30
30
  idna==3.4
31
31
  # via anyio
32
32
  # via httpx
33
- pydantic==2.7.1
33
+ pydantic==2.9.2
34
34
  # via payi
35
- pydantic-core==2.18.2
35
+ pydantic-core==2.23.4
36
36
  # via pydantic
37
37
  sniffio==1.3.0
38
38
  # via anyio
39
39
  # via httpx
40
40
  # via payi
41
- typing-extensions==4.8.0
41
+ typing-extensions==4.12.2
42
42
  # via anyio
43
43
  # via payi
44
44
  # via pydantic
@@ -143,6 +143,12 @@ class PageInfo:
143
143
  self.url = url
144
144
  self.params = params
145
145
 
146
+ @override
147
+ def __repr__(self) -> str:
148
+ if self.url:
149
+ return f"{self.__class__.__name__}(url={self.url})"
150
+ return f"{self.__class__.__name__}(params={self.params})"
151
+
146
152
 
147
153
  class BasePage(GenericModel, Generic[_T]):
148
154
  """
@@ -689,7 +695,8 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
689
695
  if retry_after is not None and 0 < retry_after <= 60:
690
696
  return retry_after
691
697
 
692
- nb_retries = max_retries - remaining_retries
698
+ # Also cap retry count to 1000 to avoid any potential overflows with `pow`
699
+ nb_retries = min(max_retries - remaining_retries, 1000)
693
700
 
694
701
  # Apply exponential backoff, but not more than the max.
695
702
  sleep_seconds = min(INITIAL_RETRY_DELAY * pow(2.0, nb_retries), MAX_RETRY_DELAY)
@@ -1568,7 +1575,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1568
1575
  except Exception as err:
1569
1576
  log.debug("Encountered Exception", exc_info=True)
1570
1577
 
1571
- if retries_taken > 0:
1578
+ if remaining_retries > 0:
1572
1579
  return await self._retry_request(
1573
1580
  input_options,
1574
1581
  cast_to,
@@ -51,6 +51,8 @@ class Payi(SyncAPIClient):
51
51
  categories: resources.CategoriesResource
52
52
  experiences: resources.ExperiencesResource
53
53
  csat: resources.CsatResource
54
+ billing_models: resources.BillingModelsResource
55
+ price_modifiers: resources.PriceModifiersResource
54
56
  with_raw_response: PayiWithRawResponse
55
57
  with_streaming_response: PayiWithStreamedResponse
56
58
 
@@ -113,6 +115,8 @@ class Payi(SyncAPIClient):
113
115
  self.categories = resources.CategoriesResource(self)
114
116
  self.experiences = resources.ExperiencesResource(self)
115
117
  self.csat = resources.CsatResource(self)
118
+ self.billing_models = resources.BillingModelsResource(self)
119
+ self.price_modifiers = resources.PriceModifiersResource(self)
116
120
  self.with_raw_response = PayiWithRawResponse(self)
117
121
  self.with_streaming_response = PayiWithStreamedResponse(self)
118
122
 
@@ -227,6 +231,8 @@ class AsyncPayi(AsyncAPIClient):
227
231
  categories: resources.AsyncCategoriesResource
228
232
  experiences: resources.AsyncExperiencesResource
229
233
  csat: resources.AsyncCsatResource
234
+ billing_models: resources.AsyncBillingModelsResource
235
+ price_modifiers: resources.AsyncPriceModifiersResource
230
236
  with_raw_response: AsyncPayiWithRawResponse
231
237
  with_streaming_response: AsyncPayiWithStreamedResponse
232
238
 
@@ -289,6 +295,8 @@ class AsyncPayi(AsyncAPIClient):
289
295
  self.categories = resources.AsyncCategoriesResource(self)
290
296
  self.experiences = resources.AsyncExperiencesResource(self)
291
297
  self.csat = resources.AsyncCsatResource(self)
298
+ self.billing_models = resources.AsyncBillingModelsResource(self)
299
+ self.price_modifiers = resources.AsyncPriceModifiersResource(self)
292
300
  self.with_raw_response = AsyncPayiWithRawResponse(self)
293
301
  self.with_streaming_response = AsyncPayiWithStreamedResponse(self)
294
302
 
@@ -404,6 +412,8 @@ class PayiWithRawResponse:
404
412
  self.categories = resources.CategoriesResourceWithRawResponse(client.categories)
405
413
  self.experiences = resources.ExperiencesResourceWithRawResponse(client.experiences)
406
414
  self.csat = resources.CsatResourceWithRawResponse(client.csat)
415
+ self.billing_models = resources.BillingModelsResourceWithRawResponse(client.billing_models)
416
+ self.price_modifiers = resources.PriceModifiersResourceWithRawResponse(client.price_modifiers)
407
417
 
408
418
 
409
419
  class AsyncPayiWithRawResponse:
@@ -413,6 +423,8 @@ class AsyncPayiWithRawResponse:
413
423
  self.categories = resources.AsyncCategoriesResourceWithRawResponse(client.categories)
414
424
  self.experiences = resources.AsyncExperiencesResourceWithRawResponse(client.experiences)
415
425
  self.csat = resources.AsyncCsatResourceWithRawResponse(client.csat)
426
+ self.billing_models = resources.AsyncBillingModelsResourceWithRawResponse(client.billing_models)
427
+ self.price_modifiers = resources.AsyncPriceModifiersResourceWithRawResponse(client.price_modifiers)
416
428
 
417
429
 
418
430
  class PayiWithStreamedResponse:
@@ -422,6 +434,8 @@ class PayiWithStreamedResponse:
422
434
  self.categories = resources.CategoriesResourceWithStreamingResponse(client.categories)
423
435
  self.experiences = resources.ExperiencesResourceWithStreamingResponse(client.experiences)
424
436
  self.csat = resources.CsatResourceWithStreamingResponse(client.csat)
437
+ self.billing_models = resources.BillingModelsResourceWithStreamingResponse(client.billing_models)
438
+ self.price_modifiers = resources.PriceModifiersResourceWithStreamingResponse(client.price_modifiers)
425
439
 
426
440
 
427
441
  class AsyncPayiWithStreamedResponse:
@@ -431,6 +445,8 @@ class AsyncPayiWithStreamedResponse:
431
445
  self.categories = resources.AsyncCategoriesResourceWithStreamingResponse(client.categories)
432
446
  self.experiences = resources.AsyncExperiencesResourceWithStreamingResponse(client.experiences)
433
447
  self.csat = resources.AsyncCsatResourceWithStreamingResponse(client.csat)
448
+ self.billing_models = resources.AsyncBillingModelsResourceWithStreamingResponse(client.billing_models)
449
+ self.price_modifiers = resources.AsyncPriceModifiersResourceWithStreamingResponse(client.price_modifiers)
434
450
 
435
451
 
436
452
  Client = Payi
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload
4
4
  from datetime import date, datetime
5
- from typing_extensions import Self
5
+ from typing_extensions import Self, Literal
6
6
 
7
7
  import pydantic
8
8
  from pydantic.fields import FieldInfo
@@ -133,13 +133,15 @@ def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str:
133
133
  def model_dump(
134
134
  model: pydantic.BaseModel,
135
135
  *,
136
- exclude: IncEx = None,
136
+ exclude: IncEx | None = None,
137
137
  exclude_unset: bool = False,
138
138
  exclude_defaults: bool = False,
139
139
  warnings: bool = True,
140
+ mode: Literal["json", "python"] = "python",
140
141
  ) -> dict[str, Any]:
141
- if PYDANTIC_V2:
142
+ if PYDANTIC_V2 or hasattr(model, "model_dump"):
142
143
  return model.model_dump(
144
+ mode=mode,
143
145
  exclude=exclude,
144
146
  exclude_unset=exclude_unset,
145
147
  exclude_defaults=exclude_defaults,
@@ -37,6 +37,7 @@ from ._utils import (
37
37
  PropertyInfo,
38
38
  is_list,
39
39
  is_given,
40
+ json_safe,
40
41
  lru_cache,
41
42
  is_mapping,
42
43
  parse_date,
@@ -176,7 +177,7 @@ class BaseModel(pydantic.BaseModel):
176
177
  # Based on https://github.com/samuelcolvin/pydantic/issues/1168#issuecomment-817742836.
177
178
  @classmethod
178
179
  @override
179
- def construct(
180
+ def construct( # pyright: ignore[reportIncompatibleMethodOverride]
180
181
  cls: Type[ModelT],
181
182
  _fields_set: set[str] | None = None,
182
183
  **values: object,
@@ -248,8 +249,8 @@ class BaseModel(pydantic.BaseModel):
248
249
  self,
249
250
  *,
250
251
  mode: Literal["json", "python"] | str = "python",
251
- include: IncEx = None,
252
- exclude: IncEx = None,
252
+ include: IncEx | None = None,
253
+ exclude: IncEx | None = None,
253
254
  by_alias: bool = False,
254
255
  exclude_unset: bool = False,
255
256
  exclude_defaults: bool = False,
@@ -279,8 +280,8 @@ class BaseModel(pydantic.BaseModel):
279
280
  Returns:
280
281
  A dictionary representation of the model.
281
282
  """
282
- if mode != "python":
283
- raise ValueError("mode is only supported in Pydantic v2")
283
+ if mode not in {"json", "python"}:
284
+ raise ValueError("mode must be either 'json' or 'python'")
284
285
  if round_trip != False:
285
286
  raise ValueError("round_trip is only supported in Pydantic v2")
286
287
  if warnings != True:
@@ -289,7 +290,7 @@ class BaseModel(pydantic.BaseModel):
289
290
  raise ValueError("context is only supported in Pydantic v2")
290
291
  if serialize_as_any != False:
291
292
  raise ValueError("serialize_as_any is only supported in Pydantic v2")
292
- return super().dict( # pyright: ignore[reportDeprecated]
293
+ dumped = super().dict( # pyright: ignore[reportDeprecated]
293
294
  include=include,
294
295
  exclude=exclude,
295
296
  by_alias=by_alias,
@@ -298,13 +299,15 @@ class BaseModel(pydantic.BaseModel):
298
299
  exclude_none=exclude_none,
299
300
  )
300
301
 
302
+ return cast(dict[str, Any], json_safe(dumped)) if mode == "json" else dumped
303
+
301
304
  @override
302
305
  def model_dump_json(
303
306
  self,
304
307
  *,
305
308
  indent: int | None = None,
306
- include: IncEx = None,
307
- exclude: IncEx = None,
309
+ include: IncEx | None = None,
310
+ exclude: IncEx | None = None,
308
311
  by_alias: bool = False,
309
312
  exclude_unset: bool = False,
310
313
  exclude_defaults: bool = False,
@@ -192,6 +192,9 @@ class BaseAPIResponse(Generic[R]):
192
192
  if cast_to == float:
193
193
  return cast(R, float(response.text))
194
194
 
195
+ if cast_to == bool:
196
+ return cast(R, response.text.lower() == "true")
197
+
195
198
  origin = get_origin(cast_to) or cast_to
196
199
 
197
200
  if origin == APIResponse: