otterapi 0.0.5__py3-none-any.whl → 0.0.6__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 (52) hide show
  1. README.md +581 -8
  2. otterapi/__init__.py +73 -0
  3. otterapi/cli.py +327 -29
  4. otterapi/codegen/__init__.py +115 -0
  5. otterapi/codegen/ast_utils.py +134 -5
  6. otterapi/codegen/client.py +1271 -0
  7. otterapi/codegen/codegen.py +1736 -0
  8. otterapi/codegen/dataframes.py +392 -0
  9. otterapi/codegen/emitter.py +473 -0
  10. otterapi/codegen/endpoints.py +2597 -343
  11. otterapi/codegen/pagination.py +1026 -0
  12. otterapi/codegen/schema.py +593 -0
  13. otterapi/codegen/splitting.py +1397 -0
  14. otterapi/codegen/types.py +1345 -0
  15. otterapi/codegen/utils.py +180 -1
  16. otterapi/config.py +1017 -24
  17. otterapi/exceptions.py +231 -0
  18. otterapi/openapi/__init__.py +46 -0
  19. otterapi/openapi/v2/__init__.py +86 -0
  20. otterapi/openapi/v2/spec.json +1607 -0
  21. otterapi/openapi/v2/v2.py +1776 -0
  22. otterapi/openapi/v3/__init__.py +131 -0
  23. otterapi/openapi/v3/spec.json +1651 -0
  24. otterapi/openapi/v3/v3.py +1557 -0
  25. otterapi/openapi/v3_1/__init__.py +133 -0
  26. otterapi/openapi/v3_1/spec.json +1411 -0
  27. otterapi/openapi/v3_1/v3_1.py +798 -0
  28. otterapi/openapi/v3_2/__init__.py +133 -0
  29. otterapi/openapi/v3_2/spec.json +1666 -0
  30. otterapi/openapi/v3_2/v3_2.py +777 -0
  31. otterapi/tests/__init__.py +3 -0
  32. otterapi/tests/fixtures/__init__.py +455 -0
  33. otterapi/tests/test_ast_utils.py +680 -0
  34. otterapi/tests/test_codegen.py +610 -0
  35. otterapi/tests/test_dataframe.py +1038 -0
  36. otterapi/tests/test_exceptions.py +493 -0
  37. otterapi/tests/test_openapi_support.py +616 -0
  38. otterapi/tests/test_openapi_upgrade.py +215 -0
  39. otterapi/tests/test_pagination.py +1101 -0
  40. otterapi/tests/test_splitting_config.py +319 -0
  41. otterapi/tests/test_splitting_integration.py +427 -0
  42. otterapi/tests/test_splitting_resolver.py +512 -0
  43. otterapi/tests/test_splitting_tree.py +525 -0
  44. otterapi-0.0.6.dist-info/METADATA +627 -0
  45. otterapi-0.0.6.dist-info/RECORD +48 -0
  46. {otterapi-0.0.5.dist-info → otterapi-0.0.6.dist-info}/WHEEL +1 -1
  47. otterapi/codegen/generator.py +0 -358
  48. otterapi/codegen/openapi_processor.py +0 -27
  49. otterapi/codegen/type_generator.py +0 -559
  50. otterapi-0.0.5.dist-info/METADATA +0 -54
  51. otterapi-0.0.5.dist-info/RECORD +0 -16
  52. {otterapi-0.0.5.dist-info → otterapi-0.0.6.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,215 @@
1
+ """Tests for OpenAPI version upgrade functionality."""
2
+
3
+ from otterapi.openapi.v3_1.v3_1 import OpenAPI as OpenAPI31
4
+ from otterapi.openapi.v3_2.v3_2 import OpenAPI as OpenAPI32
5
+
6
+
7
+ class TestOpenAPIUpgrade:
8
+ """Test suite for upgrading OpenAPI 3.1 to 3.2."""
9
+
10
+ def test_basic_upgrade(self):
11
+ """Test basic upgrade from 3.1 to 3.2."""
12
+ doc_31 = OpenAPI31.model_validate(
13
+ {'openapi': '3.1.0', 'info': {'title': 'Test API', 'version': '1.0.0'}}
14
+ )
15
+
16
+ doc_32, _ = doc_31.upgrade()
17
+
18
+ assert isinstance(doc_32, OpenAPI32)
19
+ assert doc_32.openapi == '3.2.0'
20
+ assert doc_32.info.title == 'Test API'
21
+ assert doc_32.info.version == '1.0.0'
22
+
23
+ def test_version_upgrade_preserves_patch(self):
24
+ """Test that patch version is preserved during upgrade."""
25
+ doc_31 = OpenAPI31.model_validate(
26
+ {'openapi': '3.1.5', 'info': {'title': 'Test API', 'version': '1.0.0'}}
27
+ )
28
+
29
+ doc_32, _ = doc_31.upgrade()
30
+
31
+ assert doc_32.openapi == '3.2.5'
32
+
33
+ def test_version_upgrade_preserves_suffix(self):
34
+ """Test that version suffix (e.g., -beta) is preserved."""
35
+ doc_31 = OpenAPI31.model_validate(
36
+ {
37
+ 'openapi': '3.1.0-beta1',
38
+ 'info': {'title': 'Test API', 'version': '1.0.0'},
39
+ }
40
+ )
41
+
42
+ doc_32, _ = doc_31.upgrade()
43
+
44
+ assert doc_32.openapi == '3.2.0-beta1'
45
+
46
+ def test_json_schema_dialect_upgrade(self):
47
+ """Test that default jsonSchemaDialect is updated to 3.2."""
48
+ doc_31 = OpenAPI31.model_validate(
49
+ {
50
+ 'openapi': '3.1.0',
51
+ 'info': {'title': 'Test API', 'version': '1.0.0'},
52
+ 'jsonSchemaDialect': 'https://spec.openapis.org/oas/3.1/dialect/base',
53
+ }
54
+ )
55
+
56
+ doc_32, _ = doc_31.upgrade()
57
+
58
+ assert (
59
+ doc_32.jsonSchemaDialect == 'https://spec.openapis.org/oas/3.2/dialect/base'
60
+ )
61
+
62
+ def test_custom_json_schema_dialect_preserved(self):
63
+ """Test that custom jsonSchemaDialect is preserved."""
64
+ custom_dialect = 'https://json-schema.org/draft/2020-12/schema'
65
+ doc_31 = OpenAPI31.model_validate(
66
+ {
67
+ 'openapi': '3.1.0',
68
+ 'info': {'title': 'Test API', 'version': '1.0.0'},
69
+ 'jsonSchemaDialect': custom_dialect,
70
+ }
71
+ )
72
+
73
+ doc_32, _ = doc_31.upgrade()
74
+
75
+ assert doc_32.jsonSchemaDialect == custom_dialect
76
+
77
+ def test_complex_document_upgrade(self):
78
+ """Test upgrade of complex document with paths, schemas, and servers."""
79
+ doc_31 = OpenAPI31.model_validate(
80
+ {
81
+ 'openapi': '3.1.0',
82
+ 'info': {
83
+ 'title': 'Pet Store API',
84
+ 'version': '1.0.0',
85
+ 'description': 'A sample API',
86
+ },
87
+ 'servers': [{'url': 'https://api.example.com/v1'}],
88
+ 'paths': {
89
+ '/pets': {
90
+ 'get': {
91
+ 'operationId': 'listPets',
92
+ 'summary': 'List all pets',
93
+ 'responses': {
94
+ 'default': {
95
+ 'description': 'A list of pets',
96
+ 'content': {
97
+ 'application/json': {
98
+ 'schema': {
99
+ 'type': 'array',
100
+ 'items': {'type': 'object'},
101
+ }
102
+ }
103
+ },
104
+ }
105
+ },
106
+ }
107
+ }
108
+ },
109
+ 'components': {
110
+ 'schemas': {
111
+ 'Pet': {
112
+ 'type': 'object',
113
+ 'required': ['name'],
114
+ 'properties': {
115
+ 'name': {'type': 'string'},
116
+ 'age': {'type': 'integer', 'minimum': 0},
117
+ },
118
+ }
119
+ }
120
+ },
121
+ }
122
+ )
123
+
124
+ doc_32, _ = doc_31.upgrade()
125
+
126
+ # Verify structure is preserved
127
+ assert doc_32.info.title == 'Pet Store API'
128
+ assert doc_32.info.description == 'A sample API'
129
+ assert len(doc_32.servers) == 1
130
+ assert doc_32.servers[0].url == 'https://api.example.com/v1'
131
+ assert '/pets' in doc_32.paths.root
132
+ assert 'Pet' in doc_32.components.schemas
133
+
134
+ # Verify nested schema
135
+ pet_schema = doc_32.components.schemas['Pet']
136
+ assert pet_schema.type.value == 'object'
137
+ assert pet_schema.required == ['name']
138
+ assert 'name' in pet_schema.properties
139
+ assert 'age' in pet_schema.properties
140
+
141
+ def test_webhooks_upgrade(self):
142
+ """Test that webhooks (new in 3.1) are preserved during upgrade."""
143
+ doc_31 = OpenAPI31.model_validate(
144
+ {
145
+ 'openapi': '3.1.0',
146
+ 'info': {'title': 'Webhook API', 'version': '1.0.0'},
147
+ 'webhooks': {
148
+ 'newPet': {
149
+ 'post': {
150
+ 'summary': 'New pet notification',
151
+ 'requestBody': {
152
+ 'content': {
153
+ 'application/json': {
154
+ 'schema': {
155
+ 'type': 'object',
156
+ 'properties': {
157
+ 'id': {'type': 'integer'},
158
+ 'name': {'type': 'string'},
159
+ },
160
+ }
161
+ }
162
+ }
163
+ },
164
+ 'responses': {
165
+ 'default': {'description': 'Webhook received'}
166
+ },
167
+ }
168
+ }
169
+ },
170
+ }
171
+ )
172
+
173
+ doc_32, _ = doc_31.upgrade()
174
+
175
+ assert doc_32.webhooks is not None
176
+ assert 'newPet' in doc_32.webhooks
177
+ assert doc_32.webhooks['newPet'].post.summary == 'New pet notification'
178
+
179
+ def test_minimal_document_upgrade(self):
180
+ """Test upgrade of minimal valid document."""
181
+ doc_31 = OpenAPI31.model_validate(
182
+ {'openapi': '3.1.0', 'info': {'title': 'Minimal API', 'version': '0.1.0'}}
183
+ )
184
+
185
+ doc_32, _ = doc_31.upgrade()
186
+
187
+ assert isinstance(doc_32, OpenAPI32)
188
+ assert doc_32.openapi == '3.2.0'
189
+ assert doc_32.info.title == 'Minimal API'
190
+
191
+ def test_security_schemes_upgrade(self):
192
+ """Test that security schemes are preserved during upgrade."""
193
+ doc_31 = OpenAPI31.model_validate(
194
+ {
195
+ 'openapi': '3.1.0',
196
+ 'info': {'title': 'Secure API', 'version': '1.0.0'},
197
+ 'components': {
198
+ 'securitySchemes': {
199
+ 'bearerAuth': {
200
+ 'type': 'http',
201
+ 'scheme': 'bearer',
202
+ 'bearerFormat': 'JWT',
203
+ }
204
+ }
205
+ },
206
+ 'security': [{'bearerAuth': []}],
207
+ }
208
+ )
209
+
210
+ doc_32, _ = doc_31.upgrade()
211
+
212
+ assert doc_32.components.securitySchemes is not None
213
+ assert 'bearerAuth' in doc_32.components.securitySchemes
214
+ assert doc_32.security is not None
215
+ assert len(doc_32.security) == 1