runloop-api-client 0.7.0__tar.gz → 0.8.0__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 (140) hide show
  1. runloop_api_client-0.8.0/.release-please-manifest.json +3 -0
  2. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/CHANGELOG.md +18 -0
  3. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/PKG-INFO +4 -5
  4. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/README.md +2 -2
  5. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/pyproject.toml +3 -4
  6. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/requirements-dev.lock +10 -13
  7. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/requirements.lock +4 -4
  8. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_compat.py +5 -3
  9. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_models.py +11 -8
  10. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_types.py +4 -2
  11. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/__init__.py +1 -0
  12. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_transform.py +7 -2
  13. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_utils.py +17 -0
  14. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_version.py +1 -1
  15. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared/launch_parameters.py +16 -2
  16. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared_params/launch_parameters.py +17 -3
  17. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/test_blueprints.py +16 -0
  18. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/test_devboxes.py +8 -0
  19. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/conftest.py +8 -6
  20. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_client.py +2 -2
  21. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_models.py +7 -14
  22. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_transform.py +15 -0
  23. runloop_api_client-0.7.0/.release-please-manifest.json +0 -3
  24. runloop_api_client-0.7.0/src/runloop_api_client/types/devbox_disk_snapshots_response.py +0 -32
  25. runloop_api_client-0.7.0/src/runloop_api_client/types/resource_size.py +0 -7
  26. runloop_api_client-0.7.0/src/runloop_api_client/types/shared/resource_size.py +0 -7
  27. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/.gitignore +0 -0
  28. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/CONTRIBUTING.md +0 -0
  29. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/LICENSE +0 -0
  30. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/SECURITY.md +0 -0
  31. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/api.md +0 -0
  32. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/bin/check-release-environment +0 -0
  33. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/bin/publish-pypi +0 -0
  34. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/examples/.keep +0 -0
  35. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/mypy.ini +0 -0
  36. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/noxfile.py +0 -0
  37. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/release-please-config.json +0 -0
  38. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop/lib/.keep +0 -0
  39. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/__init__.py +0 -0
  40. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_base_client.py +0 -0
  41. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_client.py +0 -0
  42. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_constants.py +0 -0
  43. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_exceptions.py +0 -0
  44. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_files.py +0 -0
  45. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_qs.py +0 -0
  46. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_resource.py +0 -0
  47. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_response.py +0 -0
  48. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_streaming.py +0 -0
  49. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_logs.py +0 -0
  50. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_proxy.py +0 -0
  51. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_reflection.py +0 -0
  52. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_streams.py +0 -0
  53. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_sync.py +0 -0
  54. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/_utils/_typing.py +0 -0
  55. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/lib/.keep +0 -0
  56. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/py.typed +0 -0
  57. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/__init__.py +0 -0
  58. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/blueprints.py +0 -0
  59. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/devboxes/__init__.py +0 -0
  60. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/devboxes/devboxes.py +0 -0
  61. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/devboxes/executions.py +0 -0
  62. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/devboxes/logs.py +0 -0
  63. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/functions/__init__.py +0 -0
  64. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/functions/functions.py +0 -0
  65. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/functions/invocations.py +0 -0
  66. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/projects/__init__.py +0 -0
  67. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/projects/logs.py +0 -0
  68. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/resources/projects/projects.py +0 -0
  69. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/__init__.py +0 -0
  70. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_build_log.py +0 -0
  71. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_build_logs_list_view.py +0 -0
  72. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_build_parameters.py +0 -0
  73. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_create_params.py +0 -0
  74. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_list_params.py +0 -0
  75. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_list_view.py +0 -0
  76. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_preview_params.py +0 -0
  77. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_preview_view.py +0 -0
  78. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/blueprint_view.py +0 -0
  79. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/code_mount_parameters.py +0 -0
  80. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/code_mount_parameters_param.py +0 -0
  81. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_async_execution_detail_view.py +0 -0
  82. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_create_params.py +0 -0
  83. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_create_ssh_key_response.py +0 -0
  84. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_create_tunnel_params.py +0 -0
  85. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_disk_snapshots_params.py +0 -0
  86. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_download_file_params.py +0 -0
  87. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_execute_async_params.py +0 -0
  88. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_execute_sync_params.py +0 -0
  89. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_execution_detail_view.py +0 -0
  90. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_list_params.py +0 -0
  91. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_list_view.py +0 -0
  92. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_read_file_contents_params.py +0 -0
  93. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_read_file_contents_response.py +0 -0
  94. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_snapshot_disk_params.py +0 -0
  95. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_snapshot_list_view.py +0 -0
  96. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_snapshot_view.py +0 -0
  97. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_tunnel_view.py +0 -0
  98. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_upload_file_params.py +0 -0
  99. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_view.py +0 -0
  100. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devbox_write_file_params.py +0 -0
  101. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/__init__.py +0 -0
  102. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/devbox_logs_list_view.py +0 -0
  103. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/execution_execute_async_params.py +0 -0
  104. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/execution_execute_sync_params.py +0 -0
  105. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/execution_retrieve_params.py +0 -0
  106. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/devboxes/log_list_params.py +0 -0
  107. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/function_invoke_async_params.py +0 -0
  108. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/function_invoke_sync_params.py +0 -0
  109. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/function_list_view.py +0 -0
  110. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/functions/__init__.py +0 -0
  111. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/functions/function_invocation_list_view.py +0 -0
  112. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/functions/invocation_list_params.py +0 -0
  113. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/project_list_view.py +0 -0
  114. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/projects/__init__.py +0 -0
  115. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared/__init__.py +0 -0
  116. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared/function_invocation_execution_detail_view.py +0 -0
  117. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared/project_logs_view.py +0 -0
  118. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/src/runloop_api_client/types/shared_params/__init__.py +0 -0
  119. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/__init__.py +0 -0
  120. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/__init__.py +0 -0
  121. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/devboxes/__init__.py +0 -0
  122. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/devboxes/test_executions.py +0 -0
  123. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/devboxes/test_logs.py +0 -0
  124. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/functions/__init__.py +0 -0
  125. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/functions/test_invocations.py +0 -0
  126. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/projects/__init__.py +0 -0
  127. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/projects/test_logs.py +0 -0
  128. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/test_functions.py +0 -0
  129. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/api_resources/test_projects.py +0 -0
  130. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/sample_file.txt +0 -0
  131. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_deepcopy.py +0 -0
  132. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_extract_files.py +0 -0
  133. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_files.py +0 -0
  134. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_qs.py +0 -0
  135. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_required_args.py +0 -0
  136. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_response.py +0 -0
  137. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_streaming.py +0 -0
  138. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_utils/test_proxy.py +0 -0
  139. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/test_utils/test_typing.py +0 -0
  140. {runloop_api_client-0.7.0 → runloop_api_client-0.8.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.8.0"
3
+ }
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 (2024-11-06)
4
+
5
+ Full Changelog: [v0.7.0...v0.8.0](https://github.com/runloopai/api-client-python/compare/v0.7.0...v0.8.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** api update ([#239](https://github.com/runloopai/api-client-python/issues/239)) ([e265611](https://github.com/runloopai/api-client-python/commit/e2656115c0ee73db6d73cf1e1efbec97988ff064))
10
+ * **api:** api update ([#241](https://github.com/runloopai/api-client-python/issues/241)) ([d69d8a8](https://github.com/runloopai/api-client-python/commit/d69d8a86ab004b4b689a8585c570ed4857af4353))
11
+ * **api:** api update ([#242](https://github.com/runloopai/api-client-python/issues/242)) ([ad2f4c7](https://github.com/runloopai/api-client-python/commit/ad2f4c75052d843b3ae1bf174b37d8b3cbfe682d))
12
+ * **api:** api update ([#243](https://github.com/runloopai/api-client-python/issues/243)) ([7b6c98f](https://github.com/runloopai/api-client-python/commit/7b6c98f6e753f36ace4804c8b3e50d2f24fca817))
13
+ * **api:** api update ([#244](https://github.com/runloopai/api-client-python/issues/244)) ([12d0039](https://github.com/runloopai/api-client-python/commit/12d0039440149afac4e599333d3c8390239f0c0f))
14
+ * **api:** api update ([#245](https://github.com/runloopai/api-client-python/issues/245)) ([2b82f31](https://github.com/runloopai/api-client-python/commit/2b82f3176032293211710a81c9c18b326cc703ad))
15
+ * **api:** api update ([#246](https://github.com/runloopai/api-client-python/issues/246)) ([ee79233](https://github.com/runloopai/api-client-python/commit/ee7923350b3bb77b52cfc30d94cadd0c06965a9d))
16
+ * **api:** api update ([#247](https://github.com/runloopai/api-client-python/issues/247)) ([492e315](https://github.com/runloopai/api-client-python/commit/492e3150dd7b27ba1b849dec84e11e9e37997037))
17
+ * **api:** api update ([#248](https://github.com/runloopai/api-client-python/issues/248)) ([045ec22](https://github.com/runloopai/api-client-python/commit/045ec22efdee8eee4f016560a16c8900666b604d))
18
+ * **api:** api update ([#249](https://github.com/runloopai/api-client-python/issues/249)) ([baa457c](https://github.com/runloopai/api-client-python/commit/baa457c6a26cca584443372f0663477fd9bc7cdd))
19
+ * **api:** api update ([#250](https://github.com/runloopai/api-client-python/issues/250)) ([e69b069](https://github.com/runloopai/api-client-python/commit/e69b069b03683916c6c96ee8a8fa1a4f2d8ba557))
20
+
3
21
  ## 0.7.0 (2024-10-24)
4
22
 
5
23
  Full Changelog: [v0.6.0...v0.7.0](https://github.com/runloopai/api-client-python/compare/v0.6.0...v0.7.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: runloop_api_client
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: The official Python library for the runloop API
5
5
  Project-URL: Homepage, https://github.com/runloopai/api-client-python
6
6
  Project-URL: Repository, https://github.com/runloopai/api-client-python
@@ -14,7 +14,6 @@ Classifier: Operating System :: Microsoft :: Windows
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Operating System :: POSIX
16
16
  Classifier: Operating System :: POSIX :: Linux
17
- Classifier: Programming Language :: Python :: 3.7
18
17
  Classifier: Programming Language :: Python :: 3.8
19
18
  Classifier: Programming Language :: Python :: 3.9
20
19
  Classifier: Programming Language :: Python :: 3.10
@@ -22,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.11
22
21
  Classifier: Programming Language :: Python :: 3.12
23
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
23
  Classifier: Typing :: Typed
25
- Requires-Python: >=3.7
24
+ Requires-Python: >=3.8
26
25
  Requires-Dist: anyio<5,>=3.5.0
27
26
  Requires-Dist: cached-property; python_version < '3.8'
28
27
  Requires-Dist: distro<2,>=1.7.0
@@ -36,7 +35,7 @@ Description-Content-Type: text/markdown
36
35
 
37
36
  [![PyPI version](https://img.shields.io/pypi/v/runloop_api_client.svg)](https://pypi.org/project/runloop_api_client/)
38
37
 
39
- The Runloop Python library provides convenient access to the Runloop REST API from any Python 3.7+
38
+ The Runloop Python library provides convenient access to the Runloop REST API from any Python 3.8+
40
39
  application. The library includes type definitions for all request params and response fields,
41
40
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
42
41
 
@@ -348,7 +347,7 @@ print(runloop_api_client.__version__)
348
347
 
349
348
  ## Requirements
350
349
 
351
- Python 3.7 or higher.
350
+ Python 3.8 or higher.
352
351
 
353
352
  ## Contributing
354
353
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![PyPI version](https://img.shields.io/pypi/v/runloop_api_client.svg)](https://pypi.org/project/runloop_api_client/)
4
4
 
5
- The Runloop Python library provides convenient access to the Runloop REST API from any Python 3.7+
5
+ The Runloop Python library provides convenient access to the Runloop 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
 
@@ -314,7 +314,7 @@ print(runloop_api_client.__version__)
314
314
 
315
315
  ## Requirements
316
316
 
317
- Python 3.7 or higher.
317
+ Python 3.8 or higher.
318
318
 
319
319
  ## Contributing
320
320
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runloop_api_client"
3
- version = "0.7.0"
3
+ version = "0.8.0"
4
4
  description = "The official Python library for the runloop API"
5
5
  dynamic = ["readme"]
6
6
  license = "MIT"
@@ -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",
@@ -139,7 +138,7 @@ filterwarnings = [
139
138
  # there are a couple of flags that are still disabled by
140
139
  # default in strict mode as they are experimental and niche.
141
140
  typeCheckingMode = "strict"
142
- pythonVersion = "3.7"
141
+ pythonVersion = "3.8"
143
142
 
144
143
  exclude = [
145
144
  "_dev",
@@ -16,8 +16,6 @@ anyio==4.4.0
16
16
  # via runloop-api-client
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 runloop-api-client
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,20 +59,18 @@ 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 runloop-api-client
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
@@ -90,10 +87,10 @@ sniffio==1.3.0
90
87
  # via httpx
91
88
  # via runloop-api-client
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 pydantic
@@ -19,7 +19,7 @@ certifi==2023.7.22
19
19
  # via httpx
20
20
  distro==1.8.0
21
21
  # via runloop-api-client
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 runloop-api-client
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 runloop-api-client
41
- typing-extensions==4.8.0
41
+ typing-extensions==4.12.2
42
42
  # via anyio
43
43
  # via pydantic
44
44
  # via pydantic-core
@@ -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,
@@ -16,7 +16,7 @@ from typing import (
16
16
  Optional,
17
17
  Sequence,
18
18
  )
19
- from typing_extensions import Literal, Protocol, TypeAlias, TypedDict, override, runtime_checkable
19
+ from typing_extensions import Set, Literal, Protocol, TypeAlias, TypedDict, override, runtime_checkable
20
20
 
21
21
  import httpx
22
22
  import pydantic
@@ -193,7 +193,9 @@ StrBytesIntFloat = Union[str, bytes, int, float]
193
193
 
194
194
  # Note: copied from Pydantic
195
195
  # https://github.com/pydantic/pydantic/blob/32ea570bf96e84234d2992e1ddf40ab8a565925a/pydantic/main.py#L49
196
- IncEx: TypeAlias = "set[int] | set[str] | dict[int, Any] | dict[str, Any] | None"
196
+ IncEx: TypeAlias = Union[
197
+ Set[int], Set[str], Mapping[int, Union["IncEx", Literal[True]]], Mapping[str, Union["IncEx", Literal[True]]]
198
+ ]
197
199
 
198
200
  PostParser = Callable[[Any], Any]
199
201
 
@@ -6,6 +6,7 @@ from ._utils import (
6
6
  is_list as is_list,
7
7
  is_given as is_given,
8
8
  is_tuple as is_tuple,
9
+ json_safe as json_safe,
9
10
  lru_cache as lru_cache,
10
11
  is_mapping as is_mapping,
11
12
  is_tuple_t as is_tuple_t,
@@ -173,6 +173,11 @@ def _transform_recursive(
173
173
  # Iterable[T]
174
174
  or (is_iterable_type(stripped_type) and is_iterable(data) and not isinstance(data, str))
175
175
  ):
176
+ # dicts are technically iterable, but it is an iterable on the keys of the dict and is not usually
177
+ # intended as an iterable, so we don't transform it.
178
+ if isinstance(data, dict):
179
+ return cast(object, data)
180
+
176
181
  inner_type = extract_type_arg(stripped_type, 0)
177
182
  return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
178
183
 
@@ -186,7 +191,7 @@ def _transform_recursive(
186
191
  return data
187
192
 
188
193
  if isinstance(data, pydantic.BaseModel):
189
- return model_dump(data, exclude_unset=True)
194
+ return model_dump(data, exclude_unset=True, mode="json")
190
195
 
191
196
  annotated_type = _get_annotated_type(annotation)
192
197
  if annotated_type is None:
@@ -324,7 +329,7 @@ async def _async_transform_recursive(
324
329
  return data
325
330
 
326
331
  if isinstance(data, pydantic.BaseModel):
327
- return model_dump(data, exclude_unset=True)
332
+ return model_dump(data, exclude_unset=True, mode="json")
328
333
 
329
334
  annotated_type = _get_annotated_type(annotation)
330
335
  if annotated_type is None:
@@ -16,6 +16,7 @@ from typing import (
16
16
  overload,
17
17
  )
18
18
  from pathlib import Path
19
+ from datetime import date, datetime
19
20
  from typing_extensions import TypeGuard
20
21
 
21
22
  import sniffio
@@ -395,3 +396,19 @@ def lru_cache(*, maxsize: int | None = 128) -> Callable[[CallableT], CallableT]:
395
396
  maxsize=maxsize,
396
397
  )
397
398
  return cast(Any, wrapper) # type: ignore[no-any-return]
399
+
400
+
401
+ def json_safe(data: object) -> object:
402
+ """Translates a mapping / sequence recursively in the same fashion
403
+ as `pydantic` v2's `model_dump(mode="json")`.
404
+ """
405
+ if is_mapping(data):
406
+ return {json_safe(key): json_safe(value) for key, value in data.items()}
407
+
408
+ if is_iterable(data) and not isinstance(data, (str, bytes, bytearray)):
409
+ return [json_safe(item) for item in data]
410
+
411
+ if isinstance(data, (datetime, date)):
412
+ return data.isoformat()
413
+
414
+ return data
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "runloop_api_client"
4
- __version__ = "0.7.0" # x-release-please-version
4
+ __version__ = "0.8.0" # x-release-please-version
@@ -5,10 +5,24 @@ from typing_extensions import Literal
5
5
 
6
6
  from ..._models import BaseModel
7
7
 
8
- __all__ = ["LaunchParameters"]
8
+ __all__ = ["LaunchParameters", "AfterIdle"]
9
+
10
+
11
+ class AfterIdle(BaseModel):
12
+ idle_time_seconds: int
13
+ """After idle_time_seconds, on_idle action will be taken."""
14
+
15
+ on_idle: Literal["unknown", "shutdown", "suspend"]
16
+ """Action to take after Devbox becomes idle."""
9
17
 
10
18
 
11
19
  class LaunchParameters(BaseModel):
20
+ after_idle: Optional[AfterIdle] = None
21
+ """Configure Devbox lifecycle based on idle activity.
22
+
23
+ If after_idle is set, Devbox will ignore keep_alive_time_seconds.
24
+ """
25
+
12
26
  available_ports: Optional[List[int]] = None
13
27
  """A list of ports to make available on the Devbox.
14
28
 
@@ -24,5 +38,5 @@ class LaunchParameters(BaseModel):
24
38
  launch_commands: Optional[List[str]] = None
25
39
  """Set of commands to be run at launch time, before the entrypoint process is run."""
26
40
 
27
- resource_size_request: Optional[Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "CUSTOM_SIZE"]] = None
41
+ resource_size_request: Optional[Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "XX_LARGE", "CUSTOM_SIZE"]] = None
28
42
  """Manual resource configuration for Devbox. If not set, defaults will be used."""
@@ -3,12 +3,26 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from typing import List, Iterable
6
- from typing_extensions import Literal, TypedDict
6
+ from typing_extensions import Literal, Required, TypedDict
7
7
 
8
- __all__ = ["LaunchParameters"]
8
+ __all__ = ["LaunchParameters", "AfterIdle"]
9
+
10
+
11
+ class AfterIdle(TypedDict, total=False):
12
+ idle_time_seconds: Required[int]
13
+ """After idle_time_seconds, on_idle action will be taken."""
14
+
15
+ on_idle: Required[Literal["unknown", "shutdown", "suspend"]]
16
+ """Action to take after Devbox becomes idle."""
9
17
 
10
18
 
11
19
  class LaunchParameters(TypedDict, total=False):
20
+ after_idle: AfterIdle
21
+ """Configure Devbox lifecycle based on idle activity.
22
+
23
+ If after_idle is set, Devbox will ignore keep_alive_time_seconds.
24
+ """
25
+
12
26
  available_ports: Iterable[int]
13
27
  """A list of ports to make available on the Devbox.
14
28
 
@@ -24,5 +38,5 @@ class LaunchParameters(TypedDict, total=False):
24
38
  launch_commands: List[str]
25
39
  """Set of commands to be run at launch time, before the entrypoint process is run."""
26
40
 
27
- resource_size_request: Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "CUSTOM_SIZE"]
41
+ resource_size_request: Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "XX_LARGE", "CUSTOM_SIZE"]
28
42
  """Manual resource configuration for Devbox. If not set, defaults will be used."""
@@ -56,6 +56,10 @@ class TestBlueprints:
56
56
  dockerfile="dockerfile",
57
57
  file_mounts={"foo": "string"},
58
58
  launch_parameters={
59
+ "after_idle": {
60
+ "idle_time_seconds": 0,
61
+ "on_idle": "unknown",
62
+ },
59
63
  "available_ports": [0, 0, 0],
60
64
  "keep_alive_time_seconds": 0,
61
65
  "launch_commands": ["string", "string", "string"],
@@ -233,6 +237,10 @@ class TestBlueprints:
233
237
  dockerfile="dockerfile",
234
238
  file_mounts={"foo": "string"},
235
239
  launch_parameters={
240
+ "after_idle": {
241
+ "idle_time_seconds": 0,
242
+ "on_idle": "unknown",
243
+ },
236
244
  "available_ports": [0, 0, 0],
237
245
  "keep_alive_time_seconds": 0,
238
246
  "launch_commands": ["string", "string", "string"],
@@ -304,6 +312,10 @@ class TestAsyncBlueprints:
304
312
  dockerfile="dockerfile",
305
313
  file_mounts={"foo": "string"},
306
314
  launch_parameters={
315
+ "after_idle": {
316
+ "idle_time_seconds": 0,
317
+ "on_idle": "unknown",
318
+ },
307
319
  "available_ports": [0, 0, 0],
308
320
  "keep_alive_time_seconds": 0,
309
321
  "launch_commands": ["string", "string", "string"],
@@ -481,6 +493,10 @@ class TestAsyncBlueprints:
481
493
  dockerfile="dockerfile",
482
494
  file_mounts={"foo": "string"},
483
495
  launch_parameters={
496
+ "after_idle": {
497
+ "idle_time_seconds": 0,
498
+ "on_idle": "unknown",
499
+ },
484
500
  "available_ports": [0, 0, 0],
485
501
  "keep_alive_time_seconds": 0,
486
502
  "launch_commands": ["string", "string", "string"],
@@ -68,6 +68,10 @@ class TestDevboxes:
68
68
  environment_variables={"foo": "string"},
69
69
  file_mounts={"foo": "string"},
70
70
  launch_parameters={
71
+ "after_idle": {
72
+ "idle_time_seconds": 0,
73
+ "on_idle": "unknown",
74
+ },
71
75
  "available_ports": [0, 0, 0],
72
76
  "keep_alive_time_seconds": 0,
73
77
  "launch_commands": ["string", "string", "string"],
@@ -780,6 +784,10 @@ class TestAsyncDevboxes:
780
784
  environment_variables={"foo": "string"},
781
785
  file_mounts={"foo": "string"},
782
786
  launch_parameters={
787
+ "after_idle": {
788
+ "idle_time_seconds": 0,
789
+ "on_idle": "unknown",
790
+ },
783
791
  "available_ports": [0, 0, 0],
784
792
  "keep_alive_time_seconds": 0,
785
793
  "launch_commands": ["string", "string", "string"],
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
- import asyncio
5
4
  import logging
6
5
  from typing import TYPE_CHECKING, Iterator, AsyncIterator
7
6
 
8
7
  import pytest
8
+ from pytest_asyncio import is_async_test
9
9
 
10
10
  from runloop_api_client import Runloop, AsyncRunloop
11
11
 
@@ -17,11 +17,13 @@ pytest.register_assert_rewrite("tests.utils")
17
17
  logging.getLogger("runloop_api_client").setLevel(logging.DEBUG)
18
18
 
19
19
 
20
- @pytest.fixture(scope="session")
21
- def event_loop() -> Iterator[asyncio.AbstractEventLoop]:
22
- loop = asyncio.new_event_loop()
23
- yield loop
24
- loop.close()
20
+ # automatically add `pytest.mark.asyncio()` to all of our async tests
21
+ # so we don't have to add that boilerplate everywhere
22
+ def pytest_collection_modifyitems(items: list[pytest.Function]) -> None:
23
+ pytest_asyncio_tests = (item for item in items if is_async_test(item))
24
+ session_scope_marker = pytest.mark.asyncio(loop_scope="session")
25
+ for async_test in pytest_asyncio_tests:
26
+ async_test.add_marker(session_scope_marker, append=False)
25
27
 
26
28
 
27
29
  base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -721,7 +721,7 @@ class TestRunloop:
721
721
  [3, "", 0.5],
722
722
  [2, "", 0.5 * 2.0],
723
723
  [1, "", 0.5 * 4.0],
724
- [-1100, "", 7.8], # test large number potentially overflowing
724
+ [-1100, "", 8], # test large number potentially overflowing
725
725
  ],
726
726
  )
727
727
  @mock.patch("time.time", mock.MagicMock(return_value=1696004797))
@@ -1514,7 +1514,7 @@ class TestAsyncRunloop:
1514
1514
  [3, "", 0.5],
1515
1515
  [2, "", 0.5 * 2.0],
1516
1516
  [1, "", 0.5 * 4.0],
1517
- [-1100, "", 7.8], # test large number potentially overflowing
1517
+ [-1100, "", 8], # test large number potentially overflowing
1518
1518
  ],
1519
1519
  )
1520
1520
  @mock.patch("time.time", mock.MagicMock(return_value=1696004797))
@@ -520,19 +520,15 @@ def test_to_dict() -> None:
520
520
  assert m3.to_dict(exclude_none=True) == {}
521
521
  assert m3.to_dict(exclude_defaults=True) == {}
522
522
 
523
- if PYDANTIC_V2:
524
-
525
- class Model2(BaseModel):
526
- created_at: datetime
523
+ class Model2(BaseModel):
524
+ created_at: datetime
527
525
 
528
- time_str = "2024-03-21T11:39:01.275859"
529
- m4 = Model2.construct(created_at=time_str)
530
- assert m4.to_dict(mode="python") == {"created_at": datetime.fromisoformat(time_str)}
531
- assert m4.to_dict(mode="json") == {"created_at": time_str}
532
- else:
533
- with pytest.raises(ValueError, match="mode is only supported in Pydantic v2"):
534
- m.to_dict(mode="json")
526
+ time_str = "2024-03-21T11:39:01.275859"
527
+ m4 = Model2.construct(created_at=time_str)
528
+ assert m4.to_dict(mode="python") == {"created_at": datetime.fromisoformat(time_str)}
529
+ assert m4.to_dict(mode="json") == {"created_at": time_str}
535
530
 
531
+ if not PYDANTIC_V2:
536
532
  with pytest.raises(ValueError, match="warnings is only supported in Pydantic v2"):
537
533
  m.to_dict(warnings=False)
538
534
 
@@ -558,9 +554,6 @@ def test_forwards_compat_model_dump_method() -> None:
558
554
  assert m3.model_dump(exclude_none=True) == {}
559
555
 
560
556
  if not PYDANTIC_V2:
561
- with pytest.raises(ValueError, match="mode is only supported in Pydantic v2"):
562
- m.model_dump(mode="json")
563
-
564
557
  with pytest.raises(ValueError, match="round_trip is only supported in Pydantic v2"):
565
558
  m.model_dump(round_trip=True)
566
559
 
@@ -177,17 +177,32 @@ class DateDict(TypedDict, total=False):
177
177
  foo: Annotated[date, PropertyInfo(format="iso8601")]
178
178
 
179
179
 
180
+ class DatetimeModel(BaseModel):
181
+ foo: datetime
182
+
183
+
184
+ class DateModel(BaseModel):
185
+ foo: Optional[date]
186
+
187
+
180
188
  @parametrize
181
189
  @pytest.mark.asyncio
182
190
  async def test_iso8601_format(use_async: bool) -> None:
183
191
  dt = datetime.fromisoformat("2023-02-23T14:16:36.337692+00:00")
192
+ tz = "Z" if PYDANTIC_V2 else "+00:00"
184
193
  assert await transform({"foo": dt}, DatetimeDict, use_async) == {"foo": "2023-02-23T14:16:36.337692+00:00"} # type: ignore[comparison-overlap]
194
+ assert await transform(DatetimeModel(foo=dt), Any, use_async) == {"foo": "2023-02-23T14:16:36.337692" + tz} # type: ignore[comparison-overlap]
185
195
 
186
196
  dt = dt.replace(tzinfo=None)
187
197
  assert await transform({"foo": dt}, DatetimeDict, use_async) == {"foo": "2023-02-23T14:16:36.337692"} # type: ignore[comparison-overlap]
198
+ assert await transform(DatetimeModel(foo=dt), Any, use_async) == {"foo": "2023-02-23T14:16:36.337692"} # type: ignore[comparison-overlap]
188
199
 
189
200
  assert await transform({"foo": None}, DateDict, use_async) == {"foo": None} # type: ignore[comparison-overlap]
201
+ assert await transform(DateModel(foo=None), Any, use_async) == {"foo": None} # type: ignore
190
202
  assert await transform({"foo": date.fromisoformat("2023-02-23")}, DateDict, use_async) == {"foo": "2023-02-23"} # type: ignore[comparison-overlap]
203
+ assert await transform(DateModel(foo=date.fromisoformat("2023-02-23")), DateDict, use_async) == {
204
+ "foo": "2023-02-23"
205
+ } # type: ignore[comparison-overlap]
191
206
 
192
207
 
193
208
  @parametrize
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.7.0"
3
- }
@@ -1,32 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from typing import Dict, List, Optional
4
-
5
- from pydantic import Field as FieldInfo
6
-
7
- from .._models import BaseModel
8
-
9
- __all__ = ["DevboxDiskSnapshotsResponse", "Snapshot"]
10
-
11
-
12
- class Snapshot(BaseModel):
13
- id: str
14
- """The unique identifier of the snapshot."""
15
-
16
- metadata: Dict[str, str]
17
- """metadata associated with the snapshot."""
18
-
19
- source_devbox_id: str = FieldInfo(alias="sourceDevboxId")
20
- """The source devbox identifier."""
21
-
22
- name: Optional[str] = None
23
- """(Optional) The custom name of the snapshot."""
24
-
25
-
26
- class DevboxDiskSnapshotsResponse(BaseModel):
27
- has_more: bool
28
-
29
- snapshots: List[Snapshot]
30
- """List of snapshots matching filter."""
31
-
32
- total_count: int
@@ -1,7 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from typing_extensions import Literal, TypeAlias
4
-
5
- __all__ = ["ResourceSize"]
6
-
7
- ResourceSize: TypeAlias = Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "CUSTOM_SIZE"]
@@ -1,7 +0,0 @@
1
- # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- from typing_extensions import Literal, TypeAlias
4
-
5
- __all__ = ["ResourceSize"]
6
-
7
- ResourceSize: TypeAlias = Literal["SMALL", "MEDIUM", "LARGE", "X_LARGE", "CUSTOM_SIZE"]