robotframework-openapitools 1.0.0b2__tar.gz → 1.0.0b4__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 (44) hide show
  1. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/PKG-INFO +98 -1
  2. robotframework_openapitools-1.0.0b4/docs/README.md +102 -0
  3. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/pyproject.toml +4 -4
  4. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/openapi_executors.py +8 -8
  5. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/openapi_reader.py +12 -13
  6. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/openapidriver.libspec +4 -41
  7. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/__init__.py +0 -2
  8. robotframework_openapitools-1.0.0b4/src/OpenApiLibCore/annotations.py +10 -0
  9. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/data_generation/__init__.py +0 -2
  10. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/data_generation/body_data_generation.py +52 -71
  11. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/data_generation/data_generation_core.py +82 -62
  12. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/data_invalidation.py +37 -20
  13. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/dto_base.py +20 -86
  14. robotframework_openapitools-1.0.0b4/src/OpenApiLibCore/localized_faker.py +88 -0
  15. robotframework_openapitools-1.0.0b4/src/OpenApiLibCore/models.py +715 -0
  16. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/openapi_libcore.libspec +47 -283
  17. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/openapi_libcore.py +20 -46
  18. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/parameter_utils.py +23 -17
  19. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/path_functions.py +5 -4
  20. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/protocols.py +7 -5
  21. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/request_data.py +67 -102
  22. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/resource_relations.py +2 -3
  23. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/validation.py +49 -161
  24. robotframework_openapitools-1.0.0b4/src/OpenApiLibCore/value_utils.py +216 -0
  25. robotframework_openapitools-1.0.0b4/src/openapi_libgen/__init__.py +0 -0
  26. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/openapi_libgen/command_line.py +7 -19
  27. robotframework_openapitools-1.0.0b4/src/openapi_libgen/generator.py +84 -0
  28. robotframework_openapitools-1.0.0b4/src/openapi_libgen/spec_parser.py +154 -0
  29. robotframework_openapitools-1.0.0b2/docs/README.md +0 -6
  30. robotframework_openapitools-1.0.0b2/src/OpenApiLibCore/annotations.py +0 -3
  31. robotframework_openapitools-1.0.0b2/src/OpenApiLibCore/value_utils.py +0 -528
  32. robotframework_openapitools-1.0.0b2/src/openapi_libgen/__init__.py +0 -46
  33. robotframework_openapitools-1.0.0b2/src/openapi_libgen/spec_parser.py +0 -221
  34. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/LICENSE +0 -0
  35. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/__init__.py +0 -0
  36. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/openapidriver.py +0 -0
  37. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiDriver/py.typed +0 -0
  38. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/dto_utils.py +0 -0
  39. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/oas_cache.py +0 -0
  40. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/path_invalidation.py +0 -0
  41. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/OpenApiLibCore/py.typed +0 -0
  42. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/openapi_libgen/parsing_utils.py +0 -0
  43. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/openapi_libgen/templates/__init__.jinja +0 -0
  44. {robotframework_openapitools-1.0.0b2 → robotframework_openapitools-1.0.0b4}/src/openapi_libgen/templates/library.jinja +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: robotframework-openapitools
3
- Version: 1.0.0b2
3
+ Version: 1.0.0b4
4
4
  Summary: A set of Robot Framework libraries to test APIs for which the OAS is available.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -220,6 +220,7 @@ Requires-Dist: Jinja2 (>=3.1.2)
220
220
  Requires-Dist: black (>=24.1.0)
221
221
  Requires-Dist: openapi-core (>=0.19.0)
222
222
  Requires-Dist: prance[cli] (>=23)
223
+ Requires-Dist: pydantic (>=2.11.0)
223
224
  Requires-Dist: requests (>=2.31.0)
224
225
  Requires-Dist: rich_click (>=1.7.0)
225
226
  Requires-Dist: robotframework (>=6.0.0,!=7.0.0)
@@ -235,3 +236,99 @@ OpenApiTools is a set of libraries centered around the OpenAPI Specification:
235
236
  - [OpenApiDriver](./driver.md)
236
237
  - [OpenApiLibCore](./libcore.md)
237
238
 
239
+
240
+ ## New in OpenApiTools v1.0.0
241
+
242
+ Inspired by the work Bartlomiej and Mateusz did on #roboswag, I've created a CLI tool that generates a fully functional Robot Framework (Python) library that builds on OpenApiLibCore for automatic request data generation and request execution.
243
+
244
+ ### So how does it work?
245
+ After installing / updating to the v1.0.0 beta (`pip install robotframework-openapitools==1.0.0b3`) , there's a new CLI command available in your (virtual) environment: `generate-library`. You'll have to provide a path to the openapi spec (json or yaml, can be a url or path to the file), provide a path to where to generate the library and (optionally) a name for the library:
246
+
247
+ ```
248
+ $ generate-library
249
+ Please provide a source for the generation:
250
+ $ http://127.0.0.1:8000/openapi.json
251
+ Please provide a path to where the library will be generated:
252
+ $ ./generated
253
+ Please provide a name for the library [default: FastAPI]:
254
+ $ My Generated Library
255
+ generated/MyGeneratedLibrary/__init__.py created
256
+ generated/MyGeneratedLibrary/my_generated_library.py created
257
+ ```
258
+
259
+ > Note: there's currently 2 environment variables that are taken into account by the generator; USE_SUMMARY_AS_KEYWORD_NAME can result in nicer keyword names (but: uniqueness is not guaranteed, so you might need to rename some of the generated keywords manually) and EXPAND_BODY_ARGUMENTS is what a recent poll in #api-testing was about.
260
+
261
+ If the location where the library is located is in your Python search path, you'll be able to use it like a regular Robot Framework library (in fact, it's a drop-in replacement for OpenApiLibCore):
262
+
263
+ ```{robot}
264
+ *** Settings ***
265
+ Library MyGeneratedLibrary
266
+ ... source=${ORIGIN}/openapi.json
267
+ ... origin=${ORIGIN}
268
+ ... base_path=${EMPTY}
269
+ ... mappings_path=${ROOT}/tests/user_implemented/custom_user_mappings.py
270
+ Variables ${ROOT}/tests/variables.py
271
+
272
+
273
+ *** Variables ***
274
+ ${ORIGIN}= http://localhost:8000
275
+
276
+
277
+ *** Test Cases ***
278
+ Test Generated Keywords: Get Employees
279
+ ${response}= Get Employees
280
+ Should Be Equal As Integers ${response.status_code} 200
281
+
282
+ Test Generated Keywords: Post Employee
283
+ VAR &{body} name=Robin the Robot
284
+ ${response}= Post Employee body=${body}
285
+ # ${response}= Post Employee name=Robin the Robot
286
+ Should Be Equal As Integers ${response.status_code} 201
287
+ Should Be Equal ${response.json()}[name] Robin the Robot
288
+
289
+ Test Generated Keywords: Get Employee
290
+ ${response}= Get Employee
291
+ Should Be Equal As Integers ${response.status_code} 200
292
+
293
+ Test Generated Keywords: Patch Employee
294
+ ${employee_id}= Get Valid Id For Path path=/employees/{employee_id}
295
+ VAR &{body} date_of_birth=2021-12-31
296
+ ${response}= Patch Employee employee_id=${employee_id} body=${body}
297
+ # ${response}= Patch Employee employee_id=${employee_id} date_of_birth=2021-12-31
298
+ Should Be Equal As Integers ${response.status_code} 403
299
+
300
+ Test Generated Keywords: Post WageGroup
301
+ VAR &{body} hourly_rate=99.99
302
+ ${response}= Post Wagegroup body=${body}
303
+ # ${response}= Post Wagegroup hourly_rate=99.99
304
+ Should Be Equal As Integers ${response.status_code} 201
305
+ Should Be Equal As Numbers ${response.json()}[hourly-rate] 99.99
306
+
307
+ Test Generated Keywords: Get Energy Label
308
+ ${response}= Get Energy Label
309
+ ... zipcode=1111AA
310
+ ... home_number=10
311
+ ... extension=too long to be acceptable
312
+ ... validate_against_schema=${FALSE}
313
+ Should Be Equal As Integers ${response.status_code} 422
314
+
315
+ VAR @{omit} extension
316
+ ${response}= Get Energy Label
317
+ ... zipcode=1111AA
318
+ ... home_number=10
319
+ ... extension=too long to be acceptable
320
+ ... omit_parameters=${omit}
321
+ Should Be Equal As Integers ${response.status_code} 200
322
+ ```
323
+
324
+ ### Contributions and feedback
325
+
326
+ So now I need your feedback! Does the library generator work for your openapi spec? Does the library work / do all the generated keywords work? Please let me know of any issues you run into!
327
+ Things I'd like to address / improve before an official release:
328
+ - parameters with union types (e.g. int or float) are currently annotated as Any.
329
+ - support for lists / arrays is limited (i.e. not supported as body)
330
+ - objects / dicts are currently only typed as dict; I'm looking into TypedDict annotation for better auto-complete / auto-conversion
331
+ - a documentation rework
332
+
333
+ Subscribe to https://app.slack.com/client/T07PJQ9S7/CKK0X68KD for updates
334
+
@@ -0,0 +1,102 @@
1
+ # OpenApiTools for Robot Framework
2
+
3
+ OpenApiTools is a set of libraries centered around the OpenAPI Specification:
4
+
5
+ - [OpenApiDriver](./driver.md)
6
+ - [OpenApiLibCore](./libcore.md)
7
+
8
+
9
+ ## New in OpenApiTools v1.0.0
10
+
11
+ Inspired by the work Bartlomiej and Mateusz did on #roboswag, I've created a CLI tool that generates a fully functional Robot Framework (Python) library that builds on OpenApiLibCore for automatic request data generation and request execution.
12
+
13
+ ### So how does it work?
14
+ After installing / updating to the v1.0.0 beta (`pip install robotframework-openapitools==1.0.0b3`) , there's a new CLI command available in your (virtual) environment: `generate-library`. You'll have to provide a path to the openapi spec (json or yaml, can be a url or path to the file), provide a path to where to generate the library and (optionally) a name for the library:
15
+
16
+ ```
17
+ $ generate-library
18
+ Please provide a source for the generation:
19
+ $ http://127.0.0.1:8000/openapi.json
20
+ Please provide a path to where the library will be generated:
21
+ $ ./generated
22
+ Please provide a name for the library [default: FastAPI]:
23
+ $ My Generated Library
24
+ generated/MyGeneratedLibrary/__init__.py created
25
+ generated/MyGeneratedLibrary/my_generated_library.py created
26
+ ```
27
+
28
+ > Note: there's currently 2 environment variables that are taken into account by the generator; USE_SUMMARY_AS_KEYWORD_NAME can result in nicer keyword names (but: uniqueness is not guaranteed, so you might need to rename some of the generated keywords manually) and EXPAND_BODY_ARGUMENTS is what a recent poll in #api-testing was about.
29
+
30
+ If the location where the library is located is in your Python search path, you'll be able to use it like a regular Robot Framework library (in fact, it's a drop-in replacement for OpenApiLibCore):
31
+
32
+ ```{robot}
33
+ *** Settings ***
34
+ Library MyGeneratedLibrary
35
+ ... source=${ORIGIN}/openapi.json
36
+ ... origin=${ORIGIN}
37
+ ... base_path=${EMPTY}
38
+ ... mappings_path=${ROOT}/tests/user_implemented/custom_user_mappings.py
39
+ Variables ${ROOT}/tests/variables.py
40
+
41
+
42
+ *** Variables ***
43
+ ${ORIGIN}= http://localhost:8000
44
+
45
+
46
+ *** Test Cases ***
47
+ Test Generated Keywords: Get Employees
48
+ ${response}= Get Employees
49
+ Should Be Equal As Integers ${response.status_code} 200
50
+
51
+ Test Generated Keywords: Post Employee
52
+ VAR &{body} name=Robin the Robot
53
+ ${response}= Post Employee body=${body}
54
+ # ${response}= Post Employee name=Robin the Robot
55
+ Should Be Equal As Integers ${response.status_code} 201
56
+ Should Be Equal ${response.json()}[name] Robin the Robot
57
+
58
+ Test Generated Keywords: Get Employee
59
+ ${response}= Get Employee
60
+ Should Be Equal As Integers ${response.status_code} 200
61
+
62
+ Test Generated Keywords: Patch Employee
63
+ ${employee_id}= Get Valid Id For Path path=/employees/{employee_id}
64
+ VAR &{body} date_of_birth=2021-12-31
65
+ ${response}= Patch Employee employee_id=${employee_id} body=${body}
66
+ # ${response}= Patch Employee employee_id=${employee_id} date_of_birth=2021-12-31
67
+ Should Be Equal As Integers ${response.status_code} 403
68
+
69
+ Test Generated Keywords: Post WageGroup
70
+ VAR &{body} hourly_rate=99.99
71
+ ${response}= Post Wagegroup body=${body}
72
+ # ${response}= Post Wagegroup hourly_rate=99.99
73
+ Should Be Equal As Integers ${response.status_code} 201
74
+ Should Be Equal As Numbers ${response.json()}[hourly-rate] 99.99
75
+
76
+ Test Generated Keywords: Get Energy Label
77
+ ${response}= Get Energy Label
78
+ ... zipcode=1111AA
79
+ ... home_number=10
80
+ ... extension=too long to be acceptable
81
+ ... validate_against_schema=${FALSE}
82
+ Should Be Equal As Integers ${response.status_code} 422
83
+
84
+ VAR @{omit} extension
85
+ ${response}= Get Energy Label
86
+ ... zipcode=1111AA
87
+ ... home_number=10
88
+ ... extension=too long to be acceptable
89
+ ... omit_parameters=${omit}
90
+ Should Be Equal As Integers ${response.status_code} 200
91
+ ```
92
+
93
+ ### Contributions and feedback
94
+
95
+ So now I need your feedback! Does the library generator work for your openapi spec? Does the library work / do all the generated keywords work? Please let me know of any issues you run into!
96
+ Things I'd like to address / improve before an official release:
97
+ - parameters with union types (e.g. int or float) are currently annotated as Any.
98
+ - support for lists / arrays is limited (i.e. not supported as body)
99
+ - objects / dicts are currently only typed as dict; I'm looking into TypedDict annotation for better auto-complete / auto-conversion
100
+ - a documentation rework
101
+
102
+ Subscribe to https://app.slack.com/client/T07PJQ9S7/CKK0X68KD for updates
@@ -1,11 +1,9 @@
1
1
  [project]
2
2
  name="robotframework-openapitools"
3
- version = "1.0.0b2"
3
+ version = "1.0.0b4"
4
4
  description = "A set of Robot Framework libraries to test APIs for which the OAS is available."
5
5
  authors = [
6
6
  {name = "Robin Mackaij", email = "r.a.mackaij@gmail.com"},
7
- {name = "Bartlomiej Hirsz", email = "bartek.hirsz@gmail.com"},
8
- {name = "Mateusz Nojek", email = "matnojek@gmail.com"},
9
7
  ]
10
8
  maintainers = [
11
9
  {name = "Robin Mackaij", email = "r.a.mackaij@gmail.com"},
@@ -33,6 +31,7 @@ dependencies = [
33
31
  "rich_click >= 1.7.0",
34
32
  "black >= 24.1.0",
35
33
  "Jinja2 >= 3.1.2",
34
+ "pydantic >= 2.11.0",
36
35
  ]
37
36
 
38
37
  [dependency-groups]
@@ -101,7 +100,8 @@ build-backend = "poetry.core.masonry.api"
101
100
  [tool.coverage.run]
102
101
  branch = true
103
102
  parallel = true
104
- source = ["src/OpenApiDriver", "src/OpenApiLibCore"]
103
+ source = ["src/OpenApiDriver", "src/OpenApiLibCore", "src/openapi_libgen"]
104
+ omit = ["src/openapi_libgen/command_line.py"]
105
105
 
106
106
  [tool.coverage.report]
107
107
  exclude_lines = [
@@ -185,8 +185,8 @@ class OpenApiExecutors(OpenApiLibCore):
185
185
  # in case of a status code indicating an error, ensure the error occurs
186
186
  if status_code >= int(HTTPStatus.BAD_REQUEST):
187
187
  invalidation_keyword_data = {
188
- "get_invalid_json_data": [
189
- "get_invalid_json_data",
188
+ "get_invalid_body_data": [
189
+ "get_invalid_body_data",
190
190
  url,
191
191
  method,
192
192
  status_code,
@@ -201,13 +201,13 @@ class OpenApiExecutors(OpenApiLibCore):
201
201
  invalidation_keywords = []
202
202
 
203
203
  if request_data.dto.get_body_relations_for_error_code(status_code):
204
- invalidation_keywords.append("get_invalid_json_data")
204
+ invalidation_keywords.append("get_invalid_body_data")
205
205
  if request_data.dto.get_parameter_relations_for_error_code(status_code):
206
206
  invalidation_keywords.append("get_invalidated_parameters")
207
207
  if invalidation_keywords:
208
208
  if (
209
209
  invalidation_keyword := choice(invalidation_keywords)
210
- ) == "get_invalid_json_data":
210
+ ) == "get_invalid_body_data":
211
211
  json_data = run_keyword(
212
212
  *invalidation_keyword_data[invalidation_keyword]
213
213
  )
@@ -225,13 +225,13 @@ class OpenApiExecutors(OpenApiLibCore):
225
225
  params, headers = run_keyword(
226
226
  *invalidation_keyword_data["get_invalidated_parameters"]
227
227
  )
228
- if request_data.dto_schema:
228
+ if request_data.body_schema:
229
229
  json_data = run_keyword(
230
- *invalidation_keyword_data["get_invalid_json_data"]
230
+ *invalidation_keyword_data["get_invalid_body_data"]
231
231
  )
232
- elif request_data.dto_schema:
232
+ elif request_data.body_schema:
233
233
  json_data = run_keyword(
234
- *invalidation_keyword_data["get_invalid_json_data"]
234
+ *invalidation_keyword_data["get_invalid_body_data"]
235
235
  )
236
236
  else:
237
237
  raise SkipExecution(
@@ -1,10 +1,12 @@
1
1
  """Module holding the OpenApiReader reader_class implementation."""
2
2
 
3
- from typing import Any
3
+ from typing import Sequence
4
4
 
5
5
  from DataDriver.AbstractReaderClass import AbstractReaderClass
6
6
  from DataDriver.ReaderConfig import TestCaseData
7
7
 
8
+ from OpenApiLibCore.models import PathItemObject
9
+
8
10
 
9
11
  class Test:
10
12
  """
@@ -16,7 +18,7 @@ class Test:
16
18
  self.method = method.lower()
17
19
  self.response = str(response)
18
20
 
19
- def __eq__(self, other: Any) -> bool:
21
+ def __eq__(self, other: object) -> bool:
20
22
  if not isinstance(other, type(self)):
21
23
  return False
22
24
  return (
@@ -33,7 +35,7 @@ class OpenApiReader(AbstractReaderClass):
33
35
  test_data: list[TestCaseData] = []
34
36
 
35
37
  read_paths_method = getattr(self, "read_paths_method")
36
- paths: dict[str, Any] = read_paths_method()
38
+ paths: dict[str, PathItemObject] = read_paths_method()
37
39
  self._filter_paths(paths)
38
40
 
39
41
  ignored_responses_ = [
@@ -43,15 +45,12 @@ class OpenApiReader(AbstractReaderClass):
43
45
  ignored_tests = [Test(*test) for test in getattr(self, "ignored_testcases", [])]
44
46
 
45
47
  for path, path_item in paths.items():
48
+ path_operations = path_item.get_operations()
49
+
46
50
  # by reseversing the items, post/put operations come before get and delete
47
- for item_name, item_data in reversed(path_item.items()):
48
- # this level of the OAS also contains data that's not related to a
49
- # path operation
50
- if item_name not in ["get", "put", "post", "delete", "patch"]:
51
- continue
52
- method, method_data = item_name, item_data
53
- tags_from_spec = method_data.get("tags", [])
54
- for response in method_data.get("responses"):
51
+ for method, operation_data in reversed(path_operations.items()):
52
+ tags_from_spec = operation_data.tags
53
+ for response in operation_data.responses.keys():
55
54
  # 'default' applies to all status codes that are not specified, in
56
55
  # which case we don't know what to expect and therefore can't verify
57
56
  if (
@@ -76,7 +75,7 @@ class OpenApiReader(AbstractReaderClass):
76
75
  )
77
76
  return test_data
78
77
 
79
- def _filter_paths(self, paths: dict[str, Any]) -> None:
78
+ def _filter_paths(self, paths: dict[str, PathItemObject]) -> None:
80
79
  def matches_include_pattern(path: str) -> bool:
81
80
  for included_path in included_paths:
82
81
  if path == included_path:
@@ -111,5 +110,5 @@ class OpenApiReader(AbstractReaderClass):
111
110
  paths.pop(path)
112
111
 
113
112
 
114
- def _get_tag_list(tags: list[str], method: str, response: str) -> list[str]:
113
+ def _get_tag_list(tags: Sequence[str], method: str, response: str) -> list[str]:
115
114
  return [*tags, f"Method: {method.upper()}", f"Response: {response}"]
@@ -1,12 +1,12 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <keywordspec name="OpenApiDriver" type="LIBRARY" format="HTML" scope="SUITE" generated="2025-04-03T11:37:57+00:00" specversion="6" source="/workspaces/robotframework-openapitools/src/OpenApiDriver/openapidriver.py" lineno="358">
3
- <version>1.0.0b2</version>
2
+ <keywordspec name="OpenApiDriver" type="LIBRARY" format="HTML" scope="SUITE" generated="2025-05-11T17:23:01+00:00" specversion="6" source="/workspaces/robotframework-openapitools/src/OpenApiDriver/openapidriver.py" lineno="358">
3
+ <version>1.0.0b3</version>
4
4
  <doc>&lt;p&gt;Visit the &lt;a href="https://github.com/MarketSquare/robotframework-openapidriver"&gt;library page&lt;/a&gt; for an introduction and examples.&lt;/p&gt;</doc>
5
5
  <tags>
6
6
  </tags>
7
7
  <inits>
8
8
  <init name="__init__" lineno="150">
9
- <arguments repr="source: str, origin: str = , base_path: str = , included_paths: Iterable[str] = frozenset(), ignored_paths: Iterable[str] = frozenset(), ignored_responses: Iterable[int] = frozenset(), ignored_testcases: Iterable[tuple[str, str, int]] = frozenset(), response_validation: ValidationLevel = WARN, disable_server_validation: bool = True, mappings_path: str | Path = , invalid_property_default_response: int = 422, default_id_property_name: str = id, faker_locale: str | list[str] = , require_body_for_invalid_url: bool = False, recursion_limit: int = 1, recursion_default: dict[str, JSON] | list[JSON] | str | bytes | int | float | bool | None = {}, username: str = , password: str = , security_token: str = , auth: AuthBase | None = None, cert: str | tuple[str, str] = , verify_tls: bool | str = True, extra_headers: Mapping[str, str] = {}, cookies: MutableMapping[str, str] | RequestsCookieJar | None = None, proxies: MutableMapping[str, str] | None = None">
9
+ <arguments repr="source: str, origin: str = , base_path: str = , included_paths: Iterable[str] = frozenset(), ignored_paths: Iterable[str] = frozenset(), ignored_responses: Iterable[int] = frozenset(), ignored_testcases: Iterable[tuple[str, str, int]] = frozenset(), response_validation: ValidationLevel = WARN, disable_server_validation: bool = True, mappings_path: str | Path = , invalid_property_default_response: int = 422, default_id_property_name: str = id, faker_locale: str | list[str] = , require_body_for_invalid_url: bool = False, recursion_limit: int = 1, recursion_default: JSON = {}, username: str = , password: str = , security_token: str = , auth: AuthBase | None = None, cert: str | tuple[str, str] = , verify_tls: bool | str = True, extra_headers: Mapping[str, str] = {}, cookies: MutableMapping[str, str] | RequestsCookieJar | None = None, proxies: MutableMapping[str, str] | None = None">
10
10
  <arg kind="POSITIONAL_OR_NAMED" required="true" repr="source: str">
11
11
  <name>source</name>
12
12
  <type name="str" typedoc="string"/>
@@ -101,23 +101,9 @@
101
101
  <type name="int" typedoc="integer"/>
102
102
  <default>1</default>
103
103
  </arg>
104
- <arg kind="POSITIONAL_OR_NAMED" required="false" repr="recursion_default: dict[str, JSON] | list[JSON] | str | bytes | int | float | bool | None = {}">
104
+ <arg kind="POSITIONAL_OR_NAMED" required="false" repr="recursion_default: JSON = {}">
105
105
  <name>recursion_default</name>
106
- <type name="Union" union="true">
107
- <type name="dict" typedoc="dictionary">
108
- <type name="str" typedoc="string"/>
109
106
  <type name="JSON"/>
110
- </type>
111
- <type name="list" typedoc="list">
112
- <type name="JSON"/>
113
- </type>
114
- <type name="str" typedoc="string"/>
115
- <type name="bytes" typedoc="bytes"/>
116
- <type name="int" typedoc="integer"/>
117
- <type name="float" typedoc="float"/>
118
- <type name="bool" typedoc="boolean"/>
119
- <type name="None" typedoc="None"/>
120
- </type>
121
107
  <default>{}</default>
122
108
  </arg>
123
109
  <arg kind="POSITIONAL_OR_NAMED" required="false" repr="username: str = ">
@@ -350,17 +336,6 @@
350
336
  <usage>__init__</usage>
351
337
  </usages>
352
338
  </type>
353
- <type name="bytes" type="Standard">
354
- <doc>&lt;p&gt;Strings are converted to bytes so that each Unicode code point below 256 is directly mapped to a matching byte. Higher code points are not allowed. Robot Framework's &lt;code&gt;\xHH&lt;/code&gt; escape syntax is convenient with bytes having non-printable values.&lt;/p&gt;
355
- &lt;p&gt;Examples: &lt;code&gt;good&lt;/code&gt;, &lt;code&gt;hyvä&lt;/code&gt; (same as &lt;code&gt;hyv\xE4&lt;/code&gt;), &lt;code&gt;\x00&lt;/code&gt; (the null byte)&lt;/p&gt;</doc>
356
- <accepts>
357
- <type>string</type>
358
- <type>bytearray</type>
359
- </accepts>
360
- <usages>
361
- <usage>__init__</usage>
362
- </usages>
363
- </type>
364
339
  <type name="dictionary" type="Standard">
365
340
  <doc>&lt;p&gt;Strings must be Python &lt;a href="https://docs.python.org/library/stdtypes.html#dict"&gt;dictionary&lt;/a&gt; literals. They are converted to actual dictionaries using the &lt;a href="https://docs.python.org/library/ast.html#ast.literal_eval"&gt;ast.literal_eval&lt;/a&gt; function. They can contain any values &lt;code&gt;ast.literal_eval&lt;/code&gt; supports, including dictionaries and other containers.&lt;/p&gt;
366
341
  &lt;p&gt;If the type has nested types like &lt;code&gt;dict[str, int]&lt;/code&gt;, items are converted to those types automatically. This in new in Robot Framework 6.0.&lt;/p&gt;
@@ -373,18 +348,6 @@
373
348
  <usage>__init__</usage>
374
349
  </usages>
375
350
  </type>
376
- <type name="float" type="Standard">
377
- <doc>&lt;p&gt;Conversion is done using Python's &lt;a href="https://docs.python.org/library/functions.html#float"&gt;float&lt;/a&gt; built-in function.&lt;/p&gt;
378
- &lt;p&gt;Starting from RF 4.1, spaces and underscores can be used as visual separators for digit grouping purposes.&lt;/p&gt;
379
- &lt;p&gt;Examples: &lt;code&gt;3.14&lt;/code&gt;, &lt;code&gt;2.9979e8&lt;/code&gt;, &lt;code&gt;10 000.000 01&lt;/code&gt;&lt;/p&gt;</doc>
380
- <accepts>
381
- <type>string</type>
382
- <type>Real</type>
383
- </accepts>
384
- <usages>
385
- <usage>__init__</usage>
386
- </usages>
387
- </type>
388
351
  <type name="integer" type="Standard">
389
352
  <doc>&lt;p&gt;Conversion is done using Python's &lt;a href="https://docs.python.org/library/functions.html#int"&gt;int&lt;/a&gt; built-in function. Floating point numbers are accepted only if they can be represented as integers exactly. For example, &lt;code&gt;1.0&lt;/code&gt; is accepted and &lt;code&gt;1.1&lt;/code&gt; is not.&lt;/p&gt;
390
353
  &lt;p&gt;Starting from RF 4.1, it is possible to use hexadecimal, octal and binary numbers by prefixing values with &lt;code&gt;0x&lt;/code&gt;, &lt;code&gt;0o&lt;/code&gt; and &lt;code&gt;0b&lt;/code&gt;, respectively.&lt;/p&gt;
@@ -21,7 +21,6 @@ from OpenApiLibCore.dto_base import (
21
21
  PropertyValueConstraint,
22
22
  ResourceRelation,
23
23
  UniquePropertyValueConstraint,
24
- resolve_schema,
25
24
  )
26
25
  from OpenApiLibCore.dto_utils import DefaultDto
27
26
  from OpenApiLibCore.openapi_libcore import (
@@ -52,5 +51,4 @@ __all__ = [
52
51
  "ResourceRelation",
53
52
  "UniquePropertyValueConstraint",
54
53
  "ValidationLevel",
55
- "resolve_schema",
56
54
  ]
@@ -0,0 +1,10 @@
1
+ """Module holding reusable compound annotations."""
2
+
3
+ from typing import Union
4
+
5
+ from typing_extensions import TypeAliasType
6
+
7
+ JSON = TypeAliasType(
8
+ "JSON",
9
+ "Union[dict[str, JSON], list[JSON], str, bytes, int, float, bool, None]",
10
+ )
@@ -3,10 +3,8 @@ Module holding the functions related to data generation
3
3
  for the requests made as part of keyword exection.
4
4
  """
5
5
 
6
- from .body_data_generation import get_json_data_for_dto_class
7
6
  from .data_generation_core import get_request_data
8
7
 
9
8
  __all__ = [
10
- "get_json_data_for_dto_class",
11
9
  "get_request_data",
12
10
  ]