robotframework-openapitools 1.0.0b4__py3-none-any.whl → 1.0.1__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 (37) hide show
  1. OpenApiDriver/__init__.py +1 -0
  2. OpenApiDriver/openapi_executors.py +32 -4
  3. OpenApiDriver/openapidriver.libspec +183 -80
  4. OpenApiDriver/openapidriver.py +8 -279
  5. OpenApiLibCore/__init__.py +26 -0
  6. OpenApiLibCore/data_generation/__init__.py +0 -0
  7. OpenApiLibCore/data_generation/body_data_generation.py +4 -4
  8. OpenApiLibCore/data_generation/data_generation_core.py +18 -45
  9. OpenApiLibCore/data_invalidation.py +1 -5
  10. OpenApiLibCore/dto_base.py +31 -22
  11. OpenApiLibCore/dto_utils.py +31 -3
  12. OpenApiLibCore/localized_faker.py +0 -0
  13. OpenApiLibCore/models.py +26 -18
  14. OpenApiLibCore/openapi_libcore.libspec +229 -121
  15. OpenApiLibCore/openapi_libcore.py +45 -274
  16. OpenApiLibCore/parameter_utils.py +3 -3
  17. OpenApiLibCore/path_functions.py +5 -6
  18. OpenApiLibCore/path_invalidation.py +5 -7
  19. OpenApiLibCore/protocols.py +6 -0
  20. OpenApiLibCore/request_data.py +0 -0
  21. OpenApiLibCore/resource_relations.py +4 -2
  22. OpenApiLibCore/validation.py +4 -9
  23. OpenApiLibCore/value_utils.py +1 -1
  24. openapi_libgen/__init__.py +3 -0
  25. openapi_libgen/generator.py +2 -4
  26. openapi_libgen/parsing_utils.py +9 -5
  27. openapi_libgen/spec_parser.py +4 -4
  28. openapitools_docs/__init__.py +0 -0
  29. openapitools_docs/docstrings.py +891 -0
  30. openapitools_docs/documentation_generator.py +35 -0
  31. openapitools_docs/templates/documentation.jinja +209 -0
  32. {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.1.dist-info}/METADATA +16 -98
  33. robotframework_openapitools-1.0.1.dist-info/RECORD +44 -0
  34. robotframework_openapitools-1.0.0b4.dist-info/RECORD +0 -40
  35. {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.1.dist-info}/LICENSE +0 -0
  36. {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.1.dist-info}/WHEEL +0 -0
  37. {robotframework_openapitools-1.0.0b4.dist-info → robotframework_openapitools-1.0.1.dist-info}/entry_points.txt +0 -0
@@ -1,123 +1,3 @@
1
- """
2
- # OpenApiLibCore for Robot Framework
3
-
4
- The OpenApiLibCore library is a utility library that is meant to simplify creation
5
- of other Robot Framework libraries for API testing based on the information in
6
- an OpenAPI document (also known as Swagger document).
7
- This document explains how to use the OpenApiLibCore library.
8
-
9
- My RoboCon 2022 talk about OpenApiDriver and OpenApiLibCore can be found
10
- [here](https://www.youtube.com/watch?v=7YWZEHxk9Ps)
11
-
12
- For more information about Robot Framework, see http://robotframework.org.
13
-
14
- ---
15
-
16
- > Note: OpenApiLibCore is still being developed so there are currently
17
- restrictions / limitations that you may encounter when using this library to run
18
- tests against an API. See [Limitations](#limitations) for details.
19
-
20
- ---
21
-
22
- ## Installation
23
-
24
- If you already have Python >= 3.8 with pip installed, you can simply run:
25
-
26
- `pip install --upgrade robotframework-openapi-libcore`
27
-
28
- ---
29
-
30
- ## OpenAPI (aka Swagger)
31
-
32
- The OpenAPI Specification (OAS) defines a standard, language-agnostic interface
33
- to RESTful APIs, see https://swagger.io/specification/
34
-
35
- The OpenApiLibCore implements a number of Robot Framework keywords that make it
36
- easy to interact with an OpenAPI implementation by using the information in the
37
- openapi document (Swagger file), for examply by automatic generation of valid values
38
- for requests based on the schema information in the document.
39
-
40
- > Note: OpenApiLibCore is designed for APIs based on the OAS v3
41
- The library has not been tested for APIs based on the OAS v2.
42
-
43
- ---
44
-
45
- ## Getting started
46
-
47
- Before trying to use the keywords exposed by OpenApiLibCore on the target API
48
- it's recommended to first ensure that the openapi document for the API is valid
49
- under the OpenAPI Specification.
50
-
51
- This can be done using the command line interface of a package that is installed as
52
- a prerequisite for OpenApiLibCore.
53
- Both a local openapi.json or openapi.yaml file or one hosted by the API server
54
- can be checked using the `prance validate <reference_to_file>` shell command:
55
-
56
- ```shell
57
- prance validate --backend=openapi-spec-validator http://localhost:8000/openapi.json
58
- Processing "http://localhost:8000/openapi.json"...
59
- -> Resolving external references.
60
- Validates OK as OpenAPI 3.0.2!
61
-
62
- prance validate --backend=openapi-spec-validator /tests/files/petstore_openapi.yaml
63
- Processing "/tests/files/petstore_openapi.yaml"...
64
- -> Resolving external references.
65
- Validates OK as OpenAPI 3.0.2!
66
- ```
67
-
68
- You'll have to change the url or file reference to the location of the openapi
69
- document for your API.
70
-
71
- > Note: Although recursion is technically allowed under the OAS, tool support is limited
72
- and changing the OAS to not use recursion is recommended.
73
- OpenApiLibCore has limited support for parsing OpenAPI documents with
74
- recursion in them. See the `recursion_limit` and `recursion_default` parameters.
75
-
76
- If the openapi document passes this validation, the next step is trying to do a test
77
- run with a minimal test suite.
78
- The example below can be used, with `source`, `origin` and `path` altered to
79
- fit your situation.
80
-
81
- ``` robotframework
82
- *** Settings ***
83
- Library OpenApiLibCore
84
- ... source=http://localhost:8000/openapi.json
85
- ... origin=http://localhost:8000
86
-
87
- *** Test Cases ***
88
- Getting Started
89
- ${url}= Get Valid Url path=/employees/{employee_id}
90
-
91
- ```
92
-
93
- Running the above suite for the first time may result in an error / failed test.
94
- You should look at the Robot Framework `log.html` to determine the reasons
95
- for the failing tests.
96
- Depending on the reasons for the failures, different solutions are possible.
97
-
98
- Details about the OpenApiLibCore library parameters and keywords that you may need can be found
99
- [here](https://marketsquare.github.io/robotframework-openapi-libcore/openapi_libcore.html).
100
-
101
- The OpenApiLibCore also support handling of relations between resources within the scope
102
- of the API being validated as well as handling dependencies on resources outside the
103
- scope of the API. In addition there is support for handling restrictions on the values
104
- of parameters and properties.
105
-
106
- Details about the `mappings_path` variable usage can be found
107
- [here](https://marketsquare.github.io/robotframework-openapi-libcore/advanced_use.html).
108
-
109
- ---
110
-
111
- ## Limitations
112
-
113
- There are currently a number of limitations to supported API structures, supported
114
- data types and properties. The following list details the most important ones:
115
- - Only JSON request and response bodies are supported.
116
- - No support for per-endpoint authorization levels.
117
- - Parsing of OAS 3.1 documents is supported by the parsing tools, but runtime behavior is untested.
118
-
119
- """
120
-
121
1
  import json as _json
122
2
  import sys
123
3
  from collections.abc import Mapping, MutableMapping
@@ -140,17 +20,18 @@ from robot.api.exceptions import FatalError
140
20
  from robot.libraries.BuiltIn import BuiltIn
141
21
 
142
22
  import OpenApiLibCore.data_generation as _data_generation
143
- import OpenApiLibCore.data_invalidation as di
144
- import OpenApiLibCore.path_functions as pf
145
- import OpenApiLibCore.path_invalidation as pi
146
- import OpenApiLibCore.resource_relations as rr
147
- import OpenApiLibCore.validation as val
23
+ import OpenApiLibCore.data_invalidation as _data_invalidation
24
+ import OpenApiLibCore.path_functions as _path_functions
25
+ import OpenApiLibCore.path_invalidation as _path_invalidation
26
+ import OpenApiLibCore.resource_relations as _resource_relations
27
+ import OpenApiLibCore.validation as _validation
148
28
  from OpenApiLibCore.annotations import JSON
149
29
  from OpenApiLibCore.dto_base import Dto, IdReference
150
30
  from OpenApiLibCore.dto_utils import (
151
31
  DEFAULT_ID_PROPERTY_NAME,
152
32
  get_dto_class,
153
33
  get_id_property_name,
34
+ get_path_dto_class,
154
35
  )
155
36
  from OpenApiLibCore.localized_faker import FAKE
156
37
  from OpenApiLibCore.models import (
@@ -164,27 +45,24 @@ from OpenApiLibCore.parameter_utils import (
164
45
  )
165
46
  from OpenApiLibCore.protocols import ResponseValidatorType
166
47
  from OpenApiLibCore.request_data import RequestData, RequestValues
48
+ from openapitools_docs.docstrings import (
49
+ OPENAPILIBCORE_INIT_DOCSTRING,
50
+ OPENAPILIBCORE_LIBRARY_DOCSTRING,
51
+ )
167
52
 
168
53
  run_keyword = BuiltIn().run_keyword
169
54
  default_str_mapping: Mapping[str, str] = MappingProxyType({})
170
55
  default_json_mapping: Mapping[str, JSON] = MappingProxyType({})
171
56
 
172
57
 
173
- @library(scope="SUITE", doc_format="ROBOT")
58
+ @library(scope="SUITE", doc_format="HTML")
174
59
  class OpenApiLibCore: # pylint: disable=too-many-public-methods
175
- """
176
- Main class providing the keywords and core logic to interact with an OpenAPI server.
177
-
178
- Visit the [https://github.com/MarketSquare/robotframework-openapi-libcore | library page]
179
- for an introduction.
180
- """
181
-
182
60
  def __init__( # noqa: PLR0913, pylint: disable=dangerous-default-value
183
61
  self,
184
62
  source: str,
185
63
  origin: str = "",
186
64
  base_path: str = "",
187
- response_validation: val.ValidationLevel = val.ValidationLevel.WARN,
65
+ response_validation: _validation.ValidationLevel = _validation.ValidationLevel.WARN,
188
66
  disable_server_validation: bool = True,
189
67
  mappings_path: str | Path = "",
190
68
  invalid_property_default_response: int = 422,
@@ -203,126 +81,6 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
203
81
  cookies: MutableMapping[str, str] | CookieJar | None = None,
204
82
  proxies: MutableMapping[str, str] | None = None,
205
83
  ) -> None:
206
- """
207
- == Base parameters ==
208
-
209
- === source ===
210
- An absolute path to an openapi.json or openapi.yaml file or an url to such a file.
211
-
212
- === origin ===
213
- The server (and port) of the target server. E.g. ``https://localhost:8000``
214
-
215
- === base_path ===
216
- The routing between ``origin`` and the paths as found in the ``paths``
217
- section in the openapi document.
218
- E.g. ``/petshop/v2``.
219
-
220
- == Test case execution ==
221
-
222
- === response_validation ===
223
- By default, a ``WARN`` is logged when the Response received after a Request does not
224
- comply with the schema as defined in the openapi document for the given operation. The
225
- following values are supported:
226
-
227
- - ``DISABLED``: All Response validation errors will be ignored
228
- - ``INFO``: Any Response validation erros will be logged at ``INFO`` level
229
- - ``WARN``: Any Response validation erros will be logged at ``WARN`` level
230
- - ``STRICT``: The Test Case will fail on any Response validation errors
231
-
232
- === disable_server_validation ===
233
- If enabled by setting this parameter to ``True``, the Response validation will also
234
- include possible errors for Requests made to a server address that is not defined in
235
- the list of servers in the openapi document. This generally means that if there is a
236
- mismatch, every Test Case will raise this error. Note that ``localhost`` and
237
- ``127.0.0.1`` are not considered the same by Response validation.
238
-
239
- == API-specific configurations ==
240
-
241
- === mappings_path ===
242
- See [https://marketsquare.github.io/robotframework-openapi-libcore/advanced_use.html | this page]
243
- for an in-depth explanation.
244
-
245
- === invalid_property_default_response ===
246
- The default response code for requests with a JSON body that does not comply
247
- with the schema.
248
- Example: a value outside the specified range or a string value
249
- for a property defined as integer in the schema.
250
-
251
- === default_id_property_name ===
252
- The default name for the property that identifies a resource (i.e. a unique
253
- entity) within the API.
254
- The default value for this property name is ``id``.
255
- If the target API uses a different name for all the resources within the API,
256
- you can configure it globally using this property.
257
-
258
- If different property names are used for the unique identifier for different
259
- types of resources, an ``ID_MAPPING`` can be implemented using the ``mappings_path``.
260
-
261
- === faker_locale ===
262
- A locale string or list of locale strings to pass to the Faker library to be
263
- used in generation of string data for supported format types.
264
-
265
- === require_body_for_invalid_url ===
266
- When a request is made against an invalid url, this usually is because of a "404" request;
267
- a request for a resource that does not exist. Depending on API implementation, when a
268
- request with a missing or invalid request body is made on a non-existent resource,
269
- either a 404 or a 422 or 400 Response is normally returned. If the API being tested
270
- processes the request body before checking if the requested resource exists, set
271
- this parameter to True.
272
-
273
- == Parsing parameters ==
274
-
275
- === recursion_limit ===
276
- The recursion depth to which to fully parse recursive references before the
277
- `recursion_default` is used to end the recursion.
278
-
279
- === recursion_default ===
280
- The value that is used instead of the referenced schema when the
281
- `recursion_limit` has been reached.
282
- The default `{}` represents an empty object in JSON.
283
- Depending on schema definitions, this may cause schema validation errors.
284
- If this is the case, 'None' (``${NONE}`` in Robot Framework) or an empty list
285
- can be tried as an alternative.
286
-
287
- == Security-related parameters ==
288
- _Note: these parameters are equivalent to those in the ``requests`` library._
289
-
290
- === username ===
291
- The username to be used for Basic Authentication.
292
-
293
- === password ===
294
- The password to be used for Basic Authentication.
295
-
296
- === security_token ===
297
- The token to be used for token based security using the ``Authorization`` header.
298
-
299
- === auth ===
300
- A [https://requests.readthedocs.io/en/latest/api/#authentication | requests ``AuthBase`` instance]
301
- to be used for authentication instead of the ``username`` and ``password``.
302
-
303
- === cert ===
304
- The SSL certificate to use with all requests.
305
- If string: the path to ssl client cert file (.pem).
306
- If tuple: the ('cert', 'key') pair.
307
-
308
- === verify_tls ===
309
- Whether or not to verify the TLS / SSL certificate of the server.
310
- If boolean: whether or not to verify the server TLS certificate.
311
- If string: path to a CA bundle to use for verification.
312
-
313
- === extra_headers ===
314
- A dictionary with extra / custom headers that will be send with every request.
315
- This parameter can be used to send headers that are not documented in the
316
- openapi document or to provide an API-key.
317
-
318
- === cookies ===
319
- A dictionary or
320
- [https://docs.python.org/3/library/http.cookiejar.html#http.cookiejar.CookieJar | CookieJar object]
321
- to send with all requests.
322
-
323
- === proxies ===
324
- A dictionary of 'protocol': 'proxy url' to use for all requests.
325
- """
326
84
  self._source = source
327
85
  self._origin = origin
328
86
  self._base_path = base_path
@@ -359,12 +117,18 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
359
117
  self.get_dto_class = get_dto_class(
360
118
  mappings_module_name=mappings_module_name
361
119
  )
120
+ self.get_path_dto_class = get_path_dto_class(
121
+ mappings_module_name=mappings_module_name
122
+ )
362
123
  self.get_id_property_name = get_id_property_name(
363
124
  mappings_module_name=mappings_module_name
364
125
  )
365
126
  sys.path.pop()
366
127
  else:
367
128
  self.get_dto_class = get_dto_class(mappings_module_name="no mapping")
129
+ self.get_path_dto_class = get_path_dto_class(
130
+ mappings_module_name="no mapping"
131
+ )
368
132
  self.get_id_property_name = get_id_property_name(
369
133
  mappings_module_name="no mapping"
370
134
  )
@@ -500,7 +264,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
500
264
  > Note: applicable UniquePropertyValueConstraint and IdReference Relations are
501
265
  considered before changes to `json_data` are made.
502
266
  """
503
- return di.get_invalid_body_data(
267
+ return _data_invalidation.get_invalid_body_data(
504
268
  url=url,
505
269
  method=method,
506
270
  status_code=status_code,
@@ -518,7 +282,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
518
282
  Returns a version of `params, headers` as present on `request_data` that has
519
283
  been modified to cause the provided `status_code`.
520
284
  """
521
- return di.get_invalidated_parameters(
285
+ return _data_invalidation.get_invalidated_parameters(
522
286
  status_code=status_code,
523
287
  request_data=request_data,
524
288
  invalid_property_default_response=self.invalid_property_default_response,
@@ -533,7 +297,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
533
297
  returned by the `get_relations` implementation on the `dto` for the given
534
298
  `conflict_status_code`.
535
299
  """
536
- return di.get_json_data_with_conflict(
300
+ return _data_invalidation.get_json_data_with_conflict(
537
301
  url=url,
538
302
  base_url=self.base_url,
539
303
  method=method,
@@ -555,10 +319,10 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
555
319
  `PathPropertiesConstraint` Relation can be used. More information can be found
556
320
  [https://marketsquare.github.io/robotframework-openapitools/advanced_use.html | here].
557
321
  """
558
- return pf.get_valid_url(
322
+ return _path_functions.get_valid_url(
559
323
  path=path,
560
324
  base_url=self.base_url,
561
- get_dto_class=self.get_dto_class,
325
+ get_path_dto_class=self.get_path_dto_class,
562
326
  openapi_spec=self.openapi_spec,
563
327
  )
564
328
 
@@ -570,7 +334,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
570
334
  To prevent resource conflicts with other test cases, a new resource is created
571
335
  (by a POST operation) if possible.
572
336
  """
573
- return pf.get_valid_id_for_path(
337
+ return _path_functions.get_valid_id_for_path(
574
338
  path=path, get_id_property_name=self.get_id_property_name
575
339
  )
576
340
 
@@ -583,7 +347,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
583
347
  path_parts = path.split("/")
584
348
  # first part will be '' since a path starts with /
585
349
  path_parts.pop(0)
586
- parameterized_path = pf.get_parametrized_path(
350
+ parameterized_path = _path_functions.get_parametrized_path(
587
351
  path=path, openapi_spec=self.openapi_spec
588
352
  )
589
353
  return parameterized_path
@@ -594,7 +358,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
594
358
  Perform a GET request on the `url` and return the list of resource
595
359
  `ids` from the response.
596
360
  """
597
- return pf.get_ids_from_url(
361
+ return _path_functions.get_ids_from_url(
598
362
  url=url, get_id_property_name=self.get_id_property_name
599
363
  )
600
364
 
@@ -611,13 +375,13 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
611
375
  on the mapped `path` and `expected_status_code`.
612
376
  If a PathPropertiesConstraint is mapped, the `invalid_value` is returned.
613
377
 
614
- Raises ValueError if the valid_url cannot be invalidated.
378
+ Raises: ValueError if the valid_url cannot be invalidated.
615
379
  """
616
- return pi.get_invalidated_url(
380
+ return _path_invalidation.get_invalidated_url(
617
381
  valid_url=valid_url,
618
382
  path=path,
619
383
  base_url=self.base_url,
620
- get_dto_class=self.get_dto_class,
384
+ get_path_dto_class=self.get_path_dto_class,
621
385
  expected_status_code=expected_status_code,
622
386
  )
623
387
 
@@ -629,7 +393,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
629
393
  Ensure that the (right-most) `id` of the resource referenced by the `url`
630
394
  is used by the resource defined by the `resource_relation`.
631
395
  """
632
- rr.ensure_in_use(
396
+ _resource_relations.ensure_in_use(
633
397
  url=url,
634
398
  base_url=self.base_url,
635
399
  openapi_spec=self.openapi_spec,
@@ -700,7 +464,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
700
464
  Response keyword and finally validates, for `DELETE` operations, whether
701
465
  the target resource was indeed deleted (OK response) or not (error responses).
702
466
  """
703
- val.perform_validated_request(
467
+ _validation.perform_validated_request(
704
468
  path=path,
705
469
  status_code=status_code,
706
470
  request_values=request_values,
@@ -713,7 +477,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
713
477
  Validate the `response` against the OpenAPI Spec that is
714
478
  loaded during library initialization.
715
479
  """
716
- val.validate_response_using_validator(
480
+ _validation.validate_response_using_validator(
717
481
  response=response,
718
482
  response_validator=self.response_validator,
719
483
  )
@@ -726,7 +490,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
726
490
  Attempt to GET the resource referenced by the `href` and validate it's equal
727
491
  to the provided `referenced_resource` object / dictionary.
728
492
  """
729
- val.assert_href_to_resource_is_valid(
493
+ _validation.assert_href_to_resource_is_valid(
730
494
  href=href,
731
495
  origin=self.origin,
732
496
  base_url=self.base_url,
@@ -750,7 +514,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
750
514
  - validate that no `original_data` is preserved when performing a PUT operation
751
515
  - validate that a PATCH operation only updates the provided properties
752
516
  """
753
- val.validate_response(
517
+ _validation.validate_response(
754
518
  path=path,
755
519
  response=response,
756
520
  response_validator=self.response_validator,
@@ -774,7 +538,9 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
774
538
  In case a PATCH request, validate that only the properties that were patched
775
539
  have changed and that other properties are still at their pre-patch values.
776
540
  """
777
- val.validate_send_response(response=response, original_data=original_data)
541
+ _validation.validate_send_response(
542
+ response=response, original_data=original_data
543
+ )
778
544
 
779
545
  # endregion
780
546
 
@@ -844,7 +610,7 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
844
610
  refstring: str, # pylint: disable=unused-argument
845
611
  recursions: JSON, # pylint: disable=unused-argument
846
612
  ) -> JSON:
847
- return self._recursion_default
613
+ return self._recursion_default # pragma: no cover
848
614
 
849
615
  try:
850
616
  # Since parsing of the OAS and creating the Spec can take a long time,
@@ -892,14 +658,19 @@ class OpenApiLibCore: # pylint: disable=too-many-public-methods
892
658
 
893
659
  return parser, validation_spec, response_validator
894
660
 
895
- except ResolutionError as exception:
661
+ except ResolutionError as exception: # pragma: no cover
896
662
  raise FatalError(
897
663
  f"ResolutionError while trying to load openapi spec: {exception}"
898
664
  ) from exception
899
- except ValidationError as exception:
665
+ except ValidationError as exception: # pragma: no cover
900
666
  raise FatalError(
901
667
  f"ValidationError while trying to load openapi spec: {exception}"
902
668
  ) from exception
903
669
 
904
670
  def read_paths(self) -> dict[str, PathItemObject]:
905
671
  return self.openapi_spec.paths
672
+
673
+ __init__.__doc__ = OPENAPILIBCORE_INIT_DOCSTRING
674
+
675
+
676
+ OpenApiLibCore.__doc__ = OPENAPILIBCORE_LIBRARY_DOCSTRING
@@ -24,7 +24,7 @@ def get_safe_name_for_oas_name(oas_name: str) -> str:
24
24
  PARAMETER_REGISTRY[oas_name] = oas_name
25
25
  return oas_name
26
26
 
27
- safe_name = _convert_string_to_python_identifier(oas_name)
27
+ safe_name = convert_string_to_python_identifier(oas_name)
28
28
 
29
29
  if safe_name not in PARAMETER_REGISTRY:
30
30
  PARAMETER_REGISTRY[safe_name] = oas_name
@@ -36,7 +36,7 @@ def get_safe_name_for_oas_name(oas_name: str) -> str:
36
36
  # We're dealing with multiple oas_names that convert to the same safe_name.
37
37
  # To resolve this, a more verbose safe_name is generated. This is less user-friendly
38
38
  # but necessary to ensure an one-to-one mapping.
39
- verbose_safe_name = _convert_string_to_python_identifier(oas_name, verbose=True)
39
+ verbose_safe_name = convert_string_to_python_identifier(oas_name, verbose=True)
40
40
  if verbose_safe_name not in PARAMETER_REGISTRY:
41
41
  PARAMETER_REGISTRY[verbose_safe_name] = oas_name
42
42
  return verbose_safe_name
@@ -46,7 +46,7 @@ def _is_python_safe(name: str) -> bool:
46
46
  return name.isidentifier()
47
47
 
48
48
 
49
- def _convert_string_to_python_identifier(string: str, verbose: bool = False) -> str:
49
+ def convert_string_to_python_identifier(string: str, verbose: bool = False) -> str:
50
50
  def _convert_string_to_python_identifier() -> Generator[str, None, None]:
51
51
  string_iterator = iter(string)
52
52
 
@@ -8,9 +8,8 @@ from typing import Any
8
8
  from requests import Response
9
9
  from robot.libraries.BuiltIn import BuiltIn
10
10
 
11
- from OpenApiLibCore.dto_base import PathPropertiesConstraint
12
11
  from OpenApiLibCore.models import OpenApiObject
13
- from OpenApiLibCore.protocols import GetDtoClassType, GetIdPropertyNameType
12
+ from OpenApiLibCore.protocols import GetIdPropertyNameType, GetPathDtoClassType
14
13
  from OpenApiLibCore.request_data import RequestData
15
14
 
16
15
  run_keyword = BuiltIn().run_keyword
@@ -64,7 +63,7 @@ def get_parametrized_path(path: str, openapi_spec: OpenApiObject) -> str:
64
63
  def get_valid_url(
65
64
  path: str,
66
65
  base_url: str,
67
- get_dto_class: GetDtoClassType,
66
+ get_path_dto_class: GetPathDtoClassType,
68
67
  openapi_spec: OpenApiObject,
69
68
  ) -> str:
70
69
  try:
@@ -75,9 +74,9 @@ def get_valid_url(
75
74
  raise ValueError(
76
75
  f"{path} not found in paths section of the OpenAPI document."
77
76
  ) from None
78
- dto_class = get_dto_class(path=path, method="get")
79
- relations = dto_class.get_relations()
80
- paths = [p.path for p in relations if isinstance(p, PathPropertiesConstraint)]
77
+ dto_class = get_path_dto_class(path=path)
78
+ relations = dto_class.get_path_relations()
79
+ paths = [p.path for p in relations]
81
80
  if paths:
82
81
  url = f"{base_url}{choice(paths)}"
83
82
  return url
@@ -5,8 +5,7 @@ from uuid import uuid4
5
5
 
6
6
  from robot.libraries.BuiltIn import BuiltIn
7
7
 
8
- from OpenApiLibCore.dto_base import PathPropertiesConstraint
9
- from OpenApiLibCore.protocols import GetDtoClassType
8
+ from OpenApiLibCore.protocols import GetPathDtoClassType
10
9
 
11
10
  run_keyword = BuiltIn().run_keyword
12
11
 
@@ -15,16 +14,15 @@ def get_invalidated_url(
15
14
  valid_url: str,
16
15
  path: str,
17
16
  base_url: str,
18
- get_dto_class: GetDtoClassType,
17
+ get_path_dto_class: GetPathDtoClassType,
19
18
  expected_status_code: int,
20
19
  ) -> str:
21
- dto_class = get_dto_class(path=path, method="get")
22
- relations = dto_class.get_relations()
20
+ dto_class = get_path_dto_class(path=path)
21
+ relations = dto_class.get_path_relations()
23
22
  paths = [
24
23
  p.invalid_value
25
24
  for p in relations
26
- if isinstance(p, PathPropertiesConstraint)
27
- and p.invalid_value_error_code == expected_status_code
25
+ if p.invalid_value_error_code == expected_status_code
28
26
  ]
29
27
  if paths:
30
28
  url = f"{base_url}{choice(paths)}"
@@ -30,3 +30,9 @@ class GetIdPropertyNameType(Protocol):
30
30
  ) -> tuple[
31
31
  str, Callable[[str], str] | Callable[[int], int]
32
32
  ]: ... # pragma: no cover
33
+
34
+
35
+ class GetPathDtoClassType(Protocol):
36
+ def __init__(self, mappings_module_name: str) -> None: ... # pragma: no cover
37
+
38
+ def __call__(self, path: str) -> Type[Dto]: ... # pragma: no cover
File without changes
@@ -4,7 +4,7 @@ from requests import Response
4
4
  from robot.api import logger
5
5
  from robot.libraries.BuiltIn import BuiltIn
6
6
 
7
- import OpenApiLibCore.path_functions as pf
7
+ import OpenApiLibCore.path_functions as _path_functions
8
8
  from OpenApiLibCore.dto_base import IdReference
9
9
  from OpenApiLibCore.models import OpenApiObject
10
10
  from OpenApiLibCore.request_data import RequestData
@@ -22,7 +22,9 @@ def ensure_in_use(
22
22
 
23
23
  path = url.replace(base_url, "")
24
24
  path_parts = path.split("/")
25
- parameterized_path = pf.get_parametrized_path(path=path, openapi_spec=openapi_spec)
25
+ parameterized_path = _path_functions.get_parametrized_path(
26
+ path=path, openapi_spec=openapi_spec
27
+ )
26
28
  parameterized_path_parts = parameterized_path.split("/")
27
29
  for part, param_part in zip(
28
30
  reversed(path_parts), reversed(parameterized_path_parts)
@@ -75,7 +75,7 @@ def perform_validated_request(
75
75
  f"\nGot: {_json.dumps(response_json, indent=4, sort_keys=True)}"
76
76
  )
77
77
  raise AssertionError(
78
- f"Response status_code {response.status_code} was not {status_code}"
78
+ f"Response status_code {response.status_code} was not {status_code}."
79
79
  )
80
80
 
81
81
  run_keyword("validate_response", path, response, original_data)
@@ -90,7 +90,7 @@ def perform_validated_request(
90
90
  if response.ok:
91
91
  if get_response.ok:
92
92
  raise AssertionError(
93
- f"Resource still exists after deletion. Url was {request_values.url}"
93
+ f"Resource still exists after deletion. Url was {request_values.url}."
94
94
  )
95
95
  # if the path supports GET, 404 is expected, if not 405 is expected
96
96
  if get_response.status_code not in [404, 405]:
@@ -102,7 +102,7 @@ def perform_validated_request(
102
102
  elif not get_response.ok:
103
103
  raise AssertionError(
104
104
  f"Resource could not be retrieved after failed deletion. "
105
- f"Url was {request_values.url}, status_code was {get_response.status_code}"
105
+ f"Url was {request_values.url}, status_code was {get_response.status_code}."
106
106
  )
107
107
 
108
108
 
@@ -279,11 +279,6 @@ def validate_send_response(
279
279
  )
280
280
  return None
281
281
 
282
- # FIXME: this applies to removed code
283
- # POST on /resource_type/{id}/array_item/ will return the updated {id} resource
284
- # instead of a newly created resource. In this case, the send_json must be
285
- # in the array of the 'array_item' property on {id}
286
-
287
282
  send_path: str = response.request.path_url
288
283
  response_path = response_data.get("href", None)
289
284
  if response_path and send_path not in response_path:
@@ -380,6 +375,6 @@ def _get_response_object(
380
375
  path_operations = path_item.get_operations()
381
376
  operation_data = path_operations.get(method)
382
377
  if operation_data is None:
383
- raise ValueError(f"method '{method}' not supported for {path}")
378
+ raise ValueError(f"method '{method}' not supported for {path}.")
384
379
 
385
380
  return operation_data.responses[status]
@@ -98,7 +98,7 @@ def get_invalid_value(
98
98
  # Violate min / max values or length if possible
99
99
  try:
100
100
  values_out_of_bounds = value_schema.get_values_out_of_bounds(
101
- current_value=current_value
101
+ current_value=current_value # type: ignore[arg-type]
102
102
  )
103
103
  invalid_values += values_out_of_bounds
104
104
  except ValueError:
@@ -0,0 +1,3 @@
1
+ from openapitools_docs.docstrings import OPENAPILIBGEN_DOCUMENTATION
2
+
3
+ __doc__ = OPENAPILIBGEN_DOCUMENTATION