Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
f8e063b
New endpoint and related tests for requests with non-object body.
robinmackaij Oct 1, 2025
4ef9dc3
Reorganize into submodules, moving logic into oas_models
robinmackaij Oct 2, 2025
c5a4df5
Fixed imports in unit tests
robinmackaij Oct 2, 2025
bff924d
Refactor towards removing get_path_dto_class
robinmackaij Oct 2, 2025
24aadd2
id_mapping attached to PathItemObject
robinmackaij Oct 3, 2025
92c64ea
path_mapping cleanup
robinmackaij Oct 3, 2025
aeb05e8
dto_mapping refactored, DefaultDto no longer needed
robinmackaij Oct 3, 2025
17fb906
Some naming improvements
robinmackaij Oct 3, 2025
a653cbf
Separate generated json_data from constraint logic, move valid value …
robinmackaij Oct 7, 2025
4624527
Improved invalidation logic for array bodies
robinmackaij Oct 7, 2025
3eff093
Add Python 3.14 to ci
robinmackaij Oct 20, 2025
2a07847
minimize devcontainer extensions
robinmackaij Oct 20, 2025
9874ba9
version bump and dependency update
robinmackaij Oct 20, 2025
8dd58ab
add .robot.tom to gitignore
robinmackaij Oct 20, 2025
b916ac5
Intermediate rename / refactor step
robinmackaij Oct 20, 2025
dafc2c8
Merge branch 'main' into 9_support_array_request_body
robinmackaij Nov 3, 2025
5868713
poetry.lock regenerated
robinmackaij Nov 3, 2025
9680d40
Merge branch 'main' into 9_support_array_request_body
robinmackaij Nov 17, 2025
c2b6b3e
Merge branch 'main' into 9_support_array_request_body
robinmackaij Nov 18, 2025
22482a4
Parameters at path level no longer need to be registered.
robinmackaij Nov 18, 2025
56a6908
refactor: get_invalid_value_from_constraint moved to models
robinmackaij Nov 19, 2025
100bb86
remove unused method
robinmackaij Nov 19, 2025
1d020eb
annotation improvements
robinmackaij Nov 19, 2025
94ec1c3
Missing tests for ID mapping added
robinmackaij Nov 20, 2025
b4d1eb8
annotation improvements
robinmackaij Nov 20, 2025
e779014
no cover markers added
robinmackaij Nov 20, 2025
08d878e
Addressing typing issues
robinmackaij Nov 25, 2025
0a8ebd2
Fix for Response headers that contain charset for json mime types
robinmackaij Nov 26, 2025
cec0df8
address deprecation in openapi_core
robinmackaij Nov 27, 2025
bd4d82d
prevent KeyError during response validation
robinmackaij Nov 27, 2025
9c12a0d
Added missing tests
robinmackaij Nov 27, 2025
deb62f9
Updated dependencies / minimum versions
robinmackaij Nov 27, 2025
ed27ecb
Additional tests on schema variations, model discriminator refactor
robinmackaij Dec 1, 2025
24deb08
Handle Content-Type case-insensitive
robinmackaij Dec 2, 2025
96a057c
get_invalid_data on ObjectSchema refactored / simplified
robinmackaij Dec 2, 2025
d2e7251
ignore markers and docuementation changes
robinmackaij Dec 2, 2025
d0c7bc7
unit tests restructured and improved
robinmackaij Dec 2, 2025
9e64e0f
example EtagListener improved header handling
robinmackaij Dec 2, 2025
780438d
Remove disfunctional byte string support
robinmackaij Dec 5, 2025
3a587a8
coverage pragma tweaks
robinmackaij Dec 5, 2025
aa51dce
Push constraint mapping to Schemas
robinmackaij Dec 9, 2025
f956c41
Further refactored, added tests
robinmackaij Dec 9, 2025
767a201
Removed unused code, updated coverage pragmas.
robinmackaij Dec 9, 2025
c95fba8
Merge pull request #99 from MarketSquare/9_support_array_request_body
robinmackaij Dec 9, 2025
c199bce
Fix unit tests under Python 3.14
robinmackaij Dec 10, 2025
e405b3b
Initial release notes
robinmackaij Dec 11, 2025
1aa4e26
various fixes, tests green
robinmackaij Dec 15, 2025
164fdc7
Fixes and additional tests
robinmackaij Dec 18, 2025
8c33740
Merge pull request #104 from MarketSquare/81_nullable_not_used_in_get…
robinmackaij Dec 18, 2025
6615484
Update to release notes
robinmackaij Dec 18, 2025
ae57c03
Use caps for encoding (consistency change)
robinmackaij Dec 19, 2025
8ffdf1e
Boyscout: address warning due to non-unique generated test name
robinmackaij Dec 19, 2025
0a2e25e
Refactor to prevent SSLErros from prance when cert is set at library …
robinmackaij Dec 19, 2025
928b4d2
Release notes update
robinmackaij Dec 19, 2025
7233403
Merge pull request #105 from MarketSquare/93_prevent_ssl_error_if_cer…
robinmackaij Dec 19, 2025
cb5b531
Support for multiple OpenApiLibCore instances within a suite added.
robinmackaij Dec 22, 2025
6ac9019
Merge pull request #106 from MarketSquare/96_allow_multiple_instances…
robinmackaij Dec 22, 2025
65ced71
Dto renamed to RelationsMapping, constraint_mapping renamed to relati…
robinmackaij Dec 22, 2025
73e671d
Merge pull request #107 from MarketSquare/95_better_name_for_dto
robinmackaij Dec 22, 2025
713e312
Validated Request, Perform Authorized Request and Get Request Values …
robinmackaij Dec 23, 2025
2490cdb
Convert Request Values To Dict keyword adeed, tests added, annotation…
robinmackaij Dec 23, 2025
0bdfa5b
Merge pull request #108 from MarketSquare/98_add_keywords_to_simplify…
robinmackaij Dec 23, 2025
8a2cee0
Generated build artifacts for v2.0.0b1 release
robinmackaij Dec 23, 2025
f979b66
Updated dependencies, test matrix updated to latest RF release
robinmackaij Dec 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
"charliermarsh.ruff",
"d-biehl.robotcode",
"tamasfe.even-better-toml",
"ms-azuretools.vscode-docker",
"Gruntfuggly.todo-tree",
"shardulm94.trailing-spaces"
"ms-azuretools.vscode-docker"

]
}
}
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/on-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,17 @@ jobs:
strategy:
matrix:
os: [ 'ubuntu-latest', 'windows-latest']
python-version: ['3.10', '3.11', '3.12', '3.13']
robot-version: ['6.1.1', '7.3.2']
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
robot-version: ['6.1.1', '7.4.1']
exclude:
- os: 'windows-latest'
python-version: '3.10'
- os: 'windows-latest'
python-version: '3.11'
- os: 'windows-latest'
python-version: '3.12'
- os: 'windows-latest'
python-version: '3.13'
- os: 'ubuntu-latest'
python-version: '3.10'
robot-version: '6.1.1'
Expand All @@ -71,6 +73,9 @@ jobs:
- os: 'ubuntu-latest'
python-version: '3.12'
robot-version: '6.1.1'
- os: 'ubuntu-latest'
python-version: '3.13'
robot-version: '6.1.1'
fail-fast: false
steps:
- uses: actions/checkout@v6
Expand All @@ -96,7 +101,7 @@ jobs:
tail: true
wait-for: 1m
- name: Run tests on latest RF 7 version
if: matrix.robot-version == '7.3.2'
if: matrix.robot-version == '7.4.1'
run: |
inv tests
- name: Run tests on latest RF 6 version
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ coverage.xml
env/
venv/

# IDE config
# IDE config and local tool settings
.vscode/launch.json
.vscode/settings.json
.robot.toml

# default logs location for the repo
tests/logs
Expand Down
2 changes: 1 addition & 1 deletion docs/coverage-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 49 additions & 49 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -644,10 +644,10 @@ <h2>The custom mappings file</h2>
<div class="code-block"><pre><code class="language-python">
from OpenApiLibCore import (
IGNORE,
Dto,
IdDependency,
IdReference,
PathPropertiesConstraint,
RelationsMapping,
PropertyValueConstraint,
UniquePropertyValueConstraint,
)
Expand All @@ -658,7 +658,7 @@ <h2>The custom mappings file</h2>
}


class MyDtoThatDoesNothing(Dto):
class MyMappingThatDoesNothing(RelationsMapping):
@staticmethod
def get_relations():
relations = []
Expand All @@ -675,13 +675,13 @@ <h2>The custom mappings file</h2>
return relations


DTO_MAPPING = {
("/myspecialpath", "post"): MyDtoThatDoesNothing
RELATIONS_MAPPING = {
("/myspecialpath", "post"): MyMappingThatDoesNothing
}


PATH_MAPPING = {
"/mypathwithexternalid/{external_id}": MyDtoThatDoesNothing
"/mypathwithexternalid/{external_id}": MyMappingThatDoesNothing
}

</code></pre></div>
Expand All @@ -693,13 +693,13 @@ <h2>The custom mappings file</h2>
Here the classes needed to implement custom mappings are imported.
This section can just be copied without changes.</li>
<li>The <code class="language-python">ID_MAPPING</code> "constant" definition / assignment.</li>
<li>The section defining the mapping Dtos. More on this later.</li>
<li>The <code class="language-python">DTO_MAPPING</code> "constant" definition / assignment.</li>
<li>The section defining the RelationsMappings. More on this later.</li>
<li>The <code class="language-python">RELATIONS_MAPPING</code> "constant" definition / assignment.</li>
<li>The <code class="language-python">PATH_MAPPING</code> "constant" definition / assignment.</li>
</ol>

<h2>The ID_MAPPING, DTO_MAPPING and PATH_MAPPING</h2>
When a custom mappings file is used, the OpenApiLibCore will attempt to import it and then import <code>DTO_MAPPING</code>, <code>PATH_MAPPING</code> and <code>ID_MAPPING</code> from it.
<h2>The ID_MAPPING, RELATIONS_MAPPING and PATH_MAPPING</h2>
When a custom mappings file is used, the OpenApiLibCore will attempt to import it and then import <code>RELATIONS_MAPPING</code>, <code>PATH_MAPPING</code> and <code>ID_MAPPING</code> from it.
For this reason, the exact same name must be used in a custom mappings file (capitilization matters).

<h3>The ID_MAPPING</h3>
Expand All @@ -721,18 +721,18 @@ <h3>The ID_MAPPING</h3>

</code></pre></div>

<h3>The DTO_MAPPING</h3>
The <code>DTO_MAPPING</code> is a dictionary with a tuple as its key and a mappings Dto as its value.
<h3>The RELATIONS_MAPPING</h3>
The <code>RELATIONS_MAPPING</code> is a dictionary with a tuple as its key and a RelationsMapping as its value.
The tuple must be in the form <code class="language-python">("path_from_the_paths_section", "method_supported_by_the_path")</code>.
The <code class="language-python">path_from_the_paths_section</code> must be exactly as found in the openapi document.
The <code class="language-python">method_supported_by_the_path</code> must be one of the methods supported by the path and must be in lowercase.

<h3>The PATH_MAPPING</h3>
The <code>PATH_MAPPING</code> is a dictionary with a <code>"path_from_the_paths_section"</code> as its key and a mappings Dto as its value.
The <code>PATH_MAPPING</code> is a dictionary with a <code>"path_from_the_paths_section"</code> as its key and a RelationsMapping as its value.
The <code>path_from_the_paths_section</code> must be exactly as found in the openapi document.


<h2>Dto mapping classes</h2>
<h2>RelationsMapping classes</h2>
As can be seen from the import section above, a number of classes are available to deal with relations between resources and / or constraints on properties.
Each of these classes is designed to handle a relation or constraint commonly seen in REST APIs.

Expand All @@ -757,7 +757,7 @@ <h3><code>IdReference</code></h3>
This relation can be implemented as follows:

<div class="code-block"><pre><code class="language-python">
class EmployeeDto(Dto):
class EmployeeMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -769,8 +769,8 @@ <h3><code>IdReference</code></h3>
]
return relations

DTO_MAPPING = {
("/employees", "post"): EmployeeDto
RELATIONS_MAPPING = {
("/employees", "post"): EmployeeMapping
}

</code></pre></div>
Expand Down Expand Up @@ -801,7 +801,7 @@ <h3><code>IdDependency</code></h3>
To verify that the specified <code>error_code</code> indeed occurs when attempting to <code>delete</code> the Wagegroup, we can implement the following dependency:

<div class="code-block"><pre><code class="language-python">
class WagegroupDto(Dto):
class WagegroupMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -813,8 +813,8 @@ <h3><code>IdDependency</code></h3>
]
return relations

DTO_MAPPING = {
("/wagegroups/{wagegroup_id}", "delete"): WagegroupDto
RELATIONS_MAPPING = {
("/wagegroups/{wagegroup_id}", "delete"): WagegroupMapping
}

</code></pre></div>
Expand All @@ -833,7 +833,7 @@ <h3><code>UniquePropertyValueConstraint</code></h3>
To verify that the specified <code>error_code</code> occurs when attempting to <code>post</code> an Employee with an <code>employee_number</code> that is already in use, we can implement the following dependency:

<div class="code-block"><pre><code class="language-python">
class EmployeeDto(Dto):
class EmployeeMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -845,15 +845,15 @@ <h3><code>UniquePropertyValueConstraint</code></h3>
]
return relations

DTO_MAPPING = {
("/employees", "post"): EmployeeDto,
("/employees/${employee_id}", "put"): EmployeeDto,
("/employees/${employee_id}", "patch"): EmployeeDto,
RELATIONS_MAPPING = {
("/employees", "post"): EmployeeMapping,
("/employees/${employee_id}", "put"): EmployeeMapping,
("/employees/${employee_id}", "patch"): EmployeeMapping,
}

</code></pre></div>

Note how this example reuses the <code>EmployeeDto</code> to model the uniqueness constraint for all the operations (<code>post</code>, <code>put</code> and <code>patch</code>) that all relate to the same <code>employee_number</code>.
Note how this example reuses the <code>EmployeeMapping</code> to model the uniqueness constraint for all the operations (<code>post</code>, <code>put</code> and <code>patch</code>) that all relate to the same <code>employee_number</code>.

<hr>

Expand All @@ -867,7 +867,7 @@ <h3><code>PropertyValueConstraint</code></h3>
This type of constraint can be modeled as follows:

<div class="code-block"><pre><code class="language-python">
class EmployeeDto(Dto):
class EmployeeMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -879,10 +879,10 @@ <h3><code>PropertyValueConstraint</code></h3>
]
return relations

DTO_MAPPING = {
("/employees", "post"): EmployeeDto,
("/employees/${employee_id}", "put"): EmployeeDto,
("/employees/${employee_id}", "patch"): EmployeeDto,
RELATIONS_MAPPING = {
("/employees", "post"): EmployeeMapping,
("/employees/${employee_id}", "put"): EmployeeMapping,
("/employees/${employee_id}", "patch"): EmployeeMapping,
}

</code></pre></div>
Expand All @@ -891,7 +891,7 @@ <h3><code>PropertyValueConstraint</code></h3>
To support additional restrictions like these, the <code class="language-python">PropertyValueConstraint</code> supports two additional properties: <code class="language-python">error_value</code> and <code class="language-python">invalid_value_error_code</code>:

<div class="code-block"><pre><code class="language-python">
class EmployeeDto(Dto):
class EmployeeMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -905,10 +905,10 @@ <h3><code>PropertyValueConstraint</code></h3>
]
return relations

DTO_MAPPING = {
("/employees", "post"): EmployeeDto,
("/employees/${employee_id}", "put"): EmployeeDto,
("/employees/${employee_id}", "patch"): EmployeeDto,
RELATIONS_MAPPING = {
("/employees", "post"): EmployeeMapping,
("/employees/${employee_id}", "put"): EmployeeMapping,
("/employees/${employee_id}", "patch"): EmployeeMapping,
}

</code></pre></div>
Expand All @@ -920,7 +920,7 @@ <h3><code>PropertyValueConstraint</code></h3>
This situation can be handled by use of the special <code class="language-python">IGNORE</code> value (see below for other uses):

<div class="code-block"><pre><code class="language-python">
class EmployeeDto(Dto):
class EmployeeMapping(RelationsMapping):
@staticmethod
def get_relations():
relations = [
Expand All @@ -934,10 +934,10 @@ <h3><code>PropertyValueConstraint</code></h3>
]
return relations

DTO_MAPPING = {
("/employees", "post"): EmployeeDto,
("/employees/${employee_id}", "put"): EmployeeDto,
("/employees/${employee_id}", "patch"): EmployeeDto,
RELATIONS_MAPPING = {
("/employees", "post"): EmployeeMapping,
("/employees/${employee_id}", "put"): EmployeeMapping,
("/employees/${employee_id}", "patch"): EmployeeMapping,
}

</code></pre></div>
Expand All @@ -950,7 +950,7 @@ <h3><code>PathPropertiesConstraint</code></h3>
<blockquote><u>Just use this for the <code>path</code></u></blockquote>

<blockquote><i>
Note: The <code class="language-python">PathPropertiesConstraint</code> is only applicable to the <code class="language-python">get_path_relations</code> in a <code class="language-python">Dto</code> and only the <code class="language-python">PATH_MAPPING</code> uses the <code class="language-python">get_path_relations</code>.
Note: The <code class="language-python">PathPropertiesConstraint</code> is only applicable to the <code class="language-python">get_path_relations</code> in a <code class="language-python">RelationsMapping</code> and only the <code class="language-python">PATH_MAPPING</code> uses the <code class="language-python">get_path_relations</code>.
</i></blockquote>

To be able to automatically perform endpoint validations, the OpenApiLibCore has to construct the <code>url</code> for the resource from the <code>path</code> as found in the openapi document.
Expand All @@ -970,7 +970,7 @@ <h3><code>PathPropertiesConstraint</code></h3>
It should be clear that the OpenApiLibCore won't be able to acquire a valid <code>month</code> and <code>date</code>. The <code class="language-python">PathPropertiesConstraint</code> can be used in this case:

<div class="code-block"><pre><code class="language-python">
class BirthdaysDto(Dto):
class BirthdaysMapping(RelationsMapping):
@staticmethod
def get_path_relations():
relations = [
Expand All @@ -979,7 +979,7 @@ <h3><code>PathPropertiesConstraint</code></h3>
return relations

PATH_MAPPING = {
"/birthdays/{month}/{date}": BirthdaysDto
"/birthdays/{month}/{date}": BirthdaysMapping
}

</code></pre></div>
Expand All @@ -999,7 +999,7 @@ <h3><code>IGNORE</code></h3>
To prevent OpenApiLibCore from generating invalid combinations of path and query parameters in this type of endpoint, the <code class="language-python">IGNORE</code> special value can be used to ensure the related query parameter is never send in a request.

<div class="code-block"><pre><code class="language-python">
class EnergyLabelDto(Dto):
class EnergyLabelMapping(RelationsMapping):
@staticmethod
def get_parameter_relations():
relations = [
Expand All @@ -1018,8 +1018,8 @@ <h3><code>IGNORE</code></h3>
]
return relations

DTO_MAPPING = {
("/energy_label/{zipcode}/{home_number}", "get"): EnergyLabelDto,
RELATIONS_MAPPING = {
("/energy_label/{zipcode}/{home_number}", "get"): EnergyLabelMapping,
}

</code></pre></div>
Expand All @@ -1032,7 +1032,7 @@ <h3><code>IGNORE</code></h3>
Such situations can be handled by a mapping as shown below:
</p>
<div class="code-block"><pre><code class="language-python">
class PatchEmployeeDto(Dto):
class PatchEmployeeMapping(RelationsMapping):
@staticmethod
def get_parameter_relations() -> list[ResourceRelation]:
relations: list[ResourceRelation] = [
Expand All @@ -1051,8 +1051,8 @@ <h3><code>IGNORE</code></h3>
]
return relations

DTO_MAPPING = {
("/employees/{employee_id}", "patch"): PatchEmployeeDto,
RELATIONS_MAPPING = {
("/employees/{employee_id}", "patch"): PatchEmployeeMapping,
}

</code></pre></div>
Expand Down
779 changes: 378 additions & 401 deletions docs/openapi_libcore.html

Large diffs are not rendered by default.

779 changes: 378 additions & 401 deletions docs/openapidriver.html

Large diffs are not rendered by default.

Loading