diff --git a/client_generator/.gitignore b/client_generator/.gitignore deleted file mode 100644 index 22d93f4..0000000 --- a/client_generator/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -.idea/ - -*.egg-info/ -.mypy_cache/ -.pytest_cache/ -.coverage -.coverage.* -htmlcov/ - -generated/ - -*.pyc - -tmp*/ - -/tests/generated_client/ -/tests/logs/ diff --git a/client_generator/Dockerfile b/client_generator/Dockerfile deleted file mode 100644 index d2fe779..0000000 --- a/client_generator/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. -FROM python:3.10-slim - -RUN apt-get update && apt-get install -y build-essential dos2unix curl -RUN pip install black autoflake isort httpx fastapi typing_extensions -ADD scripts/util/postprocess-docker.sh / -ADD scripts/util/fix_optional_defaults.py / -ADD scripts/util/fix_api_response_types.py / - -# Fix EOL in case the Docker build process runs on Windows -RUN dos2unix /postprocess-docker.sh - -ENTRYPOINT ["/postprocess-docker.sh"] diff --git a/client_generator/Dockerfile.new.new b/client_generator/Dockerfile.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/LICENSE.TXT b/client_generator/LICENSE.TXT deleted file mode 100644 index 472e4f1..0000000 --- a/client_generator/LICENSE.TXT +++ /dev/null @@ -1,192 +0,0 @@ - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/client_generator/LICENSE.TXT.new.new b/client_generator/LICENSE.TXT.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/Makefile b/client_generator/Makefile deleted file mode 100644 index 251e1c0..0000000 --- a/client_generator/Makefile +++ /dev/null @@ -1,110 +0,0 @@ - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. -.DEFAULT_GOAL := help -pkg_src = example -tests_src = tests - -isort = isort -rc $(pkg_src) $(tests_src) -autoflake = autoflake -r --remove-all-unused-imports --ignore-init-module-imports $(pkg_src) $(tests_src) -black = black $(pkg_src) $(tests_src) -flake8 = flake8 $(pkg_src) $(tests_src) -mypy_base = mypy --show-error-codes -mypy = $(mypy_base) $(pkg_src) -mypy_tests = $(mypy_base) $(pkg_src) $(tests_src) - -.PHONY: all ## Run the most common rules used during development -all: format lint mypy-tests test - -.PHONY: format ## Auto-format the source code (isort, autoflake, black) -format: - $(isort) - $(autoflake) -i - $(black) - -.PHONY: check-format ## Check the source code format without changes -check-format: - $(isort) --check-only - @echo $(autoflake) --check - @( set -o pipefail; $(autoflake) --check | (grep -v "No issues detected!" || true) ) - $(black) --check - -.PHONY: lint ## Run flake8 over the application source and tests -lint: - $(flake8) - -.PHONY: mypy ## Run mypy over the application source -mypy: - $(mypy) - -.PHONY: mypy-tests ## Run mypy over the application source *and* tests -mypy-tests: - $(mypy_tests) - -.PHONY: test ## Run tests -test: - ./scripts/dev/test.sh - @echo "All tests passed" - -.PHONY: testcov ## Run tests, generate a coverage report, and open in browser -testcov: - ./scripts/dev/testcov.sh - @echo "opening coverage html in browser" - @open htmlcov/index.html - -.PHONY: default ## CI-friendly checks -default: check-format lint mypy test - -.PHONY: regenerate ## Regenerate the example client -regenerate: - ./scripts/dev/regenerate-example.sh - @echo "Regeneration succeeded" - -.PHONY: clean ## Run all CI validation steps without making any changes to code -clean: - rm -rf `find . -name __pycache__` - rm -f `find . -type f -name '*.py[co]' ` - rm -f `find . -type f -name '*~' ` - rm -f `find . -type f -name '.*~' ` - rm -rf `find . -type d -name '*.egg-info' ` - rm -rf `find . -type d -name 'pip-wheel-metadata' ` - rm -rf `find . -type d -name 'tmp*' ` - rm -rf .cache - rm -rf .pytest_cache - rm -rf .mypy_cache - rm -rf htmlcov - rm -rf *.egg-info - rm -f .coverage - rm -f .coverage.* - rm -rf generated - -.PHONY: lock ## Update the lockfile -lock: - poetry lock - -.PHONY: develop ## Set up the development environment, or reinstall from the lockfile -develop: - ./scripts/dev/install.sh - -.PHONY: version ## Bump the version in pyproject.toml (usage: `make version version=minor`) -version: - poetry version $(version) - -.PHONY: help ## Display this message -help: - @grep -E \ - '^.PHONY: .*?## .*$$' $(MAKEFILE_LIST) | \ - sort | \ - awk 'BEGIN {FS = ".PHONY: |## "}; {printf "\033[36m%-16s\033[0m %s\n", $$2, $$3}' diff --git a/client_generator/Makefile.new.new b/client_generator/Makefile.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/README.md b/client_generator/README.md deleted file mode 100644 index ea9eaa5..0000000 --- a/client_generator/README.md +++ /dev/null @@ -1,128 +0,0 @@ - -# FastAPI-based API Client Generator - -**Generate a mypy- and IDE-friendly API client from an OpenAPI spec.** - -* Sync and async interfaces are both available -* Comes with support for the OAuth2.0 password flow -* Easily extended, with built-in support for request middleware -* Designed for integration with FastAPI, but should work with most OpenAPI specs -* Makes use of https://github.com/OpenAPITools/openapi-generator - -Look inside `example/client` to see an example of the generated output! - ----- - -*Warning: This is still in the proof-of-concept phase, and should not yet be considered to have a stable interface.* -* Some OpenAPI features (like discriminator fields) are not yet supported. -* While the goal is to support any OpenAPI spec, it is most likely to work well with specs generated by FastAPI. - -If you try this out, please help me by reporting any issues you notice! - -## Client library usage - -```python -from client.api_client import ApiClient, AsyncApis, SyncApis -from client.models import Pet - -client = ApiClient(host="http://localhost") -sync_apis = SyncApis(client) -async_apis = AsyncApis(client) - -pet_1 = sync_apis.pet_api.get_pet_by_id(pet_id=1) -assert isinstance(pet_1, Pet) - -async def get_pet_2() -> Pet: - pet_2 = await async_apis.pet_api.get_pet_by_id(pet_id=2) - assert isinstance(pet_2, Pet) - return pet_2 -``` - -The example generated client library is contained in `example/client`. - -Generated clients will have the following dependencies: - -* `pydantic` for models -* `httpx` for networking -* `fastapi` for `jsonable_encoder` and OAuth models (I hope to eventually remove this as a dependency) -* `typing_extensions` for Enums via `Literal` (I eventually hope to replace this with standard enums) - -More examples of usage (including auth) are contained in `example/usage_example.py`. - -## Generating the client library - -Using the generator looks like -```bash -./scripts/generate.sh -i -p -o - [-n ] [--include-auth] - [--] [*openapi-generator-args] -``` -and will produce a client library at `/`. - -The OpenAPI json input can be either a URL or a local file path. - -For example, running -```bash -./scripts/generate.sh \ - -i https://petstore.swagger.io/v2/swagger.json \ - -p client \ - -o generated \ - -n example.client \ - --include-auth -``` -produces the example client (along with the OAuth2.0 password flow client), places it in `generated/client`, and -makes any generated client-referencing imports start with `example.client`. - -(Note: to prevent accidental overwrites, you would need to manually remove `generated/client` if it already exists.) - -### With FastAPI - -* To generate a client for a default FastAPI app running on localhost (NOT inside a docker container): - - ./scripts/generate.sh -i http://localhost/openapi.json -p my_client -o generated - -* Since the generator runs inside docker, if your server is also running in a docker container on the same machine, -[you may need to provide a special hostname](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach). -Passing the `--map-localhost` argument will make the script attempt to perform this automatically: - - ./scripts/generate.sh --map-localhost -i http://localhost/openapi.json -p my_client -o generated - # Transforms the input to http://host.docker.internal/openapi.json - -### With package metadata - -If you want generate not only a code, but also a package metadata (e.g. setup.py) for publishing or distributing -autogenerated client you can use a `--with-meta` flag. - -### Generation details - -* The only local dependencies for generation are `docker` and standard command line tools. -* `openapi-generator` is used to generate the code from the openapi spec - * The custom templates are located in `openapi-python-templates` -* `autoflake`, `isort`, and `black` are used to format the code after generation - - -## Contributing - -There are a variety of make rules for setup/testing; here are some highlights: -* `make develop`: Sets up the local development environment. -* `make regenerate`: Regenerates the example client from the example's openapi.json and the templates. - * Note: *This will overwrite changes!* Make sure you commit (or edit the templates) before running this. -* `make`: Checks that isort, black, flake8, mypy, and pytest all pass -* `make testcov`: Generates a coverage report for the tests. - -Pull requests are welcome and appreciated! diff --git a/client_generator/README.md.new.new b/client_generator/README.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/__init__.py b/client_generator/example/client/__init__.py deleted file mode 100644 index bf317bd..0000000 --- a/client_generator/example/client/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect - -from pydantic import BaseModel - -from example.client import models -from example.client.api_client import ApiClient, AsyncApis, SyncApis # noqa F401 - -for model in inspect.getmembers(models, inspect.isclass): - if model[1].__module__ == "example.client.models": - model_class = model[1] - if isinstance(model_class, BaseModel): - model_class.update_forward_refs() diff --git a/client_generator/example/client/__init__.py.new.new b/client_generator/example/client/__init__.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/api/__init__.py b/client_generator/example/client/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/api/pet_api.py b/client_generator/example/client/api/pet_api.py deleted file mode 100644 index 1d21cf4..0000000 --- a/client_generator/example/client/api/pet_api.py +++ /dev/null @@ -1,207 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# flake8: noqa E501 -from asyncio import get_event_loop -from typing import IO, TYPE_CHECKING, Any, Awaitable, Dict, List - -from fastapi.encoders import jsonable_encoder - -from example.client import models as m - -if TYPE_CHECKING: - from example.client.api_client import ApiClient - - -class _PetApi: - def __init__(self, api_client: "ApiClient"): - self.api_client = api_client - - def _build_for_add_pet(self, body: m.Pet) -> Awaitable[None]: - body = jsonable_encoder(body) - - return self.api_client.request(type_=None, method="POST", url="/pet", json=body) - - def _build_for_delete_pet(self, pet_id: int, api_key: str = None) -> Awaitable[None]: - path_params = {"petId": str(pet_id)} - - headers = {} - if api_key is not None: - headers["api_key"] = str(api_key) - - return self.api_client.request( - type_=None, - method="DELETE", - url="/pet/{petId}", - path_params=path_params, - headers=headers, - ) - - def _build_for_find_pets_by_status(self, status: List[str]) -> Awaitable[List[m.Pet]]: - """ - Multiple status values can be provided with comma separated strings - """ - query_params = {"status": str(status)} - - return self.api_client.request( - type_=List[m.Pet], - method="GET", - url="/pet/findByStatus", - params=query_params, - ) - - def _build_for_find_pets_by_tags(self, tags: List[str]) -> Awaitable[List[m.Pet]]: - """ - Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. - """ - query_params = {"tags": str(tags)} - - return self.api_client.request( - type_=List[m.Pet], - method="GET", - url="/pet/findByTags", - params=query_params, - ) - - def _build_for_get_pet_by_id(self, pet_id: int) -> Awaitable[m.Pet]: - """ - Returns a single pet - """ - path_params = {"petId": str(pet_id)} - - return self.api_client.request( - type_=m.Pet, - method="GET", - url="/pet/{petId}", - path_params=path_params, - ) - - def _build_for_update_pet(self, body: m.Pet) -> Awaitable[None]: - body = jsonable_encoder(body) - - return self.api_client.request(type_=None, method="PUT", url="/pet", json=body) - - def _build_for_update_pet_with_form(self, pet_id: int, name: str = None, status: str = None) -> Awaitable[None]: - path_params = {"petId": str(pet_id)} - - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - if name is not None: - data["name"] = name - if status is not None: - data["status"] = status - - return self.api_client.request( - type_=None, method="POST", url="/pet/{petId}", path_params=path_params, data=data, files=files or None - ) - - def _build_for_upload_file( - self, pet_id: int, additional_metadata: str = None, file: IO[Any] = None - ) -> Awaitable[m.ApiResponse]: - path_params = {"petId": str(pet_id)} - - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - if additional_metadata is not None: - data["additionalMetadata"] = additional_metadata - if file is not None: - files["file"] = file - - return self.api_client.request( - type_=m.ApiResponse, - method="POST", - url="/pet/{petId}/uploadImage", - path_params=path_params, - data=data, - files=files, - ) - - -class AsyncPetApi(_PetApi): - async def add_pet(self, body: m.Pet) -> None: - return await self._build_for_add_pet(body=body) - - async def delete_pet(self, pet_id: int, api_key: str = None) -> None: - return await self._build_for_delete_pet(pet_id=pet_id, api_key=api_key) - - async def find_pets_by_status(self, status: List[str]) -> List[m.Pet]: - """ - Multiple status values can be provided with comma separated strings - """ - return await self._build_for_find_pets_by_status(status=status) - - async def find_pets_by_tags(self, tags: List[str]) -> List[m.Pet]: - """ - Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. - """ - return await self._build_for_find_pets_by_tags(tags=tags) - - async def get_pet_by_id(self, pet_id: int) -> m.Pet: - """ - Returns a single pet - """ - return await self._build_for_get_pet_by_id(pet_id=pet_id) - - async def update_pet(self, body: m.Pet) -> None: - return await self._build_for_update_pet(body=body) - - async def update_pet_with_form(self, pet_id: int, name: str = None, status: str = None) -> None: - return await self._build_for_update_pet_with_form(pet_id=pet_id, name=name, status=status) - - async def upload_file(self, pet_id: int, additional_metadata: str = None, file: IO[Any] = None) -> m.ApiResponse: - return await self._build_for_upload_file(pet_id=pet_id, additional_metadata=additional_metadata, file=file) - - -class SyncPetApi(_PetApi): - def add_pet(self, body: m.Pet) -> None: - coroutine = self._build_for_add_pet(body=body) - return get_event_loop().run_until_complete(coroutine) - - def delete_pet(self, pet_id: int, api_key: str = None) -> None: - coroutine = self._build_for_delete_pet(pet_id=pet_id, api_key=api_key) - return get_event_loop().run_until_complete(coroutine) - - def find_pets_by_status(self, status: List[str]) -> List[m.Pet]: - """ - Multiple status values can be provided with comma separated strings - """ - coroutine = self._build_for_find_pets_by_status(status=status) - return get_event_loop().run_until_complete(coroutine) - - def find_pets_by_tags(self, tags: List[str]) -> List[m.Pet]: - """ - Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. - """ - coroutine = self._build_for_find_pets_by_tags(tags=tags) - return get_event_loop().run_until_complete(coroutine) - - def get_pet_by_id(self, pet_id: int) -> m.Pet: - """ - Returns a single pet - """ - coroutine = self._build_for_get_pet_by_id(pet_id=pet_id) - return get_event_loop().run_until_complete(coroutine) - - def update_pet(self, body: m.Pet) -> None: - coroutine = self._build_for_update_pet(body=body) - return get_event_loop().run_until_complete(coroutine) - - def update_pet_with_form(self, pet_id: int, name: str = None, status: str = None) -> None: - coroutine = self._build_for_update_pet_with_form(pet_id=pet_id, name=name, status=status) - return get_event_loop().run_until_complete(coroutine) - - def upload_file(self, pet_id: int, additional_metadata: str = None, file: IO[Any] = None) -> m.ApiResponse: - coroutine = self._build_for_upload_file(pet_id=pet_id, additional_metadata=additional_metadata, file=file) - return get_event_loop().run_until_complete(coroutine) diff --git a/client_generator/example/client/api/pet_api.py.new.new b/client_generator/example/client/api/pet_api.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/api/store_api.py b/client_generator/example/client/api/store_api.py deleted file mode 100644 index de8d1e1..0000000 --- a/client_generator/example/client/api/store_api.py +++ /dev/null @@ -1,127 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# flake8: noqa E501 -from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable, Dict - -from fastapi.encoders import jsonable_encoder - -from example.client import models as m - -if TYPE_CHECKING: - from example.client.api_client import ApiClient - - -class _StoreApi: - def __init__(self, api_client: "ApiClient"): - self.api_client = api_client - - def _build_for_delete_order(self, order_id: int) -> Awaitable[None]: - """ - For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors - """ - path_params = {"orderId": str(order_id)} - - return self.api_client.request( - type_=None, - method="DELETE", - url="/store/order/{orderId}", - path_params=path_params, - ) - - def _build_for_get_inventory( - self, - ) -> Awaitable[Dict[str, int]]: - """ - Returns a map of status codes to quantities - """ - return self.api_client.request( - type_=Dict[str, int], - method="GET", - url="/store/inventory", - ) - - def _build_for_get_order_by_id(self, order_id: int) -> Awaitable[m.Order]: - """ - For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions - """ - path_params = {"orderId": str(order_id)} - - return self.api_client.request( - type_=m.Order, - method="GET", - url="/store/order/{orderId}", - path_params=path_params, - ) - - def _build_for_place_order(self, body: m.Order) -> Awaitable[m.Order]: - body = jsonable_encoder(body) - - return self.api_client.request(type_=m.Order, method="POST", url="/store/order", json=body) - - -class AsyncStoreApi(_StoreApi): - async def delete_order(self, order_id: int) -> None: - """ - For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors - """ - return await self._build_for_delete_order(order_id=order_id) - - async def get_inventory( - self, - ) -> Dict[str, int]: - """ - Returns a map of status codes to quantities - """ - return await self._build_for_get_inventory() - - async def get_order_by_id(self, order_id: int) -> m.Order: - """ - For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions - """ - return await self._build_for_get_order_by_id(order_id=order_id) - - async def place_order(self, body: m.Order) -> m.Order: - return await self._build_for_place_order(body=body) - - -class SyncStoreApi(_StoreApi): - def delete_order(self, order_id: int) -> None: - """ - For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors - """ - coroutine = self._build_for_delete_order(order_id=order_id) - return get_event_loop().run_until_complete(coroutine) - - def get_inventory( - self, - ) -> Dict[str, int]: - """ - Returns a map of status codes to quantities - """ - coroutine = self._build_for_get_inventory() - return get_event_loop().run_until_complete(coroutine) - - def get_order_by_id(self, order_id: int) -> m.Order: - """ - For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions - """ - coroutine = self._build_for_get_order_by_id(order_id=order_id) - return get_event_loop().run_until_complete(coroutine) - - def place_order(self, body: m.Order) -> m.Order: - coroutine = self._build_for_place_order(body=body) - return get_event_loop().run_until_complete(coroutine) diff --git a/client_generator/example/client/api/store_api.py.new.new b/client_generator/example/client/api/store_api.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/api/user_api.py b/client_generator/example/client/api/user_api.py deleted file mode 100644 index 42f573d..0000000 --- a/client_generator/example/client/api/user_api.py +++ /dev/null @@ -1,184 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# flake8: noqa E501 -from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable, List - -from fastapi.encoders import jsonable_encoder - -from example.client import models as m - -if TYPE_CHECKING: - from example.client.api_client import ApiClient - - -class _UserApi: - def __init__(self, api_client: "ApiClient"): - self.api_client = api_client - - def _build_for_create_user(self, body: m.User) -> Awaitable[None]: - """ - This can only be done by the logged in user. - """ - body = jsonable_encoder(body) - - return self.api_client.request(type_=None, method="POST", url="/user", json=body) - - def _build_for_create_users_with_array_input(self, body: List[m.User]) -> Awaitable[None]: - body = jsonable_encoder(body) - - return self.api_client.request(type_=None, method="POST", url="/user/createWithArray", json=body) - - def _build_for_create_users_with_list_input(self, body: List[m.User]) -> Awaitable[None]: - body = jsonable_encoder(body) - - return self.api_client.request(type_=None, method="POST", url="/user/createWithList", json=body) - - def _build_for_delete_user(self, username: str) -> Awaitable[None]: - """ - This can only be done by the logged in user. - """ - path_params = {"username": str(username)} - - return self.api_client.request( - type_=None, - method="DELETE", - url="/user/{username}", - path_params=path_params, - ) - - def _build_for_get_user_by_name(self, username: str) -> Awaitable[m.User]: - path_params = {"username": str(username)} - - return self.api_client.request( - type_=m.User, - method="GET", - url="/user/{username}", - path_params=path_params, - ) - - def _build_for_login_user(self, username: str, password: str) -> Awaitable[str]: - query_params = {"username": str(username), "password": str(password)} - - return self.api_client.request( - type_=str, - method="GET", - url="/user/login", - params=query_params, - ) - - def _build_for_logout_user( - self, - ) -> Awaitable[None]: - return self.api_client.request( - type_=None, - method="GET", - url="/user/logout", - ) - - def _build_for_update_user(self, username: str, body: m.User) -> Awaitable[None]: - """ - This can only be done by the logged in user. - """ - path_params = {"username": str(username)} - - body = jsonable_encoder(body) - - return self.api_client.request( - type_=None, method="PUT", url="/user/{username}", path_params=path_params, json=body - ) - - -class AsyncUserApi(_UserApi): - async def create_user(self, body: m.User) -> None: - """ - This can only be done by the logged in user. - """ - return await self._build_for_create_user(body=body) - - async def create_users_with_array_input(self, body: List[m.User]) -> None: - return await self._build_for_create_users_with_array_input(body=body) - - async def create_users_with_list_input(self, body: List[m.User]) -> None: - return await self._build_for_create_users_with_list_input(body=body) - - async def delete_user(self, username: str) -> None: - """ - This can only be done by the logged in user. - """ - return await self._build_for_delete_user(username=username) - - async def get_user_by_name(self, username: str) -> m.User: - return await self._build_for_get_user_by_name(username=username) - - async def login_user(self, username: str, password: str) -> str: - return await self._build_for_login_user(username=username, password=password) - - async def logout_user( - self, - ) -> None: - return await self._build_for_logout_user() - - async def update_user(self, username: str, body: m.User) -> None: - """ - This can only be done by the logged in user. - """ - return await self._build_for_update_user(username=username, body=body) - - -class SyncUserApi(_UserApi): - def create_user(self, body: m.User) -> None: - """ - This can only be done by the logged in user. - """ - coroutine = self._build_for_create_user(body=body) - return get_event_loop().run_until_complete(coroutine) - - def create_users_with_array_input(self, body: List[m.User]) -> None: - coroutine = self._build_for_create_users_with_array_input(body=body) - return get_event_loop().run_until_complete(coroutine) - - def create_users_with_list_input(self, body: List[m.User]) -> None: - coroutine = self._build_for_create_users_with_list_input(body=body) - return get_event_loop().run_until_complete(coroutine) - - def delete_user(self, username: str) -> None: - """ - This can only be done by the logged in user. - """ - coroutine = self._build_for_delete_user(username=username) - return get_event_loop().run_until_complete(coroutine) - - def get_user_by_name(self, username: str) -> m.User: - coroutine = self._build_for_get_user_by_name(username=username) - return get_event_loop().run_until_complete(coroutine) - - def login_user(self, username: str, password: str) -> str: - coroutine = self._build_for_login_user(username=username, password=password) - return get_event_loop().run_until_complete(coroutine) - - def logout_user( - self, - ) -> None: - coroutine = self._build_for_logout_user() - return get_event_loop().run_until_complete(coroutine) - - def update_user(self, username: str, body: m.User) -> None: - """ - This can only be done by the logged in user. - """ - coroutine = self._build_for_update_user(username=username, body=body) - return get_event_loop().run_until_complete(coroutine) diff --git a/client_generator/example/client/api/user_api.py.new.new b/client_generator/example/client/api/user_api.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/api_client.py b/client_generator/example/client/api_client.py deleted file mode 100644 index 4f3bda6..0000000 --- a/client_generator/example/client/api_client.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from asyncio import get_event_loop -from typing import Any, Awaitable, Callable, Dict, Generic, Type, TypeVar, overload - -from httpx import AsyncClient, Request, Response -from pydantic import ValidationError, parse_obj_as - -from example.client.api.pet_api import AsyncPetApi, SyncPetApi -from example.client.api.store_api import AsyncStoreApi, SyncStoreApi -from example.client.api.user_api import AsyncUserApi, SyncUserApi -from example.client.exceptions import ResponseHandlingException, UnexpectedResponse - -ClientT = TypeVar("ClientT", bound="ApiClient") - - -class AsyncApis(Generic[ClientT]): - def __init__(self, client: ClientT): - self.client = client - - self.pet_api = AsyncPetApi(self.client) - self.store_api = AsyncStoreApi(self.client) - self.user_api = AsyncUserApi(self.client) - - -class SyncApis(Generic[ClientT]): - def __init__(self, client: ClientT): - self.client = client - - self.pet_api = SyncPetApi(self.client) - self.store_api = SyncStoreApi(self.client) - self.user_api = SyncUserApi(self.client) - - -T = TypeVar("T") -Send = Callable[[Request], Awaitable[Response]] -MiddlewareT = Callable[[Request, Send], Awaitable[Response]] - - -class ApiClient: - def __init__(self, host: str = None, **kwargs: Any) -> None: - self.host = host - self.middleware: MiddlewareT = BaseMiddleware() - self._async_client = AsyncClient(**kwargs) - - @overload - async def request( - self, *, type_: Type[T], method: str, url: str, path_params: Dict[str, Any] = None, **kwargs: Any - ) -> T: - ... - - @overload # noqa F811 - async def request( - self, *, type_: None, method: str, url: str, path_params: Dict[str, Any] = None, **kwargs: Any - ) -> None: - ... - - async def request( # noqa F811 - self, *, type_: Any, method: str, url: str, path_params: Dict[str, Any] = None, **kwargs: Any - ) -> Any: - if path_params is None: - path_params = {} - url = (self.host or "") + url.format(**path_params) - request = Request(method, url, **kwargs) - return await self.send(request, type_) - - @overload - def request_sync(self, *, type_: Type[T], **kwargs: Any) -> T: - ... - - @overload # noqa F811 - def request_sync(self, *, type_: None, **kwargs: Any) -> None: - ... - - def request_sync(self, *, type_: Any, **kwargs: Any) -> Any: # noqa F811 - """ - This method is not used by the generated apis, but is included for convenience - """ - return get_event_loop().run_until_complete(self.request(type_=type_, **kwargs)) - - async def send(self, request: Request, type_: Type[T]) -> T: - response = await self.middleware(request, self.send_inner) - if response.status_code in [200, 201]: - try: - return parse_obj_as(type_, response.json()) - except ValidationError as e: - raise ResponseHandlingException(e) - raise UnexpectedResponse.for_response(response) - - async def send_inner(self, request: Request) -> Response: - try: - response = await self._async_client.send(request) - except Exception as e: - raise ResponseHandlingException(e) - return response - - def add_middleware(self, middleware: MiddlewareT) -> None: - current_middleware = self.middleware - - async def new_middleware(request: Request, call_next: Send) -> Response: - async def inner_send(request: Request) -> Response: - return await current_middleware(request, call_next) - - return await middleware(request, inner_send) - - self.middleware = new_middleware - - -class BaseMiddleware: - async def __call__(self, request: Request, call_next: Send) -> Response: - return await call_next(request) diff --git a/client_generator/example/client/api_client.py.new.new b/client_generator/example/client/api_client.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/auth.py b/client_generator/example/client/auth.py deleted file mode 100644 index 653f9f3..0000000 --- a/client_generator/example/client/auth.py +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from contextlib import suppress -from datetime import datetime, timedelta -from typing import Optional - -from fastapi.openapi.models import OAuthFlowPassword -from httpx import Request, Response -from pydantic import BaseModel - -from example.client.api_client import Send -from example.client.exceptions import UnexpectedResponse -from example.client.password_flow_client import ( - AccessTokenRequest, - PasswordFlowClient, - RefreshTokenRequest, - TokenSuccessResponse, -) - -HTTP_401_UNAUTHORIZED = 401 - - -class AuthState(BaseModel): - username: Optional[str] - password: Optional[str] - access_token: Optional[str] - refresh_token: Optional[str] - expires_at: Optional[datetime] # should be UTC - scope: Optional[str] - - def get_login_request(self) -> Optional[AccessTokenRequest]: - if self.username is None or self.password is None: - return None - return AccessTokenRequest(username=self.username, password=self.password, scope=self.scope) - - def get_refresh_request(self) -> Optional[RefreshTokenRequest]: - if self.refresh_token is None: - return None - return RefreshTokenRequest(refresh_token=self.refresh_token, scope=self.scope) - - def is_expired(self) -> bool: - if self.expires_at is None: - return False - return self.expires_at < datetime.utcnow() + timedelta(seconds=30) - - def update(self, token_success_response: TokenSuccessResponse) -> None: - self.access_token = token_success_response.access_token - self.refresh_token = token_success_response.refresh_token - self.scope = token_success_response.scope - if token_success_response.expires_in is not None: - self.expires_at = datetime.utcnow() + timedelta(seconds=token_success_response.expires_in) - - -class AuthMiddleware: - def __init__(self, auth_state: AuthState, flow: OAuthFlowPassword) -> None: - self.auth_state = auth_state - self.flow_client = PasswordFlowClient(flow) - - @staticmethod - def set_access_header(token: str, request: Request, *, replace: bool) -> None: - key = "authorization" - value = f"bearer {token}" - if replace: - request.headers[key] = value - else: - request.headers.setdefault(key, value) - - async def login(self) -> Optional[TokenSuccessResponse]: - access_token_request = self.auth_state.get_login_request() - if access_token_request is None: - return None - with suppress(UnexpectedResponse): - token_response = await self.flow_client.request_access_token(access_token_request) - if isinstance(token_response, TokenSuccessResponse): - self.update_auth_state(token_response) - return token_response - return None - - async def refresh(self) -> Optional[TokenSuccessResponse]: - refresh_token_request = self.auth_state.get_refresh_request() - if refresh_token_request is None: - return None - with suppress(UnexpectedResponse): - token_response = await self.flow_client.request_refresh_token(refresh_token_request) - if isinstance(token_response, TokenSuccessResponse): - self.update_auth_state(token_response) - return token_response - return None - - async def __call__(self, request: Request, call_next: Send) -> Response: - if self.auth_state.is_expired(): - await self.refresh() - access_token = self.auth_state.access_token - if access_token is not None: - self.set_access_header(access_token, request, replace=False) - - response = await call_next(request) - - if response.status_code != HTTP_401_UNAUTHORIZED: - return response - tokens = await self.refresh() - if tokens is None: - tokens = await self.login() - if tokens: - self.set_access_header(tokens.access_token, request, replace=True) - return await call_next(request) # note: won't work with streaming input - return response - - def update_auth_state(self, tokens: TokenSuccessResponse) -> None: - """ - Override this function if you want a hook for caching the access/refresh tokens - """ - self.auth_state.update(tokens) diff --git a/client_generator/example/client/auth.py.new.new b/client_generator/example/client/auth.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/ApiResponse.md b/client_generator/example/client/docs/ApiResponse.md deleted file mode 100644 index 7ba8508..0000000 --- a/client_generator/example/client/docs/ApiResponse.md +++ /dev/null @@ -1,28 +0,0 @@ - -# ApiResponse - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**code** | **int** | | [optional] -**type** | **str** | | [optional] -**message** | **str** | | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/ApiResponse.md.new.new b/client_generator/example/client/docs/ApiResponse.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/Category.md b/client_generator/example/client/docs/Category.md deleted file mode 100644 index 7564b4a..0000000 --- a/client_generator/example/client/docs/Category.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Category - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**id** | **int** | | [optional] -**name** | **str** | | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/Category.md.new.new b/client_generator/example/client/docs/Category.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/Order.md b/client_generator/example/client/docs/Order.md deleted file mode 100644 index db6cc1d..0000000 --- a/client_generator/example/client/docs/Order.md +++ /dev/null @@ -1,31 +0,0 @@ - -# Order - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**id** | **int** | | [optional] -**pet_id** | **int** | | [optional] -**quantity** | **int** | | [optional] -**ship_date** | **datetime** | | [optional] -**status** | **str** | Order Status | [optional] -**complete** | **bool** | | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/Order.md.new.new b/client_generator/example/client/docs/Order.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/Pet.md b/client_generator/example/client/docs/Pet.md deleted file mode 100644 index 363b3f0..0000000 --- a/client_generator/example/client/docs/Pet.md +++ /dev/null @@ -1,31 +0,0 @@ - -# Pet - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**id** | **int** | | [optional] -**category** | [**Category**](Category.md) | | [optional] -**name** | **str** | | -**photo_urls** | **List[str]** | | -**tags** | [**List[Tag]**](Tag.md) | | [optional] -**status** | **str** | pet status in the store | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/Pet.md.new.new b/client_generator/example/client/docs/Pet.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/PetApi.md b/client_generator/example/client/docs/PetApi.md deleted file mode 100644 index 7863729..0000000 --- a/client_generator/example/client/docs/PetApi.md +++ /dev/null @@ -1,517 +0,0 @@ - -# client.PetApi - -All URIs are relative to *https://petstore.swagger.io/v2* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**add_pet**](PetApi.md#add_pet) | **POST** /pet | Add a new pet to the store -[**delete_pet**](PetApi.md#delete_pet) | **DELETE** /pet/{petId} | Deletes a pet -[**find_pets_by_status**](PetApi.md#find_pets_by_status) | **GET** /pet/findByStatus | Finds Pets by status -[**find_pets_by_tags**](PetApi.md#find_pets_by_tags) | **GET** /pet/findByTags | Finds Pets by tags -[**get_pet_by_id**](PetApi.md#get_pet_by_id) | **GET** /pet/{petId} | Find pet by ID -[**update_pet**](PetApi.md#update_pet) | **PUT** /pet | Update an existing pet -[**update_pet_with_form**](PetApi.md#update_pet_with_form) | **POST** /pet/{petId} | Updates a pet in the store with form data -[**upload_file**](PetApi.md#upload_file) | **POST** /pet/{petId}/uploadImage | uploads an image - - -# **add_pet** -> add_pet(body) - -Add a new pet to the store - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -body = client.Pet() # Pet | Pet object that needs to be added to the store - -try: - # Add a new pet to the store - api_instance.add_pet(body) -except ApiException as e: - print("Exception when calling PetApi->add_pet: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | - -### Return type - -void (empty response body) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: application/json, application/xml - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**405** | Invalid input | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_pet** -> delete_pet(pet_id, api_key=api_key) - -Deletes a pet - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -pet_id = 56 # int | Pet id to delete -api_key = 'api_key_example' # str | (optional) - -try: - # Deletes a pet - api_instance.delete_pet(pet_id, api_key=api_key) -except ApiException as e: - print("Exception when calling PetApi->delete_pet: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **pet_id** | **int**| Pet id to delete | - **api_key** | **str**| | [optional] - -### Return type - -void (empty response body) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**400** | Invalid ID supplied | - | -**404** | Pet not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **find_pets_by_status** -> List[Pet] find_pets_by_status(status) - -Finds Pets by status - -Multiple status values can be provided with comma separated strings - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -status = ['status_example'] # List[str] | Status values that need to be considered for filter - -try: - # Finds Pets by status - api_response = api_instance.find_pets_by_status(status) - pprint(api_response) -except ApiException as e: - print("Exception when calling PetApi->find_pets_by_status: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **status** | [**List[str]**](str.md)| Status values that need to be considered for filter | - -### Return type - -[**List[Pet]**](Pet.md) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid status value | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **find_pets_by_tags** -> List[Pet] find_pets_by_tags(tags) - -Finds Pets by tags - -Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -tags = ['tags_example'] # List[str] | Tags to filter by - -try: - # Finds Pets by tags - api_response = api_instance.find_pets_by_tags(tags) - pprint(api_response) -except ApiException as e: - print("Exception when calling PetApi->find_pets_by_tags: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **tags** | [**List[str]**](str.md)| Tags to filter by | - -### Return type - -[**List[Pet]**](Pet.md) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid tag value | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_pet_by_id** -> Pet get_pet_by_id(pet_id) - -Find pet by ID - -Returns a single pet - -### Example - -* Api Key Authentication (api_key): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure API key authorization: api_key -configuration.api_key['api_key'] = 'YOUR_API_KEY' -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['api_key'] = 'Bearer' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -pet_id = 56 # int | ID of pet to return - -try: - # Find pet by ID - api_response = api_instance.get_pet_by_id(pet_id) - pprint(api_response) -except ApiException as e: - print("Exception when calling PetApi->get_pet_by_id: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **pet_id** | **int**| ID of pet to return | - -### Return type - -[**Pet**](Pet.md) - -### Authorization - -[api_key](../README.md#api_key) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid ID supplied | - | -**404** | Pet not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_pet** -> update_pet(body) - -Update an existing pet - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -body = client.Pet() # Pet | Pet object that needs to be added to the store - -try: - # Update an existing pet - api_instance.update_pet(body) -except ApiException as e: - print("Exception when calling PetApi->update_pet: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | - -### Return type - -void (empty response body) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: application/json, application/xml - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**400** | Invalid ID supplied | - | -**404** | Pet not found | - | -**405** | Validation exception | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_pet_with_form** -> update_pet_with_form(pet_id, name=name, status=status) - -Updates a pet in the store with form data - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -pet_id = 56 # int | ID of pet that needs to be updated -name = 'name_example' # str | Updated name of the pet (optional) -status = 'status_example' # str | Updated status of the pet (optional) - -try: - # Updates a pet in the store with form data - api_instance.update_pet_with_form(pet_id, name=name, status=status) -except ApiException as e: - print("Exception when calling PetApi->update_pet_with_form: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **pet_id** | **int**| ID of pet that needs to be updated | - **name** | **str**| Updated name of the pet | [optional] - **status** | **str**| Updated status of the pet | [optional] - -### Return type - -void (empty response body) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: application/x-www-form-urlencoded - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**405** | Invalid input | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **upload_file** -> ApiResponse upload_file(pet_id, additional_metadata=additional_metadata, file=file) - -uploads an image - -### Example - -* OAuth Authentication (petstore_auth): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure OAuth2 access token for authorization: petstore_auth -configuration.access_token = 'YOUR_ACCESS_TOKEN' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.PetApi(client.ApiClient(configuration)) -pet_id = 56 # int | ID of pet to update -additional_metadata = 'additional_metadata_example' # str | Additional data to pass to server (optional) -file = client.IO() # IO | file to upload (optional) - -try: - # uploads an image - api_response = api_instance.upload_file(pet_id, additional_metadata=additional_metadata, file=file) - pprint(api_response) -except ApiException as e: - print("Exception when calling PetApi->upload_file: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **pet_id** | **int**| ID of pet to update | - **additional_metadata** | **str**| Additional data to pass to server | [optional] - **file** | **IO**| file to upload | [optional] - -### Return type - -[**ApiResponse**](ApiResponse.md) - -### Authorization - -[petstore_auth](../README.md#petstore_auth) - -### HTTP request headers - - - **Content-Type**: multipart/form-data - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/client_generator/example/client/docs/PetApi.md.new.new b/client_generator/example/client/docs/PetApi.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/StoreApi.md b/client_generator/example/client/docs/StoreApi.md deleted file mode 100644 index b4e64ed..0000000 --- a/client_generator/example/client/docs/StoreApi.md +++ /dev/null @@ -1,249 +0,0 @@ - -# client.StoreApi - -All URIs are relative to *https://petstore.swagger.io/v2* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**delete_order**](StoreApi.md#delete_order) | **DELETE** /store/order/{orderId} | Delete purchase order by ID -[**get_inventory**](StoreApi.md#get_inventory) | **GET** /store/inventory | Returns pet inventories by status -[**get_order_by_id**](StoreApi.md#get_order_by_id) | **GET** /store/order/{orderId} | Find purchase order by ID -[**place_order**](StoreApi.md#place_order) | **POST** /store/order | Place an order for a pet - - -# **delete_order** -> delete_order(order_id) - -Delete purchase order by ID - -For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.StoreApi() -order_id = 56 # int | ID of the order that needs to be deleted - -try: - # Delete purchase order by ID - api_instance.delete_order(order_id) -except ApiException as e: - print("Exception when calling StoreApi->delete_order: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **order_id** | **int**| ID of the order that needs to be deleted | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**400** | Invalid ID supplied | - | -**404** | Order not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_inventory** -> dict(str, int) get_inventory() - -Returns pet inventories by status - -Returns a map of status codes to quantities - -### Example - -* Api Key Authentication (api_key): -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint -configuration = client.Configuration() -# Configure API key authorization: api_key -configuration.api_key['api_key'] = 'YOUR_API_KEY' -# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed -# configuration.api_key_prefix['api_key'] = 'Bearer' - -# Defining host is optional and default to https://petstore.swagger.io/v2 -configuration.host = "https://petstore.swagger.io/v2" -# Create an instance of the API class -api_instance = client.StoreApi(client.ApiClient(configuration)) - -try: - # Returns pet inventories by status - api_response = api_instance.get_inventory() - pprint(api_response) -except ApiException as e: - print("Exception when calling StoreApi->get_inventory: %s\n" % e) -``` - -### Parameters -This endpoint does not need any parameter. - -### Return type - -**dict(str, int)** - -### Authorization - -[api_key](../README.md#api_key) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_order_by_id** -> Order get_order_by_id(order_id) - -Find purchase order by ID - -For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.StoreApi() -order_id = 56 # int | ID of pet that needs to be fetched - -try: - # Find purchase order by ID - api_response = api_instance.get_order_by_id(order_id) - pprint(api_response) -except ApiException as e: - print("Exception when calling StoreApi->get_order_by_id: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **order_id** | **int**| ID of pet that needs to be fetched | - -### Return type - -[**Order**](Order.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid ID supplied | - | -**404** | Order not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **place_order** -> Order place_order(body) - -Place an order for a pet - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.StoreApi() -body = client.Order() # Order | order placed for purchasing the pet - -try: - # Place an order for a pet - api_response = api_instance.place_order(body) - pprint(api_response) -except ApiException as e: - print("Exception when calling StoreApi->place_order: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**Order**](Order.md)| order placed for purchasing the pet | - -### Return type - -[**Order**](Order.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid Order | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/client_generator/example/client/docs/StoreApi.md.new.new b/client_generator/example/client/docs/StoreApi.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/Tag.md b/client_generator/example/client/docs/Tag.md deleted file mode 100644 index 00b2882..0000000 --- a/client_generator/example/client/docs/Tag.md +++ /dev/null @@ -1,27 +0,0 @@ - -# Tag - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**id** | **int** | | [optional] -**name** | **str** | | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/Tag.md.new.new b/client_generator/example/client/docs/Tag.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/User.md b/client_generator/example/client/docs/User.md deleted file mode 100644 index 3118b86..0000000 --- a/client_generator/example/client/docs/User.md +++ /dev/null @@ -1,33 +0,0 @@ - -# User - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**id** | **int** | | [optional] -**username** | **str** | | [optional] -**first_name** | **str** | | [optional] -**last_name** | **str** | | [optional] -**email** | **str** | | [optional] -**password** | **str** | | [optional] -**phone** | **str** | | [optional] -**user_status** | **int** | User Status | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/client_generator/example/client/docs/User.md.new.new b/client_generator/example/client/docs/User.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/docs/UserApi.md b/client_generator/example/client/docs/UserApi.md deleted file mode 100644 index 12bfaac..0000000 --- a/client_generator/example/client/docs/UserApi.md +++ /dev/null @@ -1,453 +0,0 @@ - -# client.UserApi - -All URIs are relative to *https://petstore.swagger.io/v2* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_user**](UserApi.md#create_user) | **POST** /user | Create user -[**create_users_with_array_input**](UserApi.md#create_users_with_array_input) | **POST** /user/createWithArray | Creates list of users with given input array -[**create_users_with_list_input**](UserApi.md#create_users_with_list_input) | **POST** /user/createWithList | Creates list of users with given input array -[**delete_user**](UserApi.md#delete_user) | **DELETE** /user/{username} | Delete user -[**get_user_by_name**](UserApi.md#get_user_by_name) | **GET** /user/{username} | Get user by user name -[**login_user**](UserApi.md#login_user) | **GET** /user/login | Logs user into the system -[**logout_user**](UserApi.md#logout_user) | **GET** /user/logout | Logs out current logged in user session -[**update_user**](UserApi.md#update_user) | **PUT** /user/{username} | Updated user - - -# **create_user** -> create_user(body) - -Create user - -This can only be done by the logged in user. - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -body = client.User() # User | Created user object - -try: - # Create user - api_instance.create_user(body) -except ApiException as e: - print("Exception when calling UserApi->create_user: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**User**](User.md)| Created user object | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**0** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **create_users_with_array_input** -> create_users_with_array_input(body) - -Creates list of users with given input array - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -body = [client.User()] # List[User] | List of user object - -try: - # Creates list of users with given input array - api_instance.create_users_with_array_input(body) -except ApiException as e: - print("Exception when calling UserApi->create_users_with_array_input: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**List[User]**](User.md)| List of user object | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**0** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **create_users_with_list_input** -> create_users_with_list_input(body) - -Creates list of users with given input array - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -body = [client.User()] # List[User] | List of user object - -try: - # Creates list of users with given input array - api_instance.create_users_with_list_input(body) -except ApiException as e: - print("Exception when calling UserApi->create_users_with_list_input: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | [**List[User]**](User.md)| List of user object | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**0** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_user** -> delete_user(username) - -Delete user - -This can only be done by the logged in user. - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -username = 'username_example' # str | The name that needs to be deleted - -try: - # Delete user - api_instance.delete_user(username) -except ApiException as e: - print("Exception when calling UserApi->delete_user: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **username** | **str**| The name that needs to be deleted | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**400** | Invalid username supplied | - | -**404** | User not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_user_by_name** -> User get_user_by_name(username) - -Get user by user name - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -username = 'username_example' # str | The name that needs to be fetched. Use user1 for testing. - -try: - # Get user by user name - api_response = api_instance.get_user_by_name(username) - pprint(api_response) -except ApiException as e: - print("Exception when calling UserApi->get_user_by_name: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **username** | **str**| The name that needs to be fetched. Use user1 for testing. | - -### Return type - -[**User**](User.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | - | -**400** | Invalid username supplied | - | -**404** | User not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **login_user** -> str login_user(username, password) - -Logs user into the system - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -username = 'username_example' # str | The user name for login -password = 'password_example' # str | The password for login in clear text - -try: - # Logs user into the system - api_response = api_instance.login_user(username, password) - pprint(api_response) -except ApiException as e: - print("Exception when calling UserApi->login_user: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **username** | **str**| The user name for login | - **password** | **str**| The password for login in clear text | - -### Return type - -**str** - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json, application/xml - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | successful operation | * X-Rate-Limit - calls per hour allowed by the user
* X-Expires-After - date in UTC when token expires
| -**400** | Invalid username/password supplied | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **logout_user** -> logout_user() - -Logs out current logged in user session - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() - -try: - # Logs out current logged in user session - api_instance.logout_user() -except ApiException as e: - print("Exception when calling UserApi->logout_user: %s\n" % e) -``` - -### Parameters -This endpoint does not need any parameter. - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**0** | successful operation | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_user** -> update_user(username, body) - -Updated user - -This can only be done by the logged in user. - -### Example - -```python -from __future__ import print_function -import time -import client -from client.rest import ApiException -from pprint import pprint - -# Create an instance of the API class -api_instance = client.UserApi() -username = 'username_example' # str | name that need to be updated -body = client.User() # User | Updated user object - -try: - # Updated user - api_instance.update_user(username, body) -except ApiException as e: - print("Exception when calling UserApi->update_user: %s\n" % e) -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **username** | **str**| name that need to be updated | - **body** | [**User**](User.md)| Updated user object | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: Not defined - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**400** | Invalid user supplied | - | -**404** | User not found | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/client_generator/example/client/docs/UserApi.md.new.new b/client_generator/example/client/docs/UserApi.md.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/exceptions.py b/client_generator/example/client/exceptions.py deleted file mode 100644 index d826c9c..0000000 --- a/client_generator/example/client/exceptions.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -from typing import Any, Dict, Optional - -from httpx import Headers, Response - -MAX_CONTENT = 200 - - -class ApiException(Exception): - """Base class""" - - -class UnexpectedResponse(ApiException): - def __init__(self, status_code: Optional[int], reason_phrase: str, content: bytes, headers: Headers) -> None: - self.status_code = status_code - self.reason_phrase = reason_phrase - self.content = content - self.headers = headers - - @staticmethod - def for_response(response: Response) -> "ApiException": - return UnexpectedResponse( - status_code=response.status_code, - reason_phrase=response.reason_phrase, - content=response.content, - headers=response.headers, - ) - - def __str__(self) -> str: - status_code_str = f"{self.status_code}" if self.status_code is not None else "" - if self.reason_phrase == "" and self.status_code is not None: - reason_phrase_str = "(Unrecognized Status Code)" - else: - reason_phrase_str = f"({self.reason_phrase})" - status_str = f"{status_code_str} {reason_phrase_str}".strip() - short_content = self.content if len(self.content) <= MAX_CONTENT else self.content[: MAX_CONTENT - 3] + b" ..." - raw_content_str = f"Raw response content:\n{short_content!r}" - return f"Unexpected Response: {status_str}\n{raw_content_str}" - - def structured(self) -> Dict[str, Any]: - return json.loads(self.content) - - -class ResponseHandlingException(ApiException): - def __init__(self, source: Exception): - self.source = source diff --git a/client_generator/example/client/exceptions.py.new.new b/client_generator/example/client/exceptions.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/models.py b/client_generator/example/client/models.py deleted file mode 100644 index de62b7f..0000000 --- a/client_generator/example/client/models.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from datetime import datetime -from typing import Any # noqa -from typing import List, Optional - -from pydantic import BaseModel, Field -from typing_extensions import Literal - - -class ApiResponse(BaseModel): - code: "Optional[int]" = Field(None, alias="code") - type: "Optional[str]" = Field(None, alias="type") - message: "Optional[str]" = Field(None, alias="message") - - -class Category(BaseModel): - id: "Optional[int]" = Field(None, alias="id") - name: "Optional[str]" = Field(None, alias="name") - - -class Order(BaseModel): - id: "Optional[int]" = Field(None, alias="id") - pet_id: "Optional[int]" = Field(None, alias="petId") - quantity: "Optional[int]" = Field(None, alias="quantity") - ship_date: "Optional[datetime]" = Field(None, alias="shipDate") - status: "Literal['placed', 'approved', 'delivered']" = Field(None, alias="status") - complete: "Optional[bool]" = Field(None, alias="complete") - - -class Pet(BaseModel): - id: "Optional[int]" = Field(None, alias="id") - category: "Optional[Category]" = Field(None, alias="category") - name: "str" = Field(..., alias="name") - photo_urls: "List[str]" = Field(..., alias="photoUrls") - tags: "Optional[List[Tag]]" = Field(None, alias="tags") - status: "Literal['available', 'pending', 'sold']" = Field(None, alias="status") - - -class Tag(BaseModel): - id: "Optional[int]" = Field(None, alias="id") - name: "Optional[str]" = Field(None, alias="name") - - -class User(BaseModel): - id: "Optional[int]" = Field(None, alias="id") - username: "Optional[str]" = Field(None, alias="username") - first_name: "Optional[str]" = Field(None, alias="firstName") - last_name: "Optional[str]" = Field(None, alias="lastName") - email: "Optional[str]" = Field(None, alias="email") - password: "Optional[str]" = Field(None, alias="password") - phone: "Optional[str]" = Field(None, alias="phone") - user_status: "Optional[int]" = Field(None, alias="userStatus") diff --git a/client_generator/example/client/models.py.new.new b/client_generator/example/client/models.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/password_flow_client.py b/client_generator/example/client/password_flow_client.py deleted file mode 100644 index ae2cd47..0000000 --- a/client_generator/example/client/password_flow_client.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Attempting to follow the "password" flow as described in RFC 6749: https://tools.ietf.org/html/rfc6749 -""" -from asyncio import get_event_loop -from contextlib import suppress -from enum import Enum -from typing import Any, Dict, List, Optional, Type, TypeVar, Union - -from fastapi.openapi.models import OAuthFlowPassword -from httpx import AsyncClient, Response -from pydantic import BaseModel, ValidationError -from typing_extensions import Literal - -from example.client.exceptions import UnexpectedResponse - -TokenRequestT = TypeVar("TokenRequestT", bound="BaseTokenRequest") -HTTP_200_OK = 200 -HTTP_400_BAD_REQUEST = 400 -HTTP_401_UNAUTHORIZED = 401 - - -class BaseTokenRequest(BaseModel): - scope: Optional[str] - - def request_dict(self) -> Dict[str, str]: - request_dict = self.dict() - if request_dict["scope"] is None: - del request_dict["scope"] - return request_dict - - @classmethod - def from_scopes(cls: Type[TokenRequestT], *, scopes: Optional[List[str]], **kwargs: Any) -> TokenRequestT: - scope = " ".join(scopes) if scopes is not None else None - return cls(scope=scope, **kwargs) - - -class AccessTokenRequest(BaseTokenRequest): - """ - Specific to the OAuth2.0 "password" flow - """ - - grant_type: Literal["password"] = "password" - username: str - password: str - scope: Optional[str] - - -class RefreshTokenRequest(BaseTokenRequest): - grant_type: Literal["refresh_token"] = "refresh_token" - refresh_token: str - scope: Optional[str] - - -class TokenSuccessResponse(BaseModel): - access_token: str - token_type: str - expires_in: Optional[int] - refresh_token: Optional[str] - scope: Optional[str] - - -class TokenErrorType(Enum): - invalid_request = "invalid_request" - invalid_client = "invalid_client" - invalid_grant = "invalid_grant" - unauthorized_client = "unauthorized_client" - unsupported_grant_type = "unsupported_grant_type" - invalid_scope = "invalid_scope" - - -class TokenErrorResponse(BaseModel): - error: Union[TokenErrorType, str] - error_description: Optional[str] - error_uri: Optional[str] - - -TokenResponse = Union[TokenSuccessResponse, TokenErrorResponse] - - -def parse_token_response(response: Response) -> TokenResponse: - with suppress(ValidationError): - if response.status_code == HTTP_200_OK: - return TokenSuccessResponse.parse_raw(response.text) - if response.status_code in (HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED): - return TokenErrorResponse.parse_raw(response.text) - raise UnexpectedResponse.for_response(response) - - -class PasswordFlowClient: - def __init__(self, flow: OAuthFlowPassword) -> None: - self.flow = flow - self._async_client = AsyncClient() - - async def request_access_token(self, access_token_request: AccessTokenRequest) -> TokenResponse: - response = await self._async_client.post(self.flow.tokenUrl, data=access_token_request.request_dict()) - return parse_token_response(response) - - async def request_refresh_token(self, refresh_token_request: RefreshTokenRequest) -> TokenResponse: - refresh_url = self.flow.refreshUrl or self.flow.tokenUrl - response = await self._async_client.post(refresh_url, data=refresh_token_request.request_dict()) - return parse_token_response(response) - - def request_access_token_sync(self, access_token_request: AccessTokenRequest) -> TokenResponse: - return get_event_loop().run_until_complete(self.request_access_token(access_token_request)) - - def request_refresh_token_sync(self, refresh_token_request: RefreshTokenRequest) -> TokenResponse: - return get_event_loop().run_until_complete(self.request_refresh_token(refresh_token_request)) diff --git a/client_generator/example/client/password_flow_client.py.new.new b/client_generator/example/client/password_flow_client.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/client/py.typed b/client_generator/example/client/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/example/usage_example.py b/client_generator/example/usage_example.py deleted file mode 100644 index f2e7e5f..0000000 --- a/client_generator/example/usage_example.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from asyncio.events import get_event_loop -from functools import lru_cache - -from fastapi.openapi.models import OAuthFlowPassword - -from example.client.api_client import ApiClient, AsyncApis, SyncApis -from example.client.auth import AuthMiddleware, AuthState -from example.client.models import User - - -class AutoAuthClient(ApiClient): - """ - You can add custom handling behavior by subclassing ApiClient. - - This subclass adds automatic retry on auth errors via AuthMiddleware. - """ - - def __init__(self, host: str = "http://localhost", tokenUrl: str = "http://localhost/token"): - super().__init__(host) - self.auth_state = AuthState() - flow = OAuthFlowPassword(tokenUrl=tokenUrl) - auth_middleware = AuthMiddleware(auth_state=self.auth_state, flow=flow) - self.add_middleware(auth_middleware) - - def set_creds(self, username: str, password: str) -> None: - self.auth_state.username = username - self.auth_state.password = password - - -# lru_cache is used to (essentially) implement the singleton pattern for accessing the apis -@lru_cache() -def get_client() -> AutoAuthClient: - return AutoAuthClient() - - -@lru_cache() -def get_sync_apis() -> SyncApis[AutoAuthClient]: - return SyncApis(get_client()) - - -@lru_cache() -def get_async_apis() -> AsyncApis[AutoAuthClient]: - return AsyncApis(get_client()) - - -async def do_some_async_tasks() -> None: - apis = get_async_apis() - - await apis.store_api.delete_order(order_id=0) - - new_user = User(id=1, username="friend", password="globe") - await apis.user_api.create_user(new_user) - - -def do_some_sync_tasks() -> None: - apis = get_sync_apis() - - pet = apis.pet_api.get_pet_by_id(pet_id=1) - pet.status = "sold" - apis.pet_api.update_pet(pet) - - apis.store_api.delete_order(order_id=1) - - -get_client().set_creds(username="hello", password="world") - -do_some_sync_tasks() - -get_event_loop().run_until_complete(do_some_async_tasks()) diff --git a/client_generator/example/usage_example.py.new.new b/client_generator/example/usage_example.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/mypy.ini b/client_generator/mypy.ini deleted file mode 100644 index bc78868..0000000 --- a/client_generator/mypy.ini +++ /dev/null @@ -1,26 +0,0 @@ - - ; - ; Copyright (c) 2023 Project CHIP Authors - ; - ; Licensed under the Apache License, Version 2.0 (the "License"); - ; you may not use this file except in compliance with the License. - ; You may obtain a copy of the License at - ; - ; http://www.apache.org/licenses/LICENSE-2.0 - ; - ; Unless required by applicable law or agreed to in writing, software - ; distributed under the License is distributed on an "AS IS" BASIS, - ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ; See the License for the specific language governing permissions and - ; limitations under the License. -[mypy] -follow_imports = silent -strict_optional = True -warn_redundant_casts = True -warn_unused_ignores = True -disallow_any_generics = True -check_untyped_defs = True -ignore_missing_imports = True - -# for strict mypy: (this is the tricky one :-)) -disallow_untyped_defs = True diff --git a/client_generator/mypy.ini.new.new b/client_generator/mypy.ini.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/README.mustache b/client_generator/openapi-python-templates/README.mustache deleted file mode 100644 index a188452..0000000 --- a/client_generator/openapi-python-templates/README.mustache +++ /dev/null @@ -1,106 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# {{{projectName}}} -{{#appDescription}} -{{{appDescription}}} -{{/appDescription}} - -This Python package is automatically generated by the -[Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project with -[fastapi_client](https://github.com/dmontagu/fastapi_client) extension: - -- API version: {{appVersion}} -- Package version: {{packageVersion}} -{{^hideGenerationTimestamp}} -- Build date: {{generatedDate}} -{{/hideGenerationTimestamp}} -- Build package: {{generatorClass}} -{{#infoUrl}} -For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) -{{/infoUrl}} - -## Requirements. - -Python 3.7+ - -## Installation & Usage -### pip install - -If the python package is hosted on Github, you can install directly from Github - -```sh -pip install git+https://github.com/{{{gitUserId}}}/{{{gitRepoId}}}.git -``` -(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/{{{gitUserId}}}/{{{gitRepoId}}}.git`) - -Then import the package: -```python -import {{{packageName}}} -``` - -### Setuptools - -Install via [Setuptools](http://pypi.python.org/pypi/setuptools). - -```sh -python setup.py install --user -``` -(or `sudo python setup.py install` to install the package for all users) - -Then import the package: -```python -import {{{packageName}}} -``` - -## Getting Started - -Please follow the [installation procedure](#installation--usage) and then run the following: - -```python - -from __future__ import print_function -import {{{packageName}}}.api_client import ApiClient, AsyncApis, SyncApis -from pprint import pprint - -client = ApiClient(host="{{basePath}}") -sync_apis = SyncApis(client) -async_apis = AsyncApis(client) - -# TODO: get real version of usage -pet_1 = sync_apis.pet_api.get_pet_by_id(pet_id=1) -assert isinstance(pet_1, Pet) - -async def get_pet_2() -> Pet: - pet_2 = await async_apis.pet_api.get_pet_by_id(pet_id=2) - assert isinstance(pet_2, Pet) - return pet_2 -``` -## Documentation for API Endpoints - -TODO - -## Documentation For Models - -TODO - -## Documentation For Authorization - -TODO - -## Author - -{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}} -{{/hasMore}}{{/apis}}{{/apiInfo}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/README.mustache.new.new b/client_generator/openapi-python-templates/README.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/__init__api.mustache b/client_generator/openapi-python-templates/__init__api.mustache deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/__init__model.mustache b/client_generator/openapi-python-templates/__init__model.mustache deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/__init__package.mustache b/client_generator/openapi-python-templates/__init__package.mustache deleted file mode 100644 index 6a32fb2..0000000 --- a/client_generator/openapi-python-templates/__init__package.mustache +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -from pydantic import BaseModel - -from @IMPORT_NAME@ import models -from @IMPORT_NAME@.api_client import ApiClient, AsyncApis, SyncApis # noqa F401 - - -for model in inspect.getmembers(models, inspect.isclass): - if model[1].__module__ == "@IMPORT_NAME@.models": - model_class = model[1] - if issubclass(model_class, BaseModel): - model_class.update_forward_refs() diff --git a/client_generator/openapi-python-templates/__init__package.mustache.new.new b/client_generator/openapi-python-templates/__init__package.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/_dataTypeApi.mustache b/client_generator/openapi-python-templates/_dataTypeApi.mustache deleted file mode 100644 index 74b8696..0000000 --- a/client_generator/openapi-python-templates/_dataTypeApi.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isModel}}{{#isFile}}IO[Any]{{/isFile}}{{^isFile}}m.{{{dataType}}}{{/isFile}}{{/isModel}}{{#isUuid}}UUID{{/isUuid}}{{#isListContainer}}List[{{#items}}{{>_dataTypeApi}}{{/items}}]{{/isListContainer}}{{^isModel}}{{^isUuid}}{{#isFile}}IO[Any]{{/isFile}}{{^isFile}}{{^isListContainer}}{{{dataType}}}{{/isListContainer}}{{/isFile}}{{/isUuid}}{{/isModel}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/_dataTypeApi.mustache.new.new b/client_generator/openapi-python-templates/_dataTypeApi.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/_dataTypeModel.mustache b/client_generator/openapi-python-templates/_dataTypeModel.mustache deleted file mode 100644 index 36720b3..0000000 --- a/client_generator/openapi-python-templates/_dataTypeModel.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#isModel}}{{#isFile}}IO[Any]{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}}{{/isModel}}{{#isUuid}}UUID{{/isUuid}}{{#isListContainer}}List[{{#items}}{{>_dataTypeModel}}{{/items}}]{{/isListContainer}}{{^isListContainer}}{{#isMapContainer}}Dict[{{#items}}str, {{>_dataTypeModel}}{{/items}}]{{/isMapContainer}}{{/isListContainer}}{{^isModel}}{{^isUuid}}{{^isFile}}{{^isListContainer}}{{^isMapContainer}}{{{dataType}}}{{/isMapContainer}}{{/isListContainer}}{{/isFile}}{{/isUuid}}{{/isModel}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/_dataTypeModel.mustache.new.new b/client_generator/openapi-python-templates/_dataTypeModel.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/_innerReturnType.mustache b/client_generator/openapi-python-templates/_innerReturnType.mustache deleted file mode 100644 index ae1b98e..0000000 --- a/client_generator/openapi-python-templates/_innerReturnType.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#returnType}}{{#returnTypeIsPrimitive}}{{{returnBaseType}}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}m.{{{returnBaseType}}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}None{{/returnType}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/_innerReturnType.mustache.new.new b/client_generator/openapi-python-templates/_innerReturnType.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/_returnType.mustache b/client_generator/openapi-python-templates/_returnType.mustache deleted file mode 100644 index fcc5493..0000000 --- a/client_generator/openapi-python-templates/_returnType.mustache +++ /dev/null @@ -1 +0,0 @@ -{{#returnType}}{{#returnSimpleType}}{{>_innerReturnType}}{{/returnSimpleType}}{{^returnSimpleType}}{{#isMapContainer}}Dict[str, {{>_innerReturnType}}]{{/isMapContainer}}{{^isMapContainer}}List[{{>_innerReturnType}}]{{/isMapContainer}}{{/returnSimpleType}}{{/returnType}}{{^returnType}}None{{/returnType}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/_returnType.mustache.new.new b/client_generator/openapi-python-templates/_returnType.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/api.mustache b/client_generator/openapi-python-templates/api.mustache deleted file mode 100644 index f021341..0000000 --- a/client_generator/openapi-python-templates/api.mustache +++ /dev/null @@ -1,169 +0,0 @@ -# -# Copyright (c) 2023-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# flake8: noqa E501 -import json -from asyncio import get_event_loop -from typing import Any, Awaitable, Dict, IO, List, TYPE_CHECKING, Optional -from datetime import date, datetime, timedelta -from uuid import UUID - -from fastapi.encoders import jsonable_encoder - -from @IMPORT_NAME@ import models as m - -if TYPE_CHECKING: - from @IMPORT_NAME@.api_client import ApiClient - - -{{#operations}} -class _{{classname}}: - def __init__(self, api_client: "ApiClient"): - self.api_client = api_client - -{{#operation}} - def _build_for_{{operationId}}(self{{#allParams}}, {{#required}}{{paramName}}: {{>_dataTypeApi}}{{/required}}{{^required}}{{paramName}}: Optional[{{>_dataTypeApi}}] = None{{/required}}{{/allParams}}) -> Awaitable[{{>_returnType}}]: -{{#notes}} - """ - {{{notes}}} - """ -{{/notes}} -{{#pathParams.0}} - path_params = { -{{#pathParams}} -{{#required}} - "{{baseName}}": str({{paramName}}){{#hasMore}},{{/hasMore}} -{{/required}} -{{/pathParams}} - } -{{#pathParams}} -{{^required}} - if {{paramName}} is not None: - path_params["{{baseName}}"] = str({{paramName}}) -{{/required}} -{{/pathParams}} - -{{/pathParams.0}} -{{#queryParams.0}} - query_params = { -{{#queryParams}} -{{#required}} - "{{baseName}}": str({{paramName}}){{#hasMore}},{{/hasMore}} -{{/required}} -{{/queryParams}} - } -{{#queryParams}} -{{^required}} - if {{paramName}} is not None: - query_params["{{baseName}}"] = {{#isListContainer}}[str({{paramName}}_item) for {{paramName}}_item in {{paramName}}]{{/isListContainer}}{{^isListContainer}}str({{paramName}}){{/isListContainer}} -{{/required}} -{{/queryParams}} - -{{/queryParams.0}} -{{#headerParams.0}} - headers = { -{{#headerParams}} -{{#required}} - "{{baseName}}": str({{paramName}}) -{{/required}} -{{/headerParams}} - } -{{#headerParams}} -{{^required}} - if {{paramName}} is not None: - headers["{{baseName}}"] = str({{paramName}}) -{{/required}} -{{/headerParams}} - -{{/headerParams.0}} -{{#cookieParams.0}} - cookies = { -{{#cookieParams}} -{{#required}} - "{{baseName}}": str({{paramName}}) -{{/required}} -{{/cookieParams}} - } -{{#cookieParams}} -{{^required}} - if {{paramName}} is not None: - cookies["{{baseName}}"] = str({{paramName}}) -{{/required}} -{{/cookieParams}} - -{{/cookieParams.0}} -{{#formParams.0}} - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 -{{#formParams}} -{{#required}} - {{#isFile}}files{{/isFile}}{{^isFile}}data{{/isFile}}["{{baseName}}"] = {{paramName}} -{{/required}} -{{/formParams}} -{{#formParams}} -{{^required}} - if {{paramName}} is not None: - {{#isFile}}files{{/isFile}}{{^isFile}}data{{/isFile}}["{{baseName}}"] = {{paramName}} -{{/required}} -{{/formParams}} - -{{/formParams.0}} -{{#bodyParam}} - body = jsonable_encoder({{paramName}}) - -{{/bodyParam}} - return self.api_client.request( - type_={{>_returnType}}, - method="{{httpMethod}}", - url="{{{path}}}", - {{#pathParams.0}}path_params=path_params,{{/pathParams.0}} - {{#queryParams.0}}params=query_params,{{/queryParams.0}} - {{#headerParams.0}}headers=headers,{{/headerParams.0}} - {{#cookieParams.0}}cookies=cookies,{{/cookieParams.0}} - {{#formParams.0}}data=data, - files=files{{^isMultipart}} or None{{/isMultipart}}{{/formParams.0}} - {{#bodyParam}}json=body{{/bodyParam}} - ) - -{{/operation}} -{{/operations}} - -{{#operations}} -class Async{{classname}}(_{{classname}}): -{{#operation}} - async def {{operationId}}(self{{#allParams}}, {{#required}}{{paramName}}: {{>_dataTypeApi}}{{/required}}{{^required}}{{paramName}}: Optional[{{>_dataTypeApi}}] = None{{/required}}{{/allParams}}) -> {{>_returnType}}: -{{#notes}} - """ - {{{notes}}} - """ -{{/notes}} - return await self._build_for_{{operationId}}({{#allParams}}{{^-first}}, {{/-first}}{{paramName}}={{paramName}}{{/allParams}}) - -{{/operation}} -{{/operations}} - -{{#operations}} -class Sync{{classname}}(_{{classname}}): -{{#operation}} - def {{operationId}}(self{{#allParams}}, {{#required}}{{paramName}}: {{>_dataTypeApi}}{{/required}}{{^required}}{{paramName}}: Optional[{{>_dataTypeApi}}] = None{{/required}}{{/allParams}}) -> {{>_returnType}}: -{{#notes}} - """ - {{{notes}}} - """ -{{/notes}} - coroutine = self._build_for_{{operationId}}({{#allParams}}{{^-first}}, {{/-first}}{{paramName}}={{paramName}}{{/allParams}}) - return get_event_loop().run_until_complete(coroutine) -{{/operation}} -{{/operations}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/api.mustache.new.new b/client_generator/openapi-python-templates/api.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/api_client.mustache b/client_generator/openapi-python-templates/api_client.mustache deleted file mode 100644 index 5d37815..0000000 --- a/client_generator/openapi-python-templates/api_client.mustache +++ /dev/null @@ -1,134 +0,0 @@ -# -# Copyright (c) 2023-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from asyncio import get_event_loop -from typing import ( - Any, - Awaitable, - Callable, - Dict, - Generic, - Optional, - Type, - TypeVar, - overload, -) - -from httpx import AsyncClient, Request, Response -from pydantic import ValidationError, parse_obj_as - -{{#apiInfo}}{{#apis}}from @IMPORT_NAME@.api.{{classVarName}} import Async{{classname}}, Sync{{classname}} -{{/apis}}{{/apiInfo}}from @IMPORT_NAME@.exceptions import ResponseHandlingException, UnexpectedResponse - -ClientT = TypeVar("ClientT", bound="ApiClient") - - -class AsyncApis(Generic[ClientT]): - def __init__(self, client: ClientT): - self.client = client -{{#apiInfo}}{{#apis}} - self.{{classVarName}} = Async{{classname}}(self.client){{/apis}}{{/apiInfo}} - - -class SyncApis(Generic[ClientT]): - def __init__(self, client: ClientT): - self.client = client -{{#apiInfo}}{{#apis}} - self.{{classVarName}} = Sync{{classname}}(self.client){{/apis}}{{/apiInfo}} - - -T = TypeVar("T") -Send = Callable[[Request], Awaitable[Response]] -MiddlewareT = Callable[[Request, Send], Awaitable[Response]] - - -class ApiClient: - def __init__(self, host: Optional[str] = None, **kwargs: Any) -> None: - self.host = host - self.middleware: MiddlewareT = BaseMiddleware() - self._async_client = AsyncClient(**kwargs) - - async def aclose(self) -> None: - await self._async_client.aclose() - - def close(self) -> None: - get_event_loop().run_until_complete(self.aclose()) - - @overload - async def request( - self, *, type_: Type[T], method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any - ) -> T: - ... - - @overload # noqa F811 - async def request( - self, *, type_: None, method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any - ) -> None: - ... - - async def request( # noqa F811 - self, *, type_: Any, method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any - ) -> Any: - if path_params is None: - path_params = {} - url = (self.host or "") + url.format(**path_params) - request = Request(method, url, **kwargs) - return await self.send(request, type_) - - @overload - def request_sync(self, *, type_: Type[T], **kwargs: Any) -> T: - ... - - @overload # noqa F811 - def request_sync(self, *, type_: None, **kwargs: Any) -> None: - ... - - def request_sync(self, *, type_: Any, **kwargs: Any) -> Any: # noqa F811 - """ - This method is not used by the generated apis, but is included for convenience - """ - return get_event_loop().run_until_complete(self.request(type_=type_, **kwargs)) - - async def send(self, request: Request, type_: Type[T]) -> T: - response = await self.middleware(request, self.send_inner) - if response.status_code in [200, 201]: - try: - return parse_obj_as(type_, response.json()) - except ValidationError as e: - raise ResponseHandlingException(e) - raise UnexpectedResponse.for_response(response) - - async def send_inner(self, request: Request) -> Response: - try: - response = await self._async_client.send(request) - except Exception as e: - raise ResponseHandlingException(e) - return response - - def add_middleware(self, middleware: MiddlewareT) -> None: - current_middleware = self.middleware - - async def new_middleware(request: Request, call_next: Send) -> Response: - async def inner_send(request: Request) -> Response: - return await current_middleware(request, call_next) - - return await middleware(request, inner_send) - - self.middleware = new_middleware - - -class BaseMiddleware: - async def __call__(self, request: Request, call_next: Send) -> Response: - return await call_next(request) diff --git a/client_generator/openapi-python-templates/api_client.mustache.new.new b/client_generator/openapi-python-templates/api_client.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/configuration.mustache b/client_generator/openapi-python-templates/configuration.mustache deleted file mode 100644 index 4b7de86..0000000 --- a/client_generator/openapi-python-templates/configuration.mustache +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Dummy file to remove unwanted template -""" diff --git a/client_generator/openapi-python-templates/configuration.mustache.new.new b/client_generator/openapi-python-templates/configuration.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/exceptions.mustache b/client_generator/openapi-python-templates/exceptions.mustache deleted file mode 100644 index 4393629..0000000 --- a/client_generator/openapi-python-templates/exceptions.mustache +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -from typing import Any, Dict, Optional - -from httpx import Headers, Response - -MAX_CONTENT = 200 - - -class ApiException(Exception): - """Base class""" - - -class UnexpectedResponse(ApiException): - def __init__(self, status_code: Optional[int], reason_phrase: str, content: bytes, headers: Headers) -> None: - self.status_code = status_code - self.reason_phrase = reason_phrase - self.content = content - self.headers = headers - - @staticmethod - def for_response(response: Response) -> "ApiException": - return UnexpectedResponse( - status_code=response.status_code, - reason_phrase=response.reason_phrase, - content=response.content, - headers=response.headers, - ) - - def __str__(self) -> str: - status_code_str = f"{self.status_code}" if self.status_code is not None else "" - if self.reason_phrase == "" and self.status_code is not None: - reason_phrase_str = "(Unrecognized Status Code)" - else: - reason_phrase_str = f"({self.reason_phrase})" - status_str = f"{status_code_str} {reason_phrase_str}".strip() - short_content = self.content if len(self.content) <= MAX_CONTENT else self.content[: MAX_CONTENT - 3] + b" ..." - raw_content_str = f"Raw response content:\n{short_content!r}" - return f"Unexpected Response: {status_str}\n{raw_content_str}" - - def structured(self) -> Dict[str, Any]: - return json.loads(self.content) - - -class ResponseHandlingException(ApiException): - def __init__(self, source: Exception): - self.source = source diff --git a/client_generator/openapi-python-templates/exceptions.mustache.new.new b/client_generator/openapi-python-templates/exceptions.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/model.mustache b/client_generator/openapi-python-templates/model.mustache deleted file mode 100644 index 78058bd..0000000 --- a/client_generator/openapi-python-templates/model.mustache +++ /dev/null @@ -1,37 +0,0 @@ -from datetime import date, datetime, timedelta -from typing import Optional, List, Dict -from typing import Any # noqa -from typing_extensions import Literal -from uuid import UUID -from pydantic import BaseModel, Field - -{{#models}} -{{#model}} - -{{#allowableValues}} -from enum import Enum - -class {{classname}}(str, Enum): -{{#enumVars}} - {{name}} = {{{value}}}{{^-last}} -{{/-last}} -{{/enumVars}} -{{/allowableValues}} - -{{^allowableValues}} -class {{classname}}(BaseModel): -{{#vars}} -{{#isEnum}} - {{name}}: "Literal[{{#allowableValues}}{{#values}}'{{{this}}}'{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}]" = Field({{#required}}...{{/required}}{{^required}}None{{/required}}, alias="{{baseName}}") -{{/isEnum}} -{{^isEnum}} - {{name}}: "{{^required}}Optional[{{/required}}{{>_dataTypeModel}}{{^required}}]{{/required}}" = Field({{#required}}...{{/required}}{{^required}}None{{/required}}, alias="{{baseName}}") -{{/isEnum}} -{{/vars}} -{{^vars}} - pass -{{/vars}} -{{/allowableValues}} - -{{/model}} -{{/models}} diff --git a/client_generator/openapi-python-templates/model.mustache.new.new b/client_generator/openapi-python-templates/model.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/requirements.mustache b/client_generator/openapi-python-templates/requirements.mustache deleted file mode 100644 index 8bf5f3e..0000000 --- a/client_generator/openapi-python-templates/requirements.mustache +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -pydantic >= 1.0 -httpx >= 0.10 -fastapi >= 0.40 -typing_extensions >= 3.7.4 diff --git a/client_generator/openapi-python-templates/requirements.mustache.new.new b/client_generator/openapi-python-templates/requirements.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/rest.mustache b/client_generator/openapi-python-templates/rest.mustache deleted file mode 100644 index 4db4a6f..0000000 --- a/client_generator/openapi-python-templates/rest.mustache +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Dummy file to remove unwanted template -""" diff --git a/client_generator/openapi-python-templates/rest.mustache.new.new b/client_generator/openapi-python-templates/rest.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/setup.mustache b/client_generator/openapi-python-templates/setup.mustache deleted file mode 100644 index 0985ff6..0000000 --- a/client_generator/openapi-python-templates/setup.mustache +++ /dev/null @@ -1,38 +0,0 @@ -{{>partial_header}} - -from setuptools import setup, find_packages # noqa: H301 - -NAME = "{{{projectName}}}" -VERSION = "{{packageVersion}}" -{{#apiInfo}} -{{#apis}} -{{^hasMore}} -# To install the library, run the following -# -# python setup.py install -# -# prerequisite: setuptools -# http://pypi.python.org/pypi/setuptools - -REQUIRES = ["pydantic", "httpx", "fastapi", "typing_extensions"] - -setup( - name=NAME, - version=VERSION, - description="{{appName}}", - author_email="{{infoEmail}}", - url="{{packageUrl}}", - keywords=["Swagger", "{{appName}}"], - install_requires=REQUIRES, - packages=find_packages(), - include_package_data=True, - package_data={ - "{{{packageName}}}": ["py.typed"], - }, - long_description="""\ - {{appDescription}} # noqa: E501 - """ -) -{{/hasMore}} -{{/apis}} -{{/apiInfo}} diff --git a/client_generator/openapi-python-templates/setup.mustache.new.new b/client_generator/openapi-python-templates/setup.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/test-requirements.mustache b/client_generator/openapi-python-templates/test-requirements.mustache deleted file mode 100644 index e6fb883..0000000 --- a/client_generator/openapi-python-templates/test-requirements.mustache +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -pytest>=3.3.1 -pytest-cov>=2.5.1 -pluggy>=0.3.1 -py>=1.4.31 -randomize>=0.13 \ No newline at end of file diff --git a/client_generator/openapi-python-templates/test-requirements.mustache.new.new b/client_generator/openapi-python-templates/test-requirements.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/tox.mustache b/client_generator/openapi-python-templates/tox.mustache deleted file mode 100644 index bf4e71d..0000000 --- a/client_generator/openapi-python-templates/tox.mustache +++ /dev/null @@ -1,10 +0,0 @@ - -[tox] -envlist = py3 - -[testenv] -deps=-r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - -commands= - pytest -v --cov {{{projectName}}} \ No newline at end of file diff --git a/client_generator/openapi-python-templates/tox.mustache.new.new b/client_generator/openapi-python-templates/tox.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/openapi-python-templates/travis.mustache b/client_generator/openapi-python-templates/travis.mustache deleted file mode 100644 index fbf553b..0000000 --- a/client_generator/openapi-python-templates/travis.mustache +++ /dev/null @@ -1,8 +0,0 @@ -language: python -python: - - "3.7" - - "3.8" -# command to install dependencies -install: "pip install -r requirements.txt" -# command to run tests -script: nosetests \ No newline at end of file diff --git a/client_generator/openapi-python-templates/travis.mustache.new.new b/client_generator/openapi-python-templates/travis.mustache.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/other-templates/.openapi-generator-ignore b/client_generator/other-templates/.openapi-generator-ignore deleted file mode 100644 index 83d0b37..0000000 --- a/client_generator/other-templates/.openapi-generator-ignore +++ /dev/null @@ -1,35 +0,0 @@ -# OpenAPI Generator Ignore -# Generated by openapi-generator https://github.com/openapitools/openapi-generator - -# Use this file to prevent files from being overwritten by the generator. -# The patterns follow closely to .gitignore or .dockerignore. - -# As an example, the C# client generator defines ApiClient.cs. -# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: -#ApiClient.cs - -# You can match any string of characters against a directory, file or extension with a single asterisk (*): -#foo/*/qux -# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux - -# You can recursively match patterns against a directory, file or extension with a double asterisk (**): -#foo/**/qux -# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux - -# You can also negate patterns with an exclamation (!). -# For example, you can ignore all files in a docs folder with the file extension .md: -#docs/*.md -# Then explicitly reverse the ignore rule for a single file: -#!docs/README.md - - -# ### Added for FastAPI Client ### -PACKAGE_NAME/test/ -PACKAGE_NAME/docs/ -PACKAGE_NAME/configuration.py -PACKAGE_NAME/rest.py -PACKAGE_NAME_README.md - -# These may not be desired: -# PACKAGE_NAME/api/default_api.py -# PACKAGE_NAME/models/body*.py diff --git a/client_generator/other-templates/auth.template b/client_generator/other-templates/auth.template deleted file mode 100644 index 213f7bf..0000000 --- a/client_generator/other-templates/auth.template +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from contextlib import suppress -from datetime import date, datetime, timedelta -from typing import Optional - -from fastapi.openapi.models import OAuthFlowPassword -from httpx import Request, Response -from pydantic import BaseModel - -from @IMPORT_NAME@.api_client import Send -from @IMPORT_NAME@.exceptions import UnexpectedResponse -from @IMPORT_NAME@.password_flow_client import ( - AccessTokenRequest, - PasswordFlowClient, - RefreshTokenRequest, - TokenSuccessResponse, -) - -HTTP_401_UNAUTHORIZED = 401 - - -class AuthState(BaseModel): - username: Optional[str] - password: Optional[str] - access_token: Optional[str] - refresh_token: Optional[str] - expires_at: Optional[datetime] # should be UTC - scope: Optional[str] - - def get_login_request(self) -> Optional[AccessTokenRequest]: - if self.username is None or self.password is None: - return None - return AccessTokenRequest(username=self.username, password=self.password, scope=self.scope) - - def get_refresh_request(self) -> Optional[RefreshTokenRequest]: - if self.refresh_token is None: - return None - return RefreshTokenRequest(refresh_token=self.refresh_token, scope=self.scope) - - def is_expired(self) -> bool: - if self.expires_at is None: - return False - return self.expires_at < datetime.utcnow() + timedelta(seconds=30) - - def update(self, token_success_response: TokenSuccessResponse) -> None: - self.access_token = token_success_response.access_token - self.refresh_token = token_success_response.refresh_token - self.scope = token_success_response.scope - if token_success_response.expires_in is not None: - self.expires_at = datetime.utcnow() + timedelta(seconds=token_success_response.expires_in) - - -class AuthMiddleware: - def __init__(self, auth_state: AuthState, flow: OAuthFlowPassword) -> None: - self.auth_state = auth_state - self.flow_client = PasswordFlowClient(flow) - - @staticmethod - def set_access_header(token: str, request: Request, *, replace: bool) -> None: - key = "authorization" - value = f"bearer {token}" - if replace: - request.headers[key] = value - else: - request.headers.setdefault(key, value) - - async def login(self) -> Optional[TokenSuccessResponse]: - access_token_request = self.auth_state.get_login_request() - if access_token_request is None: - return None - with suppress(UnexpectedResponse): - token_response = await self.flow_client.request_access_token(access_token_request) - if isinstance(token_response, TokenSuccessResponse): - self.update_auth_state(token_response) - return token_response - return None - - async def refresh(self) -> Optional[TokenSuccessResponse]: - refresh_token_request = self.auth_state.get_refresh_request() - if refresh_token_request is None: - return None - with suppress(UnexpectedResponse): - token_response = await self.flow_client.request_refresh_token(refresh_token_request) - if isinstance(token_response, TokenSuccessResponse): - self.update_auth_state(token_response) - return token_response - return None - - async def __call__(self, request: Request, call_next: Send) -> Response: - if self.auth_state.is_expired(): - await self.refresh() - access_token = self.auth_state.access_token - if access_token is not None: - self.set_access_header(access_token, request, replace=False) - - response = await call_next(request) - - if response.status_code != HTTP_401_UNAUTHORIZED: - return response - tokens = await self.refresh() - if tokens is None: - tokens = await self.login() - if tokens: - self.set_access_header(tokens.access_token, request, replace=True) - return await call_next(request) # note: won't work with streaming input - return response - - def update_auth_state(self, tokens: TokenSuccessResponse) -> None: - """ - Override this function if you want a hook for caching the access/refresh tokens - """ - self.auth_state.update(tokens) diff --git a/client_generator/other-templates/auth.template.new.new b/client_generator/other-templates/auth.template.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/other-templates/password_flow_client.template b/client_generator/other-templates/password_flow_client.template deleted file mode 100644 index d23ec84..0000000 --- a/client_generator/other-templates/password_flow_client.template +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Attempting to follow the "password" flow as described in RFC 6749: https://tools.ietf.org/html/rfc6749 -""" -from asyncio import get_event_loop -from contextlib import suppress -from enum import Enum -from typing import Any, Dict, List, Optional, Type, TypeVar, Union - -from fastapi.openapi.models import OAuthFlowPassword -from httpx import AsyncClient, Response -from pydantic import BaseModel, ValidationError -from typing_extensions import Literal - -from @IMPORT_NAME@.exceptions import UnexpectedResponse - -TokenRequestT = TypeVar("TokenRequestT", bound="BaseTokenRequest") -HTTP_200_OK = 200 -HTTP_400_BAD_REQUEST = 400 -HTTP_401_UNAUTHORIZED = 401 - - -class BaseTokenRequest(BaseModel): - scope: Optional[str] - - def request_dict(self) -> Dict[str, str]: - request_dict = self.dict() - if request_dict["scope"] is None: - del request_dict["scope"] - return request_dict - - @classmethod - def from_scopes(cls: Type[TokenRequestT], *, scopes: Optional[List[str]], **kwargs: Any) -> TokenRequestT: - scope = " ".join(scopes) if scopes is not None else None - return cls(scope=scope, **kwargs) - - -class AccessTokenRequest(BaseTokenRequest): - """ - Specific to the OAuth2.0 "password" flow - """ - - grant_type: Literal["password"] = "password" - username: str - password: str - scope: Optional[str] - - -class RefreshTokenRequest(BaseTokenRequest): - grant_type: Literal["refresh_token"] = "refresh_token" - refresh_token: str - scope: Optional[str] - - -class TokenSuccessResponse(BaseModel): - access_token: str - token_type: str - expires_in: Optional[int] - refresh_token: Optional[str] - scope: Optional[str] - - -class TokenErrorType(Enum): - invalid_request = "invalid_request" - invalid_client = "invalid_client" - invalid_grant = "invalid_grant" - unauthorized_client = "unauthorized_client" - unsupported_grant_type = "unsupported_grant_type" - invalid_scope = "invalid_scope" - - -class TokenErrorResponse(BaseModel): - error: Union[TokenErrorType, str] - error_description: Optional[str] - error_uri: Optional[str] - - -TokenResponse = Union[TokenSuccessResponse, TokenErrorResponse] - - -def parse_token_response(response: Response) -> TokenResponse: - with suppress(ValidationError): - if response.status_code == HTTP_200_OK: - return TokenSuccessResponse.parse_raw(response.text) - if response.status_code in (HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED): - return TokenErrorResponse.parse_raw(response.text) - raise UnexpectedResponse.for_response(response) - - -class PasswordFlowClient: - def __init__(self, flow: OAuthFlowPassword) -> None: - self.flow = flow - self._async_client = AsyncClient() - - async def request_access_token(self, access_token_request: AccessTokenRequest) -> TokenResponse: - response = await self._async_client.post(self.flow.tokenUrl, data=access_token_request.request_dict()) - return parse_token_response(response) - - async def request_refresh_token(self, refresh_token_request: RefreshTokenRequest) -> TokenResponse: - refresh_url = self.flow.refreshUrl or self.flow.tokenUrl - response = await self._async_client.post(refresh_url, data=refresh_token_request.request_dict()) - return parse_token_response(response) - - def request_access_token_sync(self, access_token_request: AccessTokenRequest) -> TokenResponse: - return get_event_loop().run_until_complete(self.request_access_token(access_token_request)) - - def request_refresh_token_sync(self, refresh_token_request: RefreshTokenRequest) -> TokenResponse: - return get_event_loop().run_until_complete(self.request_refresh_token(refresh_token_request)) diff --git a/client_generator/other-templates/password_flow_client.template.new.new b/client_generator/other-templates/password_flow_client.template.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/poetry.lock b/client_generator/poetry.lock deleted file mode 100644 index 8252b81..0000000 --- a/client_generator/poetry.lock +++ /dev/null @@ -1,879 +0,0 @@ -[[package]] -category = "dev" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -name = "appdirs" -optional = false -python-versions = "*" -version = "1.4.3" - -[[package]] -category = "dev" -description = "Atomic file writes." -marker = "sys_platform == \"win32\"" -name = "atomicwrites" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.3.0" - -[[package]] -category = "dev" -description = "Classes Without Boilerplate" -name = "attrs" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.3.0" - -[package.extras] -azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] -dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] -docs = ["sphinx", "zope.interface"] -tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] - -[[package]] -category = "dev" -description = "The uncompromising code formatter." -name = "black" -optional = false -python-versions = ">=3.6" -version = "19.10b0" - -[package.dependencies] -appdirs = "*" -attrs = ">=18.1.0" -click = ">=6.5" -pathspec = ">=0.6,<1" -regex = "*" -toml = ">=0.9.4" -typed-ast = ">=1.4.0" - -[package.extras] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] - -[[package]] -category = "main" -description = "Python package for providing Mozilla's CA Bundle." -name = "certifi" -optional = false -python-versions = "*" -version = "2019.11.28" - -[[package]] -category = "main" -description = "Universal encoding detector for Python 2 and 3" -name = "chardet" -optional = false -python-versions = "*" -version = "3.0.4" - -[[package]] -category = "dev" -description = "Composable command line interface toolkit" -name = "click" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "7.0" - -[[package]] -category = "dev" -description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" -name = "colorama" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.3" - -[[package]] -category = "dev" -description = "Code coverage measurement for Python" -name = "coverage" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.0.2" - -[package.extras] -toml = ["toml"] - -[[package]] -category = "dev" -description = "Discover and load entry points from installed packages." -name = "entrypoints" -optional = false -python-versions = ">=2.7" -version = "0.3" - -[[package]] -category = "main" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -name = "fastapi" -optional = false -python-versions = ">=3.6" -version = "0.46.0" - -[package.dependencies] -pydantic = ">=0.32.2,<2.0.0" -starlette = "0.12.9" - -[package.extras] -all = ["requests", "aiofiles", "jinja2", "python-multipart", "itsdangerous", "pyyaml", "graphene", "ujson", "email-validator", "uvicorn", "async-exit-stack", "async-generator"] -dev = ["pyjwt", "passlib"] -doc = ["mkdocs", "mkdocs-material", "markdown-include"] -test = ["pytest (>=4.0.0)", "pytest-cov", "mypy", "black", "isort", "requests", "email-validator", "sqlalchemy", "peewee", "databases", "orjson", "async-exit-stack", "async-generator"] - -[[package]] -category = "dev" -description = "the modular source code checker: pep8, pyflakes and co" -name = "flake8" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.7.9" - -[package.dependencies] -entrypoints = ">=0.3.0,<0.4.0" -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.5.0,<2.6.0" -pyflakes = ">=2.1.0,<2.2.0" - -[[package]] -category = "main" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -name = "h11" -optional = false -python-versions = "*" -version = "0.9.0" - -[[package]] -category = "main" -description = "HTTP/2 State-Machine based protocol implementation" -name = "h2" -optional = false -python-versions = "*" -version = "3.1.1" - -[package.dependencies] -hpack = ">=2.3,<4" -hyperframe = ">=5.2.0,<6" - -[[package]] -category = "main" -description = "Pure-Python HPACK header compression" -name = "hpack" -optional = false -python-versions = "*" -version = "3.0.0" - -[[package]] -category = "main" -description = "Chromium HSTS Preload list as a Python package and updated daily" -name = "hstspreload" -optional = false -python-versions = ">=3.6" -version = "2020.1.7" - -[[package]] -category = "dev" -description = "A collection of framework independent HTTP protocol utils." -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"pypy\"" -name = "httptools" -optional = false -python-versions = "*" -version = "0.0.13" - -[[package]] -category = "main" -description = "The next generation HTTP client." -name = "httpx" -optional = false -python-versions = ">=3.6" -version = "0.11.0" - -[package.dependencies] -certifi = "*" -chardet = ">=3.0.0,<4.0.0" -h11 = ">=0.8,<0.10" -h2 = ">=3.0.0,<4.0.0" -hstspreload = "*" -idna = ">=2.0.0,<3.0.0" -rfc3986 = ">=1.3,<2" -sniffio = ">=1.0.0,<2.0.0" -urllib3 = ">=1.0.0,<2.0.0" - -[[package]] -category = "main" -description = "HTTP/2 framing layer for Python" -name = "hyperframe" -optional = false -python-versions = "*" -version = "5.2.0" - -[[package]] -category = "main" -description = "Internationalized Domain Names in Applications (IDNA)" -name = "idna" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8" - -[[package]] -category = "dev" -description = "Read metadata from Python packages" -marker = "python_version < \"3.8\"" -name = "importlib-metadata" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.3.0" - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "importlib-resources"] - -[[package]] -category = "dev" -description = "A Python utility / library to sort Python imports." -name = "isort" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "4.3.21" - -[package.extras] -pipfile = ["pipreqs", "requirementslib"] -pyproject = ["toml"] -requirements = ["pipreqs", "pip-api"] -xdg_home = ["appdirs (>=1.4.0)"] - -[[package]] -category = "dev" -description = "McCabe checker, plugin for flake8" -name = "mccabe" -optional = false -python-versions = "*" -version = "0.6.1" - -[[package]] -category = "dev" -description = "More routines for operating on iterables, beyond itertools" -name = "more-itertools" -optional = false -python-versions = ">=3.5" -version = "8.0.2" - -[[package]] -category = "dev" -description = "Optional static typing for Python" -name = "mypy" -optional = false -python-versions = ">=3.5" -version = "0.761" - -[package.dependencies] -mypy-extensions = ">=0.4.3,<0.5.0" -typed-ast = ">=1.4.0,<1.5.0" -typing-extensions = ">=3.7.4" - -[package.extras] -dmypy = ["psutil (>=4.0)"] - -[[package]] -category = "dev" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -name = "mypy-extensions" -optional = false -python-versions = "*" -version = "0.4.3" - -[[package]] -category = "dev" -description = "Core utilities for Python packages" -name = "packaging" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.0" - -[package.dependencies] -pyparsing = ">=2.0.2" -six = "*" - -[[package]] -category = "dev" -description = "Utility library for gitignore style pattern matching of file paths." -name = "pathspec" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.7.0" - -[[package]] -category = "dev" -description = "plugin and hook calling mechanisms for python" -name = "pluggy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.1" - -[package.dependencies] -[package.dependencies.importlib-metadata] -python = "<3.8" -version = ">=0.12" - -[package.extras] -dev = ["pre-commit", "tox"] - -[[package]] -category = "dev" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -name = "py" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.8.1" - -[[package]] -category = "dev" -description = "Python style guide checker" -name = "pycodestyle" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.5.0" - -[[package]] -category = "main" -description = "Data validation and settings management using python 3.6 type hinting" -name = "pydantic" -optional = false -python-versions = ">=3.6" -version = "1.3" - -[package.extras] -email = ["email-validator (>=1.0.3)"] -typing_extensions = ["typing-extensions (>=3.7.2)"] - -[[package]] -category = "dev" -description = "passive checker of Python programs" -name = "pyflakes" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.1.1" - -[[package]] -category = "dev" -description = "Python parsing module" -name = "pyparsing" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.4.6" - -[[package]] -category = "dev" -description = "pytest: simple powerful testing with Python" -name = "pytest" -optional = false -python-versions = ">=3.5" -version = "5.3.2" - -[package.dependencies] -atomicwrites = ">=1.0" -attrs = ">=17.4.0" -colorama = "*" -more-itertools = ">=4.0.0" -packaging = "*" -pluggy = ">=0.12,<1.0" -py = ">=1.5.0" -wcwidth = "*" - -[package.dependencies.importlib-metadata] -python = "<3.8" -version = ">=0.12" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -category = "dev" -description = "Pytest plugin for measuring coverage." -name = "pytest-cov" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8.1" - -[package.dependencies] -coverage = ">=4.4" -pytest = ">=3.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"] - -[[package]] -category = "dev" -description = "A streaming multipart parser for Python" -name = "python-multipart" -optional = false -python-versions = "*" -version = "0.0.5" - -[package.dependencies] -six = ">=1.4.0" - -[[package]] -category = "dev" -description = "Alternative regular expression module, to replace re." -name = "regex" -optional = false -python-versions = "*" -version = "2020.1.8" - -[[package]] -category = "main" -description = "Validating URI References per RFC 3986" -name = "rfc3986" -optional = false -python-versions = "*" -version = "1.3.2" - -[package.extras] -idna2008 = ["idna"] - -[[package]] -category = "dev" -description = "Python 2 and 3 compatibility utilities" -name = "six" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.13.0" - -[[package]] -category = "main" -description = "Sniff out which async library your code is running under" -name = "sniffio" -optional = false -python-versions = ">=3.5" -version = "1.1.0" - -[[package]] -category = "main" -description = "The little ASGI library that shines." -name = "starlette" -optional = false -python-versions = ">=3.6" -version = "0.12.9" - -[package.extras] -full = ["aiofiles", "graphene", "itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests", "ujson"] - -[[package]] -category = "dev" -description = "Python Library for Tom's Obvious, Minimal Language" -name = "toml" -optional = false -python-versions = "*" -version = "0.10.0" - -[[package]] -category = "dev" -description = "a fork of Python 2 and 3 ast modules with type comment support" -name = "typed-ast" -optional = false -python-versions = "*" -version = "1.4.0" - -[[package]] -category = "main" -description = "Backported and Experimental Type Hints for Python 3.5+" -name = "typing-extensions" -optional = false -python-versions = "*" -version = "3.7.4.1" - -[[package]] -category = "main" -description = "HTTP library with thread-safe connection pooling, file post, and more." -name = "urllib3" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" -version = "1.25.7" - -[package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] - -[[package]] -category = "dev" -description = "The lightning-fast ASGI server." -name = "uvicorn" -optional = false -python-versions = "*" -version = "0.11.1" - -[package.dependencies] -click = ">=7.0.0,<8.0.0" -h11 = ">=0.8,<0.10" -httptools = "0.0.13" -uvloop = ">=0.14.0" -websockets = ">=8.0.0,<9.0.0" - -[[package]] -category = "dev" -description = "Fast implementation of asyncio event loop on top of libuv" -marker = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"pypy\"" -name = "uvloop" -optional = false -python-versions = "*" -version = "0.14.0" - -[[package]] -category = "dev" -description = "Measures number of Terminal column cells of wide-character codes" -name = "wcwidth" -optional = false -python-versions = "*" -version = "0.1.8" - -[[package]] -category = "dev" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -name = "websockets" -optional = false -python-versions = ">=3.6.1" -version = "8.1" - -[[package]] -category = "dev" -description = "Backport of pathlib-compatible object wrapper for zip files" -marker = "python_version < \"3.8\"" -name = "zipp" -optional = false -python-versions = ">=2.7" -version = "0.6.0" - -[package.dependencies] -more-itertools = "*" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pathlib2", "contextlib2", "unittest2"] - -[metadata] -content-hash = "44817fa02f0c6094dd6cde4dcd935aef79788c5292b39ed4209ddf5341a61747" -python-versions = "^3.7" - -[metadata.files] -appdirs = [ - {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, - {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, -] -atomicwrites = [ - {file = "atomicwrites-1.3.0-py2.py3-none-any.whl", hash = "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4"}, - {file = "atomicwrites-1.3.0.tar.gz", hash = "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"}, -] -attrs = [ - {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, - {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, -] -black = [ - {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, - {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, -] -certifi = [ - {file = "certifi-2019.11.28-py2.py3-none-any.whl", hash = "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3"}, - {file = "certifi-2019.11.28.tar.gz", hash = "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"}, -] -chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -click = [ - {file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"}, - {file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"}, -] -colorama = [ - {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, - {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, -] -coverage = [ - {file = "coverage-5.0.2-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:511ec0c00840e12fb4e852e4db58fa6a01ca4da72f36a9766fae344c3d502033"}, - {file = "coverage-5.0.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d22b4297e7e4225ccf01f1aa55e7a96412ea0796b532dd614c3fcbafa341128e"}, - {file = "coverage-5.0.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:593853aa1ac6dcc6405324d877544c596c9d948ef20d2e9512a0f5d2d3202356"}, - {file = "coverage-5.0.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e65a5aa1670db6263f19fdc03daee1d7dbbadb5cb67fd0a1f16033659db13c1d"}, - {file = "coverage-5.0.2-cp27-cp27m-win32.whl", hash = "sha256:d4a2b578a7a70e0c71f662705262f87a456f1e6c1e40ada7ea699abaf070a76d"}, - {file = "coverage-5.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:28f7f73b34a05e23758e860a89a7f649b85c6749e252eff60ebb05532d180e86"}, - {file = "coverage-5.0.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7d1cc7acc9ce55179616cf72154f9e648136ea55987edf84addbcd9886ffeba2"}, - {file = "coverage-5.0.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:2d0cb9b1fe6ad0d915d45ad3d87f03a38e979093a98597e755930db1f897afae"}, - {file = "coverage-5.0.2-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:bfe102659e2ec13b86c7f3b1db6c9a4e7beea4255058d006351339e6b342d5d2"}, - {file = "coverage-5.0.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:23688ff75adfa8bfa2a67254d889f9bdf9302c27241d746e17547c42c732d3f4"}, - {file = "coverage-5.0.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1bf7ba2af1d373a1750888724f84cffdfc697738f29a353c98195f98fc011509"}, - {file = "coverage-5.0.2-cp35-cp35m-win32.whl", hash = "sha256:569f9ee3025682afda6e9b0f5bb14897c0db03f1a1dc088b083dd36e743f92bb"}, - {file = "coverage-5.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:cf908840896f7aa62d0ec693beb53264b154f972eb8226fb864ac38975590c4f"}, - {file = "coverage-5.0.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:eaad65bd20955131bcdb3967a4dea66b4e4d4ca488efed7c00d91ee0173387e8"}, - {file = "coverage-5.0.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:225e79a5d485bc1642cb7ba02281419c633c216cdc6b26c26494ba959f09e69f"}, - {file = "coverage-5.0.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bd82b684bb498c60ef47bb1541a50e6d006dde8579934dcbdbc61d67d1ea70d9"}, - {file = "coverage-5.0.2-cp36-cp36m-win32.whl", hash = "sha256:7ca3db38a61f3655a2613ee2c190d63639215a7a736d3c64cc7bbdb002ce6310"}, - {file = "coverage-5.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:47874b4711c5aeb295c31b228a758ce3d096be83dc37bd56da48ed99efb8813b"}, - {file = "coverage-5.0.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:955ec084f549128fa2702f0b2dc696392001d986b71acd8fd47424f28289a9c3"}, - {file = "coverage-5.0.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1f4ee8e2e4243971618bc16fcc4478317405205f135e95226c2496e2a3b8dbbf"}, - {file = "coverage-5.0.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f45fba420b94165c17896861bb0e8b27fb7abdcedfeb154895d8553df90b7b00"}, - {file = "coverage-5.0.2-cp37-cp37m-win32.whl", hash = "sha256:cca38ded59105f7705ef6ffe1e960b8db6c7d8279c1e71654a4775ab4454ca15"}, - {file = "coverage-5.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:cb2b74c123f65e8166f7e1265829a6c8ed755c3cd16d7f50e75a83456a5f3fd7"}, - {file = "coverage-5.0.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:53e7438fef0c97bc248f88ba1edd10268cd94d5609970aaf87abbe493691af87"}, - {file = "coverage-5.0.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c1e4e39e43057396a5e9d069bfbb6ffeee892e40c5d2effbd8cd71f34ee66c4d"}, - {file = "coverage-5.0.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b0a07158360d22492f9abd02a0f2ee7981b33f0646bf796598b7673f6bbab14"}, - {file = "coverage-5.0.2-cp38-cp38m-win32.whl", hash = "sha256:88b51153657612aea68fa684a5b88037597925260392b7bb4509d4f9b0bdd889"}, - {file = "coverage-5.0.2-cp38-cp38m-win_amd64.whl", hash = "sha256:189aac76d6e0d7af15572c51892e7326ee451c076c5a50a9d266406cd6c49708"}, - {file = "coverage-5.0.2-cp39-cp39m-win32.whl", hash = "sha256:d095a7b473f8a95f7efe821f92058c8a2ecfb18f8db6677ae3819e15dc11aaae"}, - {file = "coverage-5.0.2-cp39-cp39m-win_amd64.whl", hash = "sha256:ddeb42a3d5419434742bf4cc71c9eaa22df3b76808e23a82bd0b0bd360f1a9f1"}, - {file = "coverage-5.0.2.tar.gz", hash = "sha256:b251c7092cbb6d789d62dc9c9e7c4fb448c9138b51285c36aeb72462cad3600e"}, -] -entrypoints = [ - {file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"}, - {file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"}, -] -fastapi = [ - {file = "fastapi-0.46.0-py3-none-any.whl", hash = "sha256:7f8d795be11e21675b6843424b378fe2ec95a14cecba1c53c68471412cca28c7"}, - {file = "fastapi-0.46.0.tar.gz", hash = "sha256:6c9b919f2ed742d2ad78e6dce5ad1be761e67292b838ba114cb525ec784d10a1"}, -] -flake8 = [ - {file = "flake8-3.7.9-py2.py3-none-any.whl", hash = "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"}, - {file = "flake8-3.7.9.tar.gz", hash = "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb"}, -] -h11 = [ - {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, - {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, -] -h2 = [ - {file = "h2-3.1.1-py2.py3-none-any.whl", hash = "sha256:ac377fcf586314ef3177bfd90c12c7826ab0840edeb03f0f24f511858326049e"}, - {file = "h2-3.1.1.tar.gz", hash = "sha256:b8a32bd282594424c0ac55845377eea13fa54fe4a8db012f3a198ed923dc3ab4"}, -] -hpack = [ - {file = "hpack-3.0.0-py2.py3-none-any.whl", hash = "sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89"}, - {file = "hpack-3.0.0.tar.gz", hash = "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"}, -] -hstspreload = [ - {file = "hstspreload-2020.1.7.tar.gz", hash = "sha256:911ec40002cfd728cb3b962adfc376a87a4062c4f119da46e221caa0b33dc501"}, -] -httptools = [ - {file = "httptools-0.0.13.tar.gz", hash = "sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"}, -] -httpx = [ - {file = "httpx-0.11.0-py2.py3-none-any.whl", hash = "sha256:2f2a7ce82cd4373af5a72d2646e20e4061da36b637ebcb88b93265083f132bff"}, - {file = "httpx-0.11.0.tar.gz", hash = "sha256:abc46081611a86270d92c8fcaaf148f1eb33510c92096075fac27288bea3a9b2"}, -] -hyperframe = [ - {file = "hyperframe-5.2.0-py2.py3-none-any.whl", hash = "sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40"}, - {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, -] -idna = [ - {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, - {file = "idna-2.8.tar.gz", hash = "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"}, -] -importlib-metadata = [ - {file = "importlib_metadata-1.3.0-py2.py3-none-any.whl", hash = "sha256:d95141fbfa7ef2ec65cfd945e2af7e5a6ddbd7c8d9a25e66ff3be8e3daf9f60f"}, - {file = "importlib_metadata-1.3.0.tar.gz", hash = "sha256:073a852570f92da5f744a3472af1b61e28e9f78ccf0c9117658dc32b15de7b45"}, -] -isort = [ - {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, - {file = "isort-4.3.21.tar.gz", hash = "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -more-itertools = [ - {file = "more-itertools-8.0.2.tar.gz", hash = "sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d"}, - {file = "more_itertools-8.0.2-py3-none-any.whl", hash = "sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564"}, -] -mypy = [ - {file = "mypy-0.761-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:7f672d02fffcbace4db2b05369142e0506cdcde20cea0e07c7c2171c4fd11dd6"}, - {file = "mypy-0.761-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:87c556fb85d709dacd4b4cb6167eecc5bbb4f0a9864b69136a0d4640fdc76a36"}, - {file = "mypy-0.761-cp35-cp35m-win_amd64.whl", hash = "sha256:c6d27bd20c3ba60d5b02f20bd28e20091d6286a699174dfad515636cb09b5a72"}, - {file = "mypy-0.761-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:4b9365ade157794cef9685791032521233729cb00ce76b0ddc78749abea463d2"}, - {file = "mypy-0.761-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:634aef60b4ff0f650d3e59d4374626ca6153fcaff96ec075b215b568e6ee3cb0"}, - {file = "mypy-0.761-cp36-cp36m-win_amd64.whl", hash = "sha256:53ea810ae3f83f9c9b452582261ea859828a9ed666f2e1ca840300b69322c474"}, - {file = "mypy-0.761-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:0a9a45157e532da06fe56adcfef8a74629566b607fa2c1ac0122d1ff995c748a"}, - {file = "mypy-0.761-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7eadc91af8270455e0d73565b8964da1642fe226665dd5c9560067cd64d56749"}, - {file = "mypy-0.761-cp37-cp37m-win_amd64.whl", hash = "sha256:e2bb577d10d09a2d8822a042a23b8d62bc3b269667c9eb8e60a6edfa000211b1"}, - {file = "mypy-0.761-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c35cae79ceb20d47facfad51f952df16c2ae9f45db6cb38405a3da1cf8fc0a7"}, - {file = "mypy-0.761-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f97a605d7c8bc2c6d1172c2f0d5a65b24142e11a58de689046e62c2d632ca8c1"}, - {file = "mypy-0.761-cp38-cp38-win_amd64.whl", hash = "sha256:a6bd44efee4dc8c3324c13785a9dc3519b3ee3a92cada42d2b57762b7053b49b"}, - {file = "mypy-0.761-py3-none-any.whl", hash = "sha256:7e396ce53cacd5596ff6d191b47ab0ea18f8e0ec04e15d69728d530e86d4c217"}, - {file = "mypy-0.761.tar.gz", hash = "sha256:85baab8d74ec601e86134afe2bcccd87820f79d2f8d5798c889507d1088287bf"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -packaging = [ - {file = "packaging-20.0-py2.py3-none-any.whl", hash = "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb"}, - {file = "packaging-20.0.tar.gz", hash = "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8"}, -] -pathspec = [ - {file = "pathspec-0.7.0-py2.py3-none-any.whl", hash = "sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424"}, - {file = "pathspec-0.7.0.tar.gz", hash = "sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"}, -] -pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, -] -py = [ - {file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"}, - {file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"}, -] -pycodestyle = [ - {file = "pycodestyle-2.5.0-py2.py3-none-any.whl", hash = "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56"}, - {file = "pycodestyle-2.5.0.tar.gz", hash = "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"}, -] -pydantic = [ - {file = "pydantic-1.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:dd9359db7644317898816f6142f378aa48848dcc5cf14a481236235fde11a148"}, - {file = "pydantic-1.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cbe284bd5ad67333d49ecc0dc27fa52c25b4c2fe72802a5c060b5f922db58bef"}, - {file = "pydantic-1.3-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:2b32a5f14558c36e39aeefda0c550bfc0f47fc32b4ce16d80dc4df2b33838ed8"}, - {file = "pydantic-1.3-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:59235324dd7dc5363a654cd14271ea8631f1a43de5d4fc29c782318fcc498002"}, - {file = "pydantic-1.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:176885123dfdd8f7ab6e7ba1b66d4197de75ba830bb44d921af88b3d977b8aa5"}, - {file = "pydantic-1.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d4bb6a75abc2f04f6993124f1ed4221724c9dc3bd9df5cb54132e0b68775d375"}, - {file = "pydantic-1.3-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8a8e089aec18c26561e09ee6daf15a3cc06df05bdc67de60a8684535ef54562f"}, - {file = "pydantic-1.3-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:479ca8dc7cc41418751bf10302ee0a1b1f8eedb2de6c4f4c0f3cf8372b204f9a"}, - {file = "pydantic-1.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:87673d1de790c8d5282153cab0b09271be77c49aabcedf3ac5ab1a1fd4dcbac0"}, - {file = "pydantic-1.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:dacb79144bb3fdb57cf9435e1bd16c35586bc44256215cfaa33bf21565d926ae"}, - {file = "pydantic-1.3-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c0da48978382c83f9488c6bbe4350e065ea5c83e85ca5cfb8fa14ac11de3c296"}, - {file = "pydantic-1.3-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b60f2b3b0e0dd74f1800a57d1bbd597839d16faf267e45fa4a5407b15d311085"}, - {file = "pydantic-1.3-py36.py37.py38-none-any.whl", hash = "sha256:d03df07b7611004140b0fef91548878c2b5f48c520a8cb76d11d20e9887a495e"}, - {file = "pydantic-1.3.tar.gz", hash = "sha256:2eab7d548b0e530bf65bee7855ad8164c2f6a889975d5e9c4eefd1e7c98245dc"}, -] -pyflakes = [ - {file = "pyflakes-2.1.1-py2.py3-none-any.whl", hash = "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0"}, - {file = "pyflakes-2.1.1.tar.gz", hash = "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"}, -] -pyparsing = [ - {file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"}, - {file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"}, -] -pytest = [ - {file = "pytest-5.3.2-py3-none-any.whl", hash = "sha256:e41d489ff43948babd0fad7ad5e49b8735d5d55e26628a58673c39ff61d95de4"}, - {file = "pytest-5.3.2.tar.gz", hash = "sha256:6b571215b5a790f9b41f19f3531c53a45cf6bb8ef2988bc1ff9afb38270b25fa"}, -] -pytest-cov = [ - {file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"}, - {file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"}, -] -python-multipart = [ - {file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"}, -] -regex = [ - {file = "regex-2020.1.8-cp27-cp27m-win32.whl", hash = "sha256:4e8f02d3d72ca94efc8396f8036c0d3bcc812aefc28ec70f35bb888c74a25161"}, - {file = "regex-2020.1.8-cp27-cp27m-win_amd64.whl", hash = "sha256:e6c02171d62ed6972ca8631f6f34fa3281d51db8b326ee397b9c83093a6b7242"}, - {file = "regex-2020.1.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4eae742636aec40cf7ab98171ab9400393360b97e8f9da67b1867a9ee0889b26"}, - {file = "regex-2020.1.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bd25bb7980917e4e70ccccd7e3b5740614f1c408a642c245019cff9d7d1b6149"}, - {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3e77409b678b21a056415da3a56abfd7c3ad03da71f3051bbcdb68cf44d3c34d"}, - {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:07b39bf943d3d2fe63d46281d8504f8df0ff3fe4c57e13d1656737950e53e525"}, - {file = "regex-2020.1.8-cp36-cp36m-win32.whl", hash = "sha256:23e2c2c0ff50f44877f64780b815b8fd2e003cda9ce817a7fd00dea5600c84a0"}, - {file = "regex-2020.1.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27429b8d74ba683484a06b260b7bb00f312e7c757792628ea251afdbf1434003"}, - {file = "regex-2020.1.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0e182d2f097ea8549a249040922fa2b92ae28be4be4895933e369a525ba36576"}, - {file = "regex-2020.1.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e3cd21cc2840ca67de0bbe4071f79f031c81418deb544ceda93ad75ca1ee9f7b"}, - {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ecc6de77df3ef68fee966bb8cb4e067e84d4d1f397d0ef6fce46913663540d77"}, - {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:26ff99c980f53b3191d8931b199b29d6787c059f2e029b2b0c694343b1708c35"}, - {file = "regex-2020.1.8-cp37-cp37m-win32.whl", hash = "sha256:7bcd322935377abcc79bfe5b63c44abd0b29387f267791d566bbb566edfdd146"}, - {file = "regex-2020.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:10671601ee06cf4dc1bc0b4805309040bb34c9af423c12c379c83d7895622bb5"}, - {file = "regex-2020.1.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:98b8ed7bb2155e2cbb8b76f627b2fd12cf4b22ab6e14873e8641f266e0fb6d8f"}, - {file = "regex-2020.1.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6a6ba91b94427cd49cd27764679024b14a96874e0dc638ae6bdd4b1a3ce97be1"}, - {file = "regex-2020.1.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:6a6ae17bf8f2d82d1e8858a47757ce389b880083c4ff2498dba17c56e6c103b9"}, - {file = "regex-2020.1.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0932941cdfb3afcbc26cc3bcf7c3f3d73d5a9b9c56955d432dbf8bbc147d4c5b"}, - {file = "regex-2020.1.8-cp38-cp38-win32.whl", hash = "sha256:d58e4606da2a41659c84baeb3cfa2e4c87a74cec89a1e7c56bee4b956f9d7461"}, - {file = "regex-2020.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:e7c7661f7276507bce416eaae22040fd91ca471b5b33c13f8ff21137ed6f248c"}, - {file = "regex-2020.1.8.tar.gz", hash = "sha256:d0f424328f9822b0323b3b6f2e4b9c90960b24743d220763c7f07071e0778351"}, -] -rfc3986 = [ - {file = "rfc3986-1.3.2-py2.py3-none-any.whl", hash = "sha256:df4eba676077cefb86450c8f60121b9ae04b94f65f85b69f3f731af0516b7b18"}, - {file = "rfc3986-1.3.2.tar.gz", hash = "sha256:0344d0bd428126ce554e7ca2b61787b6a28d2bbd19fc70ed2dd85efe31176405"}, -] -six = [ - {file = "six-1.13.0-py2.py3-none-any.whl", hash = "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd"}, - {file = "six-1.13.0.tar.gz", hash = "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"}, -] -sniffio = [ - {file = "sniffio-1.1.0-py3-none-any.whl", hash = "sha256:20ed6d5b46f8ae136d00b9dcb807615d83ed82ceea6b2058cecb696765246da5"}, - {file = "sniffio-1.1.0.tar.gz", hash = "sha256:8e3810100f69fe0edd463d02ad407112542a11ffdc29f67db2bf3771afb87a21"}, -] -starlette = [ - {file = "starlette-0.12.9.tar.gz", hash = "sha256:c2ac9a42e0e0328ad20fe444115ac5e3760c1ee2ac1ff8cdb5ec915c4a453411"}, -] -toml = [ - {file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"}, - {file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"}, - {file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"}, -] -typed-ast = [ - {file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e"}, - {file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b"}, - {file = "typed_ast-1.4.0-cp35-cp35m-win32.whl", hash = "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4"}, - {file = "typed_ast-1.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"}, - {file = "typed_ast-1.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631"}, - {file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233"}, - {file = "typed_ast-1.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1"}, - {file = "typed_ast-1.4.0-cp36-cp36m-win32.whl", hash = "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a"}, - {file = "typed_ast-1.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c"}, - {file = "typed_ast-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a"}, - {file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e"}, - {file = "typed_ast-1.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d"}, - {file = "typed_ast-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36"}, - {file = "typed_ast-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0"}, - {file = "typed_ast-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66"}, - {file = "typed_ast-1.4.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2"}, - {file = "typed_ast-1.4.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47"}, - {file = "typed_ast-1.4.0-cp38-cp38-win32.whl", hash = "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161"}, - {file = "typed_ast-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e"}, - {file = "typed_ast-1.4.0.tar.gz", hash = "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34"}, -] -typing-extensions = [ - {file = "typing_extensions-3.7.4.1-py2-none-any.whl", hash = "sha256:910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d"}, - {file = "typing_extensions-3.7.4.1-py3-none-any.whl", hash = "sha256:cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"}, - {file = "typing_extensions-3.7.4.1.tar.gz", hash = "sha256:091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2"}, -] -urllib3 = [ - {file = "urllib3-1.25.7-py2.py3-none-any.whl", hash = "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293"}, - {file = "urllib3-1.25.7.tar.gz", hash = "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"}, -] -uvicorn = [ - {file = "uvicorn-0.11.1-py3-none-any.whl", hash = "sha256:d07129d98440ef69e4fd3aaebf16ab9b96cbcdffd813b9889bf8ec001351f4b8"}, - {file = "uvicorn-0.11.1.tar.gz", hash = "sha256:68a13fedeb38260ce663a1d01d367e6809b09b2dedd2a973af5d73291e010e28"}, -] -uvloop = [ - {file = "uvloop-0.14.0-cp35-cp35m-macosx_10_11_x86_64.whl", hash = "sha256:08b109f0213af392150e2fe6f81d33261bb5ce968a288eb698aad4f46eb711bd"}, - {file = "uvloop-0.14.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4544dcf77d74f3a84f03dd6278174575c44c67d7165d4c42c71db3fdc3860726"}, - {file = "uvloop-0.14.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:b4f591aa4b3fa7f32fb51e2ee9fea1b495eb75b0b3c8d0ca52514ad675ae63f7"}, - {file = "uvloop-0.14.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:f07909cd9fc08c52d294b1570bba92186181ca01fe3dc9ffba68955273dd7362"}, - {file = "uvloop-0.14.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:afd5513c0ae414ec71d24f6f123614a80f3d27ca655a4fcf6cabe50994cc1891"}, - {file = "uvloop-0.14.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e7514d7a48c063226b7d06617cbb12a14278d4323a065a8d46a7962686ce2e95"}, - {file = "uvloop-0.14.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:bcac356d62edd330080aed082e78d4b580ff260a677508718f88016333e2c9c5"}, - {file = "uvloop-0.14.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4315d2ec3ca393dd5bc0b0089d23101276778c304d42faff5dc4579cb6caef09"}, - {file = "uvloop-0.14.0.tar.gz", hash = "sha256:123ac9c0c7dd71464f58f1b4ee0bbd81285d96cdda8bc3519281b8973e3a461e"}, -] -wcwidth = [ - {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"}, - {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"}, -] -websockets = [ - {file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"}, - {file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"}, - {file = "websockets-8.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8"}, - {file = "websockets-8.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb"}, - {file = "websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5"}, - {file = "websockets-8.1-cp36-cp36m-win32.whl", hash = "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a"}, - {file = "websockets-8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5"}, - {file = "websockets-8.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989"}, - {file = "websockets-8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d"}, - {file = "websockets-8.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779"}, - {file = "websockets-8.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8"}, - {file = "websockets-8.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422"}, - {file = "websockets-8.1-cp37-cp37m-win32.whl", hash = "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc"}, - {file = "websockets-8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308"}, - {file = "websockets-8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092"}, - {file = "websockets-8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485"}, - {file = "websockets-8.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1"}, - {file = "websockets-8.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55"}, - {file = "websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824"}, - {file = "websockets-8.1-cp38-cp38-win32.whl", hash = "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36"}, - {file = "websockets-8.1-cp38-cp38-win_amd64.whl", hash = "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"}, - {file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"}, -] -zipp = [ - {file = "zipp-0.6.0-py2.py3-none-any.whl", hash = "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"}, - {file = "zipp-0.6.0.tar.gz", hash = "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e"}, -] diff --git a/client_generator/poetry.lock.new.new b/client_generator/poetry.lock.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/pyproject.toml b/client_generator/pyproject.toml deleted file mode 100644 index dc90919..0000000 --- a/client_generator/pyproject.toml +++ /dev/null @@ -1,66 +0,0 @@ - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. -[tool.poetry] -name = "example" -version = "0.3.0" -description = "" -authors = ["David Montague"] - -[tool.poetry.dependencies] -python = "^3.7" -fastapi = "*" -pydantic = "*" -httpx = "*" -typing_extensions = "*" - -[tool.poetry.dev-dependencies] -starlette = "*" - -pytest = "*" -pytest-cov = "*" -coverage = "*" -black = { version = "*", allow-prereleases = true } -flake8 = "*" -isort = "*" -mypy = "*" - -python-multipart = "*" -uvicorn = "*" - -[tool.black] -line-length = 120 -target_version = ['py37'] -include = '\.pyi?$' -exclude = ''' -( - /( - \.git - | \.mypy_cache - | \.pytest_cache - | htmlcov - | build - | pybind11 - )/ -) -''' - -[tool.isort] -line_length = 120 -known_first_party = ["client"] -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -combine_as_imports = true diff --git a/client_generator/pyproject.toml.new.new b/client_generator/pyproject.toml.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/scripts/dev/install.sh b/client_generator/scripts/dev/install.sh deleted file mode 100644 index d03cda0..0000000 --- a/client_generator/scripts/dev/install.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. -set -e - -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" -cd "${PROJECT_ROOT}" - -install() { - poetry install - - echo "" - echo "Virtual environment interpreter installed at:" - poetry run python -c "import sys; print(sys.executable)" -} - -install diff --git a/client_generator/scripts/dev/regenerate-example.sh b/client_generator/scripts/dev/regenerate-example.sh deleted file mode 100644 index 8ac3efb..0000000 --- a/client_generator/scripts/dev/regenerate-example.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. -set -e - -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" -cd "${PROJECT_ROOT}" - -# Generate -rm -r generated >/dev/null 2>&1 || true -./scripts/generate.sh -p client -n example.client -o generated --include-auth -i https://petstore.swagger.io/v2/swagger.json - -# Replace example -rm -r example/client >/dev/null 2>&1 || true -cp -r generated/client example diff --git a/client_generator/scripts/dev/test.sh b/client_generator/scripts/dev/test.sh deleted file mode 100644 index 850a23a..0000000 --- a/client_generator/scripts/dev/test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" -cd "${DIR}" - -export PYTHONPATH="test_client" -pytest tests - diff --git a/client_generator/scripts/dev/testcov.sh b/client_generator/scripts/dev/testcov.sh deleted file mode 100644 index 6ca2fb8..0000000 --- a/client_generator/scripts/dev/testcov.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" -cd "${DIR}" - -export PYTHONPATH="test_client" - -pytest tests --cov=tests - -echo "building coverage html" -coverage html diff --git a/client_generator/scripts/generate.sh b/client_generator/scripts/generate.sh deleted file mode 100755 index 43e6058..0000000 --- a/client_generator/scripts/generate.sh +++ /dev/null @@ -1,224 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e - -# Prevent automatic path conversions by MSYS-based bash. -# It's revelant only for Windows -export MSYS_NO_PATHCONV=1 - -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" - -CMDNAME=${0##*/} - -INCLUDE_AUTH="" -OUTPUT_PATH="" -INPUT="" -PACKAGE_NAME="" -IMPORT_NAME="" -WORK_DIR="" -TEMP_DIR="" -WITH_META="" -MAP_LOCALHOST="" - -usage() { - exitcode="$1" - cat <&2 - -Usage: - $CMDNAME -i INPUT -p PACKAGE_NAME -o OUTPUT_PATH [-n IMPORT_NAME] [--include-auth] -- [*openapi-generator-cli args] - -Options: - -i, --input The location of the OpenAPI spec, as URL or file - -p, --package-name The name to use for the generated package - -n, --import-name The name to use for imports of the package (defaults to PACKAGE_NAME) - -o, --output-path The parent folder to use for the generated package - -t, --temp-dir The location for temporary files - -m, --map-localhost (OSX): Map localhost / 127.0.0.1 to host.docker.internal - --with-meta Generate meta-data (setup.py, docs, tests) - -h, --help Show this message -USAGE - exit "$exitcode" -} - -main() { - validate_inputs - - WORK_DIR=$(mktemp -d "$TEMP_DIR/tmp.XXXXXXXXX") - echo "Storing intermediate outputs in ${WORK_DIR}; it will be removed if generation is successful" - setup_openapi_generation "$WORK_DIR" - "${PROJECT_ROOT}/scripts/util/openapi-generate.sh" -p "$PACKAGE_NAME" -w "$WORK_DIR" -i "$INPUT" ${WITH_META:+ --with-meta} -- "$@" - - cd "${PROJECT_ROOT}" - - if [ -n "$INCLUDE_AUTH" ]; then - add_auth_files "$WORK_DIR" - fi - fill_import_name_templates "$WORK_DIR" - - ./scripts/util/postprocess.sh -p "${PACKAGE_NAME}" -w "$WORK_DIR" - clean_openapi_generator_output "$WORK_DIR" - move_generated_output "$WORK_DIR" - echo "Generation succeeded 🚀" -} - -validate_inputs() { - if [ -z "$PACKAGE_NAME" ]; then - echo "Error: you need to provide --package-name argument" - usage 2 - fi - if [ -z "$OUTPUT_PATH" ]; then - echo "Error: you need to provide --output-path argument" - usage 2 - fi - mkdir -p "$OUTPUT_PATH" - OUTPUT_PATH="$(cd "$OUTPUT_PATH" && pwd)" - if [ -d "${OUTPUT_PATH}/${PACKAGE_NAME}" ]; then - echo "A folder already exists at ${OUTPUT_PATH}/${PACKAGE_NAME}; it must be removed first" - usage 2 - fi - if [ -z "$INPUT" ]; then - echo "Error: you need to provide --input argument" - usage 2 - fi - - if [ -z "$TEMP_DIR" ]; then - TEMP_DIR="$PROJECT_ROOT" - fi - if [ -z "$IMPORT_NAME" ]; then - IMPORT_NAME="$PACKAGE_NAME" - fi - - if [ ! -z "$MAP_LOCALHOST" ] && [ "$(uname -s)" == "Darwin" ]; then - INPUT=$(echo "$INPUT" | sed -E 's%^(https?://)(localhost|127\.0\.0\.1)([:/])%\1host.docker.internal\3%') - fi -} - -setup_openapi_generation() { - WORK_DIR=$1 - cp "${PROJECT_ROOT}/other-templates/.openapi-generator-ignore" "$WORK_DIR" - - # Replace @PACKAGE_NAME@ in the ignore with the appropriate value - sed -i.bak "s/@PACKAGE_NAME@/${PACKAGE_NAME}/" "$WORK_DIR"/.openapi-generator-ignore - rm "$WORK_DIR"/.openapi-generator-ignore.bak -} - -add_auth_files() { - WORK_DIR=$1 - add_extra_python_template "$WORK_DIR" auth - add_extra_python_template "$WORK_DIR" password_flow_client -} - -fill_import_name_templates() { - WORK_DIR=$1 - PACKAGE_DIR="$WORK_DIR"/"$PACKAGE_NAME" - fill_import_name_template "$PACKAGE_DIR"/api_client.py - fill_import_name_template "$PACKAGE_DIR"/__init__.py - - pushd "${PACKAGE_DIR}/api" - find . -name "*.py" | while read -r filename; do - fill_import_name_template "$filename" - done - popd - -} - -clean_openapi_generator_output() { - WORK_DIR=$1 - rm -r "$WORK_DIR"/.openapi-generator - rm "$WORK_DIR"/.openapi-generator-ignore -} - -move_generated_output() { - WORK_DIR=$1 - mkdir -p "$OUTPUT_PATH" - if [ -n "$WITH_META" ]; then - # TODO: add valid generation for docs - rm -r "$WORK_DIR"/docs - # TODO: add valid generation for tests - rm -r "$WORK_DIR"/test - mv "$WORK_DIR" "$OUTPUT_PATH"/"$PACKAGE_NAME" - else - mv "$WORK_DIR"/"$PACKAGE_NAME" "$OUTPUT_PATH" - fi - rm -r "$WORK_DIR" -} - -add_extra_python_template() { - WORK_DIR=$1 - TEMPLATE_NAME=$2 - - PACKAGE_DIR="$WORK_DIR"/"$PACKAGE_NAME" - cp other-templates/"$TEMPLATE_NAME".template "$PACKAGE_DIR"/"$TEMPLATE_NAME".py - fill_import_name_template "$PACKAGE_DIR"/"$TEMPLATE_NAME".py -} - -fill_import_name_template() { - python_filename="$1" - sed -i.bak "s/@IMPORT_NAME@/${IMPORT_NAME}/" "$python_filename" - rm "$python_filename".bak -} - -while [ $# -gt 0 ]; do - case "$1" in - -p | --package-name) - PACKAGE_NAME=$2 - shift 2 - ;; - -o | --output-path) - OUTPUT_PATH=$2 - shift 2 - ;; - -i | --input) - INPUT=$2 - shift 2 - ;; - -n | --import-name) - IMPORT_NAME=$2 - shift 2 - ;; - -h | --help) - usage 0 - ;; - -t | --temp-dir) - TEMP_DIR=$2 - shift 2 - ;; - -m | --map-localhost) - MAP_LOCALHOST="yes" - shift 1 - ;; - --include-auth) - INCLUDE_AUTH="yes" - shift 1 - ;; - --with-meta) - WITH_META="yes" - shift 1 - ;; - --) - shift 1 - break - ;; - *) - echo "Unknown argument: $1" - usage 1 - ;; - esac -done - -main "$@" diff --git a/client_generator/scripts/util/fix_api_response_types.py b/client_generator/scripts/util/fix_api_response_types.py deleted file mode 100644 index c5f057e..0000000 --- a/client_generator/scripts/util/fix_api_response_types.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Fix missing type annotations in the auto-generated api_response.py file. - -OpenAPI Generator creates an ApiResponse class with an __init__ method that -lacks type annotations, which causes mypy errors with the no-untyped-def check. - -This script adds proper type annotations to the __init__ method. -""" - -import argparse -import re -import sys -from pathlib import Path - - -def fix_api_response_init(api_response_path: Path) -> bool: - """ - Fix the __init__ method in api_response.py to include type annotations. - - Returns True if a fix was applied, False otherwise. - """ - if not api_response_path.exists(): - print(f"Warning: {api_response_path} not found, skipping api_response fix") - return False - - with open(api_response_path, 'r') as f: - content = f.read() - - # Pattern to match the untyped __init__ method (flexible with whitespace) - # Matches: def __init__(self, status_code=None, headers=None, data=None, raw_data=None): - # with flexible whitespace handling - pattern = re.compile( - r'(\s+)def\s+__init__\s*\(\s*self\s*,\s*status_code\s*=\s*None\s*,\s*headers\s*=\s*None\s*,\s*data\s*=\s*None\s*,\s*raw_data\s*=\s*None\s*\)\s*:', - re.MULTILINE - ) - - # Check if the pattern exists - match = pattern.search(content) - if not match: - # Check if it's already typed (look for type annotations in __init__) - if re.search(r'def\s+__init__\s*\([^)]*:\s*Optional', content): - print("api_response.py __init__ method already has type annotations") - return False - else: - print("Warning: api_response.py __init__ method has unexpected format, skipping") - return False - - # Replace with properly typed version (preserve the original indentation) - replacement = r'\1def __init__(self, status_code: Optional[StrictInt] = None, headers: Optional[Dict[StrictStr, StrictStr]] = None, data: Optional[Any] = None, raw_data: Optional[Any] = None) -> None:' - - fixed_content = pattern.sub(replacement, content) - - # Write the fixed content back - with open(api_response_path, 'w') as f: - f.write(fixed_content) - - print("✓ Fixed api_response.py __init__ method with proper type annotations") - return True - - -def main(): - parser = argparse.ArgumentParser( - description='Fix missing type annotations in api_response.py' - ) - parser.add_argument( - '--api-response-file', - type=Path, - required=True, - help='Path to the generated api_response.py file' - ) - - args = parser.parse_args() - - fix_applied = fix_api_response_init(args.api_response_file) - - # Always return success - if the file is already fixed or has an unexpected - # format, we don't want to fail the entire generation process - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/client_generator/scripts/util/fix_optional_defaults.py b/client_generator/scripts/util/fix_optional_defaults.py deleted file mode 100644 index 0b2d896..0000000 --- a/client_generator/scripts/util/fix_optional_defaults.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025-2026 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Fix incorrect Optional type annotations with None defaults. - -OpenAPI Generator v7.0.0 incorrectly generates fields with default values as: - field_name: "Optional[type]" = Field(None, alias="field_name") - -When they should be: - field_name: type = Field(default_value, alias="field_name") - -This script fixes these issues by: -1. Reading the OpenAPI spec to get the correct default values -2. Parsing the generated models file -3. Replacing incorrect Optional[T] = Field(None, ...) patterns with correct type = Field(default, ...) -""" - -import argparse -import json -import re -import sys -from pathlib import Path -from typing import Any, Dict, Optional - - -def load_openapi_spec(spec_path: Path) -> Dict[str, Any]: - """Load and parse the OpenAPI specification file.""" - with open(spec_path, 'r') as f: - return json.load(f) - - -def get_schema_defaults(openapi_spec: Dict[str, Any]) -> Dict[str, Dict[str, Any]]: - """ - Extract default values for all schema properties. - - Returns a nested dict: {schema_name: {property_name: {type, default}}} - """ - schemas = openapi_spec.get('components', {}).get('schemas', {}) - defaults_map = {} - - for schema_name, schema_def in schemas.items(): - properties = schema_def.get('properties', {}) - schema_defaults = {} - - for prop_name, prop_def in properties.items(): - if 'default' in prop_def: - prop_type = prop_def.get('type') - default_value = prop_def['default'] - schema_defaults[prop_name] = { - 'type': prop_type, - 'default': default_value - } - - if schema_defaults: - defaults_map[schema_name] = schema_defaults - - return defaults_map - - -def python_value_repr(value: Any, type_hint: Optional[str] = None) -> str: - """Convert a JSON value to its Python representation.""" - if value is None: - return "None" - elif isinstance(value, bool): - return "True" if value else "False" - elif isinstance(value, str): - return f'"{value}"' - elif isinstance(value, (int, float)): - return str(value) - elif isinstance(value, dict): - return "{}" - elif isinstance(value, list): - return "[]" - else: - return repr(value) - - -def get_python_type(json_type: str) -> str: - """Map JSON schema types to Python type hints.""" - type_mapping = { - 'boolean': 'bool', - 'integer': 'int', - 'number': 'float', - 'string': 'str', - 'object': 'dict', - 'array': 'list' - } - return type_mapping.get(json_type, 'Any') - - -def fix_models_file(models_path: Path, defaults_map: Dict[str, Dict[str, Any]]) -> int: - """ - Fix incorrect Optional type annotations in the models file. - - Returns the number of fixes applied. - """ - with open(models_path, 'r') as f: - content = f.read() - - original_content = content - fixes_applied = 0 - - # Pattern to match class definitions - class_pattern = re.compile(r'^class\s+(\w+)\(', re.MULTILINE) - - # Pattern to match field definitions with Optional and None default - # Example: certification_mode: "Optional[bool]" = Field(None, alias="certification_mode") - field_pattern = re.compile( - r'(\s+)(\w+):\s*"Optional\[([^\]]+)\]"\s*=\s*Field\(None,\s*alias="(\w+)"\)', - re.MULTILINE - ) - - # Find all classes in the file - current_class = None - lines = content.split('\n') - fixed_lines = [] - - for line in lines: - class_match = class_pattern.match(line) - if class_match: - current_class = class_match.group(1) - fixed_lines.append(line) - continue - - # Check if this line has an Optional field with None default - field_match = field_pattern.match(line) - if field_match and current_class: - indent = field_match.group(1) - field_name = field_match.group(2) - inner_type = field_match.group(3) - alias_name = field_match.group(4) - - # Look up the default value in the schema - if current_class in defaults_map and field_name in defaults_map[current_class]: - schema_info = defaults_map[current_class][field_name] - default_value = schema_info['default'] - json_type = schema_info['type'] - - # Get the correct Python type - python_type = get_python_type(json_type) - - # Format the default value for Python - default_repr = python_value_repr(default_value, python_type) - - # Create the fixed line - fixed_line = f'{indent}{field_name}: "{python_type}" = Field({default_repr}, alias="{alias_name}")' - fixed_lines.append(fixed_line) - fixes_applied += 1 - print(f"Fixed {current_class}.{field_name}: Optional[{inner_type}] = None -> {python_type} = {default_repr}") - continue - - # No fix needed, keep the original line - fixed_lines.append(line) - - # Write the fixed content back to the file - if fixes_applied > 0: - fixed_content = '\n'.join(fixed_lines) - with open(models_path, 'w') as f: - f.write(fixed_content) - - return fixes_applied - - -def main(): - parser = argparse.ArgumentParser( - description='Fix incorrect Optional type annotations in generated models' - ) - parser.add_argument( - '--openapi-spec', - type=Path, - required=True, - help='Path to the OpenAPI specification file' - ) - parser.add_argument( - '--models-file', - type=Path, - required=True, - help='Path to the generated models.py file' - ) - - args = parser.parse_args() - - # Validate inputs - if not args.openapi_spec.exists(): - print(f"Error: OpenAPI spec file not found: {args.openapi_spec}", file=sys.stderr) - sys.exit(1) - - if not args.models_file.exists(): - print(f"Error: Models file not found: {args.models_file}", file=sys.stderr) - sys.exit(1) - - print(f"Loading OpenAPI spec from: {args.openapi_spec}") - openapi_spec = load_openapi_spec(args.openapi_spec) - - print("Extracting default values from schema...") - defaults_map = get_schema_defaults(openapi_spec) - print(f"Found {len(defaults_map)} schemas with default values") - - print(f"Fixing models file: {args.models_file}") - fixes_applied = fix_models_file(args.models_file, defaults_map) - - if fixes_applied > 0: - print(f"✓ Applied {fixes_applied} fixes to Optional/default value issues") - else: - print("No fixes needed") - - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/client_generator/scripts/util/openapi-generate.sh b/client_generator/scripts/util/openapi-generate.sh deleted file mode 100755 index f2d86e5..0000000 --- a/client_generator/scripts/util/openapi-generate.sh +++ /dev/null @@ -1,163 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" - -CMDNAME=${0##*/} - -PACKAGE_NAME="" -INPUT="" -WORK_DIR="" -SOURCE_CODE_ONLY="true" - -OPENAPI_IMAGE="openapitools/openapi-generator-cli:v7.0.0" - -# Detect host architecture and set Docker platform -detect_architecture() { - ARCH=$(uname -m) - case "$ARCH" in - x86_64) - DOCKER_PLATFORM="linux/amd64" - ;; - aarch64|arm64) - DOCKER_PLATFORM="linux/arm64" - ;; - *) - echo "Warning: Unsupported architecture $ARCH, defaulting to linux/amd64" - DOCKER_PLATFORM="linux/amd64" - ;; - esac - echo "Detected architecture: $ARCH, using Docker platform: $DOCKER_PLATFORM" -} - -# Detect architecture on script start -detect_architecture - -usage() { - exitcode="$1" - cat <&2 - -Use openapi-generator to generate an unprocessed version of the client - -Usage: - $CMDNAME -p PACKAGE_NAME -w WORK_DIR -- [*openapi-generator-cli args] - -Options: - -p, --package-name The name to use for the generated package - -w, --work-dir The working directory to use for generator output - -i, --input The location of the OpenAPI spec, as URL or file - -m, --with-meta Generate meta-data (setup.py, docs, tests) - -h, --help Show this message -USAGE - exit "$exitcode" -} - -main() { - validate_inputs - if [ -z "$IS_HTTP" ]; then - generate_in_docker_file "$@" - else - generate_in_docker_http "$@" - fi -} - -validate_inputs() { - if [ -z "$PACKAGE_NAME" ]; then - echo "Error: you need to provide --package-name argument" - usage 2 - fi - if [ -z "$INPUT" ]; then - echo "Error: you need to provide --input argument" - usage 2 - fi - if [ -z "$WORK_DIR" ]; then - echo "Error: you need to provide --work-dir argument" - usage 2 - fi - - IS_HTTP="$(echo "$INPUT" | grep '^https\{0,1\}://' || true)" -} - -generate_in_docker_http() { - docker run --platform $DOCKER_PLATFORM --user $(id -u):$(id -g) --rm -v "$WORK_DIR":/generator-output -v "$PROJECT_ROOT":/local $OPENAPI_IMAGE generate \ - -g python \ - -o /generator-output \ - --package-name="${PACKAGE_NAME}" \ - --additional-properties=generateSourceCodeOnly="${SOURCE_CODE_ONLY}" \ - -t /local/openapi-python-templates \ - --type-mappings array=List,uuid=UUID,file=IO,object=Any \ - -i "${INPUT}" \ - "$@" - - # Download the OpenAPI spec to the work directory for post-processing - echo "Downloading OpenAPI spec for post-processing..." - curl -sSL "${INPUT}" -o "$WORK_DIR/openapi-spec.json" -} - -generate_in_docker_file() { - INPUT_FILE="$(cd "$(dirname "$INPUT")" && pwd )"/"$(basename "$INPUT")" - - docker run --platform $DOCKER_PLATFORM --user $(id -u):$(id -g) --rm -v "$WORK_DIR":/generator-output -v "$PROJECT_ROOT":/local -v "${INPUT_FILE}":/openapi.json \ - $OPENAPI_IMAGE generate \ - -g python \ - -o /generator-output \ - --package-name="${PACKAGE_NAME}" \ - --additional-properties=generateSourceCodeOnly="${SOURCE_CODE_ONLY}" \ - -t /local/openapi-python-templates \ - --type-mappings array=List,uuid=UUID,file=IO,object=Any \ - -i /openapi.json \ - "$@" - - # Copy the OpenAPI spec to the work directory for post-processing - echo "Copying OpenAPI spec for post-processing..." - cp "${INPUT_FILE}" "$WORK_DIR/openapi-spec.json" -} - -while [ $# -gt 0 ]; do - case "$1" in - -p | --package-name) - PACKAGE_NAME=$2 - shift 2 - ;; - -i | --input) - INPUT=$2 - shift 2 - ;; - -w | --work-dir) - WORK_DIR=$2 - shift 2 - ;; - -m | --with-meta) - SOURCE_CODE_ONLY="false" - shift 1 - ;; - -h | --help) - usage 0 - ;; - --) - shift 1 - break - ;; - *) - echo "Unknown argument: $1" - usage 1 - ;; - esac -done - -main "$@" diff --git a/client_generator/scripts/util/postprocess-docker.sh b/client_generator/scripts/util/postprocess-docker.sh deleted file mode 100755 index 5bc5f25..0000000 --- a/client_generator/scripts/util/postprocess-docker.sh +++ /dev/null @@ -1,134 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e -cd /generator-output - -CMDNAME=${0##*/} - -usage() { - exitcode="$1" - cat <&2 - -Postprocess the output of openapi-generator - -Usage: - $CMDNAME -p PACKAGE_NAME - -Options: - -p, --package-name The name to use for the generated package - -h, --help Show this message -USAGE - exit "$exitcode" -} - -main() { - validate_inputs - merge_generated_models - delete_unused - fix_any_of - fix_optional_defaults - fix_api_response_types - apply_formatters -} - -validate_inputs() { - if [ -z "$PACKAGE_NAME" ]; then - echo "Error: you need to provide --package-name argument" - usage 2 - fi -} - -merge_generated_models() { - # Need to merge the generated models into a single file to prevent circular imports - # shellcheck disable=SC2046 - # shellcheck disable=SC2010 - cat $(ls "${PACKAGE_NAME}"/models/*.py | grep -v __init__) >"${PACKAGE_NAME}"/models.py - rm -r "${PACKAGE_NAME}"/models >/dev/null 2>&1 || true -} - -delete_unused() { - # Delete empty folder - rm -r "${PACKAGE_NAME}"/test >/dev/null 2>&1 || true - - rm "${PACKAGE_NAME}"/rest.py >/dev/null 2>&1 || true - rm "${PACKAGE_NAME}"/configuration.py >/dev/null 2>&1 || true -} - -fix_any_of() { - find . -name "*.py" -exec sed -i.bak "s/AnyOf[a-zA-Z0-9]*/Any/" {} \; - find . -name "*.md" -exec sed -i.bak "s/AnyOf[a-zA-Z0-9]*/Any/" {} \; - find . -name "*.bak" -exec rm {} \; -} - -fix_optional_defaults() { - echo "Fixing Optional/default value issues..." - # The OpenAPI spec is copied to /generator-output/openapi-spec.json by openapi-generate.sh - # The fix script is at /fix_optional_defaults.py (added by Dockerfile) - # The models file is at models.py created by merge_generated_models() - if [ -f "/generator-output/openapi-spec.json" ] && [ -f "/fix_optional_defaults.py" ]; then - python3 /fix_optional_defaults.py \ - --openapi-spec /generator-output/openapi-spec.json \ - --models-file "${PACKAGE_NAME}/models.py" - # Clean up the spec file after processing - rm /generator-output/openapi-spec.json - else - echo "Warning: Could not find OpenAPI spec or fix script, skipping Optional/default fixes" - echo " - OpenAPI spec exists: $([ -f /generator-output/openapi-spec.json ] && echo 'yes' || echo 'no')" - echo " - Fix script exists: $([ -f /fix_optional_defaults.py ] && echo 'yes' || echo 'no')" - fi -} - -fix_api_response_types() { - echo "Fixing api_response.py type annotations..." - # The fix script is at /fix_api_response_types.py (added by Dockerfile) - # The api_response.py file is generated by openapi-generator - if [ -f "/fix_api_response_types.py" ] && [ -f "${PACKAGE_NAME}/api_response.py" ]; then - python3 /fix_api_response_types.py \ - --api-response-file "${PACKAGE_NAME}/api_response.py" - else - echo "Warning: Could not find fix script or api_response.py, skipping api_response type fixes" - echo " - Fix script exists: $([ -f /fix_api_response_types.py ] && echo 'yes' || echo 'no')" - echo " - api_response.py exists: $([ -f ${PACKAGE_NAME}/api_response.py ] && echo 'yes' || echo 'no')" - fi -} - -apply_formatters() { - echo "Applying code formatters to $PACKAGE_NAME..." - autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place "${PACKAGE_NAME}" --exclude=__init__.py - isort --float-to-top -w 120 -m 3 --trailing-comma --force-grid-wrap 0 --combine-as -p "${PACKAGE_NAME}" "${PACKAGE_NAME}" - black --fast -l 120 --target-version py310 "${PACKAGE_NAME}" - echo "All formatters applied." -} - -while [ $# -gt 0 ]; do - case "$1" in - -p | --package-name) - PACKAGE_NAME=$2 - shift 2 - ;; - -h | --help) - usage 0 - ;; - *) - echo "Unknown argument: $1" - usage 1 - ;; - esac -done - -main diff --git a/client_generator/scripts/util/postprocess.sh b/client_generator/scripts/util/postprocess.sh deleted file mode 100755 index 02fbc88..0000000 --- a/client_generator/scripts/util/postprocess.sh +++ /dev/null @@ -1,108 +0,0 @@ -#! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - -set -e -PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)" -cd "${PROJECT_ROOT}" - -CMDNAME=${0##*/} - -PACKAGE_NAME="" -WORK_DIR="" - -# Detect host architecture and set Docker platform -detect_architecture() { - ARCH=$(uname -m) - case "$ARCH" in - x86_64) - DOCKER_PLATFORM="linux/amd64" - ;; - aarch64|arm64) - DOCKER_PLATFORM="linux/arm64" - ;; - *) - echo "Warning: Unsupported architecture $ARCH, defaulting to linux/amd64" - DOCKER_PLATFORM="linux/amd64" - ;; - esac - echo "Detected architecture: $ARCH, using Docker platform: $DOCKER_PLATFORM" -} - -# Detect architecture on script start -detect_architecture - -usage() { - exitcode="$1" - cat <&2 - -Use docker to postprocess the output of openapi-generator - -Usage: - $CMDNAME -p PACKAGE_NAME - -Options: - -p, --package-name The name to use for the generated package - -w, --work-dir The working directory used for generator output - -h, --help Show this message -USAGE - exit "$exitcode" -} - -main() { - validate_inputs - docker build --platform $DOCKER_PLATFORM -t fastapi-client-generator:latest . - docker run --platform $DOCKER_PLATFORM --rm --user $(id -u):$(id -g) -v "$WORK_DIR":/generator-output fastapi-client-generator:latest -p "${PACKAGE_NAME}" - add_py_typed -} - -add_py_typed() { - touch "$WORK_DIR"/"${PACKAGE_NAME}"/py.typed - echo "include ${PACKAGE_NAME}/py.typed" > "$WORK_DIR"/MANIFEST.in -} - -validate_inputs() { - if [ -z "$PACKAGE_NAME" ]; then - echo "Error: you need to provide --package-name argument" - usage 2 - fi - if [ -z "$WORK_DIR" ]; then - echo "Error: you need to provide --work-dir argument" - usage 2 - fi -} - -while [ $# -gt 0 ]; do - case "$1" in - -p | --package-name) - PACKAGE_NAME=$2 - shift 2 - ;; - -w | --work-dir) - WORK_DIR=$2 - shift 2 - ;; - -h | --help) - usage 0 - ;; - *) - echo "Unknown argument: $1" - usage 1 - ;; - esac -done - -main diff --git a/client_generator/setup.cfg b/client_generator/setup.cfg deleted file mode 100644 index 7e21884..0000000 --- a/client_generator/setup.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[tool:pytest] -testpaths = tests -timeout = 10 -filterwarnings = error - -[coverage:run] -source = tests -branch = True - -[coverage:report] -precision = 2 -omit = - tests/server_app/__main__.py -exclude_lines = - pragma: no cover - raise NotImplementedError - raise NotImplemented - if TYPE_CHECKING: - @overload - -[flake8] -max-line-length = 120 -ignore = E203,W503 -recursive = True -;exclude = pybind11 diff --git a/client_generator/setup.cfg.new b/client_generator/setup.cfg.new deleted file mode 100644 index 7e21884..0000000 --- a/client_generator/setup.cfg.new +++ /dev/null @@ -1,25 +0,0 @@ -[tool:pytest] -testpaths = tests -timeout = 10 -filterwarnings = error - -[coverage:run] -source = tests -branch = True - -[coverage:report] -precision = 2 -omit = - tests/server_app/__main__.py -exclude_lines = - pragma: no cover - raise NotImplementedError - raise NotImplemented - if TYPE_CHECKING: - @overload - -[flake8] -max-line-length = 120 -ignore = E203,W503 -recursive = True -;exclude = pybind11 diff --git a/client_generator/tests/__init__.py b/client_generator/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/conftest.py b/client_generator/tests/conftest.py deleted file mode 100644 index f5163e9..0000000 --- a/client_generator/tests/conftest.py +++ /dev/null @@ -1,138 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -*- coding: utf-8 -*- -""" -Setup file for pytest. -Sets up paths, start and stops the test server & builds the client module -""" - -import os -import shutil -import signal -import subprocess -import sys -import time -from multiprocessing import Process - -import pytest -from fastapi import FastAPI - -from .server_app import app - -ROOT = os.path.realpath(os.path.dirname(os.path.realpath(__file__))) -sys.path.append(ROOT) - - -LOG_DIR = os.path.join(ROOT, "logs") -os.makedirs(LOG_DIR, exist_ok=True) - -CLIENT_NAME = "generated_client" -CLIENT_DIR = os.path.join(ROOT, CLIENT_NAME) - - -def run_server(app: FastAPI, host: str, port: int, log_level: str, log_dir: str) -> None: - import uvicorn - - with open(os.path.join(log_dir, "server.log"), "w") as stdout: - sys.stdout = stdout - sys.stderr = stdout - uvicorn.run(app, host=host, port=port, log_level=log_level) - - -PROC = Process( - target=run_server, # run_server, - args=(app,), - kwargs={"host": "localhost", "port": 8000, "log_level": "info", "log_dir": LOG_DIR}, - daemon=True, -) - - -def create_generated_client() -> None: - """ - Invoke scripts/generate.sh to rebuild the test client from the running server app - """ - print("Generating client") - - delete_generated_client() - args = [ - "{}/../scripts/generate.sh".format(ROOT), - "-i", - "http://localhost:8000/openapi.json", - "-p", - CLIENT_NAME, - "--include-auth", - "-o", - ROOT, - "-t", - "/tmp", - "-m", - ] - - process_result = subprocess.run(args, capture_output=True) - - with open(os.path.join(LOG_DIR, "generation.log"), "wb") as file: - file.write(process_result.stdout) - - with open(os.path.join(LOG_DIR, "generation.err"), "wb") as file: - file.write(process_result.stderr) - - if process_result.returncode != 0: # pragma: no cover - if process_result.stderr: - sys.stderr.write(process_result.stderr.decode("utf-8")) - pytest.exit( - "Failed to generate client api, code {}" - "\nLogs are in logs/generation.log and logs/generation.err".format(process_result.returncode), - returncode=process_result.returncode, - ) - - print("Client created in {}, logs in logs/generation.log\n".format(CLIENT_DIR)) - - -def delete_generated_client() -> None: - """ - Delete the generated client - """ - shutil.rmtree(CLIENT_DIR, ignore_errors=True) - - -def pytest_configure() -> None: # pragma: no cover - """ - Called before the test run. - Start the server process, generate the test client - """ - print("Starting server app") - PROC.start() - time.sleep(1) - if PROC.exitcode is not None: - pytest.exit("Failed to start the server, exit code {}\nLogs are in logs/server.log".format(PROC.exitcode)) - return - - create_generated_client() - - -def pytest_unconfigure() -> None: # pragma: no cover - """ - Called after the test run - Kill the server (forcibly if it doesn't stop with 5 seconds of being asked nicely) - """ - if PROC.exitcode is None: - assert PROC.pid is not None # not sure if this can happen (mypy error); if it does, be explicit - os.kill(PROC.pid, signal.SIGINT) - PROC.join(5) - if PROC.exitcode is None: - PROC.kill() - PROC.join() - print("\nServer app terminated, logs in logs/server.log") diff --git a/client_generator/tests/conftest.py.new.new b/client_generator/tests/conftest.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/__init__.py b/client_generator/tests/server_app/__init__.py deleted file mode 100644 index 4da92d9..0000000 --- a/client_generator/tests/server_app/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -*- coding: utf-8 -*- -""" -Export the main app -""" -from .app import app # noqa F401 diff --git a/client_generator/tests/server_app/__init__.py.new.new b/client_generator/tests/server_app/__init__.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/__main__.py b/client_generator/tests/server_app/__main__.py deleted file mode 100644 index f4b541c..0000000 --- a/client_generator/tests/server_app/__main__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -*- coding: utf-8 -*- -""" -Allows the module to be run with python -m server_app -""" -if __name__ == "__main__": - import uvicorn - - from .app import app - - uvicorn.run(app=app, host="localhost", port=8000, log_level="info") diff --git a/client_generator/tests/server_app/__main__.py.new.new b/client_generator/tests/server_app/__main__.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/app.py b/client_generator/tests/server_app/app.py deleted file mode 100644 index 65a2dbd..0000000 --- a/client_generator/tests/server_app/app.py +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Test harness app implementing the server endpoints required for -fastapi_client testing. -""" -import uvicorn -from fastapi import FastAPI -from fastapi.routing import APIRoute - -from .routers import auth_router, client_router - -app = FastAPI(debug=True) - - -@app.on_event("startup") -async def startup() -> None: - """ - Use the operation names as operation_id. The generated names are not friendly. - """ - for route in app.routes: - if isinstance(route, APIRoute): - route.operation_id = route.name - - -app.include_router(auth_router(), tags=["auth"]) -app.include_router(client_router(), tags=["client"]) - - -def main() -> None: - """ Kick off uvicorn on port 8000""" - uvicorn.run(app, host="0.0.0.0", port=8000) - - -if __name__ == "__main__": - main() diff --git a/client_generator/tests/server_app/app.py.new.new b/client_generator/tests/server_app/app.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/models.py b/client_generator/tests/server_app/models.py deleted file mode 100644 index a186c9d..0000000 --- a/client_generator/tests/server_app/models.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -*- coding: utf-8 -*- -""" -Pydantic data models for the server. -""" - -from typing import List, Optional - -from pydantic import BaseModel - - -class FormPostResponse(BaseModel): - """Response from the form testing""" - - length: int = 0 - hash: Optional[str] = None - token: Optional[str] = None - content_type: Optional[str] = None - - -class ListTagsResponse(BaseModel): - """Response from lists in query test""" - - tags: List[str] diff --git a/client_generator/tests/server_app/models.py.new.new b/client_generator/tests/server_app/models.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/routers/__init__.py b/client_generator/tests/server_app/routers/__init__.py deleted file mode 100644 index 0f43816..0000000 --- a/client_generator/tests/server_app/routers/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Import all routers -""" -from .auth import auth_router # noqa F401 -from .client import client_router # noqa F401 diff --git a/client_generator/tests/server_app/routers/__init__.py.new.new b/client_generator/tests/server_app/routers/__init__.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/routers/auth.py b/client_generator/tests/server_app/routers/auth.py deleted file mode 100644 index 81af9bb..0000000 --- a/client_generator/tests/server_app/routers/auth.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Test oauth apis -""" -from typing import Optional - -from fastapi import APIRouter, Depends, HTTPException -from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm -from pydantic import BaseModel -from starlette.responses import JSONResponse -from starlette.status import HTTP_401_UNAUTHORIZED - - -class TokenSuccessResponse(BaseModel): - """ - Copied from the test client. Required as we delete the test client & re-create it - from this code before the test run. - """ - - access_token: str - token_type: str - expires_in: Optional[int] - refresh_token: Optional[str] - scope: Optional[str] - - -def auth_router() -> APIRouter: - """ - Creates & returns the router for auth testing endpoints - """ - router = APIRouter() - reusable_oauth2 = OAuth2PasswordBearer(tokenUrl="/token") - - @router.get("/") - def access(token: str = Depends(reusable_oauth2)) -> JSONResponse: - if token != "access_token": - raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="Not authorized") - - return JSONResponse(content={"result": "success"}) - - @router.post("/token") - def get_tokens(form_data: OAuth2PasswordRequestForm = Depends()) -> TokenSuccessResponse: - if form_data.username == "username" and form_data.password == "password": - return TokenSuccessResponse(access_token="access_token", token_type="bearer") - raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="Not authorized") - - return router diff --git a/client_generator/tests/server_app/routers/auth.py.new.new b/client_generator/tests/server_app/routers/auth.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/server_app/routers/client.py b/client_generator/tests/server_app/routers/client.py deleted file mode 100644 index 6ef7941..0000000 --- a/client_generator/tests/server_app/routers/client.py +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Regression tests for fastapi_client -""" -import hashlib -from typing import Dict, List, Optional - -from fastapi import APIRouter, File, Form, Query -from starlette.requests import Request - -from ..models import FormPostResponse, ListTagsResponse - - -def client_router() -> APIRouter: - """ - Returns the router for regression test endpoints - """ - router = APIRouter() - - @router.get("/any") - async def no_schema() -> Dict[str, str]: - """ - Testing endpoints with no response_model. The client should return the dict - unmodified - """ - return {"hello": "world"} - - @router.post("/file_upload", response_model=FormPostResponse) - async def file_upload( - request: Request, file: bytes = File(...), token: Optional[str] = Form(...) - ) -> FormPostResponse: - """ - Testing file uploads using multipart/form. Responds with the size and hash of the file, - the token and the content-type of the incoming request - """ - hash_text: Optional[str] - if file: - hash_text = hashlib.sha256(file).hexdigest() - length = len(file) - else: - hash_text = None - length = 0 - content_type = request.headers.get("content-type", None) - return FormPostResponse(length=length, hash=hash_text, token=token, content_type=content_type) - - @router.post("/form_upload", response_model=FormPostResponse) - async def form_upload(request: Request, token: Optional[str] = Form(...)) -> FormPostResponse: - """ - Testing forms using application/x-www-form-urlencoded - returns the token & the request's content-type - """ - content_type = request.headers.get("content-type", None) - return FormPostResponse(token=token, content_type=content_type) - - @router.get("/tags_list", response_model=ListTagsResponse) - async def tags_list(tags: List[str] = Query(None)) -> ListTagsResponse: - """ - Check client with list of items in the query. Client should send ?tags=1&tags=2&tags=3 - Responds with the sent tags list - """ - return ListTagsResponse(tags=tags) - - return router diff --git a/client_generator/tests/server_app/routers/client.py.new.new b/client_generator/tests/server_app/routers/client.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/test_auth.py b/client_generator/tests/test_auth.py deleted file mode 100644 index 16d41db..0000000 --- a/client_generator/tests/test_auth.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from typing import Dict - -from fastapi.openapi.models import OAuthFlowPassword -from generated_client.api_client import ApiClient -from generated_client.auth import AuthMiddleware, AuthState - - -class AutoAuthClient(ApiClient): - """ - Subclasses ApiClient to add some extra functionality - """ - - def __init__(self, host: str = "http://localhost", tokenUrl: str = "http://localhost/token"): - super().__init__(host) - self.auth_state = AuthState() - flow = OAuthFlowPassword(tokenUrl=tokenUrl) - auth_middleware = AuthMiddleware(auth_state=self.auth_state, flow=flow) - self.add_middleware(auth_middleware) - - def set_creds(self, username: str, password: str) -> None: - self.auth_state.username = username - self.auth_state.password = password - - -def test_auth() -> None: - client = AutoAuthClient(host="http://localhost:8000", tokenUrl="http://localhost:8000/token") - client.set_creds("username", "password") - result = client.request_sync(type_=Dict, method="GET", url="/") - assert result == {"result": "success"} - assert client.auth_state.access_token == "access_token" diff --git a/client_generator/tests/test_auth.py.new.new b/client_generator/tests/test_auth.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/client_generator/tests/test_client.py b/client_generator/tests/test_client.py deleted file mode 100644 index 2a001ce..0000000 --- a/client_generator/tests/test_client.py +++ /dev/null @@ -1,108 +0,0 @@ -# -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -*- coding: utf-8 -*- -""" -Regression tests -""" -import hashlib -from asyncio import get_event_loop -from typing import Tuple, Type - -import generated_client.models as models -from generated_client.api_client import ApiClient, SyncApis -from mypy.ipc import TracebackType - - -class Client(SyncApis): - """ - Context manager for apis - closes the client on exit. - """ - - def __init__(self) -> None: - super().__init__(ApiClient(host="http://localhost:8000", timeout=3600)) - - def __enter__(self) -> "Client": - return self - - def __exit__(self, exc_type: Type[Exception], exc_val: Exception, exc_tb: TracebackType) -> None: - get_event_loop().run_until_complete(self.client._async_client.close()) - - -def test_any() -> None: - """ - Test apis with no response schema. Should succeed and leave the returned data alone - """ - with Client() as client: - result = client.client_api.no_schema() - assert isinstance(result, dict) - assert result["hello"] == "world" - - -def _get_file_info() -> Tuple[int, str]: - """ Return length and hash string from a file """ - with open(__file__, "rb") as file: - data = file.read() - length = len(data) - hash_text = hashlib.sha256(data).hexdigest() - - return length, hash_text - - -def test_file_post() -> None: - """ - Test files posted as multipart/form. - TODO: Optional[bytes] = File(...) doesn't yet work, test when it does. - """ - length, hash_text = _get_file_info() - - with Client() as client: - with open(__file__, "rb") as file: - ret = client.client_api.file_upload(file=file) - assert isinstance(ret, models.FormPostResponse) - assert ret.length == length - assert ret.hash == hash_text - assert ret.token is None - assert ret.content_type.startswith("multipart/form-data") - - with open(__file__, "rb") as file: - ret = client.client_api.file_upload(file=file, token="asdf") - assert ret.length == length - assert ret.hash == hash_text - assert ret.token == "asdf" - assert ret.content_type.startswith("multipart/form-data") - - -def test_form_post() -> None: - """ - Test ordinary forms with no files are sent as application/x-www-form-urlencoded - """ - with Client() as client: - ret = client.client_api.form_upload(token="asdf") - assert isinstance(ret, models.FormPostResponse) - assert ret.length == 0 - assert ret.hash is None - assert ret.token == "asdf" - assert ret.content_type.startswith("application/x-www-form-urlencoded") - - -def test_list_query() -> None: - """ - Check lists in queries are properly expanded in the constructed URL.. - """ - tags = ["2", "1", "3"] - with Client() as client: - ret = client.client_api.tags_list(tags=tags) - assert ret.tags == tags diff --git a/client_generator/tests/test_client.py.new.new b/client_generator/tests/test_client.py.new.new deleted file mode 100644 index e69de29..0000000 diff --git a/poetry.lock b/poetry.lock index ac61722..74fa12a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.3.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. [[package]] name = "aioconsole" @@ -27,13 +27,25 @@ files = [ {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"}, ] +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + [[package]] name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, @@ -49,6 +61,21 @@ doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd- test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4) ; python_version < \"3.8\"", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17) ; python_version < \"3.12\" and platform_python_implementation == \"CPython\" and platform_system != \"Windows\""] trio = ["trio (<0.22)"] +[[package]] +name = "argcomplete" +version = "3.6.3" +description = "Bash tab completion for argparse" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce"}, + {file = "argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c"}, +] + +[package.extras] +test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] + [[package]] name = "attrs" version = "21.4.0" @@ -261,14 +288,14 @@ files = [ [[package]] name = "click" -version = "8.2.1" +version = "8.3.1" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" groups = ["main", "dev"] files = [ - {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, - {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, + {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, + {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, ] [package.dependencies] @@ -418,6 +445,40 @@ json-validation = ["jsonschema[format] (>=4.18,<5.0)"] validation = ["jsonschema[format] (>=4.18,<5.0)", "lxml (>=4,<6)"] xml-validation = ["lxml (>=4,<6)"] +[[package]] +name = "datamodel-code-generator" +version = "0.53.0" +description = "Datamodel Code Generator" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "datamodel_code_generator-0.53.0-py3-none-any.whl", hash = "sha256:d1cc2abe79f99b8208c363f5f4b603c29290327ff4e3219a08c0fff45f42aff4"}, + {file = "datamodel_code_generator-0.53.0.tar.gz", hash = "sha256:af46b57ad78e6435873132c52843ef0ec7b768a591d3b9917d3409dfc1ab1c90"}, +] + +[package.dependencies] +argcomplete = ">=2.10.1,<4" +black = ">=19.10b0" +genson = ">=1.2.1,<2" +httpx = {version = ">=0.24.1", optional = true, markers = "extra == \"http\""} +inflect = ">=4.1,<8" +isort = ">=4.3.21,<8" +jinja2 = ">=2.10.1,<4" +packaging = "*" +pydantic = ">=1.5" +pyyaml = ">=6.0.1" +tomli = {version = ">=2.2.1,<3", markers = "python_version <= \"3.11\""} + +[package.extras] +all = ["graphql-core (>=3.2.3)", "httpx (>=0.24.1)", "openapi-spec-validator (>=0.2.8,<0.8)", "prance (>=0.18.2)", "pysnooper (>=0.4.1,<2)", "ruff (>=0.9.10)", "watchfiles (>=1.1)"] +debug = ["pysnooper (>=0.4.1,<2)"] +graphql = ["graphql-core (>=3.2.3)"] +http = ["httpx (>=0.24.1)"] +ruff = ["ruff (>=0.9.10)"] +validation = ["openapi-spec-validator (>=0.2.8,<0.8)", "prance (>=0.18.2)"] +watch = ["watchfiles (>=1.1)"] + [[package]] name = "defusedxml" version = "0.7.1" @@ -582,16 +643,28 @@ files = [ {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, ] +[[package]] +name = "genson" +version = "1.3.0" +description = "GenSON is a powerful, user-friendly JSON Schema generator." +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, +] + [[package]] name = "h11" -version = "0.12.0" +version = "0.16.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false -python-versions = ">=3.6" -groups = ["main"] +python-versions = ">=3.8" +groups = ["main", "dev"] files = [ - {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"}, - {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, ] [[package]] @@ -618,45 +691,50 @@ lxml = ["lxml ; platform_python_implementation == \"CPython\""] [[package]] name = "httpcore" -version = "0.13.7" +version = "1.0.9" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.6" -groups = ["main"] +python-versions = ">=3.8" +groups = ["main", "dev"] files = [ - {file = "httpcore-0.13.7-py3-none-any.whl", hash = "sha256:369aa481b014cf046f7067fddd67d00560f2f00426e79569d99cb11245134af0"}, - {file = "httpcore-0.13.7.tar.gz", hash = "sha256:036f960468759e633574d7c121afba48af6419615d36ab8ede979f1ad6276fa3"}, + {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, + {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, ] [package.dependencies] -anyio = "==3.*" -h11 = ">=0.11,<0.13" -sniffio = "==1.*" +certifi = "*" +h11 = ">=0.16" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.18.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false -python-versions = ">=3.6" -groups = ["main"] +python-versions = ">=3.8" +groups = ["main", "dev"] files = [ - {file = "httpx-0.18.2-py3-none-any.whl", hash = "sha256:979afafecb7d22a1d10340bafb403cf2cb75aff214426ff206521fc79d26408c"}, - {file = "httpx-0.18.2.tar.gz", hash = "sha256:9f99c15d33642d38bce8405df088c1c4cfd940284b4290cacbfb02e64f4877c6"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.13.3,<0.14.0" -rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} -sniffio = "*" +httpcore = "==1.*" +idna = "*" [package.extras] -brotli = ["brotlicffi (==1.*)"] -http2 = ["h2 (==3.*)"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "idna" @@ -673,6 +751,30 @@ files = [ [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +[[package]] +name = "inflect" +version = "7.5.0" +description = "Correctly generate plurals, singular nouns, ordinals, indefinite articles" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "inflect-7.5.0-py3-none-any.whl", hash = "sha256:2aea70e5e70c35d8350b8097396ec155ffd68def678c7ff97f51aa69c1d92344"}, + {file = "inflect-7.5.0.tar.gz", hash = "sha256:faf19801c3742ed5a05a8ce388e0d8fe1a07f8d095c82201eb904f5d27ad571f"}, +] + +[package.dependencies] +more_itertools = ">=8.5.0" +typeguard = ">=4.0.1" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["pygments", "pytest (>=6,!=8.1.*)"] +type = ["pytest-mypy"] + [[package]] name = "iniconfig" version = "2.3.0" @@ -700,6 +802,24 @@ files = [ [package.extras] colors = ["colorama (>=0.4.6)"] +[[package]] +name = "jinja2" +version = "3.1.6" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "license-expression" version = "30.4.4" @@ -761,6 +881,105 @@ profiling = ["gprof2dot"] rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] +[[package]] +name = "markupsafe" +version = "3.0.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, + {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, + {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, + {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, + {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, + {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, + {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, + {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, + {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -785,6 +1004,18 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "more-itertools" +version = "10.8.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b"}, + {file = "more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd"}, +] + [[package]] name = "msgpack" version = "1.1.1" @@ -1127,70 +1358,159 @@ files = [ [[package]] name = "pydantic" -version = "1.10.22" -description = "Data validation and settings management using python type hints" +version = "2.12.5" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" -groups = ["main"] +python-versions = ">=3.9" +groups = ["main", "dev"] files = [ - {file = "pydantic-1.10.22-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:57889565ccc1e5b7b73343329bbe6198ebc472e3ee874af2fa1865cfe7048228"}, - {file = "pydantic-1.10.22-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90729e22426de79bc6a3526b4c45ec4400caf0d4f10d7181ba7f12c01bb3897d"}, - {file = "pydantic-1.10.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8684d347f351554ec94fdcb507983d3116dc4577fb8799fed63c65869a2d10"}, - {file = "pydantic-1.10.22-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8dad498ceff2d9ef1d2e2bc6608f5b59b8e1ba2031759b22dfb8c16608e1802"}, - {file = "pydantic-1.10.22-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fac529cc654d4575cf8de191cce354b12ba705f528a0a5c654de6d01f76cd818"}, - {file = "pydantic-1.10.22-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4148232aded8dd1dd13cf910a01b32a763c34bd79a0ab4d1ee66164fcb0b7b9d"}, - {file = "pydantic-1.10.22-cp310-cp310-win_amd64.whl", hash = "sha256:ece68105d9e436db45d8650dc375c760cc85a6793ae019c08769052902dca7db"}, - {file = "pydantic-1.10.22-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e530a8da353f791ad89e701c35787418605d35085f4bdda51b416946070e938"}, - {file = "pydantic-1.10.22-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:654322b85642e9439d7de4c83cb4084ddd513df7ff8706005dada43b34544946"}, - {file = "pydantic-1.10.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8bece75bd1b9fc1c32b57a32831517943b1159ba18b4ba32c0d431d76a120ae"}, - {file = "pydantic-1.10.22-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eccb58767f13c6963dcf96d02cb8723ebb98b16692030803ac075d2439c07b0f"}, - {file = "pydantic-1.10.22-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7778e6200ff8ed5f7052c1516617423d22517ad36cc7a3aedd51428168e3e5e8"}, - {file = "pydantic-1.10.22-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffe02767d27c39af9ca7dc7cd479c00dda6346bb62ffc89e306f665108317a2"}, - {file = "pydantic-1.10.22-cp311-cp311-win_amd64.whl", hash = "sha256:23bc19c55427091b8e589bc08f635ab90005f2dc99518f1233386f46462c550a"}, - {file = "pydantic-1.10.22-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:92d0f97828a075a71d9efc65cf75db5f149b4d79a38c89648a63d2932894d8c9"}, - {file = "pydantic-1.10.22-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af5a2811b6b95b58b829aeac5996d465a5f0c7ed84bd871d603cf8646edf6ff"}, - {file = "pydantic-1.10.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cf06d8d40993e79af0ab2102ef5da77b9ddba51248e4cb27f9f3f591fbb096e"}, - {file = "pydantic-1.10.22-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:184b7865b171a6057ad97f4a17fbac81cec29bd103e996e7add3d16b0d95f609"}, - {file = "pydantic-1.10.22-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:923ad861677ab09d89be35d36111156063a7ebb44322cdb7b49266e1adaba4bb"}, - {file = "pydantic-1.10.22-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:82d9a3da1686443fb854c8d2ab9a473251f8f4cdd11b125522efb4d7c646e7bc"}, - {file = "pydantic-1.10.22-cp312-cp312-win_amd64.whl", hash = "sha256:1612604929af4c602694a7f3338b18039d402eb5ddfbf0db44f1ebfaf07f93e7"}, - {file = "pydantic-1.10.22-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b259dc89c9abcd24bf42f31951fb46c62e904ccf4316393f317abeeecda39978"}, - {file = "pydantic-1.10.22-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9238aa0964d80c0908d2f385e981add58faead4412ca80ef0fa352094c24e46d"}, - {file = "pydantic-1.10.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8029f05b04080e3f1a550575a1bca747c0ea4be48e2d551473d47fd768fc1b"}, - {file = "pydantic-1.10.22-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c06918894f119e0431a36c9393bc7cceeb34d1feeb66670ef9b9ca48c073937"}, - {file = "pydantic-1.10.22-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e205311649622ee8fc1ec9089bd2076823797f5cd2c1e3182dc0e12aab835b35"}, - {file = "pydantic-1.10.22-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:815f0a73d5688d6dd0796a7edb9eca7071bfef961a7b33f91e618822ae7345b7"}, - {file = "pydantic-1.10.22-cp313-cp313-win_amd64.whl", hash = "sha256:9dfce71d42a5cde10e78a469e3d986f656afc245ab1b97c7106036f088dd91f8"}, - {file = "pydantic-1.10.22-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3ecaf8177b06aac5d1f442db1288e3b46d9f05f34fd17fdca3ad34105328b61a"}, - {file = "pydantic-1.10.22-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb36c2de9ea74bd7f66b5481dea8032d399affd1cbfbb9bb7ce539437f1fce62"}, - {file = "pydantic-1.10.22-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6b8d14a256be3b8fff9286d76c532f1a7573fbba5f189305b22471c6679854d"}, - {file = "pydantic-1.10.22-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:1c33269e815db4324e71577174c29c7aa30d1bba51340ce6be976f6f3053a4c6"}, - {file = "pydantic-1.10.22-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:8661b3ab2735b2a9ccca2634738534a795f4a10bae3ab28ec0a10c96baa20182"}, - {file = "pydantic-1.10.22-cp37-cp37m-win_amd64.whl", hash = "sha256:22bdd5fe70d4549995981c55b970f59de5c502d5656b2abdfcd0a25be6f3763e"}, - {file = "pydantic-1.10.22-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e3f33d1358aa4bc2795208cc29ff3118aeaad0ea36f0946788cf7cadeccc166b"}, - {file = "pydantic-1.10.22-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:813f079f9cd136cac621f3f9128a4406eb8abd2ad9fdf916a0731d91c6590017"}, - {file = "pydantic-1.10.22-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab618ab8dca6eac7f0755db25f6aba3c22c40e3463f85a1c08dc93092d917704"}, - {file = "pydantic-1.10.22-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d128e1aaa38db88caca920d5822c98fc06516a09a58b6d3d60fa5ea9099b32cc"}, - {file = "pydantic-1.10.22-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:cc97bbc25def7025e55fc9016080773167cda2aad7294e06a37dda04c7d69ece"}, - {file = "pydantic-1.10.22-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dda5d7157d543b1fa565038cae6e952549d0f90071c839b3740fb77c820fab8"}, - {file = "pydantic-1.10.22-cp38-cp38-win_amd64.whl", hash = "sha256:a093fe44fe518cb445d23119511a71f756f8503139d02fcdd1173f7b76c95ffe"}, - {file = "pydantic-1.10.22-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec54c89b2568b258bb30d7348ac4d82bec1b58b377fb56a00441e2ac66b24587"}, - {file = "pydantic-1.10.22-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8f1d1a1532e4f3bcab4e34e8d2197a7def4b67072acd26cfa60e92d75803a48"}, - {file = "pydantic-1.10.22-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ad83ca35508c27eae1005b6b61f369f78aae6d27ead2135ec156a2599910121"}, - {file = "pydantic-1.10.22-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53cdb44b78c420f570ff16b071ea8cd5a477635c6b0efc343c8a91e3029bbf1a"}, - {file = "pydantic-1.10.22-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:16d0a5ae9d98264186ce31acdd7686ec05fd331fab9d68ed777d5cb2d1514e5e"}, - {file = "pydantic-1.10.22-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8aee040e25843f036192b1a1af62117504a209a043aa8db12e190bb86ad7e611"}, - {file = "pydantic-1.10.22-cp39-cp39-win_amd64.whl", hash = "sha256:7f691eec68dbbfca497d3c11b92a3e5987393174cbedf03ec7a4184c35c2def6"}, - {file = "pydantic-1.10.22-py3-none-any.whl", hash = "sha256:343037d608bcbd34df937ac259708bfc83664dadf88afe8516c4f282d7d471a9"}, - {file = "pydantic-1.10.22.tar.gz", hash = "sha256:ee1006cebd43a8e7158fb7190bb8f4e2da9649719bff65d0c287282ec38dec6d"}, + {file = "pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d"}, + {file = "pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.6.0" +pydantic-core = "2.41.5" +typing-extensions = ">=4.14.1" +typing-inspection = ">=0.4.2" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146"}, + {file = "pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a"}, + {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c"}, + {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2"}, + {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556"}, + {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49"}, + {file = "pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba"}, + {file = "pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9"}, + {file = "pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6"}, + {file = "pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b"}, + {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b"}, + {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284"}, + {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594"}, + {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e"}, + {file = "pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b"}, + {file = "pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe"}, + {file = "pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f"}, + {file = "pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7"}, + {file = "pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c"}, + {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5"}, + {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c"}, + {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294"}, + {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1"}, + {file = "pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d"}, + {file = "pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815"}, + {file = "pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3"}, + {file = "pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9"}, + {file = "pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586"}, + {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d"}, + {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740"}, + {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e"}, + {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858"}, + {file = "pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36"}, + {file = "pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11"}, + {file = "pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd"}, + {file = "pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a"}, + {file = "pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375"}, + {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553"}, + {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90"}, + {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07"}, + {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb"}, + {file = "pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23"}, + {file = "pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf"}, + {file = "pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c"}, + {file = "pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008"}, + {file = "pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf"}, + {file = "pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3"}, + {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425"}, + {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504"}, + {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5"}, + {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3"}, + {file = "pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460"}, + {file = "pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b"}, + {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034"}, + {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c"}, + {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2"}, + {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad"}, + {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd"}, + {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc"}, + {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56"}, + {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963"}, + {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f"}, + {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51"}, + {file = "pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e"}, +] + +[package.dependencies] +typing-extensions = ">=4.14.1" [[package]] name = "pyflakes" @@ -1371,7 +1691,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -1450,24 +1770,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "rfc3986" -version = "1.5.0" -description = "Validating URI References per RFC 3986" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, - {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, -] - -[package.dependencies] -idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} - -[package.extras] -idna2008 = ["idna"] - [[package]] name = "rich" version = "14.1.0" @@ -1626,7 +1928,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -1716,7 +2018,22 @@ files = [ {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] -markers = {dev = "python_full_version < \"3.11.0a7\""} +markers = {dev = "python_version <= \"3.11\""} + +[[package]] +name = "typeguard" +version = "4.4.4" +description = "Run-time type checker for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "typeguard-4.4.4-py3-none-any.whl", hash = "sha256:b5f562281b6bfa1f5492470464730ef001646128b180769880468bd84b68b09e"}, + {file = "typeguard-4.4.4.tar.gz", hash = "sha256:3a7fd2dffb705d4d0efaed4306a704c89b9dee850b688f060a8b1615a79e5f74"}, +] + +[package.dependencies] +typing_extensions = ">=4.14.0" [[package]] name = "types-click" @@ -1754,6 +2071,21 @@ files = [ {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, ] +[[package]] +name = "typing-inspection" +version = "0.4.2" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"}, + {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + [[package]] name = "urllib3" version = "2.5.0" @@ -1882,4 +2214,4 @@ dev = ["black (>=19.3b0) ; python_version >= \"3.6\"", "pytest (>=4.6.2)"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4.0" -content-hash = "8e9521e9b51fb0646d967d62d379d29f42d3cfd9658561e6785cd5aee65b78fa" +content-hash = "a378266a49991f7a805d9433196caafaf4eeabbe5e1b13566dcdb71e355f49c6" diff --git a/pyproject.toml b/pyproject.toml index 710f895..b0b3596 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,12 +33,12 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "httpx>=0.15.4,<0.19.0", + "httpx>=0.28.1,<0.29.0", "attrs>=20.1.0,<22.0.0", "python-dateutil>=2.8.0,<3.0.0", "websockets>=10.0,<11.0", "click>=8.0.1,<9.0.0", - "pydantic>=1.4,<2.0", + "pydantic>=2.0,<3.0", "types-click>=7.1.5,<8.0.0", "fastapi>=0.68.1,<1.0.0", "loguru>=0.5.3,<1.0.0", @@ -76,6 +76,9 @@ pytest-asyncio = "^0.21.1" # Async support for pytest pytest-click = "^1.1.0" # Click testing utilities pytest-xdist = "^3.3.1" # Parallel test execution faker = "^19.3.0" # Generate fake data for testing +datamodel-code-generator = {extras = ["http"], version = "^0.53.0"} +click = "^8.3.1" +httpx = "^0.28.1" [tool.isort] multi_line_output = 3 diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..1618055 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,72 @@ +# API Client Generator + +This directory contains scripts for managing the CLI tool. + +## Generate API Client + +The `generate_client.sh` script generates the API client from the OpenAPI specification using `datamodel-code-generator` (Pydantic v2). + +### Usage + +```bash +# Generate from local openapi.json +./scripts/generate_client.sh --input openapi.json + +# Generate from remote server +./scripts/generate_client.sh --input http://192.168.1.100/api/v1/openapi.json + +# Specify custom output directory +./scripts/generate_client.sh --input openapi.json --output th_cli/api_lib_autogen +``` + +### Features + +- ✅ **Pure Python** - No Docker required +- ✅ **Fast** - 10-20x faster than old openapi-generator +- ✅ **Pydantic v2** - 5-50x faster validation +- ✅ **Type-safe** - Full type hints and IDE support +- ✅ **Modern** - Uses latest async patterns + +### Generated Structure + +``` +th_cli/api_lib_autogen/ +├── __init__.py # Package exports +├── models.py # Pydantic v2 models +├── api_client.py # HTTP client with middleware +├── exceptions.py # Custom exceptions +├── py.typed # Type hint marker +└── api/ # API endpoint modules + ├── __init__.py + ├── projects_api.py + ├── test_run_executions_api.py + └── ... +``` + +### Requirements + +Install the development dependencies: + +```bash +poetry add --group dev 'datamodel-code-generator[http]' click httpx +``` + +### Migration from Old Generator + +The old OpenAPI Generator (Docker-based) has been removed. The new generator: + +1. **No postprocessing needed** - Generates clean code directly +2. **No templates** - Uses datamodel-code-generator +3. **Pydantic v2 native** - No v1 compatibility layer + +See the [Pydantic v2 Migration Guide](https://docs.pydantic.dev/latest/migration/) for code changes. + +--- + +## Other Scripts + +- **`check_deps.py`** - Check Python dependencies +- **`run_pytest.sh`** - Run pytest test suite +- **`lint.sh`** - Run linters (mypy, flake8, pylint) +- **`format.sh`** - Format code with black, isort, and flake8 +- **`th_cli_install.sh`** - Install CLI tool with pipx diff --git a/scripts/datamodel_generate_client.py b/scripts/datamodel_generate_client.py new file mode 100755 index 0000000..8dd836b --- /dev/null +++ b/scripts/datamodel_generate_client.py @@ -0,0 +1,963 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +""" +Modern API client generator using datamodel-code-generator. + +This replaces the Docker-based openapi-generator approach with a pure Python solution: +- Uses datamodel-code-generator for Pydantic v2 models +- Generates API endpoint classes from OpenAPI specification +- No Docker required, faster generation, cleaner output +- Minimal/no postprocessing needed +""" + +import json +import os +import shutil +import subprocess +import sys +import tempfile +import traceback +from pathlib import Path +from typing import Any + +import click + + +class OpenAPIParser: + """Parse OpenAPI specification and extract information for code generation.""" + + def __init__(self, spec: dict[str, Any]): + self.spec = spec + self.schemas = spec.get("components", {}).get("schemas", {}) + + def get_endpoints_by_tag(self) -> dict[str, list[dict[str, Any]]]: + """Group API endpoints by their tags.""" + endpoints_by_tag: dict[str, list[dict[str, Any]]] = {} + + for path, path_item in self.spec.get("paths", {}).items(): + for method in ["get", "post", "put", "delete", "patch"]: + if method not in path_item: + continue + + operation = path_item[method] + tags = operation.get("tags", ["default"]) + tag = tags[0] if tags else "default" + + if tag not in endpoints_by_tag: + endpoints_by_tag[tag] = [] + + endpoints_by_tag[tag].append( + { + "path": path, + "method": method.upper(), + "operation_id": operation.get("operationId", f"{method}_{path.replace('/', '_')}"), + "summary": operation.get("summary", ""), + "description": operation.get("description", ""), + "parameters": operation.get("parameters", []), + "request_body": operation.get("requestBody"), + "responses": operation.get("responses", {}), + } + ) + + return endpoints_by_tag + + def get_parameter_info(self, param: dict[str, Any]) -> dict[str, Any]: + """Extract parameter information.""" + schema = param.get("schema", {}) + param_type = self._get_python_type(schema) + required = param.get("required", False) + + return { + "name": param["name"], + "type": param_type, + "required": required, + "in": param.get("in", "query"), + "description": param.get("description", ""), + } + + def get_request_body_info(self, request_body: dict[str, Any] | None) -> dict[str, Any] | None: + """Extract request body information.""" + if not request_body: + return None + + content = request_body.get("content", {}) + # Try JSON first, then form data + for content_type in ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]: + if content_type in content: + schema = content[content_type].get("schema", {}) + return { + "type": self._get_python_type(schema, resolve_ref=True), + "required": request_body.get("required", False), + "content_type": content_type, + "is_multipart": content_type == "multipart/form-data", + } + + return None + + def get_response_type(self, responses: dict[str, Any]) -> str: + """Extract response type from responses.""" + # Try 200, 201, then any 2xx + for status in ["200", "201"]: + if status in responses: + response = responses[status] + content = response.get("content", {}) + if "application/json" in content: + schema = content["application/json"].get("schema", {}) + return self._get_python_type(schema, resolve_ref=True) + + # Check for any 2xx response + for status, response in responses.items(): + if status.startswith("2"): + content = response.get("content", {}) + if "application/json" in content: + schema = content["application/json"].get("schema", {}) + return self._get_python_type(schema, resolve_ref=True) + + return "None" + + def _get_python_type(self, schema: dict[str, Any], resolve_ref: bool = False) -> str: + """Convert OpenAPI schema type to Python type hint.""" + if "$ref" in schema: + ref = schema["$ref"] + model_name = ref.split("/")[-1] + if model_name.startswith("Body_"): + # TODO: handle schema names that conflicts with the models names. + model_name = "".join(word.capitalize() for word in model_name.split("_")) + if resolve_ref: + return f"m.{model_name}" + return model_name + + schema_type = schema.get("type", "object") + schema_format = schema.get("format") + + # Handle arrays + if schema_type == "array": + items = schema.get("items", {}) + item_type = self._get_python_type(items, resolve_ref=resolve_ref) + return f"list[{item_type}]" + + # Handle objects + if schema_type == "object": + additional_props = schema.get("additionalProperties") + if additional_props: + value_type = self._get_python_type(additional_props, resolve_ref=resolve_ref) + return f"dict[str, {value_type}]" + return "dict[str, Any]" + + # Primitive types + type_mapping = { + "string": "str", + "integer": "int", + "number": "float", + "boolean": "bool", + } + + # Handle string formats + if schema_type == "string": + format_mapping = { + "date-time": "datetime", + "date": "date", + "uuid": "UUID", + "binary": "bytes", + } + if schema_format in format_mapping: + return format_mapping[schema_format] + + return type_mapping.get(schema_type, "Any") + + +class APIGenerator: + """Generate API client code from OpenAPI specification.""" + + def __init__(self, spec_path: str, output_dir: Path, import_name: str = "th_cli.api_lib_autogen"): + self.spec_path = spec_path + self.output_dir = output_dir + self.import_name = import_name + self.spec = self._load_spec() + self.parser = OpenAPIParser(self.spec) + + def _load_spec(self) -> dict[str, Any]: + """Load OpenAPI specification from file or URL.""" + if self.spec_path.startswith("http://") or self.spec_path.startswith("https://"): + click.echo(f"📥 Downloading OpenAPI spec from {self.spec_path}") + import httpx + response = httpx.get(self.spec_path, follow_redirects=True) + response.raise_for_status() + return response.json() + else: + click.echo(f"📂 Loading OpenAPI spec from {self.spec_path}") + with open(self.spec_path) as f: + return json.load(f) + + def generate(self): + """Generate complete API client.""" + click.echo(f"🚀 Generating API client to {self.output_dir}") + + # Clean output directory + if self.output_dir.exists(): + + shutil.rmtree(self.output_dir) + self.output_dir.mkdir(parents=True, exist_ok=True) + + # Step 1: Generate Pydantic models + self._generate_models() + + # Step 2: Generate API endpoint classes + self._generate_api_classes() + + # Step 3: Generate api_client.py + self._generate_api_client() + + # Step 4: Generate exceptions.py + self._generate_exceptions() + + # Step 5: Generate __init__.py files + self._generate_init_files() + + # Step 6: Add py.typed marker + self._add_py_typed() + + click.echo("✨ Generation complete!") + + def _generate_models(self): + """Generate Pydantic v2 models using datamodel-code-generator.""" + click.echo("📦 Generating Pydantic v2 models...") + + models_file = self.output_dir / "models.py" + + # Save spec to temp file if it's a URL + spec_file = self.spec_path + if self.spec_path.startswith("http"): + temp_spec = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) + json.dump(self.spec, temp_spec) + temp_spec.close() + spec_file = temp_spec.name + + cmd = [ + "poetry", + "run", + "datamodel-codegen", + "--input", + spec_file, + "--output", + str(models_file), + "--input-file-type", + "openapi", + "--output-model-type", + "pydantic_v2.BaseModel", + "--use-standard-collections", + "--use-union-operator", + "--target-python-version", + "3.10", + "--use-annotated", + "--field-constraints", + "--collapse-root-models", + "--enum-field-as-literal", + "one", + "--use-title-as-name", + "--reuse-model", + "--output-datetime-class", + "datetime", + ] + + try: + result = subprocess.run(cmd, check=True, capture_output=True, text=True) + if result.stdout: + click.echo(result.stdout) + click.echo(f" ✓ Generated {models_file.relative_to(self.output_dir.parent)}") + except subprocess.CalledProcessError as e: + click.echo(f" ✗ Error generating models: {e.stderr}", err=True) + raise + except FileNotFoundError: + click.echo( + " ✗ Error: datamodel-code-generator not found. Install it with: pip install 'datamodel-code-generator[http]'", + err=True, + ) + raise + + # Clean up temp file if created + if self.spec_path.startswith("http") and spec_file != self.spec_path: + os.unlink(spec_file) + + def _generate_api_classes(self): + """Generate API endpoint classes.""" + click.echo("🔌 Generating API endpoint classes...") + + api_dir = self.output_dir / "api" + api_dir.mkdir(exist_ok=True) + + endpoints_by_tag = self.parser.get_endpoints_by_tag() + + for tag, endpoints in endpoints_by_tag.items(): + self._generate_api_class_file(tag, endpoints, api_dir) + + def _generate_api_class_file(self, tag: str, endpoints: list[dict[str, Any]], api_dir: Path): + """Generate a single API class file.""" + class_name = self._tag_to_class_name(tag) + file_name = f"{tag.replace('-', '_').replace(' ', '_')}_api.py" + file_path = api_dir / file_name + + # Generate imports + imports = self._generate_imports() + + # Generate base class + base_class = self._generate_base_api_class(class_name, endpoints) + + # Generate async class + async_class = self._generate_async_api_class(class_name, endpoints) + + # Generate sync class + sync_class = self._generate_sync_api_class(class_name, endpoints) + + content = f'''{imports} + +{base_class} + + +{async_class} + + +{sync_class} +''' + + file_path.write_text(content) + click.echo(f" ✓ Generated {file_path.relative_to(self.output_dir.parent)}") + + def _generate_imports(self) -> str: + """Generate import statements.""" + return f'''# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# flake8: noqa E501 +from asyncio import get_event_loop +from typing import Coroutine, IO, TYPE_CHECKING, Any + +from {self.import_name} import models as m + +if TYPE_CHECKING: + from {self.import_name}.api_client import ApiClient''' + + def _generate_base_api_class(self, class_name: str, endpoints: list[dict[str, Any]]) -> str: + """Generate base API class with _build_for methods.""" + methods = [] + + for endpoint in endpoints: + method = self._generate_build_method(endpoint) + methods.append(method) + + methods_code = "\n\n".join(methods) + + return f'''class _{class_name}: + def __init__(self, api_client: "ApiClient"): + self.api_client = api_client + +{methods_code}''' + + def _generate_build_method(self, endpoint: dict[str, Any]) -> str: + """Generate _build_for method for an endpoint.""" + operation_id = endpoint["operation_id"] + method = endpoint["method"] + path = endpoint["path"] + parameters = endpoint["parameters"] + request_body = endpoint.get("request_body") + responses = endpoint["responses"] + + # Parse parameters + params = [self.parser.get_parameter_info(p) for p in parameters] + path_params = [p for p in params if p["in"] == "path"] + query_params = [p for p in params if p["in"] == "query"] + header_params = [p for p in params if p["in"] == "header"] + + # Parse request body + body_info = self.parser.get_request_body_info(request_body) + + # Parse response type + return_type = self.parser.get_response_type(responses) + + # Generate method signature + sig_params = [] + if body_info: + type_hint = body_info["type"] + if not body_info["required"]: + type_hint = f"{type_hint} | None" + sig_params.append(f"body: {type_hint} = None") + else: + sig_params.append(f"body: {type_hint}") + + for p in params: + type_hint = f"{p['type']} | None" if not p["required"] else p["type"] + default = " = None" if not p["required"] else "" + sig_params.append(f"{p['name']}: {type_hint}{default}") + + sig_params_str = ", ".join(sig_params) + if sig_params_str: + sig_params_str = ", " + sig_params_str + + # Generate method body + body_lines = [] + + # Add docstring + if endpoint.get("summary") or endpoint.get("description"): + doc = endpoint.get("summary", "") or endpoint.get("description", "") + body_lines.append(f' """\n {doc}\n """') + + # Path parameters + if path_params: + path_dict_items = [f'"{p["name"]}": str({p["name"]})' for p in path_params] + body_lines.append(f" path_params = {{{', '.join(path_dict_items)}}}") + body_lines.append("") + + # Query parameters + if query_params: + req_query = [p for p in query_params if p["required"]] + opt_query = [p for p in query_params if not p["required"]] + + if req_query: + query_dict_items = [f'"{p["name"]}": str({p["name"]})' for p in req_query] + body_lines.append(f" query_params = {{{', '.join(query_dict_items)}}}") + else: + body_lines.append(" query_params = {}") + + for p in opt_query: + body_lines.append(f" if {p['name']} is not None:") + body_lines.append(f" query_params[\"{p['name']}\"] = str({p['name']})") + body_lines.append("") + + # Request body handling + if body_info: + if body_info["is_multipart"]: + # Handle multipart form data (files) + body_lines.append(" files: dict[str, IO[Any]] = {}") + body_lines.append(" data: dict[str, Any] = {}") + body_lines.append(" # TODO: Parse body for files and data") + body_lines.append("") + else: + # JSON body - use model_dump for Pydantic v2 + body_lines.append(" json_body = body.model_dump(mode='json') if hasattr(body, 'model_dump') else body") + body_lines.append("") + + # Build request call + request_args = [ + f"type_={return_type}", + f'method="{method}"', + f'url="{path}"', + ] + + if path_params: + request_args.append("path_params=path_params") + if query_params: + request_args.append("params=query_params") + if header_params: + request_args.append("# TODO: Add headers") + if body_info: + if body_info["is_multipart"]: + request_args.append("data=data") + request_args.append("files=files") + else: + request_args.append("json=json_body") + + body_lines.append(" return self.api_client.request(") + for i, arg in enumerate(request_args): + comma = "," if i < len(request_args) - 1 else "" + body_lines.append(f" {arg}{comma}") + body_lines.append(" )") + + method_body = "\n".join(body_lines) + + return f''' def _build_for_{operation_id}(self{sig_params_str}) -> Coroutine[Any, Any, {return_type}]: +{method_body}''' + + def _generate_async_api_class(self, class_name: str, endpoints: list[dict[str, Any]]) -> str: + """Generate async API class.""" + methods = [] + + for endpoint in endpoints: + method = self._generate_async_method(endpoint) + methods.append(method) + + methods_code = "\n\n".join(methods) + + return f'''class Async{class_name}(_{class_name}): +{methods_code}''' + + def _generate_async_method(self, endpoint: dict[str, Any]) -> str: + """Generate async method.""" + operation_id = endpoint["operation_id"] + parameters = endpoint["parameters"] + request_body = endpoint.get("request_body") + responses = endpoint["responses"] + + # Parse parameters + params = [self.parser.get_parameter_info(p) for p in parameters] + + # Parse request body + body_info = self.parser.get_request_body_info(request_body) + + # Parse response type + return_type = self.parser.get_response_type(responses) + + # Generate method signature + sig_params = [] + call_params = [] + if body_info: + type_hint = body_info["type"] + if not body_info["required"]: + type_hint = f"{type_hint} | None" + sig_params.append(f"body: {type_hint} = None") + else: + sig_params.append(f"body: {type_hint}") + call_params.append("body=body") + + for p in params: + type_hint = f"{p['type']} | None" if not p["required"] else p["type"] + default = " = None" if not p["required"] else "" + sig_params.append(f"{p['name']}: {type_hint}{default}") + call_params.append(f"{p['name']}={p['name']}") + + sig_params_str = ", ".join(sig_params) + if sig_params_str: + sig_params_str = ", " + sig_params_str + + call_params_str = ", ".join(call_params) + + # Add docstring + doc = endpoint.get("summary", "") or endpoint.get("description", "") + docstring = f'"""\n {doc}\n """' if doc else "" + + return f''' async def {operation_id}(self{sig_params_str}) -> {return_type}: + {docstring} + return await self._build_for_{operation_id}({call_params_str})''' + + def _generate_sync_api_class(self, class_name: str, endpoints: list[dict[str, Any]]) -> str: + """Generate sync API class.""" + methods = [] + + for endpoint in endpoints: + method = self._generate_sync_method(endpoint) + methods.append(method) + + methods_code = "\n\n".join(methods) + + return f'''class Sync{class_name}(_{class_name}): +{methods_code}''' + + def _generate_sync_method(self, endpoint: dict[str, Any]) -> str: + """Generate sync method.""" + operation_id = endpoint["operation_id"] + parameters = endpoint["parameters"] + request_body = endpoint.get("request_body") + responses = endpoint["responses"] + + # Parse parameters + params = [self.parser.get_parameter_info(p) for p in parameters] + + # Parse request body + body_info = self.parser.get_request_body_info(request_body) + + # Parse response type + return_type = self.parser.get_response_type(responses) + + # Generate method signature + sig_params = [] + call_params = [] + + if body_info: + type_hint = body_info["type"] + if not body_info["required"]: + type_hint = f"{type_hint} | None" + sig_params.append(f"body: {type_hint} = None") + else: + sig_params.append(f"body: {type_hint}") + call_params.append("body=body") + + for p in params: + type_hint = f"{p['type']} | None" if not p["required"] else p["type"] + default = " = None" if not p["required"] else "" + sig_params.append(f"{p['name']}: {type_hint}{default}") + call_params.append(f"{p['name']}={p['name']}") + + sig_params_str = ", ".join(sig_params) + if sig_params_str: + sig_params_str = ", " + sig_params_str + + call_params_str = ", ".join(call_params) + + # Add docstring + doc = endpoint.get("summary", "") or endpoint.get("description", "") + docstring = f'"""\n {doc}\n """' if doc else "" + + return f''' def {operation_id}(self{sig_params_str}) -> {return_type}: + {docstring} + coroutine = self._build_for_{operation_id}({call_params_str}) + return get_event_loop().run_until_complete(coroutine)''' + + def _generate_api_client(self): + """Generate main ApiClient class.""" + click.echo("🏗️ Generating API client...") + + endpoints_by_tag = self.parser.get_endpoints_by_tag() + tags = list(endpoints_by_tag.keys()) + + # Generate API imports + api_imports = [] + async_init = [] + sync_init = [] + + for tag in tags: + class_name = self._tag_to_class_name(tag) + module_name = tag.replace("-", "_").replace(" ", "_") + api_imports.append(f"from {self.import_name}.api.{module_name}_api import Async{class_name}, Sync{class_name}") + async_init.append(f" self.{module_name}_api = Async{class_name}(self.client)") + sync_init.append(f" self.{module_name}_api = Sync{class_name}(self.client)") + + api_imports_str = "\n".join(api_imports) + async_init_str = "\n".join(async_init) + sync_init_str = "\n".join(sync_init) + + content = f'''# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from asyncio import get_event_loop +from typing import Any, Awaitable, Callable, Generic, Type, TypeVar, overload + +from httpx import AsyncClient, Request, Response +from pydantic import TypeAdapter + +{api_imports_str} +from {self.import_name}.exceptions import ResponseHandlingException, UnexpectedResponse + +ClientT = TypeVar("ClientT", bound="ApiClient") + + +class AsyncApis(Generic[ClientT]): + def __init__(self, client: ClientT): + self.client = client + +{async_init_str} + + +class SyncApis(Generic[ClientT]): + def __init__(self, client: ClientT): + self.client = client + +{sync_init_str} + + +T = TypeVar("T") +Send = Callable[[Request], Awaitable[Response]] +MiddlewareT = Callable[[Request, Send], Awaitable[Response]] + + +class ApiClient: + def __init__(self, host: str | None = None, **kwargs: Any) -> None: + self.host = host + self.middleware: MiddlewareT = BaseMiddleware() + self._async_client = AsyncClient(**kwargs) + + async def aclose(self) -> None: + await self._async_client.aclose() + + def close(self) -> None: + get_event_loop().run_until_complete(self.aclose()) + + @overload + async def request( + self, *, type_: Type[T], method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any + ) -> T: ... + + @overload + async def request( + self, *, type_: None, method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any + ) -> None: ... + + async def request( + self, *, type_: Any, method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any + ) -> Any: + if path_params is None: + path_params = {{}} + url = (self.host or "") + url.format(**path_params) + request = Request(method, url, **kwargs) + return await self.send(request, type_) + + @overload + def request_sync(self, *, type_: Type[T], **kwargs: Any) -> T: ... + + @overload + def request_sync(self, *, type_: None, **kwargs: Any) -> None: ... + + def request_sync(self, *, type_: Any, **kwargs: Any) -> Any: + """ + This method is not used by the generated apis, but is included for convenience + """ + return get_event_loop().run_until_complete(self.request(type_=type_, **kwargs)) + + async def send(self, request: Request, type_: Type[T]) -> T | str: + response = await self.middleware(request, self.send_inner) + if response.status_code in [200, 201]: + try: + # Use Pydantic v2 TypeAdapter for validation + adapter = TypeAdapter(type_) + return adapter.validate_python(response.json()) if type_ else response.text + except Exception as e: + raise ResponseHandlingException(e) + raise UnexpectedResponse.for_response(response) + + async def send_inner(self, request: Request) -> Response: + try: + response = await self._async_client.send(request) + except Exception as e: + raise ResponseHandlingException(e) + return response + + def add_middleware(self, middleware: MiddlewareT) -> None: + current_middleware = self.middleware + + async def new_middleware(request: Request, call_next: Send) -> Response: + async def inner_send(request: Request) -> Response: + return await current_middleware(request, call_next) + + return await middleware(request, inner_send) + + self.middleware = new_middleware + + +class BaseMiddleware: + async def __call__(self, request: Request, call_next: Send) -> Response: + return await call_next(request) +''' + + api_client_file = self.output_dir / "api_client.py" + api_client_file.write_text(content) + click.echo(f" ✓ Generated {api_client_file.relative_to(self.output_dir.parent)}") + + def _generate_exceptions(self): + """Generate exceptions module.""" + click.echo("⚠️ Generating exceptions...") + + content = '''# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import Any + +from httpx import Response + + +class ApiException(Exception): + """Base exception for API client errors.""" + pass + + +class ResponseHandlingException(ApiException): + """Exception raised when response handling fails.""" + + def __init__(self, error: Exception): + self.error = error + super().__init__(f"Error handling response: {error}") + + +class UnexpectedResponse(ApiException): + """Exception raised when response status is unexpected.""" + + def __init__(self, status_code: int, content: Any): + self.status_code = status_code + self.content = content + super().__init__(f"Unexpected response status: {status_code}") + + @classmethod + def for_response(cls, response: Response) -> "UnexpectedResponse": + """Create exception from httpx Response.""" + try: + content = response.json() + except Exception: + content = response.text + return cls(response.status_code, content) +''' + + exceptions_file = self.output_dir / "exceptions.py" + exceptions_file.write_text(content) + click.echo(f" ✓ Generated {exceptions_file.relative_to(self.output_dir.parent)}") + + def _generate_init_files(self): + """Generate __init__.py files.""" + click.echo("📝 Generating __init__.py files...") + + # Main package __init__.py + main_init = f'''# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Auto-generated API client for Test Harness.""" + +from {self.import_name}.api_client import ApiClient, AsyncApis, SyncApis +from {self.import_name}.exceptions import ApiException, ResponseHandlingException, UnexpectedResponse + +__all__ = [ + "ApiClient", + "AsyncApis", + "SyncApis", + "ApiException", + "ResponseHandlingException", + "UnexpectedResponse", +] +''' + (self.output_dir / "__init__.py").write_text(main_init) + + # API package __init__.py + endpoints_by_tag = self.parser.get_endpoints_by_tag() + api_imports = [] + api_all = [] + + for tag in endpoints_by_tag.keys(): + class_name = self._tag_to_class_name(tag) + module_name = tag.replace("-", "_").replace(" ", "_") + api_imports.append(f"from {self.import_name}.api.{module_name}_api import Async{class_name}, Sync{class_name}") + api_all.extend([f'"{class_name}"', f'"Async{class_name}"', f'"Sync{class_name}"']) + + api_imports_str = "\n".join(api_imports) + api_all_str = ", ".join(api_all) + + api_init = f'''# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""API endpoint classes.""" + +{api_imports_str} + +__all__ = [{api_all_str}] +''' + (self.output_dir / "api" / "__init__.py").write_text(api_init) + + click.echo(" ✓ Generated __init__.py files") + + def _add_py_typed(self): + """Add py.typed marker for PEP 561 compliance.""" + (self.output_dir / "py.typed").touch() + click.echo(" ✓ Added py.typed marker") + + def _tag_to_class_name(self, tag: str) -> str: + """Convert tag to PascalCase class name.""" + return "".join(word.capitalize() for word in tag.replace("-", "_").replace(" ", "_").split("_")) + "Api" + + +@click.command() +@click.option("--input", "-i", "input_spec", required=True, help="OpenAPI spec path or URL") +@click.option( + "--output", + "-o", + "output_dir", + default="th_cli/api_lib_autogen", + help="Output directory (default: th_cli/api_lib_autogen)", +) +@click.option( + "--import-name", + "-n", + default="th_cli.api_lib_autogen", + help="Import name for the package (default: th_cli.api_lib_autogen)", +) +@click.option("--verbose", "-v", is_flag=True, help="Verbose output") +def main(input_spec: str, output_dir: str, import_name: str, verbose: bool): + """ + Generate API client from OpenAPI specification. + + This is a modern replacement for the Docker-based openapi-generator approach. + It uses datamodel-code-generator for Pydantic v2 models and generates clean, + type-safe API client code with no postprocessing required. + + Example: + python scripts/generate_client_v2.py --input openapi.json + + python scripts/generate_client_v2.py --input http://localhost/api/v1/openapi.json + """ + try: + output_path = Path(output_dir) + generator = APIGenerator(input_spec, output_path, import_name) + generator.generate() + + click.echo("\n✅ Success! Next steps:") + click.echo(f" 1. Review generated code in {output_path}") + click.echo(" 2. Run: poetry run mypy " + str(output_path)) + click.echo(" 3. Run: poetry run black " + str(output_path)) + click.echo(" 4. Run tests to verify everything works") + + except Exception as e: + click.echo(f"\n❌ Error: {e}", err=True) + if verbose: + traceback.print_exc() + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/generate_client.sh b/scripts/generate_client.sh index 6d9b94f..e6462ff 100755 --- a/scripts/generate_client.sh +++ b/scripts/generate_client.sh @@ -1,103 +1,23 @@ #! /usr/bin/env bash - - # - # Copyright (c) 2023 Project CHIP Authors - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. +# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. set -e -# Prevent automatic path conversions by MSYS-based bash. -# It's revelant only for Windows -export MSYS_NO_PATHCONV=1 - -CMDNAME=${0##*/} - -PACKAGE_NAME=api_lib_autogen -OUTPUT_DIR="th_cli" -PACKAGE_PATH=$OUTPUT_DIR/$PACKAGE_NAME -OPENAPI_PATH="." -OPENAPI_FILE="openapi.json" -OPENAPI_IP_ADDRESS="" - -usage() { - exitcode="$1" - cat <&2 - -Generate API client from OpenAPI specification - -Usage: - $CMDNAME [OPTIONS] - -Options: - -i, --ip IP_ADDRESS Use remote OpenAPI spec from http://IP_ADDRESS/api/v1/openapi.json - If not provided, uses local openapi.json file - -h, --help Show this message - -Examples: - # Generate from local file - $CMDNAME - - # Generate from remote server - $CMDNAME --ip 192.168.1.100 - $CMDNAME -i 10.0.0.50 - -USAGE - exit "$exitcode" -} - -main() { - PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" - - # Set OPENAPI_PATH based on whether IP was provided - if [ -n "$OPENAPI_IP_ADDRESS" ]; then - OPENAPI_PATH="http://$OPENAPI_IP_ADDRESS/api/v1" - echo "Using remote OpenAPI spec from: $OPENAPI_PATH/$OPENAPI_FILE" - else - OPENAPI_PATH="." - echo "Using local OpenAPI spec: $OPENAPI_PATH/$OPENAPI_FILE" - fi - - [ -d "$PACKAGE_PATH" ] && rm -rf "$PACKAGE_PATH" - - ./client_generator/scripts/generate.sh -i $OPENAPI_PATH/$OPENAPI_FILE -t "/tmp" -p $PACKAGE_NAME -o $OUTPUT_DIR -n $OUTPUT_DIR.$PACKAGE_NAME - - echo "Running type checking with mypy..." - poetry run mypy ./$PACKAGE_PATH - - echo "Running code formatters..." - poetry run black ./$PACKAGE_PATH - poetry run flake8 ./$PACKAGE_PATH - poetry run isort ./$PACKAGE_PATH - - echo "API client generation completed successfully! ✨" -} - -# Parse command line arguments -while [ $# -gt 0 ]; do - case "$1" in - -i | --ip) - OPENAPI_IP_ADDRESS=$2 - shift 2 - ;; - -h | --help) - usage 0 - ;; - *) - echo "Unknown argument: $1" - usage 1 - ;; - esac -done +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" -main +#Using an array to store the arguments, to handle 'whitespaces' correctly +args=("$@") +poetry run $PROJECT_ROOT/scripts/datamodel_generate_client.py "${args[@]}" diff --git a/scripts/run_pytest.py b/scripts/run_pytest.sh similarity index 94% rename from scripts/run_pytest.py rename to scripts/run_pytest.sh index 90e1599..752dff9 100755 --- a/scripts/run_pytest.py +++ b/scripts/run_pytest.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash # -# Copyright (c) 2025 Project CHIP Authors +# Copyright (c) 2025-2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tests/conftest.py b/tests/conftest.py index 1a920c9..1545059 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -19,6 +19,7 @@ import json import os import tempfile +from datetime import UTC from pathlib import Path from typing import Any, Generator from unittest.mock import AsyncMock, Mock @@ -220,8 +221,8 @@ def sample_project() -> api_models.Project: "trace_log": False } }, - created_at=fake.date_time(), - updated_at=fake.date_time() + created_at=fake.date_time(tzinfo=UTC), + updated_at=fake.date_time(tzinfo=UTC) ) @@ -244,8 +245,8 @@ def sample_projects() -> list[api_models.Project]: "trace_log": False } }, - created_at=fake.date_time(), - updated_at=fake.date_time() + created_at=fake.date_time(tzinfo=UTC), + updated_at=fake.date_time(tzinfo=UTC) ) for i in range(1, 4) ] @@ -354,7 +355,7 @@ def sample_test_run_execution() -> api_models.TestRunExecutionWithChildren: return api_models.TestRunExecutionWithChildren( id=1, title="Test Run 1", - state=api_models.TestStateEnum.PENDING, + state=api_models.TestStateEnum.pending, project_id=1, test_suite_executions=[ api_models.TestSuiteExecution( @@ -363,7 +364,7 @@ def sample_test_run_execution() -> api_models.TestRunExecutionWithChildren: collection_id="SDK YAML Tests", public_id="FirstChipToolSuite", mandatory=False, - state=api_models.TestStateEnum.PENDING, + state=api_models.TestStateEnum.pending, test_run_execution_id=1, test_suite_metadata_id=1, test_case_executions=[ @@ -371,7 +372,7 @@ def sample_test_run_execution() -> api_models.TestRunExecutionWithChildren: id=1, execution_index=1, public_id="TC-ACE-1.1", - state=api_models.TestStateEnum.PENDING, + state=api_models.TestStateEnum.pending, test_suite_execution_id=1, test_case_metadata_id=1, test_case_metadata=api_models.TestCaseMetadata( @@ -402,7 +403,7 @@ def sample_test_run_execution() -> api_models.TestRunExecutionWithChildren: def sample_test_runner_status() -> api_models.TestRunnerStatus: """Create a sample test runner status for testing.""" return api_models.TestRunnerStatus( - state=api_models.TestRunnerState.IDLE, + state=api_models.TestRunnerState.idle, test_run_execution_id=None ) @@ -412,7 +413,6 @@ def mock_unexpected_response() -> UnexpectedResponse: """Create a mock UnexpectedResponse exception.""" return UnexpectedResponse( status_code=404, - reason_phrase="Not Found", content=b"Not Found", headers=Headers() ) diff --git a/tests/test_abort_testing.py b/tests/test_abort_testing.py index 15d8519..9a8b727 100644 --- a/tests/test_abort_testing.py +++ b/tests/test_abort_testing.py @@ -84,9 +84,7 @@ def test_abort_testing_api_error(self, cli_runner: CliRunner, mock_sync_apis: Mo # Arrange api_exception = UnexpectedResponse( status_code=404, - reason_phrase="Not Found", content=b"Not Found", - headers=Headers(), ) api = mock_sync_apis.test_run_executions_api.abort_testing_api_v1_test_run_executions_abort_testing_post @@ -203,9 +201,7 @@ def test_abort_testing_various_api_errors( # Arrange api_exception = UnexpectedResponse( status_code=status_code, - reason_phrase=content, content=content.encode('utf-8'), - headers=Headers(), ) api = mock_sync_apis.test_run_executions_api.abort_testing_api_v1_test_run_executions_abort_testing_post diff --git a/tests/test_available_tests.py b/tests/test_available_tests.py index 9174ff9..4c99ed7 100644 --- a/tests/test_available_tests.py +++ b/tests/test_available_tests.py @@ -41,7 +41,7 @@ def test_available_tests_success_yaml_output( ) -> None: """Test successful available tests retrieval with YAML output (default).""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.get_client", return_value=mock_api_client): @@ -66,7 +66,7 @@ def test_available_tests_success_json_output( ) -> None: """Test successful available tests retrieval with JSON output.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -89,7 +89,7 @@ def test_available_tests_empty_collections( ) -> None: """Test handling of empty test collections.""" # Arrange - mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get.return_value = None + mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get.return_value = None with patch("th_cli.commands.available_tests.get_client", return_value=mock_api_client): with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -125,11 +125,9 @@ def test_available_tests_api_error( # Arrange api_exception = UnexpectedResponse( status_code=500, - reason_phrase="Internal Server Error", content=b"Internal Server Error", - headers=Headers(), ) - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.side_effect = api_exception with patch("th_cli.commands.available_tests.get_client", return_value=mock_api_client): @@ -150,7 +148,7 @@ def test_available_tests_generic_exception( ) -> None: """Test available tests with generic exception.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.side_effect = Exception("Network error") with patch("th_cli.commands.available_tests.get_client", return_value=mock_api_client): @@ -199,7 +197,7 @@ def test_available_tests_output_formats( ) -> None: """Test available tests with both JSON and YAML output formats.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -270,7 +268,7 @@ def test_available_tests_complex_test_structure( ) } ) - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = complex_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -304,11 +302,9 @@ def test_available_tests_various_api_errors( # Arrange api_exception = UnexpectedResponse( status_code=status_code, - reason_phrase=content, content=content.encode('utf-8'), - headers=Headers(), ) - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.side_effect = api_exception with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -328,7 +324,7 @@ def test_available_tests_yaml_dump_functionality( ) -> None: """Test that YAML output is properly formatted and readable.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -351,7 +347,7 @@ def test_available_tests_compact( ) -> None: """Test --compact flag shows test IDs with titles.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -375,7 +371,7 @@ def test_available_tests_group_by_cluster( ) -> None: """Test --group-by-cluster flag groups tests by cluster.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -401,7 +397,7 @@ def test_available_tests_cluster_filter( ) -> None: """Test --cluster filter shows only tests from specified cluster.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -425,7 +421,7 @@ def test_available_tests_cluster_filter_case_insensitive( ) -> None: """Test --cluster filter is case insensitive.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -447,7 +443,7 @@ def test_available_tests_cluster_and_compact_combined( ) -> None: """Test combining --cluster and --compact flags.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -496,7 +492,7 @@ def test_generate_compact( from th_cli.commands.available_tests import _extract_test_cases, _generate_compact # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -526,7 +522,7 @@ def test_generate_grouped_by_cluster( from th_cli.commands.available_tests import _extract_test_cases, _generate_grouped_by_cluster # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -558,7 +554,7 @@ def test_available_tests_compact_four_per_line( ) -> None: """Test --compact flag shows 4 elements per line.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -585,7 +581,7 @@ def test_available_tests_group_by_cluster_four_per_line( ) -> None: """Test --group-by-cluster flag shows 4 elements per line within clusters.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -610,7 +606,7 @@ def test_available_tests_with_pagination_mock( ) -> None: """Test available_tests command uses echo_via_pager.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -636,7 +632,7 @@ def test_available_tests_echo_via_pager_behavior( ) -> None: """Test that echo_via_pager is called for all custom formatting options.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): @@ -659,7 +655,7 @@ def test_available_tests_cluster_detailed_info( ) -> None: """Test --cluster flag shows detailed information.""" # Arrange - api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + api = mock_sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get api.return_value = sample_test_collections with patch("th_cli.commands.available_tests.SyncApis", return_value=mock_sync_apis): diff --git a/tests/test_project_commands.py b/tests/test_project_commands.py index 172bcf2..5db4f23 100644 --- a/tests/test_project_commands.py +++ b/tests/test_project_commands.py @@ -54,7 +54,7 @@ def test_create_project_success_with_default_config( } } mock_sync_apis.projects_api.default_config_api_v1_projects_default_config_get.return_value = default_config - mock_sync_apis.projects_api.create_project_api_v1_projects_post.return_value = sample_project + mock_sync_apis.projects_api.create_project_api_v1_projects__post.return_value = sample_project with patch("th_cli.commands.project.get_client", return_value=mock_api_client): with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): @@ -65,7 +65,7 @@ def test_create_project_success_with_default_config( assert result.exit_code == 0 assert "Project 'Test Project' created with ID 1" in result.output mock_sync_apis.projects_api.default_config_api_v1_projects_default_config_get.assert_called_once() - mock_sync_apis.projects_api.create_project_api_v1_projects_post.assert_called_once() + mock_sync_apis.projects_api.create_project_api_v1_projects__post.assert_called_once() mock_api_client.close.assert_called_once() def test_create_project_success_with_custom_config( @@ -90,7 +90,7 @@ def test_create_project_success_with_custom_config( } } mock_sync_apis.projects_api.default_config_api_v1_projects_default_config_get.return_value = default_config - mock_sync_apis.projects_api.create_project_api_v1_projects_post.return_value = sample_project + mock_sync_apis.projects_api.create_project_api_v1_projects__post.return_value = sample_project with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -189,11 +189,9 @@ def test_create_project_api_error( api_exception = UnexpectedResponse( status_code=400, - reason_phrase="Bad Request", content=b"Bad Request", - headers=Headers(), ) - mock_sync_apis.projects_api.create_project_api_v1_projects_post.side_effect = api_exception + mock_sync_apis.projects_api.create_project_api_v1_projects__post.side_effect = api_exception with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -227,7 +225,7 @@ def test_delete_project_success_with_yes_flag( ) -> None: """Test successful project deletion with --yes flag.""" # Arrange - mock_sync_apis.projects_api.delete_project_api_v1_projects_id_delete.return_value = None + mock_sync_apis.projects_api.delete_project_api_v1_projects__id__delete.return_value = None with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -236,7 +234,7 @@ def test_delete_project_success_with_yes_flag( # Assert assert result.exit_code == 0 assert "Project 1 was deleted." in result.output - mock_sync_apis.projects_api.delete_project_api_v1_projects_id_delete.assert_called_once_with(id=1) + mock_sync_apis.projects_api.delete_project_api_v1_projects__id__delete.assert_called_once_with(id=1) def test_delete_project_success_with_confirmation( self, @@ -245,7 +243,7 @@ def test_delete_project_success_with_confirmation( ) -> None: """Test successful project deletion with user confirmation.""" # Arrange - mock_sync_apis.projects_api.delete_project_api_v1_projects_id_delete.return_value = None + mock_sync_apis.projects_api.delete_project_api_v1_projects__id__delete.return_value = None with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -269,7 +267,7 @@ def test_delete_project_abort_on_no_confirmation( # Assert assert result.exit_code == 0 # Aborted assert "Operation cancelled." in result.output - mock_sync_apis.projects_api.delete_project_api_v1_projects_id_delete.assert_not_called() + mock_sync_apis.projects_api.delete_project_api_v1_projects__id__delete.assert_not_called() def test_delete_project_api_error( self, @@ -280,11 +278,9 @@ def test_delete_project_api_error( # Arrange api_exception = UnexpectedResponse( status_code=404, - reason_phrase="Not Found", content=b"Not Found", - headers=Headers(), ) - mock_sync_apis.projects_api.delete_project_api_v1_projects_id_delete.side_effect = api_exception + mock_sync_apis.projects_api.delete_project_api_v1_projects__id__delete.side_effect = api_exception with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -319,7 +315,7 @@ def test_list_projects_success_all_projects( ) -> None: """Test successful listing of all projects.""" # Arrange - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.return_value = sample_projects + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.return_value = sample_projects with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -342,7 +338,7 @@ def test_list_projects_success_specific_project( ) -> None: """Test successful listing of a specific project by ID.""" # Arrange - mock_sync_apis.projects_api.read_project_api_v1_projects_id_get.return_value = sample_project + mock_sync_apis.projects_api.read_project_api_v1_projects__id__get.return_value = sample_project with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -352,7 +348,7 @@ def test_list_projects_success_specific_project( assert result.exit_code == 0 assert str(sample_project.id) in result.output assert sample_project.name in result.output - mock_sync_apis.projects_api.read_project_api_v1_projects_id_get.assert_called_once_with(id=1) + mock_sync_apis.projects_api.read_project_api_v1_projects__id__get.assert_called_once_with(id=1) def test_list_projects_json_output( self, @@ -362,7 +358,7 @@ def test_list_projects_json_output( ) -> None: """Test listing projects with JSON output.""" # Arrange - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.return_value = sample_projects + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.return_value = sample_projects with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -382,7 +378,7 @@ def test_list_projects_with_pagination( ) -> None: """Test listing projects with pagination parameters.""" # Arrange - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.return_value = sample_projects[:2] + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.return_value = sample_projects[:2] with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -390,7 +386,7 @@ def test_list_projects_with_pagination( # Assert assert result.exit_code == 0 - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.assert_called_once_with( + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.assert_called_once_with( archived=False, skip=0, limit=2 ) @@ -402,7 +398,7 @@ def test_list_projects_archived( ) -> None: """Test listing archived projects.""" # Arrange - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.return_value = sample_projects + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.return_value = sample_projects with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -410,7 +406,7 @@ def test_list_projects_archived( # Assert assert result.exit_code == 0 - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.assert_called_once_with( + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.assert_called_once_with( archived=True, skip=None, limit=None ) @@ -421,7 +417,7 @@ def test_list_projects_no_projects_found( ) -> None: """Test listing projects when no projects are found.""" # Arrange - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.return_value = [] + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.return_value = [] with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -440,11 +436,9 @@ def test_list_projects_api_error( # Arrange api_exception = UnexpectedResponse( status_code=500, - reason_phrase="Internal Server Error", content=b"Internal Server Error", - headers=Headers(), ) - mock_sync_apis.projects_api.read_projects_api_v1_projects_get.side_effect = api_exception + mock_sync_apis.projects_api.read_projects_api_v1_projects__get.side_effect = api_exception with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -483,7 +477,8 @@ def test_update_project_success( ) -> None: """Test successful project update.""" # Arrange - mock_sync_apis.projects_api.update_project_api_v1_projects_id_put.return_value = sample_project + mock_sync_apis.projects_api.read_project_api_v1_projects__id__get.return_value = sample_project + mock_sync_apis.projects_api.update_project_api_v1_projects__id__put.return_value = sample_project with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act @@ -492,7 +487,7 @@ def test_update_project_success( # Assert assert result.exit_code == 0 assert "Project Test Project is updated with the new config." in result.output - mock_sync_apis.projects_api.update_project_api_v1_projects_id_put.assert_called_once() + mock_sync_apis.projects_api.update_project_api_v1_projects__id__put.assert_called_once() def test_update_project_config_file_not_found( self, @@ -532,17 +527,17 @@ def test_update_project_api_error( self, cli_runner: CliRunner, mock_sync_apis: Mock, - mock_config: Path + mock_config: Path, + sample_project: api_models.Project ) -> None: """Test project update with API error.""" # Arrange api_exception = UnexpectedResponse( status_code=404, - reason_phrase="Not Found", content=b"Not Found", - headers=Headers(), ) - mock_sync_apis.projects_api.update_project_api_v1_projects_id_put.side_effect = api_exception + mock_sync_apis.projects_api.read_project_api_v1_projects__id__get.return_value = sample_project + mock_sync_apis.projects_api.update_project_api_v1_projects__id__put.side_effect = api_exception with patch("th_cli.commands.project.SyncApis", return_value=mock_sync_apis): # Act diff --git a/tests/test_run_tests.py b/tests/test_run_tests.py index 2115e69..6669e39 100644 --- a/tests/test_run_tests.py +++ b/tests/test_run_tests.py @@ -45,7 +45,7 @@ def test_run_tests_success_minimal_args( """Test successful test run with minimal arguments.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -92,7 +92,7 @@ def test_run_tests_success_with_custom_config( """Test successful test run with custom JSON configuration file.""" # Arrange projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -138,7 +138,7 @@ def test_run_tests_success_with_pics_config( """Test successful test run with PICS configuration.""" # Arrange projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -185,7 +185,7 @@ def test_run_tests_success_with_project_id( """Test successful test run with project ID.""" # Arrange projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -224,7 +224,7 @@ def test_run_tests_success_with_no_color( """Test successful test run with colors disabled.""" # Arrange projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -354,7 +354,7 @@ def test_run_tests_api_error_getting_test_collections( # Arrange projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get projects_api.return_value = sample_default_config_dict - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_collections_api.side_effect = Exception("Collections API error") with patch("th_cli.commands.run_tests.AsyncApis", return_value=mock_async_apis): @@ -382,13 +382,11 @@ def test_run_tests_api_error_creating_test_run( # Arrange api_exception = UnexpectedResponse( status_code=400, - reason_phrase="Bad Request", content=b"Bad Request", - headers=Headers(), ) projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post @@ -421,16 +419,14 @@ def test_run_tests_api_error_starting_test_run( # Arrange api_exception = UnexpectedResponse( status_code=500, - reason_phrase="Internal Server Error", content=b"Internal Server Error", - headers=Headers(), ) projects_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collections_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post - start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post + start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions__id__start_post test_collections_api.return_value = sample_test_collections projects_api.return_value = sample_default_config_dict @@ -500,7 +496,7 @@ def test_run_tests_various_test_lists( """Test run tests with various test list formats.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post start_api = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -538,7 +534,7 @@ def test_run_tests_test_selection_building( """Test that test selection is properly built from test collections.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -582,7 +578,7 @@ def test_run_tests_logger_configuration( """Test that logger is properly configured for the test run.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -623,7 +619,7 @@ def test_run_tests_default_title_generation( """Test that default title is generated when not provided.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -672,7 +668,7 @@ def test_run_tests_config_data_processing( """Test that JSON configuration data is properly processed and displayed.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -870,7 +866,7 @@ def test_run_tests_with_extra_args_basic( """Test run tests with basic extra arguments.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -912,7 +908,7 @@ def test_run_tests_with_multiple_extra_args( """Test run tests with multiple extra arguments.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -958,7 +954,7 @@ def test_run_tests_without_extra_args( """Test run tests without extra arguments (normal behavior).""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -1000,7 +996,7 @@ def test_run_tests_extra_args_with_config_file( """Test run tests with both config file and extra arguments.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post @@ -1043,7 +1039,7 @@ def test_run_tests_verify_deep_copy_isolation( """Test that test_run_config uses deepcopy for isolation.""" # Arrange project_api = mock_async_apis.projects_api.default_config_api_v1_projects_default_config_get - test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections_get + test_collection_api = mock_async_apis.test_collections_api.read_test_collections_api_v1_test_collections__get test_run_executions_api = mock_async_apis.test_run_executions_api cli_api = test_run_executions_api.create_cli_test_run_execution_api_v1_test_run_executions_cli_post id_start = test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post diff --git a/tests/test_test_run_execution.py b/tests/test_test_run_execution.py index ca4e5f6..3f1abbd 100644 --- a/tests/test_test_run_execution.py +++ b/tests/test_test_run_execution.py @@ -44,17 +44,17 @@ def test_test_run_execution_success_all( api_models.TestRunExecution( id=1, title="Test Run 1", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=2, title="Test Run 2", - state=api_models.TestStateEnum.FAILED, + state=api_models.TestStateEnum.failed, project_id=1, ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -83,10 +83,10 @@ def test_test_run_execution_success_specific_id( test_execution = api_models.TestRunExecution( id=1, title="Specific Test Run", - state=api_models.TestStateEnum.EXECUTING, + state=api_models.TestStateEnum.executing, project_id=1 ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.return_value = test_execution with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -110,11 +110,11 @@ def test_test_run_execution_success_with_pagination( api_models.TestRunExecution( id=3, title="Test Run 3", - state=api_models.TestStateEnum.PENDING, + state=api_models.TestStateEnum.pending, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -136,10 +136,10 @@ def test_test_run_execution_success_json_output( test_execution = api_models.TestRunExecution( id=1, title="JSON Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.return_value = test_execution with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -177,11 +177,9 @@ def test_test_run_execution_api_error_by_id( # Arrange api_exception = UnexpectedResponse( status_code=404, - reason_phrase="Not Found", content=b"Not Found", - headers=Headers(), ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.side_effect = api_exception with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -203,11 +201,9 @@ def test_test_run_execution_api_error_batch( # Arrange api_exception = UnexpectedResponse( status_code=500, - reason_phrase="Internal Server Error", content=b"Internal Server Error", - headers=Headers(), ) - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.side_effect = api_exception with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -250,13 +246,13 @@ def test_test_run_execution_help_message(self, cli_runner: CliRunner) -> None: assert "--json" in result.output @pytest.mark.parametrize("state,expected_display", [ - (api_models.TestStateEnum.PENDING, "PENDING"), - (api_models.TestStateEnum.EXECUTING, "EXECUTING"), - (api_models.TestStateEnum.PASSED, "PASSED"), - (api_models.TestStateEnum.FAILED, "FAILED"), - (api_models.TestStateEnum.ERROR, "ERROR"), - (api_models.TestStateEnum.CANCELLED, "CANCELLED"), - (api_models.TestStateEnum.NOT_APPLICABLE, "NOT_APPLICABLE"), + (api_models.TestStateEnum.pending, "PENDING"), + (api_models.TestStateEnum.executing, "EXECUTING"), + (api_models.TestStateEnum.passed, "PASSED"), + (api_models.TestStateEnum.failed, "FAILED"), + (api_models.TestStateEnum.error, "ERROR"), + (api_models.TestStateEnum.cancelled, "CANCELLED"), + (api_models.TestStateEnum.not_applicable, "NOT_APPLICABLE"), ]) def test_test_run_execution_various_states( self, @@ -273,7 +269,7 @@ def test_test_run_execution_various_states( state=state, project_id=1 ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.return_value = test_execution with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -295,17 +291,17 @@ def test_test_run_execution_table_output_format( api_models.TestRunExecution( id=1, title="Long Test Run Title That Should Be Formatted Properly", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=2, title="Short Title", - state=api_models.TestStateEnum.FAILED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -343,11 +339,11 @@ def test_test_run_execution_pagination_parameters( api_models.TestRunExecution( id=1, title="Paginated Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -373,10 +369,10 @@ def test_test_run_execution_error_display( test_execution = api_models.TestRunExecution( id=1, title="Failed Test Run", - state=api_models.TestStateEnum.ERROR, + state=api_models.TestStateEnum.error, project_id=1 ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.return_value = test_execution with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -397,10 +393,10 @@ def test_test_run_execution_passed_state_display( test_execution = api_models.TestRunExecution( id=1, title="Successful Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) - api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions_id_get + api = mock_sync_apis.test_run_executions_api.read_test_run_execution_api_v1_test_run_executions__id__get api.return_value = test_execution with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -424,11 +420,11 @@ def test_test_run_execution_output_modes( api_models.TestRunExecution( id=1, title="Output Mode Test", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -465,7 +461,7 @@ def test_test_run_execution_log_success_with_content( 2025-01-01 10:00:11 [INFO] Test execution completed successfully """.strip() - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -486,7 +482,7 @@ def test_test_run_execution_log_success_no_content( ) -> None: """Test successful test run execution log retrieval with no log content.""" # Arrange - mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get.return_value = None + mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get.return_value = None with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): # Act @@ -503,7 +499,7 @@ def test_test_run_execution_log_success_empty_content( ) -> None: """Test successful test run execution log retrieval with empty log content.""" # Arrange - mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get.return_value = "" + mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get.return_value = "" with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): # Act @@ -534,11 +530,9 @@ def test_test_run_execution_log_api_error( # Arrange api_exception = UnexpectedResponse( status_code=404, - reason_phrase="Test run execution not found", content=b"Test run execution not found", - headers=Headers(), ) - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.side_effect = api_exception with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -578,7 +572,7 @@ def test_test_run_execution_log_multiline_content( - Failed: 0 """ - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -605,7 +599,7 @@ def test_test_run_execution_log_special_characters( XML-like content: TC-ACE-1.1 Escape sequences: \n\t\r""" - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -629,7 +623,7 @@ def test_test_run_execution_log_large_content( log_lines = [f"Log line {i}: Some test execution details" for i in range(1000)] log_content = "\n".join(log_lines) - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -653,7 +647,7 @@ def test_test_run_execution_log_various_ids( """Test test run execution log with various ID values.""" # Arrange log_content = f"Log for test run execution ID: {test_id}" - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -686,11 +680,9 @@ def test_test_run_execution_log_various_api_errors( # Arrange api_exception = UnexpectedResponse( status_code=status_code, - reason_phrase=content, content=content.encode('utf-8'), - headers=Headers(), ) - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.side_effect = api_exception with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -711,7 +703,7 @@ def test_test_run_execution_log_client_context_manager( """Test that client is properly managed using context manager.""" # Arrange log_content = "Test log content" - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -732,7 +724,7 @@ def test_test_run_execution_log_api_parameters( """Test that the correct API parameters are passed.""" # Arrange log_content = "Test log content" - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -754,7 +746,7 @@ def test_test_run_execution_log_whitespace_content( """Test test run execution log with whitespace-only content.""" # Arrange log_content = " \n\t \n " - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.return_value = log_content with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -773,7 +765,7 @@ def test_test_run_execution_log_generic_exception( ) -> None: """Test test run execution log with generic exception.""" # Arrange - api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions_id_log_get + api = mock_sync_apis.test_run_executions_api.download_log_api_v1_test_run_executions__id__log_get api.side_effect = Exception("Network timeout") with patch("th_cli.commands.test_run_execution.SyncApis", return_value=mock_sync_apis): @@ -796,17 +788,17 @@ def test_test_run_execution_sort_parameter_asc( api_models.TestRunExecution( id=1, title="Old Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=2, title="New Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -832,17 +824,17 @@ def test_test_run_execution_sort_parameter_desc_default( api_models.TestRunExecution( id=2, title="New Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=1, title="Old Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -869,17 +861,17 @@ def test_test_run_execution_sort_parameter_explicit_desc( api_models.TestRunExecution( id=2, title="New Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=1, title="Old Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -906,17 +898,17 @@ def test_test_run_execution_all_flag( api_models.TestRunExecution( id=1, title="Test Run 1", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=1 ), api_models.TestRunExecution( id=2, title="Test Run 2", - state=api_models.TestStateEnum.FAILED, + state=api_models.TestStateEnum.failed, project_id=1, ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -977,11 +969,11 @@ def test_test_run_execution_with_project_id( api_models.TestRunExecution( id=1, title="Project 5 Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=5 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -1007,11 +999,11 @@ def test_test_run_execution_with_project_id_short_form( api_models.TestRunExecution( id=1, title="Project 10 Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=10 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -1037,11 +1029,11 @@ def test_test_run_execution_with_project_id_and_pagination( api_models.TestRunExecution( id=3, title="Filtered Paginated Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=7 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): @@ -1067,11 +1059,11 @@ def test_test_run_execution_with_project_id_and_sort( api_models.TestRunExecution( id=1, title="Old Test Run", - state=api_models.TestStateEnum.PASSED, + state=api_models.TestStateEnum.passed, project_id=3 ) ] - api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions_get + api = mock_sync_apis.test_run_executions_api.read_test_run_executions_api_v1_test_run_executions__get api.return_value = test_executions with patch("th_cli.commands.test_run_execution.get_client", return_value=mock_api_client): diff --git a/tests/test_test_runner_status.py b/tests/test_test_runner_status.py index b6cd757..36b60d3 100644 --- a/tests/test_test_runner_status.py +++ b/tests/test_test_runner_status.py @@ -39,7 +39,7 @@ def test_test_runner_status_success_idle( """Test successful test runner status retrieval when idle.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.IDLE, + state=api_models.TestRunnerState.idle, test_run_execution_id=None ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -66,7 +66,7 @@ def test_test_runner_status_success_running( """Test successful test runner status retrieval when running.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.RUNNING, + state=api_models.TestRunnerState.running, test_run_execution_id=123 ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -91,7 +91,7 @@ def test_test_runner_status_success_json_output( """Test successful test runner status retrieval with JSON output.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.READY, + state=api_models.TestRunnerState.ready, test_run_execution_id=None ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -168,10 +168,10 @@ def test_test_runner_status_help_message(self, cli_runner: CliRunner) -> None: assert "Print JSON response for more details" in result.output @pytest.mark.parametrize("state,execution_id,expected_state", [ - (api_models.TestRunnerState.IDLE, None, "IDLE"), - (api_models.TestRunnerState.LOADING, None, "LOADING"), - (api_models.TestRunnerState.READY, None, "READY"), - (api_models.TestRunnerState.RUNNING, 456, "RUNNING"), + (api_models.TestRunnerState.idle, None, "IDLE"), + (api_models.TestRunnerState.loading, None, "LOADING"), + (api_models.TestRunnerState.ready, None, "READY"), + (api_models.TestRunnerState.running, 456, "RUNNING"), ]) def test_test_runner_status_various_states( self, @@ -210,7 +210,7 @@ def test_test_runner_status_output_format_consistency( """Test that output format is consistent and well-formatted.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.RUNNING, + state=api_models.TestRunnerState.running, test_run_execution_id=789 ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -240,7 +240,7 @@ def test_test_runner_status_output_modes( """Test test runner status with both table and JSON output modes.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.IDLE, + state=api_models.TestRunnerState.idle, test_run_execution_id=None ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -272,7 +272,7 @@ def test_test_runner_status_state_display_formatting( """Test that state is properly formatted with colorization.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.RUNNING, + state=api_models.TestRunnerState.running, test_run_execution_id=999 ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get @@ -296,7 +296,7 @@ def test_test_runner_status_no_active_test_run_message( """Test the 'No active test run' message is displayed correctly.""" # Arrange status = api_models.TestRunnerStatus( - state=api_models.TestRunnerState.READY, + state=api_models.TestRunnerState.ready, test_run_execution_id=None ) api = mock_sync_apis.test_run_executions_api.get_test_runner_status_api_v1_test_run_executions_status_get diff --git a/th_cli/api_lib_autogen/__init__.py b/th_cli/api_lib_autogen/__init__.py index 8886ce2..b63d77d 100644 --- a/th_cli/api_lib_autogen/__init__.py +++ b/th_cli/api_lib_autogen/__init__.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,15 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import inspect +"""Auto-generated API client for Test Harness.""" -from pydantic import BaseModel +from th_cli.api_lib_autogen.api_client import ApiClient, AsyncApis, SyncApis +from th_cli.api_lib_autogen.exceptions import ApiException, ResponseHandlingException, UnexpectedResponse -from th_cli.api_lib_autogen import models -from th_cli.api_lib_autogen.api_client import ApiClient, AsyncApis, SyncApis # noqa F401 - -for model in inspect.getmembers(models, inspect.isclass): - if model[1].__module__ == "th_cli.api_lib_autogen.models": - model_class = model[1] - if issubclass(model_class, BaseModel): - model_class.update_forward_refs() +__all__ = [ + "ApiClient", + "AsyncApis", + "SyncApis", + "ApiException", + "ResponseHandlingException", + "UnexpectedResponse", +] diff --git a/th_cli/api_lib_autogen/api/__init__.py b/th_cli/api_lib_autogen/api/__init__.py index e69de29..a9a086a 100644 --- a/th_cli/api_lib_autogen/api/__init__.py +++ b/th_cli/api_lib_autogen/api/__init__.py @@ -0,0 +1,52 @@ +# +# Copyright (c) 2026 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""API endpoint classes.""" + +from th_cli.api_lib_autogen.api.test_collections_api import AsyncTestCollectionsApi, SyncTestCollectionsApi +from th_cli.api_lib_autogen.api.projects_api import AsyncProjectsApi, SyncProjectsApi +from th_cli.api_lib_autogen.api.operators_api import AsyncOperatorsApi, SyncOperatorsApi +from th_cli.api_lib_autogen.api.test_run_executions_api import AsyncTestRunExecutionsApi, SyncTestRunExecutionsApi +from th_cli.api_lib_autogen.api.test_run_configs_api import AsyncTestRunConfigsApi, SyncTestRunConfigsApi +from th_cli.api_lib_autogen.api.version_api import AsyncVersionApi, SyncVersionApi +from th_cli.api_lib_autogen.api.utils_api import AsyncUtilsApi, SyncUtilsApi +from th_cli.api_lib_autogen.api.devices_api import AsyncDevicesApi, SyncDevicesApi + +__all__ = [ + "TestCollectionsApi", + "AsyncTestCollectionsApi", + "SyncTestCollectionsApi", + "ProjectsApi", + "AsyncProjectsApi", + "SyncProjectsApi", + "OperatorsApi", + "AsyncOperatorsApi", + "SyncOperatorsApi", + "TestRunExecutionsApi", + "AsyncTestRunExecutionsApi", + "SyncTestRunExecutionsApi", + "TestRunConfigsApi", + "AsyncTestRunConfigsApi", + "SyncTestRunConfigsApi", + "VersionApi", + "AsyncVersionApi", + "SyncVersionApi", + "UtilsApi", + "AsyncUtilsApi", + "SyncUtilsApi", + "DevicesApi", + "AsyncDevicesApi", + "SyncDevicesApi", +] diff --git a/th_cli/api_lib_autogen/api/devices_api.py b/th_cli/api_lib_autogen/api/devices_api.py index 590f83b..fac88fc 100644 --- a/th_cli/api_lib_autogen/api/devices_api.py +++ b/th_cli/api_lib_autogen/api/devices_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Any, Awaitable - -from fastapi.encoders import jsonable_encoder +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -29,32 +27,48 @@ class _DevicesApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_add_device_config_api_v1_devices_put(self, body: Any) -> Awaitable[m.Any]: - body = jsonable_encoder(body) + def _build_for_get_device_configs_api_v1_devices__get(self) -> Coroutine[Any, Any, dict[str, Any]]: + """ + Get Device Configs + """ + return self.api_client.request(type_=dict[str, Any], method="GET", url="/api/v1/devices/") - return self.api_client.request(type_=m.Any, method="PUT", url="/api/v1/devices/", json=body) + def _build_for_add_device_config_api_v1_devices__put( + self, body: dict[str, Any] + ) -> Coroutine[Any, Any, dict[str, Any]]: + """ + Add Device Config + """ + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body - def _build_for_get_device_configs_api_v1_devices_get(self) -> Awaitable[m.Any]: - return self.api_client.request( - type_=m.Any, - method="GET", - url="/api/v1/devices/", - ) + return self.api_client.request(type_=dict[str, Any], method="PUT", url="/api/v1/devices/", json=json_body) class AsyncDevicesApi(_DevicesApi): - async def add_device_config_api_v1_devices_put(self, body: Any) -> m.Any: - return await self._build_for_add_device_config_api_v1_devices_put(body=body) + async def get_device_configs_api_v1_devices__get(self) -> dict[str, Any]: + """ + Get Device Configs + """ + return await self._build_for_get_device_configs_api_v1_devices__get() - async def get_device_configs_api_v1_devices_get(self) -> m.Any: - return await self._build_for_get_device_configs_api_v1_devices_get() + async def add_device_config_api_v1_devices__put(self, body: dict[str, Any]) -> dict[str, Any]: + """ + Add Device Config + """ + return await self._build_for_add_device_config_api_v1_devices__put(body=body) class SyncDevicesApi(_DevicesApi): - def add_device_config_api_v1_devices_put(self, body: Any) -> m.Any: - coroutine = self._build_for_add_device_config_api_v1_devices_put(body=body) + def get_device_configs_api_v1_devices__get(self) -> dict[str, Any]: + """ + Get Device Configs + """ + coroutine = self._build_for_get_device_configs_api_v1_devices__get() return get_event_loop().run_until_complete(coroutine) - def get_device_configs_api_v1_devices_get(self) -> m.Any: - coroutine = self._build_for_get_device_configs_api_v1_devices_get() + def add_device_config_api_v1_devices__put(self, body: dict[str, Any]) -> dict[str, Any]: + """ + Add Device Config + """ + coroutine = self._build_for_add_device_config_api_v1_devices__put(body=body) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/operators_api.py b/th_cli/api_lib_autogen/api/operators_api.py index 60d14fa..5ed9bee 100644 --- a/th_cli/api_lib_autogen/api/operators_api.py +++ b/th_cli/api_lib_autogen/api/operators_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable, List, Optional - -from fastapi.encoders import jsonable_encoder +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -29,144 +27,135 @@ class _OperatorsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_create_operator_api_v1_operators_post( - self, operator_create: m.OperatorCreate - ) -> Awaitable[m.Operator]: + def _build_for_read_operators_api_v1_operators__get( + self, skip: int | None = None, limit: int | None = None + ) -> Coroutine[Any, Any, list[m.Operator]]: """ - Create new operator. Args: operator_in (OperatorCreate): Parameters for new operator. Returns: Operator: newly created operator record + Read Operators """ - body = jsonable_encoder(operator_create) + query_params = {} + if skip is not None: + query_params["skip"] = str(skip) + if limit is not None: + query_params["limit"] = str(limit) - return self.api_client.request(type_=m.Operator, method="POST", url="/api/v1/operators/", json=body) + return self.api_client.request( + type_=list[m.Operator], method="GET", url="/api/v1/operators/", params=query_params + ) - def _build_for_delete_operator_api_v1_operators_id_delete(self, id: int) -> Awaitable[m.Operator]: + def _build_for_create_operator_api_v1_operators__post( + self, body: m.OperatorCreate + ) -> Coroutine[Any, Any, m.Operator]: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record that was deleted + Create Operator """ - path_params = {"id": str(id)} + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body - return self.api_client.request( - type_=m.Operator, - method="DELETE", - url="/api/v1/operators/{id}", - path_params=path_params, - ) + return self.api_client.request(type_=m.Operator, method="POST", url="/api/v1/operators/", json=json_body) - def _build_for_read_operator_api_v1_operators_id_get(self, id: int) -> Awaitable[m.Operator]: + def _build_for_read_operator_api_v1_operators__id__get(self, id: int) -> Coroutine[Any, Any, m.Operator]: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record + Read Operator """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.Operator, - method="GET", - url="/api/v1/operators/{id}", - path_params=path_params, + type_=m.Operator, method="GET", url="/api/v1/operators/{id}", path_params=path_params ) - def _build_for_read_operators_api_v1_operators_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> Awaitable[List[m.Operator]]: + def _build_for_update_operator_api_v1_operators__id__put( + self, body: m.OperatorUpdate, id: int + ) -> Coroutine[Any, Any, m.Operator]: """ - Retrive list of operators. Args: skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Operator]: List of operators + Update Operator """ - query_params = {} - if skip is not None: - query_params["skip"] = str(skip) - if limit is not None: - query_params["limit"] = str(limit) + path_params = {"id": str(id)} + + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body return self.api_client.request( - type_=List[m.Operator], - method="GET", - url="/api/v1/operators/", - params=query_params, + type_=m.Operator, method="PUT", url="/api/v1/operators/{id}", path_params=path_params, json=json_body ) - def _build_for_update_operator_api_v1_operators_id_put( - self, id: int, operator_update: m.OperatorUpdate - ) -> Awaitable[m.Operator]: + def _build_for_delete_operator_api_v1_operators__id__delete(self, id: int) -> Coroutine[Any, Any, m.Operator]: """ - Update an existing operator. Args: id (int): operator id operator_in (schemas.OperatorUpdate): operators parameters to be updated Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: updated operator record + Delete Operator """ path_params = {"id": str(id)} - body = jsonable_encoder(operator_update) - return self.api_client.request( - type_=m.Operator, method="PUT", url="/api/v1/operators/{id}", path_params=path_params, json=body + type_=m.Operator, method="DELETE", url="/api/v1/operators/{id}", path_params=path_params ) class AsyncOperatorsApi(_OperatorsApi): - async def create_operator_api_v1_operators_post(self, operator_create: m.OperatorCreate) -> m.Operator: + async def read_operators_api_v1_operators__get( + self, skip: int | None = None, limit: int | None = None + ) -> list[m.Operator]: """ - Create new operator. Args: operator_in (OperatorCreate): Parameters for new operator. Returns: Operator: newly created operator record + Read Operators """ - return await self._build_for_create_operator_api_v1_operators_post(operator_create=operator_create) + return await self._build_for_read_operators_api_v1_operators__get(skip=skip, limit=limit) - async def delete_operator_api_v1_operators_id_delete(self, id: int) -> m.Operator: + async def create_operator_api_v1_operators__post(self, body: m.OperatorCreate) -> m.Operator: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record that was deleted + Create Operator """ - return await self._build_for_delete_operator_api_v1_operators_id_delete(id=id) + return await self._build_for_create_operator_api_v1_operators__post(body=body) - async def read_operator_api_v1_operators_id_get(self, id: int) -> m.Operator: + async def read_operator_api_v1_operators__id__get(self, id: int) -> m.Operator: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record + Read Operator """ - return await self._build_for_read_operator_api_v1_operators_id_get(id=id) + return await self._build_for_read_operator_api_v1_operators__id__get(id=id) - async def read_operators_api_v1_operators_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.Operator]: + async def update_operator_api_v1_operators__id__put(self, body: m.OperatorUpdate, id: int) -> m.Operator: """ - Retrive list of operators. Args: skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Operator]: List of operators + Update Operator """ - return await self._build_for_read_operators_api_v1_operators_get(skip=skip, limit=limit) + return await self._build_for_update_operator_api_v1_operators__id__put(body=body, id=id) - async def update_operator_api_v1_operators_id_put(self, id: int, operator_update: m.OperatorUpdate) -> m.Operator: + async def delete_operator_api_v1_operators__id__delete(self, id: int) -> m.Operator: """ - Update an existing operator. Args: id (int): operator id operator_in (schemas.OperatorUpdate): operators parameters to be updated Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: updated operator record + Delete Operator """ - return await self._build_for_update_operator_api_v1_operators_id_put(id=id, operator_update=operator_update) + return await self._build_for_delete_operator_api_v1_operators__id__delete(id=id) class SyncOperatorsApi(_OperatorsApi): - def create_operator_api_v1_operators_post(self, operator_create: m.OperatorCreate) -> m.Operator: + def read_operators_api_v1_operators__get( + self, skip: int | None = None, limit: int | None = None + ) -> list[m.Operator]: """ - Create new operator. Args: operator_in (OperatorCreate): Parameters for new operator. Returns: Operator: newly created operator record + Read Operators """ - coroutine = self._build_for_create_operator_api_v1_operators_post(operator_create=operator_create) + coroutine = self._build_for_read_operators_api_v1_operators__get(skip=skip, limit=limit) return get_event_loop().run_until_complete(coroutine) - def delete_operator_api_v1_operators_id_delete(self, id: int) -> m.Operator: + def create_operator_api_v1_operators__post(self, body: m.OperatorCreate) -> m.Operator: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record that was deleted + Create Operator """ - coroutine = self._build_for_delete_operator_api_v1_operators_id_delete(id=id) + coroutine = self._build_for_create_operator_api_v1_operators__post(body=body) return get_event_loop().run_until_complete(coroutine) - def read_operator_api_v1_operators_id_get(self, id: int) -> m.Operator: + def read_operator_api_v1_operators__id__get(self, id: int) -> m.Operator: """ - Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record + Read Operator """ - coroutine = self._build_for_read_operator_api_v1_operators_id_get(id=id) + coroutine = self._build_for_read_operator_api_v1_operators__id__get(id=id) return get_event_loop().run_until_complete(coroutine) - def read_operators_api_v1_operators_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.Operator]: + def update_operator_api_v1_operators__id__put(self, body: m.OperatorUpdate, id: int) -> m.Operator: """ - Retrive list of operators. Args: skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Operator]: List of operators + Update Operator """ - coroutine = self._build_for_read_operators_api_v1_operators_get(skip=skip, limit=limit) + coroutine = self._build_for_update_operator_api_v1_operators__id__put(body=body, id=id) return get_event_loop().run_until_complete(coroutine) - def update_operator_api_v1_operators_id_put(self, id: int, operator_update: m.OperatorUpdate) -> m.Operator: + def delete_operator_api_v1_operators__id__delete(self, id: int) -> m.Operator: """ - Update an existing operator. Args: id (int): operator id operator_in (schemas.OperatorUpdate): operators parameters to be updated Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: updated operator record + Delete Operator """ - coroutine = self._build_for_update_operator_api_v1_operators_id_put(id=id, operator_update=operator_update) + coroutine = self._build_for_delete_operator_api_v1_operators__id__delete(id=id) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/projects_api.py b/th_cli/api_lib_autogen/api/projects_api.py index cee0ab5..f790fb3 100644 --- a/th_cli/api_lib_autogen/api/projects_api.py +++ b/th_cli/api_lib_autogen/api/projects_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import IO, TYPE_CHECKING, Any, Awaitable, Dict, List, Optional - -from fastapi.encoders import jsonable_encoder +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -29,131 +27,120 @@ class _ProjectsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_applicable_test_cases_api_v1_projects_id_applicable_test_cases_get( - self, id: int - ) -> Awaitable[m.PICSApplicableTestCases]: + def _build_for_read_projects_api_v1_projects__get( + self, archived: bool | None = None, skip: int | None = None, limit: int | None = None + ) -> Coroutine[Any, Any, list[m.Project]]: """ - Retrieve list of applicable test cases based on project identifier. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: PICSApplicableTestCases: List of applicable test cases + Read Projects """ - path_params = {"id": str(id)} + query_params = {} + if archived is not None: + query_params["archived"] = str(archived) + if skip is not None: + query_params["skip"] = str(skip) + if limit is not None: + query_params["limit"] = str(limit) return self.api_client.request( - type_=m.PICSApplicableTestCases, - method="GET", - url="/api/v1/projects/{id}/applicable_test_cases", - path_params=path_params, + type_=list[m.Project], method="GET", url="/api/v1/projects/", params=query_params ) - def _build_for_archive_project_api_v1_projects_id_archive_post(self, id: int) -> Awaitable[m.Project]: + def _build_for_create_project_api_v1_projects__post(self, body: m.ProjectCreate) -> Coroutine[Any, Any, m.Project]: """ - Archive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was archived + Create Project """ - path_params = {"id": str(id)} + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body - return self.api_client.request( - type_=m.Project, - method="POST", - url="/api/v1/projects/{id}/archive", - path_params=path_params, - ) + return self.api_client.request(type_=m.Project, method="POST", url="/api/v1/projects/", json=json_body) - def _build_for_create_project_api_v1_projects_post(self, project_create: m.ProjectCreate) -> Awaitable[m.Project]: + def _build_for_default_config_api_v1_projects_default_config_get(self) -> Coroutine[Any, Any, dict[str, Any]]: """ - Create new project Args: project_in (ProjectCreate): Parameters for new project, see schema for details Returns: Project: newly created project record + Default Config """ - body = jsonable_encoder(project_create) + return self.api_client.request(type_=dict[str, Any], method="GET", url="/api/v1/projects/default_config") - return self.api_client.request(type_=m.Project, method="POST", url="/api/v1/projects/", json=body) - - def _build_for_default_config_api_v1_projects_default_config_get( - self, - ) -> Awaitable[m.ResponseDefaultConfigApiV1ProjectsDefaultConfigGet]: + def _build_for_read_project_api_v1_projects__id__get(self, id: int) -> Coroutine[Any, Any, m.Project]: """ - Return default configuration for projects. Returns: List[Project]: List of projects + Read Project """ + path_params = {"id": str(id)} + return self.api_client.request( - type_=m.ResponseDefaultConfigApiV1ProjectsDefaultConfigGet, - method="GET", - url="/api/v1/projects/default_config", + type_=m.Project, method="GET", url="/api/v1/projects/{id}", path_params=path_params ) - def _build_for_delete_project_api_v1_projects_id_delete(self, id: int) -> Awaitable[m.Project]: + def _build_for_update_project_api_v1_projects__id__put( + self, body: m.ProjectUpdate, id: int + ) -> Coroutine[Any, Any, m.Project]: """ - Delete project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was deleted + Update Project """ path_params = {"id": str(id)} + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body + return self.api_client.request( - type_=m.Project, - method="DELETE", - url="/api/v1/projects/{id}", - path_params=path_params, + type_=m.Project, method="PUT", url="/api/v1/projects/{id}", path_params=path_params, json=json_body ) - def _build_for_export_project_config_api_v1_projects_id_export_get(self, id: int) -> Awaitable[m.ProjectCreate]: + def _build_for_delete_project_api_v1_projects__id__delete(self, id: int) -> Coroutine[Any, Any, m.Project]: """ - Exports the project config by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: JSONResponse: json representation of the project with the informed project id + Delete Project """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.ProjectCreate, - method="GET", - url="/api/v1/projects/{id}/export", - path_params=path_params, + type_=m.Project, method="DELETE", url="/api/v1/projects/{id}", path_params=path_params ) - def _build_for_importproject_config_api_v1_projects_import_post(self, import_file: IO[Any]) -> Awaitable[m.Project]: + def _build_for_archive_project_api_v1_projects__id__archive_post(self, id: int) -> Coroutine[Any, Any, m.Project]: """ - Imports the project config Args: import_file : The project config file to be imported Raises: ValidationError: if the imported project config contains invalid information Returns: Project: newly created project record + Archive Project """ - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - files["import_file"] = import_file + path_params = {"id": str(id)} return self.api_client.request( - type_=m.Project, method="POST", url="/api/v1/projects/import", data=data, files=files + type_=m.Project, method="POST", url="/api/v1/projects/{id}/archive", path_params=path_params ) - def _build_for_read_project_api_v1_projects_id_get(self, id: int) -> Awaitable[m.Project]: + def _build_for_unarchive_project_api_v1_projects__id__unarchive_post( + self, id: int + ) -> Coroutine[Any, Any, m.Project]: """ - Lookup project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record + Unarchive Project """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.Project, - method="GET", - url="/api/v1/projects/{id}", - path_params=path_params, + type_=m.Project, method="POST", url="/api/v1/projects/{id}/unarchive", path_params=path_params ) - def _build_for_read_projects_api_v1_projects_get( - self, archived: Optional[bool] = None, skip: Optional[int] = None, limit: Optional[int] = None - ) -> Awaitable[List[m.Project]]: + def _build_for_upload_pics_api_v1_projects__id__upload_pics_put( + self, body: m.BodyUploadPicsApiV1ProjectsIdUploadPicsPut, id: int + ) -> Coroutine[Any, Any, m.Project]: """ - Retrieve list of projects Args: archived (bool, optional): Get archived projects, when true will; get archived projects only, when false only non-archived projects are returned. Defaults to false. skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Project]: List of projects + Upload Pics """ - query_params = {} - if archived is not None: - query_params["archived"] = str(archived) - if skip is not None: - query_params["skip"] = str(skip) - if limit is not None: - query_params["limit"] = str(limit) + path_params = {"id": str(id)} + + files: dict[str, IO[Any]] = {} + data: dict[str, Any] = {} + # TODO: Parse body for files and data return self.api_client.request( - type_=List[m.Project], - method="GET", - url="/api/v1/projects/", - params=query_params, + type_=m.Project, + method="PUT", + url="/api/v1/projects/{id}/upload_pics", + path_params=path_params, + data=data, + files=files, ) - def _build_for_remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete( + def _build_for_remove_pics_cluster_type_api_v1_projects__id__pics_cluster_type_delete( self, id: int, cluster_name: str - ) -> Awaitable[m.Project]: + ) -> Coroutine[Any, Any, m.Project]: """ - Removes cluster based on given cluster name Args: id (int): ID of Project cluster_name (str): Name of the cluster to delete Raises: HTTPException: if no project exists for provided project id Returns: models.Project: Project with updated PICS entry + Remove Pics Cluster Type """ path_params = {"id": str(id)} @@ -167,237 +154,240 @@ def _build_for_remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_del params=query_params, ) - def _build_for_unarchive_project_api_v1_projects_id_unarchive_post(self, id: int) -> Awaitable[m.Project]: + def _build_for_applicable_test_cases_api_v1_projects__id__applicable_test_cases_get( + self, id: int + ) -> Coroutine[Any, Any, m.PICSApplicableTestCases]: """ - Unarchive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was unarchived + Applicable Test Cases """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.Project, - method="POST", - url="/api/v1/projects/{id}/unarchive", + type_=m.PICSApplicableTestCases, + method="GET", + url="/api/v1/projects/{id}/applicable_test_cases", path_params=path_params, ) - def _build_for_update_project_api_v1_projects_id_put( - self, id: int, project_update: m.ProjectUpdate - ) -> Awaitable[m.Project]: + def _build_for_export_project_config_api_v1_projects__id__export_get( + self, id: int + ) -> Coroutine[Any, Any, m.ProjectCreate]: """ - Update an existing project Args: id (int): project id project_in (schemas.ProjectUpdate): projects parameters to be updated Raises: HTTPException: if no project exists for provided project id Returns: Project: updated project record + Export Project Config """ path_params = {"id": str(id)} - body = jsonable_encoder(project_update) - return self.api_client.request( - type_=m.Project, method="PUT", url="/api/v1/projects/{id}", path_params=path_params, json=body + type_=m.ProjectCreate, method="GET", url="/api/v1/projects/{id}/export", path_params=path_params ) - def _build_for_upload_pics_api_v1_projects_id_upload_pics_put(self, id: int, file: IO[Any]) -> Awaitable[m.Project]: + def _build_for_importproject_config_api_v1_projects_import_post( + self, body: m.BodyImportprojectConfigApiV1ProjectsImportPost + ) -> Coroutine[Any, Any, m.Project]: """ - Upload PICS or dmp-test-skip.xml file of a project based on project identifier. Args: id (int): project id file : the PICS or dmp-test-skip.xml file to upload Raises: HTTPException: if no project exists for provided project id (or) if the PICS file is invalid Returns: Project: project record that was updated with the PICS and dmp_test_skip information. + Importproject Config """ - path_params = {"id": str(id)} - - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - files["file"] = file + files: dict[str, IO[Any]] = {} + data: dict[str, Any] = {} + # TODO: Parse body for files and data return self.api_client.request( - type_=m.Project, - method="PUT", - url="/api/v1/projects/{id}/upload_pics", - path_params=path_params, - data=data, - files=files, + type_=m.Project, method="POST", url="/api/v1/projects/import", data=data, files=files ) class AsyncProjectsApi(_ProjectsApi): - async def applicable_test_cases_api_v1_projects_id_applicable_test_cases_get( - self, id: int - ) -> m.PICSApplicableTestCases: + async def read_projects_api_v1_projects__get( + self, archived: bool | None = None, skip: int | None = None, limit: int | None = None + ) -> list[m.Project]: """ - Retrieve list of applicable test cases based on project identifier. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: PICSApplicableTestCases: List of applicable test cases + Read Projects """ - return await self._build_for_applicable_test_cases_api_v1_projects_id_applicable_test_cases_get(id=id) + return await self._build_for_read_projects_api_v1_projects__get(archived=archived, skip=skip, limit=limit) - async def archive_project_api_v1_projects_id_archive_post(self, id: int) -> m.Project: + async def create_project_api_v1_projects__post(self, body: m.ProjectCreate) -> m.Project: """ - Archive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was archived + Create Project """ - return await self._build_for_archive_project_api_v1_projects_id_archive_post(id=id) + return await self._build_for_create_project_api_v1_projects__post(body=body) - async def create_project_api_v1_projects_post(self, project_create: m.ProjectCreate) -> m.Project: + async def default_config_api_v1_projects_default_config_get(self) -> dict[str, Any]: """ - Create new project Args: project_in (ProjectCreate): Parameters for new project, see schema for details Returns: Project: newly created project record + Default Config """ - return await self._build_for_create_project_api_v1_projects_post(project_create=project_create) + return await self._build_for_default_config_api_v1_projects_default_config_get() - async def default_config_api_v1_projects_default_config_get( - self, - ) -> m.ResponseDefaultConfigApiV1ProjectsDefaultConfigGet: + async def read_project_api_v1_projects__id__get(self, id: int) -> m.Project: """ - Return default configuration for projects. Returns: List[Project]: List of projects + Read Project """ - return await self._build_for_default_config_api_v1_projects_default_config_get() + return await self._build_for_read_project_api_v1_projects__id__get(id=id) - async def delete_project_api_v1_projects_id_delete(self, id: int) -> m.Project: + async def update_project_api_v1_projects__id__put(self, body: m.ProjectUpdate, id: int) -> m.Project: """ - Delete project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was deleted + Update Project """ - return await self._build_for_delete_project_api_v1_projects_id_delete(id=id) + return await self._build_for_update_project_api_v1_projects__id__put(body=body, id=id) - async def export_project_config_api_v1_projects_id_export_get(self, id: int) -> m.ProjectCreate: + async def delete_project_api_v1_projects__id__delete(self, id: int) -> m.Project: """ - Exports the project config by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: JSONResponse: json representation of the project with the informed project id + Delete Project """ - return await self._build_for_export_project_config_api_v1_projects_id_export_get(id=id) + return await self._build_for_delete_project_api_v1_projects__id__delete(id=id) - async def importproject_config_api_v1_projects_import_post(self, import_file: IO[Any]) -> m.Project: + async def archive_project_api_v1_projects__id__archive_post(self, id: int) -> m.Project: """ - Imports the project config Args: import_file : The project config file to be imported Raises: ValidationError: if the imported project config contains invalid information Returns: Project: newly created project record + Archive Project """ - return await self._build_for_importproject_config_api_v1_projects_import_post(import_file=import_file) + return await self._build_for_archive_project_api_v1_projects__id__archive_post(id=id) - async def read_project_api_v1_projects_id_get(self, id: int) -> m.Project: + async def unarchive_project_api_v1_projects__id__unarchive_post(self, id: int) -> m.Project: """ - Lookup project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record + Unarchive Project """ - return await self._build_for_read_project_api_v1_projects_id_get(id=id) + return await self._build_for_unarchive_project_api_v1_projects__id__unarchive_post(id=id) - async def read_projects_api_v1_projects_get( - self, archived: Optional[bool] = None, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.Project]: + async def upload_pics_api_v1_projects__id__upload_pics_put( + self, body: m.BodyUploadPicsApiV1ProjectsIdUploadPicsPut, id: int + ) -> m.Project: """ - Retrieve list of projects Args: archived (bool, optional): Get archived projects, when true will; get archived projects only, when false only non-archived projects are returned. Defaults to false. skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Project]: List of projects + Upload Pics """ - return await self._build_for_read_projects_api_v1_projects_get(archived=archived, skip=skip, limit=limit) + return await self._build_for_upload_pics_api_v1_projects__id__upload_pics_put(body=body, id=id) - async def remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete( + async def remove_pics_cluster_type_api_v1_projects__id__pics_cluster_type_delete( self, id: int, cluster_name: str ) -> m.Project: """ - Removes cluster based on given cluster name Args: id (int): ID of Project cluster_name (str): Name of the cluster to delete Raises: HTTPException: if no project exists for provided project id Returns: models.Project: Project with updated PICS entry + Remove Pics Cluster Type """ - return await self._build_for_remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete( + return await self._build_for_remove_pics_cluster_type_api_v1_projects__id__pics_cluster_type_delete( id=id, cluster_name=cluster_name ) - async def unarchive_project_api_v1_projects_id_unarchive_post(self, id: int) -> m.Project: + async def applicable_test_cases_api_v1_projects__id__applicable_test_cases_get( + self, id: int + ) -> m.PICSApplicableTestCases: """ - Unarchive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was unarchived + Applicable Test Cases """ - return await self._build_for_unarchive_project_api_v1_projects_id_unarchive_post(id=id) + return await self._build_for_applicable_test_cases_api_v1_projects__id__applicable_test_cases_get(id=id) - async def update_project_api_v1_projects_id_put(self, id: int, project_update: m.ProjectUpdate) -> m.Project: + async def export_project_config_api_v1_projects__id__export_get(self, id: int) -> m.ProjectCreate: """ - Update an existing project Args: id (int): project id project_in (schemas.ProjectUpdate): projects parameters to be updated Raises: HTTPException: if no project exists for provided project id Returns: Project: updated project record + Export Project Config """ - return await self._build_for_update_project_api_v1_projects_id_put(id=id, project_update=project_update) + return await self._build_for_export_project_config_api_v1_projects__id__export_get(id=id) - async def upload_pics_api_v1_projects_id_upload_pics_put(self, id: int, file: IO[Any]) -> m.Project: + async def importproject_config_api_v1_projects_import_post( + self, body: m.BodyImportprojectConfigApiV1ProjectsImportPost + ) -> m.Project: """ - Upload PICS or dmp-test-skip.xml file of a project based on project identifier. Args: id (int): project id file : the PICS or dmp-test-skip.xml file to upload Raises: HTTPException: if no project exists for provided project id (or) if the PICS file is invalid Returns: Project: project record that was updated with the PICS and dmp_test_skip information. + Importproject Config """ - return await self._build_for_upload_pics_api_v1_projects_id_upload_pics_put(id=id, file=file) + return await self._build_for_importproject_config_api_v1_projects_import_post(body=body) class SyncProjectsApi(_ProjectsApi): - def applicable_test_cases_api_v1_projects_id_applicable_test_cases_get(self, id: int) -> m.PICSApplicableTestCases: + def read_projects_api_v1_projects__get( + self, archived: bool | None = None, skip: int | None = None, limit: int | None = None + ) -> list[m.Project]: """ - Retrieve list of applicable test cases based on project identifier. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: PICSApplicableTestCases: List of applicable test cases + Read Projects """ - coroutine = self._build_for_applicable_test_cases_api_v1_projects_id_applicable_test_cases_get(id=id) + coroutine = self._build_for_read_projects_api_v1_projects__get(archived=archived, skip=skip, limit=limit) return get_event_loop().run_until_complete(coroutine) - def archive_project_api_v1_projects_id_archive_post(self, id: int) -> m.Project: + def create_project_api_v1_projects__post(self, body: m.ProjectCreate) -> m.Project: """ - Archive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was archived + Create Project """ - coroutine = self._build_for_archive_project_api_v1_projects_id_archive_post(id=id) + coroutine = self._build_for_create_project_api_v1_projects__post(body=body) return get_event_loop().run_until_complete(coroutine) - def create_project_api_v1_projects_post(self, project_create: m.ProjectCreate) -> m.Project: + def default_config_api_v1_projects_default_config_get(self) -> dict[str, Any]: """ - Create new project Args: project_in (ProjectCreate): Parameters for new project, see schema for details Returns: Project: newly created project record + Default Config """ - coroutine = self._build_for_create_project_api_v1_projects_post(project_create=project_create) + coroutine = self._build_for_default_config_api_v1_projects_default_config_get() return get_event_loop().run_until_complete(coroutine) - def default_config_api_v1_projects_default_config_get(self) -> m.ResponseDefaultConfigApiV1ProjectsDefaultConfigGet: + def read_project_api_v1_projects__id__get(self, id: int) -> m.Project: """ - Return default configuration for projects. Returns: List[Project]: List of projects + Read Project """ - coroutine = self._build_for_default_config_api_v1_projects_default_config_get() + coroutine = self._build_for_read_project_api_v1_projects__id__get(id=id) return get_event_loop().run_until_complete(coroutine) - def delete_project_api_v1_projects_id_delete(self, id: int) -> m.Project: + def update_project_api_v1_projects__id__put(self, body: m.ProjectUpdate, id: int) -> m.Project: """ - Delete project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was deleted + Update Project """ - coroutine = self._build_for_delete_project_api_v1_projects_id_delete(id=id) + coroutine = self._build_for_update_project_api_v1_projects__id__put(body=body, id=id) return get_event_loop().run_until_complete(coroutine) - def export_project_config_api_v1_projects_id_export_get(self, id: int) -> m.ProjectCreate: + def delete_project_api_v1_projects__id__delete(self, id: int) -> m.Project: """ - Exports the project config by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: JSONResponse: json representation of the project with the informed project id + Delete Project """ - coroutine = self._build_for_export_project_config_api_v1_projects_id_export_get(id=id) + coroutine = self._build_for_delete_project_api_v1_projects__id__delete(id=id) return get_event_loop().run_until_complete(coroutine) - def importproject_config_api_v1_projects_import_post(self, import_file: IO[Any]) -> m.Project: + def archive_project_api_v1_projects__id__archive_post(self, id: int) -> m.Project: """ - Imports the project config Args: import_file : The project config file to be imported Raises: ValidationError: if the imported project config contains invalid information Returns: Project: newly created project record + Archive Project """ - coroutine = self._build_for_importproject_config_api_v1_projects_import_post(import_file=import_file) + coroutine = self._build_for_archive_project_api_v1_projects__id__archive_post(id=id) return get_event_loop().run_until_complete(coroutine) - def read_project_api_v1_projects_id_get(self, id: int) -> m.Project: + def unarchive_project_api_v1_projects__id__unarchive_post(self, id: int) -> m.Project: """ - Lookup project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record + Unarchive Project """ - coroutine = self._build_for_read_project_api_v1_projects_id_get(id=id) + coroutine = self._build_for_unarchive_project_api_v1_projects__id__unarchive_post(id=id) return get_event_loop().run_until_complete(coroutine) - def read_projects_api_v1_projects_get( - self, archived: Optional[bool] = None, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.Project]: + def upload_pics_api_v1_projects__id__upload_pics_put( + self, body: m.BodyUploadPicsApiV1ProjectsIdUploadPicsPut, id: int + ) -> m.Project: """ - Retrieve list of projects Args: archived (bool, optional): Get archived projects, when true will; get archived projects only, when false only non-archived projects are returned. Defaults to false. skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Project]: List of projects + Upload Pics """ - coroutine = self._build_for_read_projects_api_v1_projects_get(archived=archived, skip=skip, limit=limit) + coroutine = self._build_for_upload_pics_api_v1_projects__id__upload_pics_put(body=body, id=id) return get_event_loop().run_until_complete(coroutine) - def remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete( + def remove_pics_cluster_type_api_v1_projects__id__pics_cluster_type_delete( self, id: int, cluster_name: str ) -> m.Project: """ - Removes cluster based on given cluster name Args: id (int): ID of Project cluster_name (str): Name of the cluster to delete Raises: HTTPException: if no project exists for provided project id Returns: models.Project: Project with updated PICS entry + Remove Pics Cluster Type """ - coroutine = self._build_for_remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete( + coroutine = self._build_for_remove_pics_cluster_type_api_v1_projects__id__pics_cluster_type_delete( id=id, cluster_name=cluster_name ) return get_event_loop().run_until_complete(coroutine) - def unarchive_project_api_v1_projects_id_unarchive_post(self, id: int) -> m.Project: + def applicable_test_cases_api_v1_projects__id__applicable_test_cases_get( + self, id: int + ) -> m.PICSApplicableTestCases: """ - Unarchive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was unarchived + Applicable Test Cases """ - coroutine = self._build_for_unarchive_project_api_v1_projects_id_unarchive_post(id=id) + coroutine = self._build_for_applicable_test_cases_api_v1_projects__id__applicable_test_cases_get(id=id) return get_event_loop().run_until_complete(coroutine) - def update_project_api_v1_projects_id_put(self, id: int, project_update: m.ProjectUpdate) -> m.Project: + def export_project_config_api_v1_projects__id__export_get(self, id: int) -> m.ProjectCreate: """ - Update an existing project Args: id (int): project id project_in (schemas.ProjectUpdate): projects parameters to be updated Raises: HTTPException: if no project exists for provided project id Returns: Project: updated project record + Export Project Config """ - coroutine = self._build_for_update_project_api_v1_projects_id_put(id=id, project_update=project_update) + coroutine = self._build_for_export_project_config_api_v1_projects__id__export_get(id=id) return get_event_loop().run_until_complete(coroutine) - def upload_pics_api_v1_projects_id_upload_pics_put(self, id: int, file: IO[Any]) -> m.Project: + def importproject_config_api_v1_projects_import_post( + self, body: m.BodyImportprojectConfigApiV1ProjectsImportPost + ) -> m.Project: """ - Upload PICS or dmp-test-skip.xml file of a project based on project identifier. Args: id (int): project id file : the PICS or dmp-test-skip.xml file to upload Raises: HTTPException: if no project exists for provided project id (or) if the PICS file is invalid Returns: Project: project record that was updated with the PICS and dmp_test_skip information. + Importproject Config """ - coroutine = self._build_for_upload_pics_api_v1_projects_id_upload_pics_put(id=id, file=file) + coroutine = self._build_for_importproject_config_api_v1_projects_import_post(body=body) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/test_collections_api.py b/th_cli/api_lib_autogen/api/test_collections_api.py index 2f7e1a4..fc0c4ac 100644 --- a/th_cli/api_lib_autogen/api/test_collections_api.py +++ b/th_cli/api_lib_autogen/api/test_collections_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -27,29 +27,25 @@ class _TestCollectionsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_read_test_collections_api_v1_test_collections_get(self) -> Awaitable[m.TestCollections]: + def _build_for_read_test_collections_api_v1_test_collections__get(self) -> Coroutine[Any, Any, m.TestCollections]: """ - Retrieve available test collections. + Read Test Collections """ - return self.api_client.request( - type_=m.TestCollections, - method="GET", - url="/api/v1/test_collections/", - ) + return self.api_client.request(type_=m.TestCollections, method="GET", url="/api/v1/test_collections/") class AsyncTestCollectionsApi(_TestCollectionsApi): - async def read_test_collections_api_v1_test_collections_get(self) -> m.TestCollections: + async def read_test_collections_api_v1_test_collections__get(self) -> m.TestCollections: """ - Retrieve available test collections. + Read Test Collections """ - return await self._build_for_read_test_collections_api_v1_test_collections_get() + return await self._build_for_read_test_collections_api_v1_test_collections__get() class SyncTestCollectionsApi(_TestCollectionsApi): - def read_test_collections_api_v1_test_collections_get(self) -> m.TestCollections: + def read_test_collections_api_v1_test_collections__get(self) -> m.TestCollections: """ - Retrieve available test collections. + Read Test Collections """ - coroutine = self._build_for_read_test_collections_api_v1_test_collections_get() + coroutine = self._build_for_read_test_collections_api_v1_test_collections__get() return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/test_run_configs_api.py b/th_cli/api_lib_autogen/api/test_run_configs_api.py index d73df13..fe597be 100644 --- a/th_cli/api_lib_autogen/api/test_run_configs_api.py +++ b/th_cli/api_lib_autogen/api/test_run_configs_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable, List, Optional - -from fastapi.encoders import jsonable_encoder +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -29,134 +27,126 @@ class _TestRunConfigsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_create_test_run_config_api_v1_test_run_configs_post( - self, test_run_config_create: m.TestRunConfigCreate - ) -> Awaitable[m.TestRunConfig]: + def _build_for_read_test_run_configs_api_v1_test_run_configs__get( + self, skip: int | None = None, limit: int | None = None + ) -> Coroutine[Any, Any, list[m.TestRunConfig]]: """ - Create new test run config. + Read Test Run Configs """ - body = jsonable_encoder(test_run_config_create) + query_params = {} + if skip is not None: + query_params["skip"] = str(skip) + if limit is not None: + query_params["limit"] = str(limit) - return self.api_client.request(type_=m.TestRunConfig, method="POST", url="/api/v1/test_run_configs/", json=body) + return self.api_client.request( + type_=list[m.TestRunConfig], method="GET", url="/api/v1/test_run_configs/", params=query_params + ) - def _build_for_read_test_run_config_api_v1_test_run_configs_id_get(self, id: int) -> Awaitable[m.TestRunConfig]: + def _build_for_create_test_run_config_api_v1_test_run_configs__post( + self, body: m.TestRunConfigCreate + ) -> Coroutine[Any, Any, m.TestRunConfig]: """ - Get test run config by ID. + Create Test Run Config """ - path_params = {"id": str(id)} + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body return self.api_client.request( - type_=m.TestRunConfig, - method="GET", - url="/api/v1/test_run_configs/{id}", - path_params=path_params, + type_=m.TestRunConfig, method="POST", url="/api/v1/test_run_configs/", json=json_body ) - def _build_for_read_test_run_configs_api_v1_test_run_configs_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> Awaitable[List[m.TestRunConfig]]: + def _build_for_read_test_run_config_api_v1_test_run_configs__id__get( + self, id: int + ) -> Coroutine[Any, Any, m.TestRunConfig]: """ - Retrieve test_run_configs. + Read Test Run Config """ - query_params = {} - if skip is not None: - query_params["skip"] = str(skip) - if limit is not None: - query_params["limit"] = str(limit) + path_params = {"id": str(id)} return self.api_client.request( - type_=List[m.TestRunConfig], - method="GET", - url="/api/v1/test_run_configs/", - params=query_params, + type_=m.TestRunConfig, method="GET", url="/api/v1/test_run_configs/{id}", path_params=path_params ) - def _build_for_update_test_run_config_api_v1_test_run_configs_id_put( - self, id: int, test_run_config_update: m.TestRunConfigUpdate - ) -> Awaitable[m.TestRunConfig]: + def _build_for_update_test_run_config_api_v1_test_run_configs__id__put( + self, body: m.TestRunConfigUpdate, id: int + ) -> Coroutine[Any, Any, m.TestRunConfig]: """ - Update a test run config. + Update Test Run Config """ path_params = {"id": str(id)} - body = jsonable_encoder(test_run_config_update) + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body return self.api_client.request( - type_=m.TestRunConfig, method="PUT", url="/api/v1/test_run_configs/{id}", path_params=path_params, json=body + type_=m.TestRunConfig, + method="PUT", + url="/api/v1/test_run_configs/{id}", + path_params=path_params, + json=json_body, ) class AsyncTestRunConfigsApi(_TestRunConfigsApi): - async def create_test_run_config_api_v1_test_run_configs_post( - self, test_run_config_create: m.TestRunConfigCreate - ) -> m.TestRunConfig: + async def read_test_run_configs_api_v1_test_run_configs__get( + self, skip: int | None = None, limit: int | None = None + ) -> list[m.TestRunConfig]: """ - Create new test run config. + Read Test Run Configs """ - return await self._build_for_create_test_run_config_api_v1_test_run_configs_post( - test_run_config_create=test_run_config_create - ) + return await self._build_for_read_test_run_configs_api_v1_test_run_configs__get(skip=skip, limit=limit) - async def read_test_run_config_api_v1_test_run_configs_id_get(self, id: int) -> m.TestRunConfig: + async def create_test_run_config_api_v1_test_run_configs__post( + self, body: m.TestRunConfigCreate + ) -> m.TestRunConfig: """ - Get test run config by ID. + Create Test Run Config """ - return await self._build_for_read_test_run_config_api_v1_test_run_configs_id_get(id=id) + return await self._build_for_create_test_run_config_api_v1_test_run_configs__post(body=body) - async def read_test_run_configs_api_v1_test_run_configs_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.TestRunConfig]: + async def read_test_run_config_api_v1_test_run_configs__id__get(self, id: int) -> m.TestRunConfig: """ - Retrieve test_run_configs. + Read Test Run Config """ - return await self._build_for_read_test_run_configs_api_v1_test_run_configs_get(skip=skip, limit=limit) + return await self._build_for_read_test_run_config_api_v1_test_run_configs__id__get(id=id) - async def update_test_run_config_api_v1_test_run_configs_id_put( - self, id: int, test_run_config_update: m.TestRunConfigUpdate + async def update_test_run_config_api_v1_test_run_configs__id__put( + self, body: m.TestRunConfigUpdate, id: int ) -> m.TestRunConfig: """ - Update a test run config. + Update Test Run Config """ - return await self._build_for_update_test_run_config_api_v1_test_run_configs_id_put( - id=id, test_run_config_update=test_run_config_update - ) + return await self._build_for_update_test_run_config_api_v1_test_run_configs__id__put(body=body, id=id) class SyncTestRunConfigsApi(_TestRunConfigsApi): - def create_test_run_config_api_v1_test_run_configs_post( - self, test_run_config_create: m.TestRunConfigCreate - ) -> m.TestRunConfig: + def read_test_run_configs_api_v1_test_run_configs__get( + self, skip: int | None = None, limit: int | None = None + ) -> list[m.TestRunConfig]: """ - Create new test run config. + Read Test Run Configs """ - coroutine = self._build_for_create_test_run_config_api_v1_test_run_configs_post( - test_run_config_create=test_run_config_create - ) + coroutine = self._build_for_read_test_run_configs_api_v1_test_run_configs__get(skip=skip, limit=limit) return get_event_loop().run_until_complete(coroutine) - def read_test_run_config_api_v1_test_run_configs_id_get(self, id: int) -> m.TestRunConfig: + def create_test_run_config_api_v1_test_run_configs__post(self, body: m.TestRunConfigCreate) -> m.TestRunConfig: """ - Get test run config by ID. + Create Test Run Config """ - coroutine = self._build_for_read_test_run_config_api_v1_test_run_configs_id_get(id=id) + coroutine = self._build_for_create_test_run_config_api_v1_test_run_configs__post(body=body) return get_event_loop().run_until_complete(coroutine) - def read_test_run_configs_api_v1_test_run_configs_get( - self, skip: Optional[int] = None, limit: Optional[int] = None - ) -> List[m.TestRunConfig]: + def read_test_run_config_api_v1_test_run_configs__id__get(self, id: int) -> m.TestRunConfig: """ - Retrieve test_run_configs. + Read Test Run Config """ - coroutine = self._build_for_read_test_run_configs_api_v1_test_run_configs_get(skip=skip, limit=limit) + coroutine = self._build_for_read_test_run_config_api_v1_test_run_configs__id__get(id=id) return get_event_loop().run_until_complete(coroutine) - def update_test_run_config_api_v1_test_run_configs_id_put( - self, id: int, test_run_config_update: m.TestRunConfigUpdate + def update_test_run_config_api_v1_test_run_configs__id__put( + self, body: m.TestRunConfigUpdate, id: int ) -> m.TestRunConfig: """ - Update a test run config. + Update Test Run Config """ - coroutine = self._build_for_update_test_run_config_api_v1_test_run_configs_id_put( - id=id, test_run_config_update=test_run_config_update - ) + coroutine = self._build_for_update_test_run_config_api_v1_test_run_configs__id__put(body=body, id=id) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/test_run_executions_api.py b/th_cli/api_lib_autogen/api/test_run_executions_api.py index 572f6d1..fd31089 100644 --- a/th_cli/api_lib_autogen/api/test_run_executions_api.py +++ b/th_cli/api_lib_autogen/api/test_run_executions_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import IO, TYPE_CHECKING, Any, Awaitable, Dict, List, Optional - -from fastapi.encoders import jsonable_encoder +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -29,147 +27,117 @@ class _TestRunExecutionsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_abort_testing_api_v1_test_run_executions_abort_testing_post(self) -> Awaitable[List[str]]: - """ - Cancel the current testing - """ - return self.api_client.request( - type_=List[str], - method="POST", - url="/api/v1/test_run_executions/abort-testing", - ) - - def _build_for_archive_api_v1_test_run_executions_id_archive_post(self, id: int) -> Awaitable[m.TestRunExecution]: - """ - Archive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was archived - """ - path_params = {"id": str(id)} - - return self.api_client.request( - type_=m.TestRunExecution, - method="POST", - url="/api/v1/test_run_executions/{id}/archive", - path_params=path_params, - ) - - def _build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + def _build_for_read_test_run_executions_api_v1_test_run_executions__get( self, - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost, - ) -> Awaitable[m.TestRunExecutionWithChildren]: + project_id: int | None = None, + archived: bool | None = None, + search_query: str | None = None, + skip: int | None = None, + limit: int | None = None, + sort_order: str | None = None, + ) -> Coroutine[Any, Any, list[m.TestRunExecutionWithStats]]: """ - Creates a new test run execution on CLI request. Attention: if both config and execution_config are provided, only config will be persisted, while execution_config will be for this execution only. Args: test_run_execution_in: Test run execution data selected_tests: Selected tests to run config: Configuration parameters that update project (optional, persists) execution_config: Execution-specific config override (optional, temporary) pics: PICS configuration (optional) + Read Test Run Executions """ - body = jsonable_encoder(body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post) + query_params = {} + if project_id is not None: + query_params["project_id"] = str(project_id) + if archived is not None: + query_params["archived"] = str(archived) + if search_query is not None: + query_params["search_query"] = str(search_query) + if skip is not None: + query_params["skip"] = str(skip) + if limit is not None: + query_params["limit"] = str(limit) + if sort_order is not None: + query_params["sort_order"] = str(sort_order) return self.api_client.request( - type_=m.TestRunExecutionWithChildren, method="POST", url="/api/v1/test_run_executions/cli", json=body + type_=list[m.TestRunExecutionWithStats], + method="GET", + url="/api/v1/test_run_executions/", + params=query_params, ) - def _build_for_create_test_run_execution_api_v1_test_run_executions_post( - self, - body_create_test_run_execution_api_v1_test_run_executions_post: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, - certification_mode: Optional[bool] = None, - ) -> Awaitable[m.TestRunExecutionWithChildren]: + def _build_for_create_test_run_execution_api_v1_test_run_executions__post( + self, body: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, certification_mode: bool | None = None + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Create a new test run execution. + Create Test Run Execution """ query_params = {} if certification_mode is not None: query_params["certification_mode"] = str(certification_mode) - body = jsonable_encoder(body_create_test_run_execution_api_v1_test_run_executions_post) + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body return self.api_client.request( type_=m.TestRunExecutionWithChildren, method="POST", url="/api/v1/test_run_executions/", params=query_params, - json=body, + json=json_body, ) - def _build_for_download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(self, id: int) -> Awaitable[None]: + def _build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + self, body: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Download the logs from a test run, grouped by test case state. Args: id (int): ID of the TestRunExectution the log is requested for Raises: HTTPException: If there's no TestRunExectution with the given ID Returns: StreamingResponse: .zip file containing: one file with the list of test cases for each state; one file with the logs from the executed test suites; one file per state with the logs from all test cases that finished with that state + Create Cli Test Run Execution """ - path_params = {"id": str(id)} + json_body = body.model_dump(mode="json") if hasattr(body, "model_dump") else body return self.api_client.request( - type_=None, - method="GET", - url="/api/v1/test_run_executions/{id}/grouped-log", - path_params=path_params, + type_=m.TestRunExecutionWithChildren, method="POST", url="/api/v1/test_run_executions/cli", json=json_body ) - def _build_for_download_log_api_v1_test_run_executions_id_log_get( - self, id: int, json_entries: Optional[bool] = None, download: Optional[bool] = None - ) -> Awaitable[None]: + def _build_for_rename_test_run_execution_api_v1_test_run_executions__id__rename_put( + self, id: int, new_execution_name: str + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Download the logs from a test run. Args: id (int): Id of the TestRunExectution the log is requested for json_entries (bool, optional): When set, return each log line as a json object download (bool, optional): When set, return as attachment + Rename Test Run Execution """ path_params = {"id": str(id)} - query_params = {} - if json_entries is not None: - query_params["json_entries"] = str(json_entries) - if download is not None: - query_params["download"] = str(download) + query_params = {"new_execution_name": str(new_execution_name)} return self.api_client.request( - type_=None, - method="GET", - url="/api/v1/test_run_executions/{id}/log", + type_=m.TestRunExecutionWithChildren, + method="PUT", + url="/api/v1/test_run_executions/{id}/rename", path_params=path_params, params=query_params, ) - def _build_for_export_test_run_execution_api_v1_test_run_executions_id_export_get( - self, id: int, download: Optional[bool] = None - ) -> Awaitable[m.ExportedTestRunExecution]: + def _build_for_abort_testing_api_v1_test_run_executions_abort_testing_post( + self, + ) -> Coroutine[Any, Any, dict[str, str]]: """ - Exports a test run execution by the given ID. + Abort Testing """ - path_params = {"id": str(id)} - - query_params = {} - if download is not None: - query_params["download"] = str(download) - return self.api_client.request( - type_=m.ExportedTestRunExecution, - method="GET", - url="/api/v1/test_run_executions/{id}/export", - path_params=path_params, - params=query_params, + type_=dict[str, str], method="POST", url="/api/v1/test_run_executions/abort-testing" ) - def _build_for_generate_summary_log_api_v1_test_run_executions_id_performance_summary_post( - self, id: int, project_id: int - ) -> Awaitable[object]: + def _build_for_get_test_runner_status_api_v1_test_run_executions_status_get( + self, + ) -> Coroutine[Any, Any, m.TestRunnerStatus]: """ - Imports a test run execution to the the given project_id. + Get Test Runner Status """ - path_params = {"id": str(id)} - - query_params = {"project_id": str(project_id)} - - return self.api_client.request( - type_=object, - method="POST", - url="/api/v1/test_run_executions/{id}/performance_summary", - path_params=path_params, - params=query_params, - ) + return self.api_client.request(type_=m.TestRunnerStatus, method="GET", url="/api/v1/test_run_executions/status") def _build_for_get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( self, - discriminator: Optional[str] = None, - setup_pin_code: Optional[str] = None, - version: Optional[int] = None, - vendor_id: Optional[int] = None, - product_id: Optional[int] = None, - ) -> Awaitable[m.ChipServerInfo]: + discriminator: str | None = None, + setup_pin_code: str | None = None, + version: int | None = None, + vendor_id: int | None = None, + product_id: int | None = None, + ) -> Coroutine[Any, Any, m.ChipServerInfo]: """ - Retrieve ChipServer node ID information and generate manual pairing code. Note: Manual pairing code generation requires the SDK container to be running. If called before the SDK container starts, manual_pairing_code will be None. Args: discriminator: Device discriminator (optional) setup_pin_code: Setup PIN code (optional) version: Version number (default: 0) vendor_id: Vendor ID (default: 0) product_id: Product ID (default: 0) Returns: ChipServerInfo: Contains node_id, node_id_hex, and optional manual_pairing_code. + Get Chip Server Info """ query_params = {} if discriminator is not None: @@ -190,123 +158,86 @@ def _build_for_get_chip_server_info_api_v1_test_run_executions_chip_server_info_ params=query_params, ) - def _build_for_get_test_runner_status_api_v1_test_run_executions_status_get(self) -> Awaitable[m.TestRunnerStatus]: - """ - Retrieve status of the Test Engine. When the Test Engine is actively running the status will include the current test_run and the details of the states. - """ - return self.api_client.request( - type_=m.TestRunnerStatus, - method="GET", - url="/api/v1/test_run_executions/status", - ) - - def _build_for_import_test_run_execution_api_v1_test_run_executions_import_post( - self, project_id: int, import_file: IO[Any] - ) -> Awaitable[m.TestRunExecutionWithChildren]: + def _build_for_read_test_run_execution_api_v1_test_run_executions__id__get( + self, id: int + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Imports a test run execution to the the given project_id. + Read Test Run Execution """ - query_params = {"project_id": str(project_id)} - - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - files["import_file"] = import_file + path_params = {"id": str(id)} return self.api_client.request( type_=m.TestRunExecutionWithChildren, - method="POST", - url="/api/v1/test_run_executions/import", - params=query_params, - data=data, - files=files, + method="GET", + url="/api/v1/test_run_executions/{id}", + path_params=path_params, ) - def _build_for_read_test_run_execution_api_v1_test_run_executions_id_get( + def _build_for_remove_test_run_execution_api_v1_test_run_executions__id__delete( self, id: int - ) -> Awaitable[m.TestRunExecutionWithChildren]: + ) -> Coroutine[Any, Any, m.TestRunExecutionInDBBase]: """ - Get test run by ID, including state on all children + Remove Test Run Execution """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.TestRunExecutionWithChildren, - method="GET", + type_=m.TestRunExecutionInDBBase, + method="DELETE", url="/api/v1/test_run_executions/{id}", path_params=path_params, ) - def _build_for_read_test_run_executions_api_v1_test_run_executions_get( - self, - project_id: Optional[int] = None, - archived: Optional[bool] = None, - search_query: Optional[str] = None, - skip: Optional[int] = None, - limit: Optional[int] = None, - sort_order: Optional[str] = None, - ) -> Awaitable[List[m.TestRunExecutionWithStats]]: + def _build_for_start_test_run_execution_api_v1_test_run_executions__id__start_post( + self, id: int + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Retrieve test runs, including statistics. Args: project_id: Filter test runs by project. archived: Get archived test runs, when true will return archived test runs only, when false only non-archived test runs are returned. skip: Pagination offset. limit: Max number of records to return. Set to 0 to return all results. sort_order: Sort order for results. Either \"asc\" or \"desc\". Defaults to \"asc\". Results are sorted by ID. Returns: List of test runs with execution statistics. + Start Test Run Execution """ - query_params = {} - if project_id is not None: - query_params["project_id"] = str(project_id) - if archived is not None: - query_params["archived"] = str(archived) - if search_query is not None: - query_params["search_query"] = str(search_query) - if skip is not None: - query_params["skip"] = str(skip) - if limit is not None: - query_params["limit"] = str(limit) - if sort_order is not None: - query_params["sort_order"] = str(sort_order) + path_params = {"id": str(id)} return self.api_client.request( - type_=List[m.TestRunExecutionWithStats], - method="GET", - url="/api/v1/test_run_executions/", - params=query_params, + type_=m.TestRunExecutionWithChildren, + method="POST", + url="/api/v1/test_run_executions/{id}/start", + path_params=path_params, ) - def _build_for_remove_test_run_execution_api_v1_test_run_executions_id_delete( + def _build_for_archive_api_v1_test_run_executions__id__archive_post( self, id: int - ) -> Awaitable[m.TestRunExecutionInDBBase]: + ) -> Coroutine[Any, Any, m.TestRunExecution]: """ - Remove test run execution + Archive """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.TestRunExecutionInDBBase, - method="DELETE", - url="/api/v1/test_run_executions/{id}", + type_=m.TestRunExecution, + method="POST", + url="/api/v1/test_run_executions/{id}/archive", path_params=path_params, ) - def _build_for_rename_test_run_execution_api_v1_test_run_executions_id_rename_put( - self, id: int, new_execution_name: str - ) -> Awaitable[m.TestRunExecutionWithChildren]: + def _build_for_unarchive_api_v1_test_run_executions__id__unarchive_post( + self, id: int + ) -> Coroutine[Any, Any, m.TestRunExecution]: """ - Rename the name of a test run execution. + Unarchive """ path_params = {"id": str(id)} - query_params = {"new_execution_name": str(new_execution_name)} - return self.api_client.request( - type_=m.TestRunExecutionWithChildren, - method="PUT", - url="/api/v1/test_run_executions/{id}/rename", + type_=m.TestRunExecution, + method="POST", + url="/api/v1/test_run_executions/{id}/unarchive", path_params=path_params, - params=query_params, ) - def _build_for_repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post( - self, id: int, title: Optional[str] = None - ) -> Awaitable[m.TestRunExecutionWithChildren]: + def _build_for_repeat_test_run_execution_api_v1_test_run_executions__id__repeat_post( + self, id: int, title: str | None = None + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Repeat a test run execution by id. Args: id (int): test run execution id title (str): Optional title to the repeated test run execution. If not provided, the old title will be used with the date and time updated. Raises: HTTPException: if no test run execution exists for the provided id Returns: TestRunExecution: new test run execution with the same test cases from id + Repeat Test Run Execution """ path_params = {"id": str(id)} @@ -322,132 +253,186 @@ def _build_for_repeat_test_run_execution_api_v1_test_run_executions_id_repeat_po params=query_params, ) - def _build_for_start_test_run_execution_api_v1_test_run_executions_id_start_post( - self, id: int - ) -> Awaitable[m.TestRunExecutionWithChildren]: + def _build_for_download_log_api_v1_test_run_executions__id__log_get( + self, id: int, json_entries: bool | None = None, download: bool | None = None + ) -> Coroutine[Any, Any, None]: """ - Start a test run by ID + Download Log """ path_params = {"id": str(id)} + query_params = {} + if json_entries is not None: + query_params["json_entries"] = str(json_entries) + if download is not None: + query_params["download"] = str(download) + return self.api_client.request( - type_=m.TestRunExecutionWithChildren, - method="POST", - url="/api/v1/test_run_executions/{id}/start", + type_=None, + method="GET", + url="/api/v1/test_run_executions/{id}/log", path_params=path_params, + params=query_params, ) - def _build_for_unarchive_api_v1_test_run_executions_id_unarchive_post( + def _build_for_download_grouped_log_api_v1_test_run_executions__id__grouped_log_get( self, id: int - ) -> Awaitable[m.TestRunExecution]: + ) -> Coroutine[Any, Any, None]: """ - Unarchive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was unarchived + Download Grouped Log """ path_params = {"id": str(id)} return self.api_client.request( - type_=m.TestRunExecution, - method="POST", - url="/api/v1/test_run_executions/{id}/unarchive", - path_params=path_params, + type_=None, method="GET", url="/api/v1/test_run_executions/{id}/grouped-log", path_params=path_params ) - def _build_for_upload_file_api_v1_test_run_executions_file_upload_post(self, file: IO[Any]) -> Awaitable[object]: + def _build_for_upload_file_api_v1_test_run_executions_file_upload__post( + self, body: m.BodyUploadFileApiV1TestRunExecutionsFileUploadPost + ) -> Coroutine[Any, Any, dict[str, Any]]: """ - Upload a file to the specified path of the current test run. Args: file: The file to upload. + Upload File """ - files: Dict[str, IO[Any]] = {} # noqa F841 - data: Dict[str, Any] = {} # noqa F841 - files["file"] = file + files: dict[str, IO[Any]] = {} + data: dict[str, Any] = {} + # TODO: Parse body for files and data return self.api_client.request( - type_=object, method="POST", url="/api/v1/test_run_executions/file_upload/", data=data, files=files + type_=dict[str, Any], method="POST", url="/api/v1/test_run_executions/file_upload/", data=data, files=files ) + def _build_for_export_test_run_execution_api_v1_test_run_executions__id__export_get( + self, id: int, download: bool | None = None + ) -> Coroutine[Any, Any, m.ExportedTestRunExecution]: + """ + Export Test Run Execution + """ + path_params = {"id": str(id)} -class AsyncTestRunExecutionsApi(_TestRunExecutionsApi): - async def abort_testing_api_v1_test_run_executions_abort_testing_post(self) -> List[str]: + query_params = {} + if download is not None: + query_params["download"] = str(download) + + return self.api_client.request( + type_=m.ExportedTestRunExecution, + method="GET", + url="/api/v1/test_run_executions/{id}/export", + path_params=path_params, + params=query_params, + ) + + def _build_for_import_test_run_execution_api_v1_test_run_executions_import_post( + self, body: m.BodyImportTestRunExecutionApiV1TestRunExecutionsImportPost, project_id: int + ) -> Coroutine[Any, Any, m.TestRunExecutionWithChildren]: """ - Cancel the current testing + Import Test Run Execution """ - return await self._build_for_abort_testing_api_v1_test_run_executions_abort_testing_post() + query_params = {"project_id": str(project_id)} + + files: dict[str, IO[Any]] = {} + data: dict[str, Any] = {} + # TODO: Parse body for files and data + + return self.api_client.request( + type_=m.TestRunExecutionWithChildren, + method="POST", + url="/api/v1/test_run_executions/import", + params=query_params, + data=data, + files=files, + ) - async def archive_api_v1_test_run_executions_id_archive_post(self, id: int) -> m.TestRunExecution: + def _build_for_generate_summary_log_api_v1_test_run_executions__id__performance_summary_post( + self, id: int, project_id: int + ) -> Coroutine[Any, Any, dict[str, Any]]: """ - Archive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was archived + Generate Summary Log """ - return await self._build_for_archive_api_v1_test_run_executions_id_archive_post(id=id) + path_params = {"id": str(id)} - async def create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + query_params = {"project_id": str(project_id)} + + return self.api_client.request( + type_=dict[str, Any], + method="POST", + url="/api/v1/test_run_executions/{id}/performance_summary", + path_params=path_params, + params=query_params, + ) + + +class AsyncTestRunExecutionsApi(_TestRunExecutionsApi): + async def read_test_run_executions_api_v1_test_run_executions__get( self, - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost, - ) -> m.TestRunExecutionWithChildren: + project_id: int | None = None, + archived: bool | None = None, + search_query: str | None = None, + skip: int | None = None, + limit: int | None = None, + sort_order: str | None = None, + ) -> list[m.TestRunExecutionWithStats]: """ - Creates a new test run execution on CLI request. Attention: if both config and execution_config are provided, only config will be persisted, while execution_config will be for this execution only. Args: test_run_execution_in: Test run execution data selected_tests: Selected tests to run config: Configuration parameters that update project (optional, persists) execution_config: Execution-specific config override (optional, temporary) pics: PICS configuration (optional) + Read Test Run Executions """ - return await self._build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post( - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post=body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post + return await self._build_for_read_test_run_executions_api_v1_test_run_executions__get( + project_id=project_id, + archived=archived, + search_query=search_query, + skip=skip, + limit=limit, + sort_order=sort_order, ) - async def create_test_run_execution_api_v1_test_run_executions_post( - self, - body_create_test_run_execution_api_v1_test_run_executions_post: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, - certification_mode: Optional[bool] = None, + async def create_test_run_execution_api_v1_test_run_executions__post( + self, body: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, certification_mode: bool | None = None ) -> m.TestRunExecutionWithChildren: """ - Create a new test run execution. + Create Test Run Execution """ - return await self._build_for_create_test_run_execution_api_v1_test_run_executions_post( - body_create_test_run_execution_api_v1_test_run_executions_post=body_create_test_run_execution_api_v1_test_run_executions_post, - certification_mode=certification_mode, + return await self._build_for_create_test_run_execution_api_v1_test_run_executions__post( + body=body, certification_mode=certification_mode ) - async def download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(self, id: int) -> None: + async def create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + self, body: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost + ) -> m.TestRunExecutionWithChildren: """ - Download the logs from a test run, grouped by test case state. Args: id (int): ID of the TestRunExectution the log is requested for Raises: HTTPException: If there's no TestRunExectution with the given ID Returns: StreamingResponse: .zip file containing: one file with the list of test cases for each state; one file with the logs from the executed test suites; one file per state with the logs from all test cases that finished with that state + Create Cli Test Run Execution """ - return await self._build_for_download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(id=id) + return await self._build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post(body=body) - async def download_log_api_v1_test_run_executions_id_log_get( - self, id: int, json_entries: Optional[bool] = None, download: Optional[bool] = None - ) -> None: + async def rename_test_run_execution_api_v1_test_run_executions__id__rename_put( + self, id: int, new_execution_name: str + ) -> m.TestRunExecutionWithChildren: """ - Download the logs from a test run. Args: id (int): Id of the TestRunExectution the log is requested for json_entries (bool, optional): When set, return each log line as a json object download (bool, optional): When set, return as attachment + Rename Test Run Execution """ - return await self._build_for_download_log_api_v1_test_run_executions_id_log_get( - id=id, json_entries=json_entries, download=download + return await self._build_for_rename_test_run_execution_api_v1_test_run_executions__id__rename_put( + id=id, new_execution_name=new_execution_name ) - async def export_test_run_execution_api_v1_test_run_executions_id_export_get( - self, id: int, download: Optional[bool] = None - ) -> m.ExportedTestRunExecution: + async def abort_testing_api_v1_test_run_executions_abort_testing_post(self) -> dict[str, str]: """ - Exports a test run execution by the given ID. + Abort Testing """ - return await self._build_for_export_test_run_execution_api_v1_test_run_executions_id_export_get( - id=id, download=download - ) + return await self._build_for_abort_testing_api_v1_test_run_executions_abort_testing_post() - async def generate_summary_log_api_v1_test_run_executions_id_performance_summary_post( - self, id: int, project_id: int - ) -> object: + async def get_test_runner_status_api_v1_test_run_executions_status_get(self) -> m.TestRunnerStatus: """ - Imports a test run execution to the the given project_id. + Get Test Runner Status """ - return await self._build_for_generate_summary_log_api_v1_test_run_executions_id_performance_summary_post( - id=id, project_id=project_id - ) + return await self._build_for_get_test_runner_status_api_v1_test_run_executions_status_get() async def get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( self, - discriminator: Optional[str] = None, - setup_pin_code: Optional[str] = None, - version: Optional[int] = None, - vendor_id: Optional[int] = None, - product_id: Optional[int] = None, + discriminator: str | None = None, + setup_pin_code: str | None = None, + version: int | None = None, + vendor_id: int | None = None, + product_id: int | None = None, ) -> m.ChipServerInfo: """ - Retrieve ChipServer node ID information and generate manual pairing code. Note: Manual pairing code generation requires the SDK container to be running. If called before the SDK container starts, manual_pairing_code will be None. Args: discriminator: Device discriminator (optional) setup_pin_code: Setup PIN code (optional) version: Version number (default: 0) vendor_id: Vendor ID (default: 0) product_id: Product ID (default: 0) Returns: ChipServerInfo: Contains node_id, node_id_hex, and optional manual_pairing_code. + Get Chip Server Info """ return await self._build_for_get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( discriminator=discriminator, @@ -457,191 +442,185 @@ async def get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( product_id=product_id, ) - async def get_test_runner_status_api_v1_test_run_executions_status_get(self) -> m.TestRunnerStatus: + async def read_test_run_execution_api_v1_test_run_executions__id__get( + self, id: int + ) -> m.TestRunExecutionWithChildren: """ - Retrieve status of the Test Engine. When the Test Engine is actively running the status will include the current test_run and the details of the states. + Read Test Run Execution """ - return await self._build_for_get_test_runner_status_api_v1_test_run_executions_status_get() + return await self._build_for_read_test_run_execution_api_v1_test_run_executions__id__get(id=id) - async def import_test_run_execution_api_v1_test_run_executions_import_post( - self, project_id: int, import_file: IO[Any] - ) -> m.TestRunExecutionWithChildren: + async def remove_test_run_execution_api_v1_test_run_executions__id__delete( + self, id: int + ) -> m.TestRunExecutionInDBBase: """ - Imports a test run execution to the the given project_id. + Remove Test Run Execution """ - return await self._build_for_import_test_run_execution_api_v1_test_run_executions_import_post( - project_id=project_id, import_file=import_file - ) + return await self._build_for_remove_test_run_execution_api_v1_test_run_executions__id__delete(id=id) - async def read_test_run_execution_api_v1_test_run_executions_id_get( + async def start_test_run_execution_api_v1_test_run_executions__id__start_post( self, id: int ) -> m.TestRunExecutionWithChildren: """ - Get test run by ID, including state on all children + Start Test Run Execution """ - return await self._build_for_read_test_run_execution_api_v1_test_run_executions_id_get(id=id) + return await self._build_for_start_test_run_execution_api_v1_test_run_executions__id__start_post(id=id) - async def read_test_run_executions_api_v1_test_run_executions_get( - self, - project_id: Optional[int] = None, - archived: Optional[bool] = None, - search_query: Optional[str] = None, - skip: Optional[int] = None, - limit: Optional[int] = None, - sort_order: Optional[str] = None, - ) -> List[m.TestRunExecutionWithStats]: + async def archive_api_v1_test_run_executions__id__archive_post(self, id: int) -> m.TestRunExecution: """ - Retrieve test runs, including statistics. Args: project_id: Filter test runs by project. archived: Get archived test runs, when true will return archived test runs only, when false only non-archived test runs are returned. skip: Pagination offset. limit: Max number of records to return. Set to 0 to return all results. sort_order: Sort order for results. Either \"asc\" or \"desc\". Defaults to \"asc\". Results are sorted by ID. Returns: List of test runs with execution statistics. + Archive """ - return await self._build_for_read_test_run_executions_api_v1_test_run_executions_get( - project_id=project_id, - archived=archived, - search_query=search_query, - skip=skip, - limit=limit, - sort_order=sort_order, - ) + return await self._build_for_archive_api_v1_test_run_executions__id__archive_post(id=id) - async def remove_test_run_execution_api_v1_test_run_executions_id_delete( - self, id: int - ) -> m.TestRunExecutionInDBBase: + async def unarchive_api_v1_test_run_executions__id__unarchive_post(self, id: int) -> m.TestRunExecution: """ - Remove test run execution + Unarchive """ - return await self._build_for_remove_test_run_execution_api_v1_test_run_executions_id_delete(id=id) + return await self._build_for_unarchive_api_v1_test_run_executions__id__unarchive_post(id=id) - async def rename_test_run_execution_api_v1_test_run_executions_id_rename_put( - self, id: int, new_execution_name: str + async def repeat_test_run_execution_api_v1_test_run_executions__id__repeat_post( + self, id: int, title: str | None = None ) -> m.TestRunExecutionWithChildren: """ - Rename the name of a test run execution. + Repeat Test Run Execution """ - return await self._build_for_rename_test_run_execution_api_v1_test_run_executions_id_rename_put( - id=id, new_execution_name=new_execution_name + return await self._build_for_repeat_test_run_execution_api_v1_test_run_executions__id__repeat_post( + id=id, title=title ) - async def repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post( - self, id: int, title: Optional[str] = None - ) -> m.TestRunExecutionWithChildren: + async def download_log_api_v1_test_run_executions__id__log_get( + self, id: int, json_entries: bool | None = None, download: bool | None = None + ) -> None: """ - Repeat a test run execution by id. Args: id (int): test run execution id title (str): Optional title to the repeated test run execution. If not provided, the old title will be used with the date and time updated. Raises: HTTPException: if no test run execution exists for the provided id Returns: TestRunExecution: new test run execution with the same test cases from id + Download Log """ - return await self._build_for_repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post( - id=id, title=title + return await self._build_for_download_log_api_v1_test_run_executions__id__log_get( + id=id, json_entries=json_entries, download=download ) - async def start_test_run_execution_api_v1_test_run_executions_id_start_post( - self, id: int - ) -> m.TestRunExecutionWithChildren: + async def download_grouped_log_api_v1_test_run_executions__id__grouped_log_get(self, id: int) -> None: """ - Start a test run by ID + Download Grouped Log """ - return await self._build_for_start_test_run_execution_api_v1_test_run_executions_id_start_post(id=id) + return await self._build_for_download_grouped_log_api_v1_test_run_executions__id__grouped_log_get(id=id) - async def unarchive_api_v1_test_run_executions_id_unarchive_post(self, id: int) -> m.TestRunExecution: + async def upload_file_api_v1_test_run_executions_file_upload__post( + self, body: m.BodyUploadFileApiV1TestRunExecutionsFileUploadPost + ) -> dict[str, Any]: """ - Unarchive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was unarchived + Upload File """ - return await self._build_for_unarchive_api_v1_test_run_executions_id_unarchive_post(id=id) + return await self._build_for_upload_file_api_v1_test_run_executions_file_upload__post(body=body) - async def upload_file_api_v1_test_run_executions_file_upload_post(self, file: IO[Any]) -> object: + async def export_test_run_execution_api_v1_test_run_executions__id__export_get( + self, id: int, download: bool | None = None + ) -> m.ExportedTestRunExecution: """ - Upload a file to the specified path of the current test run. Args: file: The file to upload. + Export Test Run Execution """ - return await self._build_for_upload_file_api_v1_test_run_executions_file_upload_post(file=file) - + return await self._build_for_export_test_run_execution_api_v1_test_run_executions__id__export_get( + id=id, download=download + ) -class SyncTestRunExecutionsApi(_TestRunExecutionsApi): - def abort_testing_api_v1_test_run_executions_abort_testing_post(self) -> List[str]: + async def import_test_run_execution_api_v1_test_run_executions_import_post( + self, body: m.BodyImportTestRunExecutionApiV1TestRunExecutionsImportPost, project_id: int + ) -> m.TestRunExecutionWithChildren: """ - Cancel the current testing + Import Test Run Execution """ - coroutine = self._build_for_abort_testing_api_v1_test_run_executions_abort_testing_post() - return get_event_loop().run_until_complete(coroutine) + return await self._build_for_import_test_run_execution_api_v1_test_run_executions_import_post( + body=body, project_id=project_id + ) - def archive_api_v1_test_run_executions_id_archive_post(self, id: int) -> m.TestRunExecution: + async def generate_summary_log_api_v1_test_run_executions__id__performance_summary_post( + self, id: int, project_id: int + ) -> dict[str, Any]: """ - Archive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was archived + Generate Summary Log """ - coroutine = self._build_for_archive_api_v1_test_run_executions_id_archive_post(id=id) - return get_event_loop().run_until_complete(coroutine) + return await self._build_for_generate_summary_log_api_v1_test_run_executions__id__performance_summary_post( + id=id, project_id=project_id + ) - def create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + +class SyncTestRunExecutionsApi(_TestRunExecutionsApi): + def read_test_run_executions_api_v1_test_run_executions__get( self, - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost, - ) -> m.TestRunExecutionWithChildren: + project_id: int | None = None, + archived: bool | None = None, + search_query: str | None = None, + skip: int | None = None, + limit: int | None = None, + sort_order: str | None = None, + ) -> list[m.TestRunExecutionWithStats]: """ - Creates a new test run execution on CLI request. Attention: if both config and execution_config are provided, only config will be persisted, while execution_config will be for this execution only. Args: test_run_execution_in: Test run execution data selected_tests: Selected tests to run config: Configuration parameters that update project (optional, persists) execution_config: Execution-specific config override (optional, temporary) pics: PICS configuration (optional) + Read Test Run Executions """ - coroutine = self._build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post( - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post=body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post + coroutine = self._build_for_read_test_run_executions_api_v1_test_run_executions__get( + project_id=project_id, + archived=archived, + search_query=search_query, + skip=skip, + limit=limit, + sort_order=sort_order, ) return get_event_loop().run_until_complete(coroutine) - def create_test_run_execution_api_v1_test_run_executions_post( - self, - body_create_test_run_execution_api_v1_test_run_executions_post: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, - certification_mode: Optional[bool] = None, + def create_test_run_execution_api_v1_test_run_executions__post( + self, body: m.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost, certification_mode: bool | None = None ) -> m.TestRunExecutionWithChildren: """ - Create a new test run execution. + Create Test Run Execution """ - coroutine = self._build_for_create_test_run_execution_api_v1_test_run_executions_post( - body_create_test_run_execution_api_v1_test_run_executions_post=body_create_test_run_execution_api_v1_test_run_executions_post, - certification_mode=certification_mode, + coroutine = self._build_for_create_test_run_execution_api_v1_test_run_executions__post( + body=body, certification_mode=certification_mode ) return get_event_loop().run_until_complete(coroutine) - def download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(self, id: int) -> None: + def create_cli_test_run_execution_api_v1_test_run_executions_cli_post( + self, body: m.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost + ) -> m.TestRunExecutionWithChildren: """ - Download the logs from a test run, grouped by test case state. Args: id (int): ID of the TestRunExectution the log is requested for Raises: HTTPException: If there's no TestRunExectution with the given ID Returns: StreamingResponse: .zip file containing: one file with the list of test cases for each state; one file with the logs from the executed test suites; one file per state with the logs from all test cases that finished with that state + Create Cli Test Run Execution """ - coroutine = self._build_for_download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(id=id) + coroutine = self._build_for_create_cli_test_run_execution_api_v1_test_run_executions_cli_post(body=body) return get_event_loop().run_until_complete(coroutine) - def download_log_api_v1_test_run_executions_id_log_get( - self, id: int, json_entries: Optional[bool] = None, download: Optional[bool] = None - ) -> None: + def rename_test_run_execution_api_v1_test_run_executions__id__rename_put( + self, id: int, new_execution_name: str + ) -> m.TestRunExecutionWithChildren: """ - Download the logs from a test run. Args: id (int): Id of the TestRunExectution the log is requested for json_entries (bool, optional): When set, return each log line as a json object download (bool, optional): When set, return as attachment + Rename Test Run Execution """ - coroutine = self._build_for_download_log_api_v1_test_run_executions_id_log_get( - id=id, json_entries=json_entries, download=download + coroutine = self._build_for_rename_test_run_execution_api_v1_test_run_executions__id__rename_put( + id=id, new_execution_name=new_execution_name ) return get_event_loop().run_until_complete(coroutine) - def export_test_run_execution_api_v1_test_run_executions_id_export_get( - self, id: int, download: Optional[bool] = None - ) -> m.ExportedTestRunExecution: + def abort_testing_api_v1_test_run_executions_abort_testing_post(self) -> dict[str, str]: """ - Exports a test run execution by the given ID. + Abort Testing """ - coroutine = self._build_for_export_test_run_execution_api_v1_test_run_executions_id_export_get( - id=id, download=download - ) + coroutine = self._build_for_abort_testing_api_v1_test_run_executions_abort_testing_post() return get_event_loop().run_until_complete(coroutine) - def generate_summary_log_api_v1_test_run_executions_id_performance_summary_post( - self, id: int, project_id: int - ) -> object: + def get_test_runner_status_api_v1_test_run_executions_status_get(self) -> m.TestRunnerStatus: """ - Imports a test run execution to the the given project_id. + Get Test Runner Status """ - coroutine = self._build_for_generate_summary_log_api_v1_test_run_executions_id_performance_summary_post( - id=id, project_id=project_id - ) + coroutine = self._build_for_get_test_runner_status_api_v1_test_run_executions_status_get() return get_event_loop().run_until_complete(coroutine) def get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( self, - discriminator: Optional[str] = None, - setup_pin_code: Optional[str] = None, - version: Optional[int] = None, - vendor_id: Optional[int] = None, - product_id: Optional[int] = None, + discriminator: str | None = None, + setup_pin_code: str | None = None, + version: int | None = None, + vendor_id: int | None = None, + product_id: int | None = None, ) -> m.ChipServerInfo: """ - Retrieve ChipServer node ID information and generate manual pairing code. Note: Manual pairing code generation requires the SDK container to be running. If called before the SDK container starts, manual_pairing_code will be None. Args: discriminator: Device discriminator (optional) setup_pin_code: Setup PIN code (optional) version: Version number (default: 0) vendor_id: Vendor ID (default: 0) product_id: Product ID (default: 0) Returns: ChipServerInfo: Contains node_id, node_id_hex, and optional manual_pairing_code. + Get Chip Server Info """ coroutine = self._build_for_get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( discriminator=discriminator, @@ -652,101 +631,110 @@ def get_chip_server_info_api_v1_test_run_executions_chip_server_info_get( ) return get_event_loop().run_until_complete(coroutine) - def get_test_runner_status_api_v1_test_run_executions_status_get(self) -> m.TestRunnerStatus: + def read_test_run_execution_api_v1_test_run_executions__id__get(self, id: int) -> m.TestRunExecutionWithChildren: """ - Retrieve status of the Test Engine. When the Test Engine is actively running the status will include the current test_run and the details of the states. + Read Test Run Execution """ - coroutine = self._build_for_get_test_runner_status_api_v1_test_run_executions_status_get() + coroutine = self._build_for_read_test_run_execution_api_v1_test_run_executions__id__get(id=id) return get_event_loop().run_until_complete(coroutine) - def import_test_run_execution_api_v1_test_run_executions_import_post( - self, project_id: int, import_file: IO[Any] - ) -> m.TestRunExecutionWithChildren: + def remove_test_run_execution_api_v1_test_run_executions__id__delete(self, id: int) -> m.TestRunExecutionInDBBase: """ - Imports a test run execution to the the given project_id. + Remove Test Run Execution """ - coroutine = self._build_for_import_test_run_execution_api_v1_test_run_executions_import_post( - project_id=project_id, import_file=import_file - ) + coroutine = self._build_for_remove_test_run_execution_api_v1_test_run_executions__id__delete(id=id) return get_event_loop().run_until_complete(coroutine) - def read_test_run_execution_api_v1_test_run_executions_id_get(self, id: int) -> m.TestRunExecutionWithChildren: + def start_test_run_execution_api_v1_test_run_executions__id__start_post( + self, id: int + ) -> m.TestRunExecutionWithChildren: """ - Get test run by ID, including state on all children + Start Test Run Execution """ - coroutine = self._build_for_read_test_run_execution_api_v1_test_run_executions_id_get(id=id) + coroutine = self._build_for_start_test_run_execution_api_v1_test_run_executions__id__start_post(id=id) return get_event_loop().run_until_complete(coroutine) - def read_test_run_executions_api_v1_test_run_executions_get( - self, - project_id: Optional[int] = None, - archived: Optional[bool] = None, - search_query: Optional[str] = None, - skip: Optional[int] = None, - limit: Optional[int] = None, - sort_order: Optional[str] = None, - ) -> List[m.TestRunExecutionWithStats]: + def archive_api_v1_test_run_executions__id__archive_post(self, id: int) -> m.TestRunExecution: """ - Retrieve test runs, including statistics. Args: project_id: Filter test runs by project. archived: Get archived test runs, when true will return archived test runs only, when false only non-archived test runs are returned. skip: Pagination offset. limit: Max number of records to return. Set to 0 to return all results. sort_order: Sort order for results. Either \"asc\" or \"desc\". Defaults to \"asc\". Results are sorted by ID. Returns: List of test runs with execution statistics. + Archive """ - coroutine = self._build_for_read_test_run_executions_api_v1_test_run_executions_get( - project_id=project_id, - archived=archived, - search_query=search_query, - skip=skip, - limit=limit, - sort_order=sort_order, - ) + coroutine = self._build_for_archive_api_v1_test_run_executions__id__archive_post(id=id) return get_event_loop().run_until_complete(coroutine) - def remove_test_run_execution_api_v1_test_run_executions_id_delete(self, id: int) -> m.TestRunExecutionInDBBase: + def unarchive_api_v1_test_run_executions__id__unarchive_post(self, id: int) -> m.TestRunExecution: """ - Remove test run execution + Unarchive """ - coroutine = self._build_for_remove_test_run_execution_api_v1_test_run_executions_id_delete(id=id) + coroutine = self._build_for_unarchive_api_v1_test_run_executions__id__unarchive_post(id=id) return get_event_loop().run_until_complete(coroutine) - def rename_test_run_execution_api_v1_test_run_executions_id_rename_put( - self, id: int, new_execution_name: str + def repeat_test_run_execution_api_v1_test_run_executions__id__repeat_post( + self, id: int, title: str | None = None ) -> m.TestRunExecutionWithChildren: """ - Rename the name of a test run execution. + Repeat Test Run Execution """ - coroutine = self._build_for_rename_test_run_execution_api_v1_test_run_executions_id_rename_put( - id=id, new_execution_name=new_execution_name + coroutine = self._build_for_repeat_test_run_execution_api_v1_test_run_executions__id__repeat_post( + id=id, title=title ) return get_event_loop().run_until_complete(coroutine) - def repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post( - self, id: int, title: Optional[str] = None - ) -> m.TestRunExecutionWithChildren: + def download_log_api_v1_test_run_executions__id__log_get( + self, id: int, json_entries: bool | None = None, download: bool | None = None + ) -> None: """ - Repeat a test run execution by id. Args: id (int): test run execution id title (str): Optional title to the repeated test run execution. If not provided, the old title will be used with the date and time updated. Raises: HTTPException: if no test run execution exists for the provided id Returns: TestRunExecution: new test run execution with the same test cases from id + Download Log """ - coroutine = self._build_for_repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post( - id=id, title=title + coroutine = self._build_for_download_log_api_v1_test_run_executions__id__log_get( + id=id, json_entries=json_entries, download=download ) return get_event_loop().run_until_complete(coroutine) - def start_test_run_execution_api_v1_test_run_executions_id_start_post( - self, id: int - ) -> m.TestRunExecutionWithChildren: + def download_grouped_log_api_v1_test_run_executions__id__grouped_log_get(self, id: int) -> None: """ - Start a test run by ID + Download Grouped Log """ - coroutine = self._build_for_start_test_run_execution_api_v1_test_run_executions_id_start_post(id=id) + coroutine = self._build_for_download_grouped_log_api_v1_test_run_executions__id__grouped_log_get(id=id) return get_event_loop().run_until_complete(coroutine) - def unarchive_api_v1_test_run_executions_id_unarchive_post(self, id: int) -> m.TestRunExecution: + def upload_file_api_v1_test_run_executions_file_upload__post( + self, body: m.BodyUploadFileApiV1TestRunExecutionsFileUploadPost + ) -> dict[str, Any]: """ - Unarchive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was unarchived + Upload File """ - coroutine = self._build_for_unarchive_api_v1_test_run_executions_id_unarchive_post(id=id) + coroutine = self._build_for_upload_file_api_v1_test_run_executions_file_upload__post(body=body) return get_event_loop().run_until_complete(coroutine) - def upload_file_api_v1_test_run_executions_file_upload_post(self, file: IO[Any]) -> object: + def export_test_run_execution_api_v1_test_run_executions__id__export_get( + self, id: int, download: bool | None = None + ) -> m.ExportedTestRunExecution: + """ + Export Test Run Execution """ - Upload a file to the specified path of the current test run. Args: file: The file to upload. + coroutine = self._build_for_export_test_run_execution_api_v1_test_run_executions__id__export_get( + id=id, download=download + ) + return get_event_loop().run_until_complete(coroutine) + + def import_test_run_execution_api_v1_test_run_executions_import_post( + self, body: m.BodyImportTestRunExecutionApiV1TestRunExecutionsImportPost, project_id: int + ) -> m.TestRunExecutionWithChildren: """ - coroutine = self._build_for_upload_file_api_v1_test_run_executions_file_upload_post(file=file) + Import Test Run Execution + """ + coroutine = self._build_for_import_test_run_execution_api_v1_test_run_executions_import_post( + body=body, project_id=project_id + ) + return get_event_loop().run_until_complete(coroutine) + + def generate_summary_log_api_v1_test_run_executions__id__performance_summary_post( + self, id: int, project_id: int + ) -> dict[str, Any]: + """ + Generate Summary Log + """ + coroutine = self._build_for_generate_summary_log_api_v1_test_run_executions__id__performance_summary_post( + id=id, project_id=project_id + ) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/utils_api.py b/th_cli/api_lib_autogen/api/utils_api.py index f50e790..c794553 100644 --- a/th_cli/api_lib_autogen/api/utils_api.py +++ b/th_cli/api_lib_autogen/api/utils_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -27,32 +27,27 @@ class _UtilsApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_test_email_api_v1_utils_test_email_post(self, email_to: str) -> Awaitable[m.Msg]: + def _build_for_test_email_api_v1_utils_test_email__post(self, email_to: str) -> Coroutine[Any, Any, m.Msg]: """ - Test emails. + Test Email """ query_params = {"email_to": str(email_to)} - return self.api_client.request( - type_=m.Msg, - method="POST", - url="/api/v1/utils/test-email/", - params=query_params, - ) + return self.api_client.request(type_=m.Msg, method="POST", url="/api/v1/utils/test-email/", params=query_params) class AsyncUtilsApi(_UtilsApi): - async def test_email_api_v1_utils_test_email_post(self, email_to: str) -> m.Msg: + async def test_email_api_v1_utils_test_email__post(self, email_to: str) -> m.Msg: """ - Test emails. + Test Email """ - return await self._build_for_test_email_api_v1_utils_test_email_post(email_to=email_to) + return await self._build_for_test_email_api_v1_utils_test_email__post(email_to=email_to) class SyncUtilsApi(_UtilsApi): - def test_email_api_v1_utils_test_email_post(self, email_to: str) -> m.Msg: + def test_email_api_v1_utils_test_email__post(self, email_to: str) -> m.Msg: """ - Test emails. + Test Email """ - coroutine = self._build_for_test_email_api_v1_utils_test_email_post(email_to=email_to) + coroutine = self._build_for_test_email_api_v1_utils_test_email__post(email_to=email_to) return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api/version_api.py b/th_cli/api_lib_autogen/api/version_api.py index 4aa4176..599ba19 100644 --- a/th_cli/api_lib_autogen/api/version_api.py +++ b/th_cli/api_lib_autogen/api/version_api.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ # # flake8: noqa E501 from asyncio import get_event_loop -from typing import TYPE_CHECKING, Awaitable +from typing import Coroutine, IO, TYPE_CHECKING, Any from th_cli.api_lib_autogen import models as m @@ -27,21 +27,19 @@ class _VersionApi: def __init__(self, api_client: "ApiClient"): self.api_client = api_client - def _build_for_get_test_harness_backend_version_api_v1_version_get(self) -> Awaitable[m.TestHarnessBackendVersion]: + def _build_for_get_test_harness_backend_version_api_v1_version_get( + self, + ) -> Coroutine[Any, Any, m.TestHarnessBackendVersion]: """ - Retrieve version of the Test Engine. + Get Test Harness Backend Version """ - return self.api_client.request( - type_=m.TestHarnessBackendVersion, - method="GET", - url="/api/v1/version", - ) + return self.api_client.request(type_=m.TestHarnessBackendVersion, method="GET", url="/api/v1/version") class AsyncVersionApi(_VersionApi): async def get_test_harness_backend_version_api_v1_version_get(self) -> m.TestHarnessBackendVersion: """ - Retrieve version of the Test Engine. + Get Test Harness Backend Version """ return await self._build_for_get_test_harness_backend_version_api_v1_version_get() @@ -49,7 +47,7 @@ async def get_test_harness_backend_version_api_v1_version_get(self) -> m.TestHar class SyncVersionApi(_VersionApi): def get_test_harness_backend_version_api_v1_version_get(self) -> m.TestHarnessBackendVersion: """ - Retrieve version of the Test Engine. + Get Test Harness Backend Version """ coroutine = self._build_for_get_test_harness_backend_version_api_v1_version_get() return get_event_loop().run_until_complete(coroutine) diff --git a/th_cli/api_lib_autogen/api_client.py b/th_cli/api_lib_autogen/api_client.py index 55587e7..85fc18e 100644 --- a/th_cli/api_lib_autogen/api_client.py +++ b/th_cli/api_lib_autogen/api_client.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,19 +14,19 @@ # limitations under the License. # from asyncio import get_event_loop -from typing import Any, Awaitable, Callable, Dict, Generic, Optional, Type, TypeVar, overload +from typing import Any, Awaitable, Callable, Generic, Type, TypeVar, overload from httpx import AsyncClient, Request, Response -from pydantic import ValidationError, parse_obj_as +from pydantic import TypeAdapter -from th_cli.api_lib_autogen.api.devices_api import AsyncDevicesApi, SyncDevicesApi -from th_cli.api_lib_autogen.api.operators_api import AsyncOperatorsApi, SyncOperatorsApi -from th_cli.api_lib_autogen.api.projects_api import AsyncProjectsApi, SyncProjectsApi from th_cli.api_lib_autogen.api.test_collections_api import AsyncTestCollectionsApi, SyncTestCollectionsApi -from th_cli.api_lib_autogen.api.test_run_configs_api import AsyncTestRunConfigsApi, SyncTestRunConfigsApi +from th_cli.api_lib_autogen.api.projects_api import AsyncProjectsApi, SyncProjectsApi +from th_cli.api_lib_autogen.api.operators_api import AsyncOperatorsApi, SyncOperatorsApi from th_cli.api_lib_autogen.api.test_run_executions_api import AsyncTestRunExecutionsApi, SyncTestRunExecutionsApi -from th_cli.api_lib_autogen.api.utils_api import AsyncUtilsApi, SyncUtilsApi +from th_cli.api_lib_autogen.api.test_run_configs_api import AsyncTestRunConfigsApi, SyncTestRunConfigsApi from th_cli.api_lib_autogen.api.version_api import AsyncVersionApi, SyncVersionApi +from th_cli.api_lib_autogen.api.utils_api import AsyncUtilsApi, SyncUtilsApi +from th_cli.api_lib_autogen.api.devices_api import AsyncDevicesApi, SyncDevicesApi from th_cli.api_lib_autogen.exceptions import ResponseHandlingException, UnexpectedResponse ClientT = TypeVar("ClientT", bound="ApiClient") @@ -36,28 +36,28 @@ class AsyncApis(Generic[ClientT]): def __init__(self, client: ClientT): self.client = client - self.devices_api = AsyncDevicesApi(self.client) - self.operators_api = AsyncOperatorsApi(self.client) - self.projects_api = AsyncProjectsApi(self.client) self.test_collections_api = AsyncTestCollectionsApi(self.client) - self.test_run_configs_api = AsyncTestRunConfigsApi(self.client) + self.projects_api = AsyncProjectsApi(self.client) + self.operators_api = AsyncOperatorsApi(self.client) self.test_run_executions_api = AsyncTestRunExecutionsApi(self.client) - self.utils_api = AsyncUtilsApi(self.client) + self.test_run_configs_api = AsyncTestRunConfigsApi(self.client) self.version_api = AsyncVersionApi(self.client) + self.utils_api = AsyncUtilsApi(self.client) + self.devices_api = AsyncDevicesApi(self.client) class SyncApis(Generic[ClientT]): def __init__(self, client: ClientT): self.client = client - self.devices_api = SyncDevicesApi(self.client) - self.operators_api = SyncOperatorsApi(self.client) - self.projects_api = SyncProjectsApi(self.client) self.test_collections_api = SyncTestCollectionsApi(self.client) - self.test_run_configs_api = SyncTestRunConfigsApi(self.client) + self.projects_api = SyncProjectsApi(self.client) + self.operators_api = SyncOperatorsApi(self.client) self.test_run_executions_api = SyncTestRunExecutionsApi(self.client) - self.utils_api = SyncUtilsApi(self.client) + self.test_run_configs_api = SyncTestRunConfigsApi(self.client) self.version_api = SyncVersionApi(self.client) + self.utils_api = SyncUtilsApi(self.client) + self.devices_api = SyncDevicesApi(self.client) T = TypeVar("T") @@ -66,7 +66,7 @@ def __init__(self, client: ClientT): class ApiClient: - def __init__(self, host: Optional[str] = None, **kwargs: Any) -> None: + def __init__(self, host: str | None = None, **kwargs: Any) -> None: self.host = host self.middleware: MiddlewareT = BaseMiddleware() self._async_client = AsyncClient(**kwargs) @@ -79,18 +79,18 @@ def close(self) -> None: @overload async def request( - self, *, type_: Type[T], method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any + self, *, type_: Type[T], method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any ) -> T: ... - @overload # noqa F811 + @overload async def request( - self, *, type_: None, method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any + self, *, type_: None, method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any ) -> None: ... - async def request( # noqa F811 - self, *, type_: Any, method: str, url: str, path_params: Optional[Dict[str, Any]] = None, **kwargs: Any + async def request( + self, *, type_: Any, method: str, url: str, path_params: dict[str, Any] | None = None, **kwargs: Any ) -> Any: if path_params is None: path_params = {} @@ -102,22 +102,24 @@ async def request( # noqa F811 def request_sync(self, *, type_: Type[T], **kwargs: Any) -> T: ... - @overload # noqa F811 + @overload def request_sync(self, *, type_: None, **kwargs: Any) -> None: ... - def request_sync(self, *, type_: Any, **kwargs: Any) -> Any: # noqa F811 + def request_sync(self, *, type_: Any, **kwargs: Any) -> Any: """ This method is not used by the generated apis, but is included for convenience """ return get_event_loop().run_until_complete(self.request(type_=type_, **kwargs)) - async def send(self, request: Request, type_: Type[T]) -> T: + async def send(self, request: Request, type_: Type[T]) -> T | str: response = await self.middleware(request, self.send_inner) if response.status_code in [200, 201]: try: - return parse_obj_as(type_, response.json()) - except ValidationError as e: + # Use Pydantic v2 TypeAdapter for validation + adapter = TypeAdapter(type_) + return adapter.validate_python(response.json()) if type_ else response.text + except Exception as e: raise ResponseHandlingException(e) raise UnexpectedResponse.for_response(response) diff --git a/th_cli/api_lib_autogen/api_response.py b/th_cli/api_lib_autogen/api_response.py deleted file mode 100644 index 1307c2f..0000000 --- a/th_cli/api_lib_autogen/api_response.py +++ /dev/null @@ -1,30 +0,0 @@ -"""API response object.""" - -from __future__ import annotations - -from typing import Any, Dict, Optional - -from pydantic import Field, StrictInt, StrictStr - - -class ApiResponse: - """ - API response object - """ - - status_code: Optional[StrictInt] = Field(None, description="HTTP status code") - headers: Optional[Dict[StrictStr, StrictStr]] = Field(None, description="HTTP headers") - data: Optional[Any] = Field(None, description="Deserialized data given the data type") - raw_data: Optional[Any] = Field(None, description="Raw data (HTTP response body)") - - def __init__( - self, - status_code: Optional[StrictInt] = None, - headers: Optional[Dict[StrictStr, StrictStr]] = None, - data: Optional[Any] = None, - raw_data: Optional[Any] = None, - ) -> None: - self.status_code = status_code - self.headers = headers - self.data = data - self.raw_data = raw_data diff --git a/th_cli/api_lib_autogen/docs/BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.md b/th_cli/api_lib_autogen/docs/BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.md deleted file mode 100644 index 41aec81..0000000 --- a/th_cli/api_lib_autogen/docs/BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.md +++ /dev/null @@ -1,32 +0,0 @@ -# BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_run_execution_in** | [**TestRunExecutionCreate**](TestRunExecutionCreate.md) | | -**selected_tests** | **Dict[str, Dict[str, Dict[str, int]]]** | | -**config** | [**Any**](.md) | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**pics** | [**Any**](.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post import BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost - -# TODO update the JSON string below -json = "{}" -# create an instance of BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost from a JSON string -body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post_instance = BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.from_json(json) -# print the JSON string representation of the object -print BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.to_json() - -# convert the object into a dict -body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post_dict = body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post_instance.to_dict() -# create an instance of BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost from a dict -body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post_form_dict = body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post.from_dict(body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.md b/th_cli/api_lib_autogen/docs/BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.md deleted file mode 100644 index 0fc145d..0000000 --- a/th_cli/api_lib_autogen/docs/BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.md +++ /dev/null @@ -1,29 +0,0 @@ -# BodyCreateTestRunExecutionApiV1TestRunExecutionsPost - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_run_execution_in** | [**TestRunExecutionCreate**](TestRunExecutionCreate.md) | | -**selected_tests** | **Dict[str, Dict[str, Dict[str, int]]]** | | - -## Example - -```python -from api_lib_autogen.models.body_create_test_run_execution_api_v1_test_run_executions_post import BodyCreateTestRunExecutionApiV1TestRunExecutionsPost - -# TODO update the JSON string below -json = "{}" -# create an instance of BodyCreateTestRunExecutionApiV1TestRunExecutionsPost from a JSON string -body_create_test_run_execution_api_v1_test_run_executions_post_instance = BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.from_json(json) -# print the JSON string representation of the object -print BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.to_json() - -# convert the object into a dict -body_create_test_run_execution_api_v1_test_run_executions_post_dict = body_create_test_run_execution_api_v1_test_run_executions_post_instance.to_dict() -# create an instance of BodyCreateTestRunExecutionApiV1TestRunExecutionsPost from a dict -body_create_test_run_execution_api_v1_test_run_executions_post_form_dict = body_create_test_run_execution_api_v1_test_run_executions_post.from_dict(body_create_test_run_execution_api_v1_test_run_executions_post_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/ChipServerInfo.md b/th_cli/api_lib_autogen/docs/ChipServerInfo.md deleted file mode 100644 index ffd64c6..0000000 --- a/th_cli/api_lib_autogen/docs/ChipServerInfo.md +++ /dev/null @@ -1,31 +0,0 @@ -# ChipServerInfo - -Schema for ChipServer information. - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**node_id** | **int** | | -**node_id_hex** | **str** | | -**manual_pairing_code** | **str** | | [optional] - -## Example - -```python -from api_lib_autogen.models.chip_server_info import ChipServerInfo - -# TODO update the JSON string below -json = "{}" -# create an instance of ChipServerInfo from a JSON string -chip_server_info_instance = ChipServerInfo.from_json(json) -# print the JSON string representation of the object -print ChipServerInfo.to_json() - -# convert the object into a dict -chip_server_info_dict = chip_server_info_instance.to_dict() -# create an instance of ChipServerInfo from a dict -chip_server_info_form_dict = chip_server_info.from_dict(chip_server_info_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/DevicesApi.md b/th_cli/api_lib_autogen/docs/DevicesApi.md deleted file mode 100644 index e32541c..0000000 --- a/th_cli/api_lib_autogen/docs/DevicesApi.md +++ /dev/null @@ -1,135 +0,0 @@ -# api_lib_autogen.DevicesApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**add_device_config_api_v1_devices_put**](DevicesApi.md#add_device_config_api_v1_devices_put) | **PUT** /api/v1/devices/ | Add Device Config -[**get_device_configs_api_v1_devices_get**](DevicesApi.md#get_device_configs_api_v1_devices_get) | **GET** /api/v1/devices/ | Get Device Configs - - -# **add_device_config_api_v1_devices_put** -> Any add_device_config_api_v1_devices_put(body) - -Add Device Config - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.DevicesApi(api_client) - body = {'key': api_lib_autogen.Any()} # Any | - - try: - # Add Device Config - api_response = api_instance.add_device_config_api_v1_devices_put(body) - print("The response of DevicesApi->add_device_config_api_v1_devices_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling DevicesApi->add_device_config_api_v1_devices_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body** | **Any**| | - -### Return type - -[**Any**](Any.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_device_configs_api_v1_devices_get** -> Any get_device_configs_api_v1_devices_get() - -Get Device Configs - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.DevicesApi(api_client) - - try: - # Get Device Configs - api_response = api_instance.get_device_configs_api_v1_devices_get() - print("The response of DevicesApi->get_device_configs_api_v1_devices_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling DevicesApi->get_device_configs_api_v1_devices_get: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**Any**](Any.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/ExportedTestRunExecution.md b/th_cli/api_lib_autogen/docs/ExportedTestRunExecution.md deleted file mode 100644 index 86ac827..0000000 --- a/th_cli/api_lib_autogen/docs/ExportedTestRunExecution.md +++ /dev/null @@ -1,29 +0,0 @@ -# ExportedTestRunExecution - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**db_revision** | **str** | | -**test_run_execution** | [**TestRunExecutionToExport**](TestRunExecutionToExport.md) | | - -## Example - -```python -from api_lib_autogen.models.exported_test_run_execution import ExportedTestRunExecution - -# TODO update the JSON string below -json = "{}" -# create an instance of ExportedTestRunExecution from a JSON string -exported_test_run_execution_instance = ExportedTestRunExecution.from_json(json) -# print the JSON string representation of the object -print ExportedTestRunExecution.to_json() - -# convert the object into a dict -exported_test_run_execution_dict = exported_test_run_execution_instance.to_dict() -# create an instance of ExportedTestRunExecution from a dict -exported_test_run_execution_form_dict = exported_test_run_execution.from_dict(exported_test_run_execution_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/HTTPValidationError.md b/th_cli/api_lib_autogen/docs/HTTPValidationError.md deleted file mode 100644 index 48e6819..0000000 --- a/th_cli/api_lib_autogen/docs/HTTPValidationError.md +++ /dev/null @@ -1,28 +0,0 @@ -# HTTPValidationError - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.http_validation_error import HTTPValidationError - -# TODO update the JSON string below -json = "{}" -# create an instance of HTTPValidationError from a JSON string -http_validation_error_instance = HTTPValidationError.from_json(json) -# print the JSON string representation of the object -print HTTPValidationError.to_json() - -# convert the object into a dict -http_validation_error_dict = http_validation_error_instance.to_dict() -# create an instance of HTTPValidationError from a dict -http_validation_error_form_dict = http_validation_error.from_dict(http_validation_error_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/LocationInner.md b/th_cli/api_lib_autogen/docs/LocationInner.md deleted file mode 100644 index ef4d515..0000000 --- a/th_cli/api_lib_autogen/docs/LocationInner.md +++ /dev/null @@ -1,27 +0,0 @@ -# LocationInner - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - -## Example - -```python -from api_lib_autogen.models.location_inner import LocationInner - -# TODO update the JSON string below -json = "{}" -# create an instance of LocationInner from a JSON string -location_inner_instance = LocationInner.from_json(json) -# print the JSON string representation of the object -print LocationInner.to_json() - -# convert the object into a dict -location_inner_dict = location_inner_instance.to_dict() -# create an instance of LocationInner from a dict -location_inner_form_dict = location_inner.from_dict(location_inner_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/Msg.md b/th_cli/api_lib_autogen/docs/Msg.md deleted file mode 100644 index 1fc3805..0000000 --- a/th_cli/api_lib_autogen/docs/Msg.md +++ /dev/null @@ -1,28 +0,0 @@ -# Msg - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**msg** | **str** | | - -## Example - -```python -from api_lib_autogen.models.msg import Msg - -# TODO update the JSON string below -json = "{}" -# create an instance of Msg from a JSON string -msg_instance = Msg.from_json(json) -# print the JSON string representation of the object -print Msg.to_json() - -# convert the object into a dict -msg_dict = msg_instance.to_dict() -# create an instance of Msg from a dict -msg_form_dict = msg.from_dict(msg_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/Operator.md b/th_cli/api_lib_autogen/docs/Operator.md deleted file mode 100644 index ea2ff71..0000000 --- a/th_cli/api_lib_autogen/docs/Operator.md +++ /dev/null @@ -1,30 +0,0 @@ -# Operator - -Default schema, used when return data to API clients - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**id** | **int** | | - -## Example - -```python -from api_lib_autogen.models.operator import Operator - -# TODO update the JSON string below -json = "{}" -# create an instance of Operator from a JSON string -operator_instance = Operator.from_json(json) -# print the JSON string representation of the object -print Operator.to_json() - -# convert the object into a dict -operator_dict = operator_instance.to_dict() -# create an instance of Operator from a dict -operator_form_dict = operator.from_dict(operator_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/OperatorCreate.md b/th_cli/api_lib_autogen/docs/OperatorCreate.md deleted file mode 100644 index 66c3d54..0000000 --- a/th_cli/api_lib_autogen/docs/OperatorCreate.md +++ /dev/null @@ -1,29 +0,0 @@ -# OperatorCreate - -Create schema. Name is required for new Operators. - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | - -## Example - -```python -from api_lib_autogen.models.operator_create import OperatorCreate - -# TODO update the JSON string below -json = "{}" -# create an instance of OperatorCreate from a JSON string -operator_create_instance = OperatorCreate.from_json(json) -# print the JSON string representation of the object -print OperatorCreate.to_json() - -# convert the object into a dict -operator_create_dict = operator_create_instance.to_dict() -# create an instance of OperatorCreate from a dict -operator_create_form_dict = operator_create.from_dict(operator_create_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/OperatorToExport.md b/th_cli/api_lib_autogen/docs/OperatorToExport.md deleted file mode 100644 index 9194c2f..0000000 --- a/th_cli/api_lib_autogen/docs/OperatorToExport.md +++ /dev/null @@ -1,29 +0,0 @@ -# OperatorToExport - -Base schema for Operator, with shared properties. - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | - -## Example - -```python -from api_lib_autogen.models.operator_to_export import OperatorToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of OperatorToExport from a JSON string -operator_to_export_instance = OperatorToExport.from_json(json) -# print the JSON string representation of the object -print OperatorToExport.to_json() - -# convert the object into a dict -operator_to_export_dict = operator_to_export_instance.to_dict() -# create an instance of OperatorToExport from a dict -operator_to_export_form_dict = operator_to_export.from_dict(operator_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/OperatorUpdate.md b/th_cli/api_lib_autogen/docs/OperatorUpdate.md deleted file mode 100644 index b7c3ac6..0000000 --- a/th_cli/api_lib_autogen/docs/OperatorUpdate.md +++ /dev/null @@ -1,29 +0,0 @@ -# OperatorUpdate - -Update Schema. Same as the base schema, only name can be changed - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] - -## Example - -```python -from api_lib_autogen.models.operator_update import OperatorUpdate - -# TODO update the JSON string below -json = "{}" -# create an instance of OperatorUpdate from a JSON string -operator_update_instance = OperatorUpdate.from_json(json) -# print the JSON string representation of the object -print OperatorUpdate.to_json() - -# convert the object into a dict -operator_update_dict = operator_update_instance.to_dict() -# create an instance of OperatorUpdate from a dict -operator_update_form_dict = operator_update.from_dict(operator_update_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/OperatorsApi.md b/th_cli/api_lib_autogen/docs/OperatorsApi.md deleted file mode 100644 index eb487ee..0000000 --- a/th_cli/api_lib_autogen/docs/OperatorsApi.md +++ /dev/null @@ -1,359 +0,0 @@ -# api_lib_autogen.OperatorsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_operator_api_v1_operators_post**](OperatorsApi.md#create_operator_api_v1_operators_post) | **POST** /api/v1/operators/ | Create Operator -[**delete_operator_api_v1_operators_id_delete**](OperatorsApi.md#delete_operator_api_v1_operators_id_delete) | **DELETE** /api/v1/operators/{id} | Delete Operator -[**read_operator_api_v1_operators_id_get**](OperatorsApi.md#read_operator_api_v1_operators_id_get) | **GET** /api/v1/operators/{id} | Read Operator -[**read_operators_api_v1_operators_get**](OperatorsApi.md#read_operators_api_v1_operators_get) | **GET** /api/v1/operators/ | Read Operators -[**update_operator_api_v1_operators_id_put**](OperatorsApi.md#update_operator_api_v1_operators_id_put) | **PUT** /api/v1/operators/{id} | Update Operator - - -# **create_operator_api_v1_operators_post** -> Operator create_operator_api_v1_operators_post(operator_create) - -Create Operator - -Create new operator. Args: operator_in (OperatorCreate): Parameters for new operator. Returns: Operator: newly created operator record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.operator import Operator -from api_lib_autogen.models.operator_create import OperatorCreate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.OperatorsApi(api_client) - operator_create = api_lib_autogen.OperatorCreate() # OperatorCreate | - - try: - # Create Operator - api_response = api_instance.create_operator_api_v1_operators_post(operator_create) - print("The response of OperatorsApi->create_operator_api_v1_operators_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling OperatorsApi->create_operator_api_v1_operators_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **operator_create** | [**OperatorCreate**](OperatorCreate.md)| | - -### Return type - -[**Operator**](Operator.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_operator_api_v1_operators_id_delete** -> Operator delete_operator_api_v1_operators_id_delete(id) - -Delete Operator - -Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record that was deleted - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.operator import Operator -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.OperatorsApi(api_client) - id = 56 # int | - - try: - # Delete Operator - api_response = api_instance.delete_operator_api_v1_operators_id_delete(id) - print("The response of OperatorsApi->delete_operator_api_v1_operators_id_delete:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling OperatorsApi->delete_operator_api_v1_operators_id_delete: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Operator**](Operator.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_operator_api_v1_operators_id_get** -> Operator read_operator_api_v1_operators_id_get(id) - -Read Operator - -Lookup operator by id. Args: id (int): operator id Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: operator record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.operator import Operator -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.OperatorsApi(api_client) - id = 56 # int | - - try: - # Read Operator - api_response = api_instance.read_operator_api_v1_operators_id_get(id) - print("The response of OperatorsApi->read_operator_api_v1_operators_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling OperatorsApi->read_operator_api_v1_operators_id_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Operator**](Operator.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_operators_api_v1_operators_get** -> List[Operator] read_operators_api_v1_operators_get(skip=skip, limit=limit) - -Read Operators - -Retrive list of operators. Args: skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Operator]: List of operators - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.operator import Operator -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.OperatorsApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # Read Operators - api_response = api_instance.read_operators_api_v1_operators_get(skip=skip, limit=limit) - print("The response of OperatorsApi->read_operators_api_v1_operators_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling OperatorsApi->read_operators_api_v1_operators_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[Operator]**](Operator.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_operator_api_v1_operators_id_put** -> Operator update_operator_api_v1_operators_id_put(id, operator_update) - -Update Operator - -Update an existing operator. Args: id (int): operator id operator_in (schemas.OperatorUpdate): operators parameters to be updated Raises: HTTPException: if no operator exists for provided operator id Returns: Operator: updated operator record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.operator import Operator -from api_lib_autogen.models.operator_update import OperatorUpdate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.OperatorsApi(api_client) - id = 56 # int | - operator_update = api_lib_autogen.OperatorUpdate() # OperatorUpdate | - - try: - # Update Operator - api_response = api_instance.update_operator_api_v1_operators_id_put(id, operator_update) - print("The response of OperatorsApi->update_operator_api_v1_operators_id_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling OperatorsApi->update_operator_api_v1_operators_id_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **operator_update** | [**OperatorUpdate**](OperatorUpdate.md)| | - -### Return type - -[**Operator**](Operator.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/PICS.md b/th_cli/api_lib_autogen/docs/PICS.md deleted file mode 100644 index e64feb0..0000000 --- a/th_cli/api_lib_autogen/docs/PICS.md +++ /dev/null @@ -1,28 +0,0 @@ -# PICS - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**clusters** | [**Dict[str, PICSCluster]**](PICSCluster.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.pics import PICS - -# TODO update the JSON string below -json = "{}" -# create an instance of PICS from a JSON string -pics_instance = PICS.from_json(json) -# print the JSON string representation of the object -print PICS.to_json() - -# convert the object into a dict -pics_dict = pics_instance.to_dict() -# create an instance of PICS from a dict -pics_form_dict = pics.from_dict(pics_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/PICSApplicableTestCases.md b/th_cli/api_lib_autogen/docs/PICSApplicableTestCases.md deleted file mode 100644 index a819294..0000000 --- a/th_cli/api_lib_autogen/docs/PICSApplicableTestCases.md +++ /dev/null @@ -1,28 +0,0 @@ -# PICSApplicableTestCases - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_cases** | **List[str]** | | - -## Example - -```python -from api_lib_autogen.models.pics_applicable_test_cases import PICSApplicableTestCases - -# TODO update the JSON string below -json = "{}" -# create an instance of PICSApplicableTestCases from a JSON string -pics_applicable_test_cases_instance = PICSApplicableTestCases.from_json(json) -# print the JSON string representation of the object -print PICSApplicableTestCases.to_json() - -# convert the object into a dict -pics_applicable_test_cases_dict = pics_applicable_test_cases_instance.to_dict() -# create an instance of PICSApplicableTestCases from a dict -pics_applicable_test_cases_form_dict = pics_applicable_test_cases.from_dict(pics_applicable_test_cases_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/PICSCluster.md b/th_cli/api_lib_autogen/docs/PICSCluster.md deleted file mode 100644 index 52d3664..0000000 --- a/th_cli/api_lib_autogen/docs/PICSCluster.md +++ /dev/null @@ -1,29 +0,0 @@ -# PICSCluster - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**items** | [**Dict[str, PICSItem]**](PICSItem.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.pics_cluster import PICSCluster - -# TODO update the JSON string below -json = "{}" -# create an instance of PICSCluster from a JSON string -pics_cluster_instance = PICSCluster.from_json(json) -# print the JSON string representation of the object -print PICSCluster.to_json() - -# convert the object into a dict -pics_cluster_dict = pics_cluster_instance.to_dict() -# create an instance of PICSCluster from a dict -pics_cluster_form_dict = pics_cluster.from_dict(pics_cluster_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/PICSItem.md b/th_cli/api_lib_autogen/docs/PICSItem.md deleted file mode 100644 index a0ef73c..0000000 --- a/th_cli/api_lib_autogen/docs/PICSItem.md +++ /dev/null @@ -1,29 +0,0 @@ -# PICSItem - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**number** | **str** | | -**enabled** | **bool** | | - -## Example - -```python -from api_lib_autogen.models.pics_item import PICSItem - -# TODO update the JSON string below -json = "{}" -# create an instance of PICSItem from a JSON string -pics_item_instance = PICSItem.from_json(json) -# print the JSON string representation of the object -print PICSItem.to_json() - -# convert the object into a dict -pics_item_dict = pics_item_instance.to_dict() -# create an instance of PICSItem from a dict -pics_item_form_dict = pics_item.from_dict(pics_item_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/Project.md b/th_cli/api_lib_autogen/docs/Project.md deleted file mode 100644 index c994de2..0000000 --- a/th_cli/api_lib_autogen/docs/Project.md +++ /dev/null @@ -1,34 +0,0 @@ -# Project - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**config** | [**Any**](.md) | | [optional] -**pics** | [**PICS**](PICS.md) | | [optional] -**id** | **int** | | -**created_at** | **datetime** | | -**updated_at** | **datetime** | | -**archived_at** | **datetime** | | [optional] - -## Example - -```python -from api_lib_autogen.models.project import Project - -# TODO update the JSON string below -json = "{}" -# create an instance of Project from a JSON string -project_instance = Project.from_json(json) -# print the JSON string representation of the object -print Project.to_json() - -# convert the object into a dict -project_dict = project_instance.to_dict() -# create an instance of Project from a dict -project_form_dict = project.from_dict(project_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/ProjectCreate.md b/th_cli/api_lib_autogen/docs/ProjectCreate.md deleted file mode 100644 index d0cffbc..0000000 --- a/th_cli/api_lib_autogen/docs/ProjectCreate.md +++ /dev/null @@ -1,30 +0,0 @@ -# ProjectCreate - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**config** | [**Any**](.md) | | [optional] -**pics** | [**PICS**](PICS.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.project_create import ProjectCreate - -# TODO update the JSON string below -json = "{}" -# create an instance of ProjectCreate from a JSON string -project_create_instance = ProjectCreate.from_json(json) -# print the JSON string representation of the object -print ProjectCreate.to_json() - -# convert the object into a dict -project_create_dict = project_create_instance.to_dict() -# create an instance of ProjectCreate from a dict -project_create_form_dict = project_create.from_dict(project_create_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/ProjectUpdate.md b/th_cli/api_lib_autogen/docs/ProjectUpdate.md deleted file mode 100644 index 67d85d9..0000000 --- a/th_cli/api_lib_autogen/docs/ProjectUpdate.md +++ /dev/null @@ -1,30 +0,0 @@ -# ProjectUpdate - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] -**config** | [**Any**](.md) | | [optional] -**pics** | [**PICS**](PICS.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.project_update import ProjectUpdate - -# TODO update the JSON string below -json = "{}" -# create an instance of ProjectUpdate from a JSON string -project_update_instance = ProjectUpdate.from_json(json) -# print the JSON string representation of the object -print ProjectUpdate.to_json() - -# convert the object into a dict -project_update_dict = project_update_instance.to_dict() -# create an instance of ProjectUpdate from a dict -project_update_form_dict = project_update.from_dict(project_update_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/ProjectsApi.md b/th_cli/api_lib_autogen/docs/ProjectsApi.md deleted file mode 100644 index cd5c8a4..0000000 --- a/th_cli/api_lib_autogen/docs/ProjectsApi.md +++ /dev/null @@ -1,912 +0,0 @@ -# api_lib_autogen.ProjectsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**applicable_test_cases_api_v1_projects_id_applicable_test_cases_get**](ProjectsApi.md#applicable_test_cases_api_v1_projects_id_applicable_test_cases_get) | **GET** /api/v1/projects/{id}/applicable_test_cases | Applicable Test Cases -[**archive_project_api_v1_projects_id_archive_post**](ProjectsApi.md#archive_project_api_v1_projects_id_archive_post) | **POST** /api/v1/projects/{id}/archive | Archive Project -[**create_project_api_v1_projects_post**](ProjectsApi.md#create_project_api_v1_projects_post) | **POST** /api/v1/projects/ | Create Project -[**default_config_api_v1_projects_default_config_get**](ProjectsApi.md#default_config_api_v1_projects_default_config_get) | **GET** /api/v1/projects/default_config | Default Config -[**delete_project_api_v1_projects_id_delete**](ProjectsApi.md#delete_project_api_v1_projects_id_delete) | **DELETE** /api/v1/projects/{id} | Delete Project -[**export_project_config_api_v1_projects_id_export_get**](ProjectsApi.md#export_project_config_api_v1_projects_id_export_get) | **GET** /api/v1/projects/{id}/export | Export Project Config -[**importproject_config_api_v1_projects_import_post**](ProjectsApi.md#importproject_config_api_v1_projects_import_post) | **POST** /api/v1/projects/import | Importproject Config -[**read_project_api_v1_projects_id_get**](ProjectsApi.md#read_project_api_v1_projects_id_get) | **GET** /api/v1/projects/{id} | Read Project -[**read_projects_api_v1_projects_get**](ProjectsApi.md#read_projects_api_v1_projects_get) | **GET** /api/v1/projects/ | Read Projects -[**remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete**](ProjectsApi.md#remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete) | **DELETE** /api/v1/projects/{id}/pics_cluster_type | Remove Pics Cluster Type -[**unarchive_project_api_v1_projects_id_unarchive_post**](ProjectsApi.md#unarchive_project_api_v1_projects_id_unarchive_post) | **POST** /api/v1/projects/{id}/unarchive | Unarchive Project -[**update_project_api_v1_projects_id_put**](ProjectsApi.md#update_project_api_v1_projects_id_put) | **PUT** /api/v1/projects/{id} | Update Project -[**upload_pics_api_v1_projects_id_upload_pics_put**](ProjectsApi.md#upload_pics_api_v1_projects_id_upload_pics_put) | **PUT** /api/v1/projects/{id}/upload_pics | Upload Pics - - -# **applicable_test_cases_api_v1_projects_id_applicable_test_cases_get** -> PICSApplicableTestCases applicable_test_cases_api_v1_projects_id_applicable_test_cases_get(id) - -Applicable Test Cases - -Retrieve list of applicable test cases based on project identifier. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: PICSApplicableTestCases: List of applicable test cases - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.pics_applicable_test_cases import PICSApplicableTestCases -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Applicable Test Cases - api_response = api_instance.applicable_test_cases_api_v1_projects_id_applicable_test_cases_get(id) - print("The response of ProjectsApi->applicable_test_cases_api_v1_projects_id_applicable_test_cases_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->applicable_test_cases_api_v1_projects_id_applicable_test_cases_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**PICSApplicableTestCases**](PICSApplicableTestCases.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **archive_project_api_v1_projects_id_archive_post** -> Project archive_project_api_v1_projects_id_archive_post(id) - -Archive Project - -Archive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was archived - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Archive Project - api_response = api_instance.archive_project_api_v1_projects_id_archive_post(id) - print("The response of ProjectsApi->archive_project_api_v1_projects_id_archive_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->archive_project_api_v1_projects_id_archive_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **create_project_api_v1_projects_post** -> Project create_project_api_v1_projects_post(project_create) - -Create Project - -Create new project Args: project_in (ProjectCreate): Parameters for new project, see schema for details Returns: Project: newly created project record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.models.project_create import ProjectCreate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - project_create = api_lib_autogen.ProjectCreate() # ProjectCreate | - - try: - # Create Project - api_response = api_instance.create_project_api_v1_projects_post(project_create) - print("The response of ProjectsApi->create_project_api_v1_projects_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->create_project_api_v1_projects_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **project_create** | [**ProjectCreate**](ProjectCreate.md)| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **default_config_api_v1_projects_default_config_get** -> ResponseDefaultConfigApiV1ProjectsDefaultConfigGet default_config_api_v1_projects_default_config_get() - -Default Config - -Return default configuration for projects. Returns: List[Project]: List of projects - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.response_default_config_api_v1_projects_default_config_get import ResponseDefaultConfigApiV1ProjectsDefaultConfigGet -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - - try: - # Default Config - api_response = api_instance.default_config_api_v1_projects_default_config_get() - print("The response of ProjectsApi->default_config_api_v1_projects_default_config_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->default_config_api_v1_projects_default_config_get: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**ResponseDefaultConfigApiV1ProjectsDefaultConfigGet**](ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_project_api_v1_projects_id_delete** -> Project delete_project_api_v1_projects_id_delete(id) - -Delete Project - -Delete project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was deleted - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Delete Project - api_response = api_instance.delete_project_api_v1_projects_id_delete(id) - print("The response of ProjectsApi->delete_project_api_v1_projects_id_delete:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->delete_project_api_v1_projects_id_delete: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **export_project_config_api_v1_projects_id_export_get** -> ProjectCreate export_project_config_api_v1_projects_id_export_get(id) - -Export Project Config - -Exports the project config by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: JSONResponse: json representation of the project with the informed project id - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project_create import ProjectCreate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Export Project Config - api_response = api_instance.export_project_config_api_v1_projects_id_export_get(id) - print("The response of ProjectsApi->export_project_config_api_v1_projects_id_export_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->export_project_config_api_v1_projects_id_export_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**ProjectCreate**](ProjectCreate.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **importproject_config_api_v1_projects_import_post** -> Project importproject_config_api_v1_projects_import_post(import_file) - -Importproject Config - -Imports the project config Args: import_file : The project config file to be imported Raises: ValidationError: if the imported project config contains invalid information Returns: Project: newly created project record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - import_file = api_lib_autogen.IO() # IO | - - try: - # Importproject Config - api_response = api_instance.importproject_config_api_v1_projects_import_post(import_file) - print("The response of ProjectsApi->importproject_config_api_v1_projects_import_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->importproject_config_api_v1_projects_import_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **import_file** | **IO**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: multipart/form-data - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_project_api_v1_projects_id_get** -> Project read_project_api_v1_projects_id_get(id) - -Read Project - -Lookup project by id Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Read Project - api_response = api_instance.read_project_api_v1_projects_id_get(id) - print("The response of ProjectsApi->read_project_api_v1_projects_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->read_project_api_v1_projects_id_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_projects_api_v1_projects_get** -> List[Project] read_projects_api_v1_projects_get(archived=archived, skip=skip, limit=limit) - -Read Projects - -Retrieve list of projects Args: archived (bool, optional): Get archived projects, when true will; get archived projects only, when false only non-archived projects are returned. Defaults to false. skip (int, optional): Pagination offset. Defaults to 0. limit (int, optional): max number of records to return. Defaults to 100. Returns: List[Project]: List of projects - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - archived = False # bool | (optional) (default to False) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # Read Projects - api_response = api_instance.read_projects_api_v1_projects_get(archived=archived, skip=skip, limit=limit) - print("The response of ProjectsApi->read_projects_api_v1_projects_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->read_projects_api_v1_projects_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **archived** | **bool**| | [optional] [default to False] - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[Project]**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete** -> Project remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete(id, cluster_name) - -Remove Pics Cluster Type - -Removes cluster based on given cluster name Args: id (int): ID of Project cluster_name (str): Name of the cluster to delete Raises: HTTPException: if no project exists for provided project id Returns: models.Project: Project with updated PICS entry - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - cluster_name = 'cluster_name_example' # str | - - try: - # Remove Pics Cluster Type - api_response = api_instance.remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete(id, cluster_name) - print("The response of ProjectsApi->remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->remove_pics_cluster_type_api_v1_projects_id_pics_cluster_type_delete: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **cluster_name** | **str**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **unarchive_project_api_v1_projects_id_unarchive_post** -> Project unarchive_project_api_v1_projects_id_unarchive_post(id) - -Unarchive Project - -Unarchive project by id. Args: id (int): project id Raises: HTTPException: if no project exists for provided project id Returns: Project: project record that was unarchived - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - - try: - # Unarchive Project - api_response = api_instance.unarchive_project_api_v1_projects_id_unarchive_post(id) - print("The response of ProjectsApi->unarchive_project_api_v1_projects_id_unarchive_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->unarchive_project_api_v1_projects_id_unarchive_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_project_api_v1_projects_id_put** -> Project update_project_api_v1_projects_id_put(id, project_update) - -Update Project - -Update an existing project Args: id (int): project id project_in (schemas.ProjectUpdate): projects parameters to be updated Raises: HTTPException: if no project exists for provided project id Returns: Project: updated project record - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.models.project_update import ProjectUpdate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - project_update = api_lib_autogen.ProjectUpdate() # ProjectUpdate | - - try: - # Update Project - api_response = api_instance.update_project_api_v1_projects_id_put(id, project_update) - print("The response of ProjectsApi->update_project_api_v1_projects_id_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->update_project_api_v1_projects_id_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **project_update** | [**ProjectUpdate**](ProjectUpdate.md)| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **upload_pics_api_v1_projects_id_upload_pics_put** -> Project upload_pics_api_v1_projects_id_upload_pics_put(id, file) - -Upload Pics - -Upload PICS or dmp-test-skip.xml file of a project based on project identifier. Args: id (int): project id file : the PICS or dmp-test-skip.xml file to upload Raises: HTTPException: if no project exists for provided project id (or) if the PICS file is invalid Returns: Project: project record that was updated with the PICS and dmp_test_skip information. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.project import Project -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.ProjectsApi(api_client) - id = 56 # int | - file = api_lib_autogen.IO() # IO | - - try: - # Upload Pics - api_response = api_instance.upload_pics_api_v1_projects_id_upload_pics_put(id, file) - print("The response of ProjectsApi->upload_pics_api_v1_projects_id_upload_pics_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling ProjectsApi->upload_pics_api_v1_projects_id_upload_pics_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **file** | **IO**| | - -### Return type - -[**Project**](Project.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: multipart/form-data - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.md b/th_cli/api_lib_autogen/docs/ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.md deleted file mode 100644 index 6aed1bd..0000000 --- a/th_cli/api_lib_autogen/docs/ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.md +++ /dev/null @@ -1,28 +0,0 @@ -# ResponseDefaultConfigApiV1ProjectsDefaultConfigGet - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_parameters** | [**Any**](.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.response_default_config_api_v1_projects_default_config_get import ResponseDefaultConfigApiV1ProjectsDefaultConfigGet - -# TODO update the JSON string below -json = "{}" -# create an instance of ResponseDefaultConfigApiV1ProjectsDefaultConfigGet from a JSON string -response_default_config_api_v1_projects_default_config_get_instance = ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.from_json(json) -# print the JSON string representation of the object -print ResponseDefaultConfigApiV1ProjectsDefaultConfigGet.to_json() - -# convert the object into a dict -response_default_config_api_v1_projects_default_config_get_dict = response_default_config_api_v1_projects_default_config_get_instance.to_dict() -# create an instance of ResponseDefaultConfigApiV1ProjectsDefaultConfigGet from a dict -response_default_config_api_v1_projects_default_config_get_form_dict = response_default_config_api_v1_projects_default_config_get.from_dict(response_default_config_api_v1_projects_default_config_get_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCase.md b/th_cli/api_lib_autogen/docs/TestCase.md deleted file mode 100644 index d44714b..0000000 --- a/th_cli/api_lib_autogen/docs/TestCase.md +++ /dev/null @@ -1,28 +0,0 @@ -# TestCase - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**metadata** | [**TestMetadata**](TestMetadata.md) | | - -## Example - -```python -from api_lib_autogen.models.test_case import TestCase - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCase from a JSON string -test_case_instance = TestCase.from_json(json) -# print the JSON string representation of the object -print TestCase.to_json() - -# convert the object into a dict -test_case_dict = test_case_instance.to_dict() -# create an instance of TestCase from a dict -test_case_form_dict = test_case.from_dict(test_case_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCaseExecution.md b/th_cli/api_lib_autogen/docs/TestCaseExecution.md deleted file mode 100644 index 6dc1bdf..0000000 --- a/th_cli/api_lib_autogen/docs/TestCaseExecution.md +++ /dev/null @@ -1,38 +0,0 @@ -# TestCaseExecution - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**public_id** | **str** | | -**execution_index** | **int** | | -**id** | **int** | | -**test_suite_execution_id** | **int** | | -**test_case_metadata_id** | **int** | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**test_case_metadata** | [**TestCaseMetadata**](TestCaseMetadata.md) | | -**test_step_executions** | [**List[TestStepExecution]**](TestStepExecution.md) | | - -## Example - -```python -from api_lib_autogen.models.test_case_execution import TestCaseExecution - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCaseExecution from a JSON string -test_case_execution_instance = TestCaseExecution.from_json(json) -# print the JSON string representation of the object -print TestCaseExecution.to_json() - -# convert the object into a dict -test_case_execution_dict = test_case_execution_instance.to_dict() -# create an instance of TestCaseExecution from a dict -test_case_execution_form_dict = test_case_execution.from_dict(test_case_execution_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCaseExecutionToExport.md b/th_cli/api_lib_autogen/docs/TestCaseExecutionToExport.md deleted file mode 100644 index ede94c3..0000000 --- a/th_cli/api_lib_autogen/docs/TestCaseExecutionToExport.md +++ /dev/null @@ -1,36 +0,0 @@ -# TestCaseExecutionToExport - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**public_id** | **str** | | -**execution_index** | **int** | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**test_case_metadata** | [**TestCaseMetadataBase**](TestCaseMetadataBase.md) | | -**test_step_executions** | [**List[TestStepExecutionToExport]**](TestStepExecutionToExport.md) | | -**created_at** | **datetime** | | - -## Example - -```python -from api_lib_autogen.models.test_case_execution_to_export import TestCaseExecutionToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCaseExecutionToExport from a JSON string -test_case_execution_to_export_instance = TestCaseExecutionToExport.from_json(json) -# print the JSON string representation of the object -print TestCaseExecutionToExport.to_json() - -# convert the object into a dict -test_case_execution_to_export_dict = test_case_execution_to_export_instance.to_dict() -# create an instance of TestCaseExecutionToExport from a dict -test_case_execution_to_export_form_dict = test_case_execution_to_export.from_dict(test_case_execution_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCaseMetadata.md b/th_cli/api_lib_autogen/docs/TestCaseMetadata.md deleted file mode 100644 index 7f4b170..0000000 --- a/th_cli/api_lib_autogen/docs/TestCaseMetadata.md +++ /dev/null @@ -1,34 +0,0 @@ -# TestCaseMetadata - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**public_id** | **str** | | -**title** | **str** | | -**description** | **str** | | -**version** | **str** | | -**source_hash** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] -**id** | **int** | | - -## Example - -```python -from api_lib_autogen.models.test_case_metadata import TestCaseMetadata - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCaseMetadata from a JSON string -test_case_metadata_instance = TestCaseMetadata.from_json(json) -# print the JSON string representation of the object -print TestCaseMetadata.to_json() - -# convert the object into a dict -test_case_metadata_dict = test_case_metadata_instance.to_dict() -# create an instance of TestCaseMetadata from a dict -test_case_metadata_form_dict = test_case_metadata.from_dict(test_case_metadata_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCaseMetadataBase.md b/th_cli/api_lib_autogen/docs/TestCaseMetadataBase.md deleted file mode 100644 index 79df2e9..0000000 --- a/th_cli/api_lib_autogen/docs/TestCaseMetadataBase.md +++ /dev/null @@ -1,33 +0,0 @@ -# TestCaseMetadataBase - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**public_id** | **str** | | -**title** | **str** | | -**description** | **str** | | -**version** | **str** | | -**source_hash** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] - -## Example - -```python -from api_lib_autogen.models.test_case_metadata_base import TestCaseMetadataBase - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCaseMetadataBase from a JSON string -test_case_metadata_base_instance = TestCaseMetadataBase.from_json(json) -# print the JSON string representation of the object -print TestCaseMetadataBase.to_json() - -# convert the object into a dict -test_case_metadata_base_dict = test_case_metadata_base_instance.to_dict() -# create an instance of TestCaseMetadataBase from a dict -test_case_metadata_base_form_dict = test_case_metadata_base.from_dict(test_case_metadata_base_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCollection.md b/th_cli/api_lib_autogen/docs/TestCollection.md deleted file mode 100644 index 6edb943..0000000 --- a/th_cli/api_lib_autogen/docs/TestCollection.md +++ /dev/null @@ -1,30 +0,0 @@ -# TestCollection - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**path** | **str** | | -**test_suites** | [**Dict[str, TestSuite]**](TestSuite.md) | | - -## Example - -```python -from api_lib_autogen.models.test_collection import TestCollection - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCollection from a JSON string -test_collection_instance = TestCollection.from_json(json) -# print the JSON string representation of the object -print TestCollection.to_json() - -# convert the object into a dict -test_collection_dict = test_collection_instance.to_dict() -# create an instance of TestCollection from a dict -test_collection_form_dict = test_collection.from_dict(test_collection_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCollections.md b/th_cli/api_lib_autogen/docs/TestCollections.md deleted file mode 100644 index f99419e..0000000 --- a/th_cli/api_lib_autogen/docs/TestCollections.md +++ /dev/null @@ -1,28 +0,0 @@ -# TestCollections - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_collections** | [**Dict[str, TestCollection]**](TestCollection.md) | | - -## Example - -```python -from api_lib_autogen.models.test_collections import TestCollections - -# TODO update the JSON string below -json = "{}" -# create an instance of TestCollections from a JSON string -test_collections_instance = TestCollections.from_json(json) -# print the JSON string representation of the object -print TestCollections.to_json() - -# convert the object into a dict -test_collections_dict = test_collections_instance.to_dict() -# create an instance of TestCollections from a dict -test_collections_form_dict = test_collections.from_dict(test_collections_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestCollectionsApi.md b/th_cli/api_lib_autogen/docs/TestCollectionsApi.md deleted file mode 100644 index 2f208d4..0000000 --- a/th_cli/api_lib_autogen/docs/TestCollectionsApi.md +++ /dev/null @@ -1,72 +0,0 @@ -# api_lib_autogen.TestCollectionsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**read_test_collections_api_v1_test_collections_get**](TestCollectionsApi.md#read_test_collections_api_v1_test_collections_get) | **GET** /api/v1/test_collections/ | Read Test Collections - - -# **read_test_collections_api_v1_test_collections_get** -> TestCollections read_test_collections_api_v1_test_collections_get() - -Read Test Collections - -Retrieve available test collections. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_collections import TestCollections -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestCollectionsApi(api_client) - - try: - # Read Test Collections - api_response = api_instance.read_test_collections_api_v1_test_collections_get() - print("The response of TestCollectionsApi->read_test_collections_api_v1_test_collections_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestCollectionsApi->read_test_collections_api_v1_test_collections_get: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**TestCollections**](TestCollections.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/TestEnvironmentConfig.md b/th_cli/api_lib_autogen/docs/TestEnvironmentConfig.md deleted file mode 100644 index 786dbe4..0000000 --- a/th_cli/api_lib_autogen/docs/TestEnvironmentConfig.md +++ /dev/null @@ -1,28 +0,0 @@ -# TestEnvironmentConfig - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_parameters** | [**Any**](.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_environment_config import TestEnvironmentConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of TestEnvironmentConfig from a JSON string -test_environment_config_instance = TestEnvironmentConfig.from_json(json) -# print the JSON string representation of the object -print TestEnvironmentConfig.to_json() - -# convert the object into a dict -test_environment_config_dict = test_environment_config_instance.to_dict() -# create an instance of TestEnvironmentConfig from a dict -test_environment_config_form_dict = test_environment_config.from_dict(test_environment_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestHarnessBackendVersion.md b/th_cli/api_lib_autogen/docs/TestHarnessBackendVersion.md deleted file mode 100644 index 227e3c9..0000000 --- a/th_cli/api_lib_autogen/docs/TestHarnessBackendVersion.md +++ /dev/null @@ -1,32 +0,0 @@ -# TestHarnessBackendVersion - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**version** | **str** | | -**sha** | **str** | | -**sdk_sha** | **str** | | -**sdk_docker_tag** | **str** | | -**db_revision** | **str** | | - -## Example - -```python -from api_lib_autogen.models.test_harness_backend_version import TestHarnessBackendVersion - -# TODO update the JSON string below -json = "{}" -# create an instance of TestHarnessBackendVersion from a JSON string -test_harness_backend_version_instance = TestHarnessBackendVersion.from_json(json) -# print the JSON string representation of the object -print TestHarnessBackendVersion.to_json() - -# convert the object into a dict -test_harness_backend_version_dict = test_harness_backend_version_instance.to_dict() -# create an instance of TestHarnessBackendVersion from a dict -test_harness_backend_version_form_dict = test_harness_backend_version.from_dict(test_harness_backend_version_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestMetadata.md b/th_cli/api_lib_autogen/docs/TestMetadata.md deleted file mode 100644 index c614237..0000000 --- a/th_cli/api_lib_autogen/docs/TestMetadata.md +++ /dev/null @@ -1,32 +0,0 @@ -# TestMetadata - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**public_id** | **str** | | -**version** | **str** | | -**title** | **str** | | -**description** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] - -## Example - -```python -from api_lib_autogen.models.test_metadata import TestMetadata - -# TODO update the JSON string below -json = "{}" -# create an instance of TestMetadata from a JSON string -test_metadata_instance = TestMetadata.from_json(json) -# print the JSON string representation of the object -print TestMetadata.to_json() - -# convert the object into a dict -test_metadata_dict = test_metadata_instance.to_dict() -# create an instance of TestMetadata from a dict -test_metadata_form_dict = test_metadata.from_dict(test_metadata_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunConfig.md b/th_cli/api_lib_autogen/docs/TestRunConfig.md deleted file mode 100644 index cadc29b..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunConfig.md +++ /dev/null @@ -1,31 +0,0 @@ -# TestRunConfig - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**dut_name** | **str** | | -**selected_tests** | **Dict[str, Dict[str, Dict[str, int]]]** | | [optional] -**id** | **int** | | - -## Example - -```python -from api_lib_autogen.models.test_run_config import TestRunConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunConfig from a JSON string -test_run_config_instance = TestRunConfig.from_json(json) -# print the JSON string representation of the object -print TestRunConfig.to_json() - -# convert the object into a dict -test_run_config_dict = test_run_config_instance.to_dict() -# create an instance of TestRunConfig from a dict -test_run_config_form_dict = test_run_config.from_dict(test_run_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunConfigCreate.md b/th_cli/api_lib_autogen/docs/TestRunConfigCreate.md deleted file mode 100644 index ad5dbbc..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunConfigCreate.md +++ /dev/null @@ -1,30 +0,0 @@ -# TestRunConfigCreate - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**dut_name** | **str** | | -**selected_tests** | **Dict[str, Dict[str, Dict[str, int]]]** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_config_create import TestRunConfigCreate - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunConfigCreate from a JSON string -test_run_config_create_instance = TestRunConfigCreate.from_json(json) -# print the JSON string representation of the object -print TestRunConfigCreate.to_json() - -# convert the object into a dict -test_run_config_create_dict = test_run_config_create_instance.to_dict() -# create an instance of TestRunConfigCreate from a dict -test_run_config_create_form_dict = test_run_config_create.from_dict(test_run_config_create_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunConfigToExport.md b/th_cli/api_lib_autogen/docs/TestRunConfigToExport.md deleted file mode 100644 index 05f8652..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunConfigToExport.md +++ /dev/null @@ -1,31 +0,0 @@ -# TestRunConfigToExport - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**dut_name** | **str** | | -**selected_tests** | **Dict[str, Dict[str, Dict[str, int]]]** | | [optional] -**created_at** | **datetime** | | - -## Example - -```python -from api_lib_autogen.models.test_run_config_to_export import TestRunConfigToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunConfigToExport from a JSON string -test_run_config_to_export_instance = TestRunConfigToExport.from_json(json) -# print the JSON string representation of the object -print TestRunConfigToExport.to_json() - -# convert the object into a dict -test_run_config_to_export_dict = test_run_config_to_export_instance.to_dict() -# create an instance of TestRunConfigToExport from a dict -test_run_config_to_export_form_dict = test_run_config_to_export.from_dict(test_run_config_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunConfigUpdate.md b/th_cli/api_lib_autogen/docs/TestRunConfigUpdate.md deleted file mode 100644 index 9e3af03..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunConfigUpdate.md +++ /dev/null @@ -1,28 +0,0 @@ -# TestRunConfigUpdate - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | - -## Example - -```python -from api_lib_autogen.models.test_run_config_update import TestRunConfigUpdate - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunConfigUpdate from a JSON string -test_run_config_update_instance = TestRunConfigUpdate.from_json(json) -# print the JSON string representation of the object -print TestRunConfigUpdate.to_json() - -# convert the object into a dict -test_run_config_update_dict = test_run_config_update_instance.to_dict() -# create an instance of TestRunConfigUpdate from a dict -test_run_config_update_form_dict = test_run_config_update.from_dict(test_run_config_update_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunConfigsApi.md b/th_cli/api_lib_autogen/docs/TestRunConfigsApi.md deleted file mode 100644 index 10a3bdb..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunConfigsApi.md +++ /dev/null @@ -1,290 +0,0 @@ -# api_lib_autogen.TestRunConfigsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_test_run_config_api_v1_test_run_configs_post**](TestRunConfigsApi.md#create_test_run_config_api_v1_test_run_configs_post) | **POST** /api/v1/test_run_configs/ | Create Test Run Config -[**read_test_run_config_api_v1_test_run_configs_id_get**](TestRunConfigsApi.md#read_test_run_config_api_v1_test_run_configs_id_get) | **GET** /api/v1/test_run_configs/{id} | Read Test Run Config -[**read_test_run_configs_api_v1_test_run_configs_get**](TestRunConfigsApi.md#read_test_run_configs_api_v1_test_run_configs_get) | **GET** /api/v1/test_run_configs/ | Read Test Run Configs -[**update_test_run_config_api_v1_test_run_configs_id_put**](TestRunConfigsApi.md#update_test_run_config_api_v1_test_run_configs_id_put) | **PUT** /api/v1/test_run_configs/{id} | Update Test Run Config - - -# **create_test_run_config_api_v1_test_run_configs_post** -> TestRunConfig create_test_run_config_api_v1_test_run_configs_post(test_run_config_create) - -Create Test Run Config - -Create new test run config. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_config import TestRunConfig -from api_lib_autogen.models.test_run_config_create import TestRunConfigCreate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunConfigsApi(api_client) - test_run_config_create = api_lib_autogen.TestRunConfigCreate() # TestRunConfigCreate | - - try: - # Create Test Run Config - api_response = api_instance.create_test_run_config_api_v1_test_run_configs_post(test_run_config_create) - print("The response of TestRunConfigsApi->create_test_run_config_api_v1_test_run_configs_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunConfigsApi->create_test_run_config_api_v1_test_run_configs_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **test_run_config_create** | [**TestRunConfigCreate**](TestRunConfigCreate.md)| | - -### Return type - -[**TestRunConfig**](TestRunConfig.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_test_run_config_api_v1_test_run_configs_id_get** -> TestRunConfig read_test_run_config_api_v1_test_run_configs_id_get(id) - -Read Test Run Config - -Get test run config by ID. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_config import TestRunConfig -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunConfigsApi(api_client) - id = 56 # int | - - try: - # Read Test Run Config - api_response = api_instance.read_test_run_config_api_v1_test_run_configs_id_get(id) - print("The response of TestRunConfigsApi->read_test_run_config_api_v1_test_run_configs_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunConfigsApi->read_test_run_config_api_v1_test_run_configs_id_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunConfig**](TestRunConfig.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_test_run_configs_api_v1_test_run_configs_get** -> List[TestRunConfig] read_test_run_configs_api_v1_test_run_configs_get(skip=skip, limit=limit) - -Read Test Run Configs - -Retrieve test_run_configs. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_config import TestRunConfig -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunConfigsApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # Read Test Run Configs - api_response = api_instance.read_test_run_configs_api_v1_test_run_configs_get(skip=skip, limit=limit) - print("The response of TestRunConfigsApi->read_test_run_configs_api_v1_test_run_configs_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunConfigsApi->read_test_run_configs_api_v1_test_run_configs_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[TestRunConfig]**](TestRunConfig.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_test_run_config_api_v1_test_run_configs_id_put** -> TestRunConfig update_test_run_config_api_v1_test_run_configs_id_put(id, test_run_config_update) - -Update Test Run Config - -Update a test run config. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_config import TestRunConfig -from api_lib_autogen.models.test_run_config_update import TestRunConfigUpdate -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunConfigsApi(api_client) - id = 56 # int | - test_run_config_update = api_lib_autogen.TestRunConfigUpdate() # TestRunConfigUpdate | - - try: - # Update Test Run Config - api_response = api_instance.update_test_run_config_api_v1_test_run_configs_id_put(id, test_run_config_update) - print("The response of TestRunConfigsApi->update_test_run_config_api_v1_test_run_configs_id_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunConfigsApi->update_test_run_config_api_v1_test_run_configs_id_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **test_run_config_update** | [**TestRunConfigUpdate**](TestRunConfigUpdate.md)| | - -### Return type - -[**TestRunConfig**](TestRunConfig.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecution.md b/th_cli/api_lib_autogen/docs/TestRunExecution.md deleted file mode 100644 index 6d0655c..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecution.md +++ /dev/null @@ -1,40 +0,0 @@ -# TestRunExecution - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**test_run_config_id** | **int** | | [optional] -**project_id** | **int** | | [optional] -**id** | **int** | | -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**imported_at** | **datetime** | | [optional] -**archived_at** | **datetime** | | [optional] -**operator** | [**Operator**](Operator.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution import TestRunExecution - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecution from a JSON string -test_run_execution_instance = TestRunExecution.from_json(json) -# print the JSON string representation of the object -print TestRunExecution.to_json() - -# convert the object into a dict -test_run_execution_dict = test_run_execution_instance.to_dict() -# create an instance of TestRunExecution from a dict -test_run_execution_form_dict = test_run_execution.from_dict(test_run_execution_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionCreate.md b/th_cli/api_lib_autogen/docs/TestRunExecutionCreate.md deleted file mode 100644 index 75fe60c..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionCreate.md +++ /dev/null @@ -1,34 +0,0 @@ -# TestRunExecutionCreate - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**test_run_config_id** | **int** | | [optional] -**project_id** | **int** | | [optional] -**operator_id** | **int** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution_create import TestRunExecutionCreate - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionCreate from a JSON string -test_run_execution_create_instance = TestRunExecutionCreate.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionCreate.to_json() - -# convert the object into a dict -test_run_execution_create_dict = test_run_execution_create_instance.to_dict() -# create an instance of TestRunExecutionCreate from a dict -test_run_execution_create_form_dict = test_run_execution_create.from_dict(test_run_execution_create_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionInDBBase.md b/th_cli/api_lib_autogen/docs/TestRunExecutionInDBBase.md deleted file mode 100644 index 66bc3a2..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionInDBBase.md +++ /dev/null @@ -1,39 +0,0 @@ -# TestRunExecutionInDBBase - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**test_run_config_id** | **int** | | [optional] -**project_id** | **int** | | [optional] -**id** | **int** | | -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**imported_at** | **datetime** | | [optional] -**archived_at** | **datetime** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution_in_db_base import TestRunExecutionInDBBase - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionInDBBase from a JSON string -test_run_execution_in_db_base_instance = TestRunExecutionInDBBase.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionInDBBase.to_json() - -# convert the object into a dict -test_run_execution_in_db_base_dict = test_run_execution_in_db_base_instance.to_dict() -# create an instance of TestRunExecutionInDBBase from a dict -test_run_execution_in_db_base_form_dict = test_run_execution_in_db_base.from_dict(test_run_execution_in_db_base_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionStats.md b/th_cli/api_lib_autogen/docs/TestRunExecutionStats.md deleted file mode 100644 index 53c7c9b..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionStats.md +++ /dev/null @@ -1,29 +0,0 @@ -# TestRunExecutionStats - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**test_case_count** | **int** | | [optional] [default to 0] -**states** | **Dict[str, int]** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution_stats import TestRunExecutionStats - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionStats from a JSON string -test_run_execution_stats_instance = TestRunExecutionStats.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionStats.to_json() - -# convert the object into a dict -test_run_execution_stats_dict = test_run_execution_stats_instance.to_dict() -# create an instance of TestRunExecutionStats from a dict -test_run_execution_stats_form_dict = test_run_execution_stats.from_dict(test_run_execution_stats_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionToExport.md b/th_cli/api_lib_autogen/docs/TestRunExecutionToExport.md deleted file mode 100644 index d7e76ec..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionToExport.md +++ /dev/null @@ -1,40 +0,0 @@ -# TestRunExecutionToExport - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**archived_at** | **datetime** | | [optional] -**test_suite_executions** | [**List[TestSuiteExecutionToExport]**](TestSuiteExecutionToExport.md) | | [optional] -**created_at** | **datetime** | | -**log** | [**List[TestRunLogEntry]**](TestRunLogEntry.md) | | -**operator** | [**OperatorToExport**](OperatorToExport.md) | | [optional] -**test_run_config** | [**TestRunConfigToExport**](TestRunConfigToExport.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution_to_export import TestRunExecutionToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionToExport from a JSON string -test_run_execution_to_export_instance = TestRunExecutionToExport.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionToExport.to_json() - -# convert the object into a dict -test_run_execution_to_export_dict = test_run_execution_to_export_instance.to_dict() -# create an instance of TestRunExecutionToExport from a dict -test_run_execution_to_export_form_dict = test_run_execution_to_export.from_dict(test_run_execution_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionWithChildren.md b/th_cli/api_lib_autogen/docs/TestRunExecutionWithChildren.md deleted file mode 100644 index 5101387..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionWithChildren.md +++ /dev/null @@ -1,41 +0,0 @@ -# TestRunExecutionWithChildren - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**test_run_config_id** | **int** | | [optional] -**project_id** | **int** | | [optional] -**id** | **int** | | -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**imported_at** | **datetime** | | [optional] -**archived_at** | **datetime** | | [optional] -**operator** | [**Operator**](Operator.md) | | [optional] -**test_suite_executions** | [**List[TestSuiteExecution]**](TestSuiteExecution.md) | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionWithChildren from a JSON string -test_run_execution_with_children_instance = TestRunExecutionWithChildren.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionWithChildren.to_json() - -# convert the object into a dict -test_run_execution_with_children_dict = test_run_execution_with_children_instance.to_dict() -# create an instance of TestRunExecutionWithChildren from a dict -test_run_execution_with_children_form_dict = test_run_execution_with_children.from_dict(test_run_execution_with_children_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionWithStats.md b/th_cli/api_lib_autogen/docs/TestRunExecutionWithStats.md deleted file mode 100644 index 2f179fe..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionWithStats.md +++ /dev/null @@ -1,41 +0,0 @@ -# TestRunExecutionWithStats - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**title** | **str** | | -**description** | **str** | | [optional] -**execution_config** | [**Any**](.md) | | [optional] -**certification_mode** | **bool** | | [optional] [default to False] -**test_run_config_id** | **int** | | [optional] -**project_id** | **int** | | [optional] -**id** | **int** | | -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**imported_at** | **datetime** | | [optional] -**archived_at** | **datetime** | | [optional] -**operator** | [**Operator**](Operator.md) | | [optional] -**test_case_stats** | [**TestRunExecutionStats**](TestRunExecutionStats.md) | | - -## Example - -```python -from api_lib_autogen.models.test_run_execution_with_stats import TestRunExecutionWithStats - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunExecutionWithStats from a JSON string -test_run_execution_with_stats_instance = TestRunExecutionWithStats.from_json(json) -# print the JSON string representation of the object -print TestRunExecutionWithStats.to_json() - -# convert the object into a dict -test_run_execution_with_stats_dict = test_run_execution_with_stats_instance.to_dict() -# create an instance of TestRunExecutionWithStats from a dict -test_run_execution_with_stats_form_dict = test_run_execution_with_stats.from_dict(test_run_execution_with_stats_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunExecutionsApi.md b/th_cli/api_lib_autogen/docs/TestRunExecutionsApi.md deleted file mode 100644 index 894fb61..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunExecutionsApi.md +++ /dev/null @@ -1,1336 +0,0 @@ -# api_lib_autogen.TestRunExecutionsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**abort_testing_api_v1_test_run_executions_abort_testing_post**](TestRunExecutionsApi.md#abort_testing_api_v1_test_run_executions_abort_testing_post) | **POST** /api/v1/test_run_executions/abort-testing | Abort Testing -[**archive_api_v1_test_run_executions_id_archive_post**](TestRunExecutionsApi.md#archive_api_v1_test_run_executions_id_archive_post) | **POST** /api/v1/test_run_executions/{id}/archive | Archive -[**create_cli_test_run_execution_api_v1_test_run_executions_cli_post**](TestRunExecutionsApi.md#create_cli_test_run_execution_api_v1_test_run_executions_cli_post) | **POST** /api/v1/test_run_executions/cli | Create Cli Test Run Execution -[**create_test_run_execution_api_v1_test_run_executions_post**](TestRunExecutionsApi.md#create_test_run_execution_api_v1_test_run_executions_post) | **POST** /api/v1/test_run_executions/ | Create Test Run Execution -[**download_grouped_log_api_v1_test_run_executions_id_grouped_log_get**](TestRunExecutionsApi.md#download_grouped_log_api_v1_test_run_executions_id_grouped_log_get) | **GET** /api/v1/test_run_executions/{id}/grouped-log | Download Grouped Log -[**download_log_api_v1_test_run_executions_id_log_get**](TestRunExecutionsApi.md#download_log_api_v1_test_run_executions_id_log_get) | **GET** /api/v1/test_run_executions/{id}/log | Download Log -[**export_test_run_execution_api_v1_test_run_executions_id_export_get**](TestRunExecutionsApi.md#export_test_run_execution_api_v1_test_run_executions_id_export_get) | **GET** /api/v1/test_run_executions/{id}/export | Export Test Run Execution -[**generate_summary_log_api_v1_test_run_executions_id_performance_summary_post**](TestRunExecutionsApi.md#generate_summary_log_api_v1_test_run_executions_id_performance_summary_post) | **POST** /api/v1/test_run_executions/{id}/performance_summary | Generate Summary Log -[**get_chip_server_info_api_v1_test_run_executions_chip_server_info_get**](TestRunExecutionsApi.md#get_chip_server_info_api_v1_test_run_executions_chip_server_info_get) | **GET** /api/v1/test_run_executions/chip-server/info | Get Chip Server Info -[**get_test_runner_status_api_v1_test_run_executions_status_get**](TestRunExecutionsApi.md#get_test_runner_status_api_v1_test_run_executions_status_get) | **GET** /api/v1/test_run_executions/status | Get Test Runner Status -[**import_test_run_execution_api_v1_test_run_executions_import_post**](TestRunExecutionsApi.md#import_test_run_execution_api_v1_test_run_executions_import_post) | **POST** /api/v1/test_run_executions/import | Import Test Run Execution -[**read_test_run_execution_api_v1_test_run_executions_id_get**](TestRunExecutionsApi.md#read_test_run_execution_api_v1_test_run_executions_id_get) | **GET** /api/v1/test_run_executions/{id} | Read Test Run Execution -[**read_test_run_executions_api_v1_test_run_executions_get**](TestRunExecutionsApi.md#read_test_run_executions_api_v1_test_run_executions_get) | **GET** /api/v1/test_run_executions/ | Read Test Run Executions -[**remove_test_run_execution_api_v1_test_run_executions_id_delete**](TestRunExecutionsApi.md#remove_test_run_execution_api_v1_test_run_executions_id_delete) | **DELETE** /api/v1/test_run_executions/{id} | Remove Test Run Execution -[**rename_test_run_execution_api_v1_test_run_executions_id_rename_put**](TestRunExecutionsApi.md#rename_test_run_execution_api_v1_test_run_executions_id_rename_put) | **PUT** /api/v1/test_run_executions/{id}/rename | Rename Test Run Execution -[**repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post**](TestRunExecutionsApi.md#repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post) | **POST** /api/v1/test_run_executions/{id}/repeat | Repeat Test Run Execution -[**start_test_run_execution_api_v1_test_run_executions_id_start_post**](TestRunExecutionsApi.md#start_test_run_execution_api_v1_test_run_executions_id_start_post) | **POST** /api/v1/test_run_executions/{id}/start | Start Test Run Execution -[**unarchive_api_v1_test_run_executions_id_unarchive_post**](TestRunExecutionsApi.md#unarchive_api_v1_test_run_executions_id_unarchive_post) | **POST** /api/v1/test_run_executions/{id}/unarchive | Unarchive -[**upload_file_api_v1_test_run_executions_file_upload_post**](TestRunExecutionsApi.md#upload_file_api_v1_test_run_executions_file_upload_post) | **POST** /api/v1/test_run_executions/file_upload/ | Upload File - - -# **abort_testing_api_v1_test_run_executions_abort_testing_post** -> Dict[str, str] abort_testing_api_v1_test_run_executions_abort_testing_post() - -Abort Testing - -Cancel the current testing - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - - try: - # Abort Testing - api_response = api_instance.abort_testing_api_v1_test_run_executions_abort_testing_post() - print("The response of TestRunExecutionsApi->abort_testing_api_v1_test_run_executions_abort_testing_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->abort_testing_api_v1_test_run_executions_abort_testing_post: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -**Dict[str, str]** - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **archive_api_v1_test_run_executions_id_archive_post** -> TestRunExecution archive_api_v1_test_run_executions_id_archive_post(id) - -Archive - -Archive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was archived - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution import TestRunExecution -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Archive - api_response = api_instance.archive_api_v1_test_run_executions_id_archive_post(id) - print("The response of TestRunExecutionsApi->archive_api_v1_test_run_executions_id_archive_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->archive_api_v1_test_run_executions_id_archive_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunExecution**](TestRunExecution.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **create_cli_test_run_execution_api_v1_test_run_executions_cli_post** -> TestRunExecutionWithChildren create_cli_test_run_execution_api_v1_test_run_executions_cli_post(body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post) - -Create Cli Test Run Execution - -Creates a new test run execution on CLI request. Attention: if both config and execution_config are provided, only config will be persisted, while execution_config will be for this execution only. Args: test_run_execution_in: Test run execution data selected_tests: Selected tests to run config: Configuration parameters that update project (optional, persists) execution_config: Execution-specific config override (optional, temporary) pics: PICS configuration (optional) - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post import BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post = api_lib_autogen.BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost() # BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost | - - try: - # Create Cli Test Run Execution - api_response = api_instance.create_cli_test_run_execution_api_v1_test_run_executions_cli_post(body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post) - print("The response of TestRunExecutionsApi->create_cli_test_run_execution_api_v1_test_run_executions_cli_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->create_cli_test_run_execution_api_v1_test_run_executions_cli_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body_create_cli_test_run_execution_api_v1_test_run_executions_cli_post** | [**BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost**](BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost.md)| | - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **create_test_run_execution_api_v1_test_run_executions_post** -> TestRunExecutionWithChildren create_test_run_execution_api_v1_test_run_executions_post(body_create_test_run_execution_api_v1_test_run_executions_post, certification_mode=certification_mode) - -Create Test Run Execution - -Create a new test run execution. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.body_create_test_run_execution_api_v1_test_run_executions_post import BodyCreateTestRunExecutionApiV1TestRunExecutionsPost -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - body_create_test_run_execution_api_v1_test_run_executions_post = api_lib_autogen.BodyCreateTestRunExecutionApiV1TestRunExecutionsPost() # BodyCreateTestRunExecutionApiV1TestRunExecutionsPost | - certification_mode = False # bool | (optional) (default to False) - - try: - # Create Test Run Execution - api_response = api_instance.create_test_run_execution_api_v1_test_run_executions_post(body_create_test_run_execution_api_v1_test_run_executions_post, certification_mode=certification_mode) - print("The response of TestRunExecutionsApi->create_test_run_execution_api_v1_test_run_executions_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->create_test_run_execution_api_v1_test_run_executions_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **body_create_test_run_execution_api_v1_test_run_executions_post** | [**BodyCreateTestRunExecutionApiV1TestRunExecutionsPost**](BodyCreateTestRunExecutionApiV1TestRunExecutionsPost.md)| | - **certification_mode** | **bool**| | [optional] [default to False] - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **download_grouped_log_api_v1_test_run_executions_id_grouped_log_get** -> download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(id) - -Download Grouped Log - -Download the logs from a test run, grouped by test case state. Args: id (int): ID of the TestRunExectution the log is requested for Raises: HTTPException: If there's no TestRunExectution with the given ID Returns: StreamingResponse: .zip file containing: one file with the list of test cases for each state; one file with the logs from the executed test suites; one file per state with the logs from all test cases that finished with that state - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Download Grouped Log - api_instance.download_grouped_log_api_v1_test_run_executions_id_grouped_log_get(id) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->download_grouped_log_api_v1_test_run_executions_id_grouped_log_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **download_log_api_v1_test_run_executions_id_log_get** -> download_log_api_v1_test_run_executions_id_log_get(id, json_entries=json_entries, download=download) - -Download Log - -Download the logs from a test run. Args: id (int): Id of the TestRunExectution the log is requested for json_entries (bool, optional): When set, return each log line as a json object download (bool, optional): When set, return as attachment - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - json_entries = False # bool | (optional) (default to False) - download = False # bool | (optional) (default to False) - - try: - # Download Log - api_instance.download_log_api_v1_test_run_executions_id_log_get(id, json_entries=json_entries, download=download) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->download_log_api_v1_test_run_executions_id_log_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **json_entries** | **bool**| | [optional] [default to False] - **download** | **bool**| | [optional] [default to False] - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **export_test_run_execution_api_v1_test_run_executions_id_export_get** -> ExportedTestRunExecution export_test_run_execution_api_v1_test_run_executions_id_export_get(id, download=download) - -Export Test Run Execution - -Exports a test run execution by the given ID. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.exported_test_run_execution import ExportedTestRunExecution -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - download = False # bool | (optional) (default to False) - - try: - # Export Test Run Execution - api_response = api_instance.export_test_run_execution_api_v1_test_run_executions_id_export_get(id, download=download) - print("The response of TestRunExecutionsApi->export_test_run_execution_api_v1_test_run_executions_id_export_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->export_test_run_execution_api_v1_test_run_executions_id_export_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **download** | **bool**| | [optional] [default to False] - -### Return type - -[**ExportedTestRunExecution**](ExportedTestRunExecution.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **generate_summary_log_api_v1_test_run_executions_id_performance_summary_post** -> Any generate_summary_log_api_v1_test_run_executions_id_performance_summary_post(id, project_id) - -Generate Summary Log - -Imports a test run execution to the the given project_id. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - project_id = 56 # int | - - try: - # Generate Summary Log - api_response = api_instance.generate_summary_log_api_v1_test_run_executions_id_performance_summary_post(id, project_id) - print("The response of TestRunExecutionsApi->generate_summary_log_api_v1_test_run_executions_id_performance_summary_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->generate_summary_log_api_v1_test_run_executions_id_performance_summary_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **project_id** | **int**| | - -### Return type - -**Any** - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_chip_server_info_api_v1_test_run_executions_chip_server_info_get** -> ChipServerInfo get_chip_server_info_api_v1_test_run_executions_chip_server_info_get(discriminator=discriminator, setup_pin_code=setup_pin_code, version=version, vendor_id=vendor_id, product_id=product_id) - -Get Chip Server Info - -Retrieve ChipServer node ID information and generate manual pairing code. Note: Manual pairing code generation requires the SDK container to be running. If called before the SDK container starts, manual_pairing_code will be None. Args: discriminator: Device discriminator (optional) setup_pin_code: Setup PIN code (optional) version: Version number (default: 0) vendor_id: Vendor ID (default: 0) product_id: Product ID (default: 0) Returns: ChipServerInfo: Contains node_id, node_id_hex, and optional manual_pairing_code. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.chip_server_info import ChipServerInfo -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - discriminator = 'discriminator_example' # str | (optional) - setup_pin_code = 'setup_pin_code_example' # str | (optional) - version = 0 # int | (optional) (default to 0) - vendor_id = 0 # int | (optional) (default to 0) - product_id = 0 # int | (optional) (default to 0) - - try: - # Get Chip Server Info - api_response = api_instance.get_chip_server_info_api_v1_test_run_executions_chip_server_info_get(discriminator=discriminator, setup_pin_code=setup_pin_code, version=version, vendor_id=vendor_id, product_id=product_id) - print("The response of TestRunExecutionsApi->get_chip_server_info_api_v1_test_run_executions_chip_server_info_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->get_chip_server_info_api_v1_test_run_executions_chip_server_info_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **discriminator** | **str**| | [optional] - **setup_pin_code** | **str**| | [optional] - **version** | **int**| | [optional] [default to 0] - **vendor_id** | **int**| | [optional] [default to 0] - **product_id** | **int**| | [optional] [default to 0] - -### Return type - -[**ChipServerInfo**](ChipServerInfo.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_test_runner_status_api_v1_test_run_executions_status_get** -> TestRunnerStatus get_test_runner_status_api_v1_test_run_executions_status_get() - -Get Test Runner Status - -Retrieve status of the Test Engine. When the Test Engine is actively running the status will include the current test_run and the details of the states. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_runner_status import TestRunnerStatus -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - - try: - # Get Test Runner Status - api_response = api_instance.get_test_runner_status_api_v1_test_run_executions_status_get() - print("The response of TestRunExecutionsApi->get_test_runner_status_api_v1_test_run_executions_status_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->get_test_runner_status_api_v1_test_run_executions_status_get: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**TestRunnerStatus**](TestRunnerStatus.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **import_test_run_execution_api_v1_test_run_executions_import_post** -> TestRunExecutionWithChildren import_test_run_execution_api_v1_test_run_executions_import_post(project_id, import_file) - -Import Test Run Execution - -Imports a test run execution to the the given project_id. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - project_id = 56 # int | - import_file = api_lib_autogen.IO() # IO | - - try: - # Import Test Run Execution - api_response = api_instance.import_test_run_execution_api_v1_test_run_executions_import_post(project_id, import_file) - print("The response of TestRunExecutionsApi->import_test_run_execution_api_v1_test_run_executions_import_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->import_test_run_execution_api_v1_test_run_executions_import_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **project_id** | **int**| | - **import_file** | **IO**| | - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: multipart/form-data - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_test_run_execution_api_v1_test_run_executions_id_get** -> TestRunExecutionWithChildren read_test_run_execution_api_v1_test_run_executions_id_get(id) - -Read Test Run Execution - -Get test run by ID, including state on all children - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Read Test Run Execution - api_response = api_instance.read_test_run_execution_api_v1_test_run_executions_id_get(id) - print("The response of TestRunExecutionsApi->read_test_run_execution_api_v1_test_run_executions_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->read_test_run_execution_api_v1_test_run_executions_id_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **read_test_run_executions_api_v1_test_run_executions_get** -> List[TestRunExecutionWithStats] read_test_run_executions_api_v1_test_run_executions_get(project_id=project_id, archived=archived, search_query=search_query, skip=skip, limit=limit, sort_order=sort_order) - -Read Test Run Executions - -Retrieve test runs, including statistics. Args: project_id: Filter test runs by project. archived: Get archived test runs, when true will return archived test runs only, when false only non-archived test runs are returned. skip: Pagination offset. limit: Max number of records to return. Set to 0 to return all results. sort_order: Sort order for results. Either \"asc\" or \"desc\". Defaults to \"asc\". Results are sorted by ID. Returns: List of test runs with execution statistics. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_stats import TestRunExecutionWithStats -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - project_id = 56 # int | (optional) - archived = False # bool | (optional) (default to False) - search_query = 'search_query_example' # str | (optional) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - sort_order = 'asc' # str | (optional) (default to 'asc') - - try: - # Read Test Run Executions - api_response = api_instance.read_test_run_executions_api_v1_test_run_executions_get(project_id=project_id, archived=archived, search_query=search_query, skip=skip, limit=limit, sort_order=sort_order) - print("The response of TestRunExecutionsApi->read_test_run_executions_api_v1_test_run_executions_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->read_test_run_executions_api_v1_test_run_executions_get: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **project_id** | **int**| | [optional] - **archived** | **bool**| | [optional] [default to False] - **search_query** | **str**| | [optional] - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - **sort_order** | **str**| | [optional] [default to 'asc'] - -### Return type - -[**List[TestRunExecutionWithStats]**](TestRunExecutionWithStats.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **remove_test_run_execution_api_v1_test_run_executions_id_delete** -> TestRunExecutionInDBBase remove_test_run_execution_api_v1_test_run_executions_id_delete(id) - -Remove Test Run Execution - -Remove test run execution - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_in_db_base import TestRunExecutionInDBBase -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Remove Test Run Execution - api_response = api_instance.remove_test_run_execution_api_v1_test_run_executions_id_delete(id) - print("The response of TestRunExecutionsApi->remove_test_run_execution_api_v1_test_run_executions_id_delete:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->remove_test_run_execution_api_v1_test_run_executions_id_delete: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunExecutionInDBBase**](TestRunExecutionInDBBase.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **rename_test_run_execution_api_v1_test_run_executions_id_rename_put** -> TestRunExecutionWithChildren rename_test_run_execution_api_v1_test_run_executions_id_rename_put(id, new_execution_name) - -Rename Test Run Execution - -Rename the name of a test run execution. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - new_execution_name = 'new_execution_name_example' # str | - - try: - # Rename Test Run Execution - api_response = api_instance.rename_test_run_execution_api_v1_test_run_executions_id_rename_put(id, new_execution_name) - print("The response of TestRunExecutionsApi->rename_test_run_execution_api_v1_test_run_executions_id_rename_put:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->rename_test_run_execution_api_v1_test_run_executions_id_rename_put: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **new_execution_name** | **str**| | - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post** -> TestRunExecutionWithChildren repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post(id, title=title) - -Repeat Test Run Execution - -Repeat a test run execution by id. Args: id (int): test run execution id title (str): Optional title to the repeated test run execution. If not provided, the old title will be used with the date and time updated. Raises: HTTPException: if no test run execution exists for the provided id Returns: TestRunExecution: new test run execution with the same test cases from id - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - title = 'title_example' # str | (optional) - - try: - # Repeat Test Run Execution - api_response = api_instance.repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post(id, title=title) - print("The response of TestRunExecutionsApi->repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->repeat_test_run_execution_api_v1_test_run_executions_id_repeat_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - **title** | **str**| | [optional] - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **start_test_run_execution_api_v1_test_run_executions_id_start_post** -> TestRunExecutionWithChildren start_test_run_execution_api_v1_test_run_executions_id_start_post(id) - -Start Test Run Execution - -Start a test run by ID - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution_with_children import TestRunExecutionWithChildren -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Start Test Run Execution - api_response = api_instance.start_test_run_execution_api_v1_test_run_executions_id_start_post(id) - print("The response of TestRunExecutionsApi->start_test_run_execution_api_v1_test_run_executions_id_start_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->start_test_run_execution_api_v1_test_run_executions_id_start_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunExecutionWithChildren**](TestRunExecutionWithChildren.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **unarchive_api_v1_test_run_executions_id_unarchive_post** -> TestRunExecution unarchive_api_v1_test_run_executions_id_unarchive_post(id) - -Unarchive - -Unarchive test run execution by id. Args: id (int): test run execution id Raises: HTTPException: if no test run execution exists for provided id Returns: TestRunExecution: test run execution record that was unarchived - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_run_execution import TestRunExecution -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - id = 56 # int | - - try: - # Unarchive - api_response = api_instance.unarchive_api_v1_test_run_executions_id_unarchive_post(id) - print("The response of TestRunExecutionsApi->unarchive_api_v1_test_run_executions_id_unarchive_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->unarchive_api_v1_test_run_executions_id_unarchive_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **int**| | - -### Return type - -[**TestRunExecution**](TestRunExecution.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **upload_file_api_v1_test_run_executions_file_upload_post** -> Any upload_file_api_v1_test_run_executions_file_upload_post(file) - -Upload File - -Upload a file to the specified path of the current test run. Args: file: The file to upload. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.TestRunExecutionsApi(api_client) - file = api_lib_autogen.IO() # IO | - - try: - # Upload File - api_response = api_instance.upload_file_api_v1_test_run_executions_file_upload_post(file) - print("The response of TestRunExecutionsApi->upload_file_api_v1_test_run_executions_file_upload_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling TestRunExecutionsApi->upload_file_api_v1_test_run_executions_file_upload_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **file** | **IO**| | - -### Return type - -**Any** - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: multipart/form-data - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/TestRunLogEntry.md b/th_cli/api_lib_autogen/docs/TestRunLogEntry.md deleted file mode 100644 index 7e5f9eb..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunLogEntry.md +++ /dev/null @@ -1,33 +0,0 @@ -# TestRunLogEntry - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**level** | **str** | | -**timestamp** | **float** | | -**message** | **str** | | -**test_suite_execution_index** | **int** | | [optional] -**test_case_execution_index** | **int** | | [optional] -**test_step_execution_index** | **int** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_run_log_entry import TestRunLogEntry - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunLogEntry from a JSON string -test_run_log_entry_instance = TestRunLogEntry.from_json(json) -# print the JSON string representation of the object -print TestRunLogEntry.to_json() - -# convert the object into a dict -test_run_log_entry_dict = test_run_log_entry_instance.to_dict() -# create an instance of TestRunLogEntry from a dict -test_run_log_entry_form_dict = test_run_log_entry.from_dict(test_run_log_entry_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunnerState.md b/th_cli/api_lib_autogen/docs/TestRunnerState.md deleted file mode 100644 index ea83770..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunnerState.md +++ /dev/null @@ -1,11 +0,0 @@ -# TestRunnerState - -An enumeration. - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestRunnerStatus.md b/th_cli/api_lib_autogen/docs/TestRunnerStatus.md deleted file mode 100644 index e2f15c3..0000000 --- a/th_cli/api_lib_autogen/docs/TestRunnerStatus.md +++ /dev/null @@ -1,29 +0,0 @@ -# TestRunnerStatus - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestRunnerState**](TestRunnerState.md) | | -**test_run_execution_id** | **int** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_runner_status import TestRunnerStatus - -# TODO update the JSON string below -json = "{}" -# create an instance of TestRunnerStatus from a JSON string -test_runner_status_instance = TestRunnerStatus.from_json(json) -# print the JSON string representation of the object -print TestRunnerStatus.to_json() - -# convert the object into a dict -test_runner_status_dict = test_runner_status_instance.to_dict() -# create an instance of TestRunnerStatus from a dict -test_runner_status_form_dict = test_runner_status.from_dict(test_runner_status_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestStateEnum.md b/th_cli/api_lib_autogen/docs/TestStateEnum.md deleted file mode 100644 index b153ddf..0000000 --- a/th_cli/api_lib_autogen/docs/TestStateEnum.md +++ /dev/null @@ -1,11 +0,0 @@ -# TestStateEnum - -An enumeration. - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestStepExecution.md b/th_cli/api_lib_autogen/docs/TestStepExecution.md deleted file mode 100644 index 85b5dcc..0000000 --- a/th_cli/api_lib_autogen/docs/TestStepExecution.md +++ /dev/null @@ -1,36 +0,0 @@ -# TestStepExecution - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**title** | **str** | | -**execution_index** | **int** | | -**id** | **int** | | -**test_case_execution_id** | **int** | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**failures** | **List[str]** | | [optional] - -## Example - -```python -from api_lib_autogen.models.test_step_execution import TestStepExecution - -# TODO update the JSON string below -json = "{}" -# create an instance of TestStepExecution from a JSON string -test_step_execution_instance = TestStepExecution.from_json(json) -# print the JSON string representation of the object -print TestStepExecution.to_json() - -# convert the object into a dict -test_step_execution_dict = test_step_execution_instance.to_dict() -# create an instance of TestStepExecution from a dict -test_step_execution_form_dict = test_step_execution.from_dict(test_step_execution_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestStepExecutionToExport.md b/th_cli/api_lib_autogen/docs/TestStepExecutionToExport.md deleted file mode 100644 index 221efbc..0000000 --- a/th_cli/api_lib_autogen/docs/TestStepExecutionToExport.md +++ /dev/null @@ -1,35 +0,0 @@ -# TestStepExecutionToExport - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**title** | **str** | | -**execution_index** | **int** | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**failures** | **List[str]** | | [optional] -**created_at** | **datetime** | | - -## Example - -```python -from api_lib_autogen.models.test_step_execution_to_export import TestStepExecutionToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of TestStepExecutionToExport from a JSON string -test_step_execution_to_export_instance = TestStepExecutionToExport.from_json(json) -# print the JSON string representation of the object -print TestStepExecutionToExport.to_json() - -# convert the object into a dict -test_step_execution_to_export_dict = test_step_execution_to_export_instance.to_dict() -# create an instance of TestStepExecutionToExport from a dict -test_step_execution_to_export_form_dict = test_step_execution_to_export.from_dict(test_step_execution_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestSuite.md b/th_cli/api_lib_autogen/docs/TestSuite.md deleted file mode 100644 index 4e5b1a4..0000000 --- a/th_cli/api_lib_autogen/docs/TestSuite.md +++ /dev/null @@ -1,29 +0,0 @@ -# TestSuite - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**metadata** | [**TestMetadata**](TestMetadata.md) | | -**test_cases** | [**Dict[str, TestCase]**](TestCase.md) | | - -## Example - -```python -from api_lib_autogen.models.test_suite import TestSuite - -# TODO update the JSON string below -json = "{}" -# create an instance of TestSuite from a JSON string -test_suite_instance = TestSuite.from_json(json) -# print the JSON string representation of the object -print TestSuite.to_json() - -# convert the object into a dict -test_suite_dict = test_suite_instance.to_dict() -# create an instance of TestSuite from a dict -test_suite_form_dict = test_suite.from_dict(test_suite_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestSuiteExecution.md b/th_cli/api_lib_autogen/docs/TestSuiteExecution.md deleted file mode 100644 index 0e3fb19..0000000 --- a/th_cli/api_lib_autogen/docs/TestSuiteExecution.md +++ /dev/null @@ -1,40 +0,0 @@ -# TestSuiteExecution - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**public_id** | **str** | | -**execution_index** | **int** | | -**collection_id** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] -**id** | **int** | | -**test_run_execution_id** | **int** | | -**test_suite_metadata_id** | **int** | | -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**test_case_executions** | [**List[TestCaseExecution]**](TestCaseExecution.md) | | -**test_suite_metadata** | [**TestSuiteMetadata**](TestSuiteMetadata.md) | | - -## Example - -```python -from api_lib_autogen.models.test_suite_execution import TestSuiteExecution - -# TODO update the JSON string below -json = "{}" -# create an instance of TestSuiteExecution from a JSON string -test_suite_execution_instance = TestSuiteExecution.from_json(json) -# print the JSON string representation of the object -print TestSuiteExecution.to_json() - -# convert the object into a dict -test_suite_execution_dict = test_suite_execution_instance.to_dict() -# create an instance of TestSuiteExecution from a dict -test_suite_execution_form_dict = test_suite_execution.from_dict(test_suite_execution_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestSuiteExecutionToExport.md b/th_cli/api_lib_autogen/docs/TestSuiteExecutionToExport.md deleted file mode 100644 index 2877317..0000000 --- a/th_cli/api_lib_autogen/docs/TestSuiteExecutionToExport.md +++ /dev/null @@ -1,38 +0,0 @@ -# TestSuiteExecutionToExport - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**state** | [**TestStateEnum**](TestStateEnum.md) | | -**public_id** | **str** | | -**execution_index** | **int** | | -**collection_id** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] -**started_at** | **datetime** | | [optional] -**completed_at** | **datetime** | | [optional] -**errors** | **List[str]** | | [optional] -**test_case_executions** | [**List[TestCaseExecutionToExport]**](TestCaseExecutionToExport.md) | | -**test_suite_metadata** | [**TestSuiteMetadataBase**](TestSuiteMetadataBase.md) | | -**created_at** | **datetime** | | - -## Example - -```python -from api_lib_autogen.models.test_suite_execution_to_export import TestSuiteExecutionToExport - -# TODO update the JSON string below -json = "{}" -# create an instance of TestSuiteExecutionToExport from a JSON string -test_suite_execution_to_export_instance = TestSuiteExecutionToExport.from_json(json) -# print the JSON string representation of the object -print TestSuiteExecutionToExport.to_json() - -# convert the object into a dict -test_suite_execution_to_export_dict = test_suite_execution_to_export_instance.to_dict() -# create an instance of TestSuiteExecutionToExport from a dict -test_suite_execution_to_export_form_dict = test_suite_execution_to_export.from_dict(test_suite_execution_to_export_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestSuiteMetadata.md b/th_cli/api_lib_autogen/docs/TestSuiteMetadata.md deleted file mode 100644 index 1b65884..0000000 --- a/th_cli/api_lib_autogen/docs/TestSuiteMetadata.md +++ /dev/null @@ -1,34 +0,0 @@ -# TestSuiteMetadata - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**public_id** | **str** | | -**title** | **str** | | -**description** | **str** | | -**version** | **str** | | -**source_hash** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] -**id** | **int** | | - -## Example - -```python -from api_lib_autogen.models.test_suite_metadata import TestSuiteMetadata - -# TODO update the JSON string below -json = "{}" -# create an instance of TestSuiteMetadata from a JSON string -test_suite_metadata_instance = TestSuiteMetadata.from_json(json) -# print the JSON string representation of the object -print TestSuiteMetadata.to_json() - -# convert the object into a dict -test_suite_metadata_dict = test_suite_metadata_instance.to_dict() -# create an instance of TestSuiteMetadata from a dict -test_suite_metadata_form_dict = test_suite_metadata.from_dict(test_suite_metadata_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/TestSuiteMetadataBase.md b/th_cli/api_lib_autogen/docs/TestSuiteMetadataBase.md deleted file mode 100644 index 3b59296..0000000 --- a/th_cli/api_lib_autogen/docs/TestSuiteMetadataBase.md +++ /dev/null @@ -1,33 +0,0 @@ -# TestSuiteMetadataBase - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**public_id** | **str** | | -**title** | **str** | | -**description** | **str** | | -**version** | **str** | | -**source_hash** | **str** | | -**mandatory** | **bool** | | [optional] [default to False] - -## Example - -```python -from api_lib_autogen.models.test_suite_metadata_base import TestSuiteMetadataBase - -# TODO update the JSON string below -json = "{}" -# create an instance of TestSuiteMetadataBase from a JSON string -test_suite_metadata_base_instance = TestSuiteMetadataBase.from_json(json) -# print the JSON string representation of the object -print TestSuiteMetadataBase.to_json() - -# convert the object into a dict -test_suite_metadata_base_dict = test_suite_metadata_base_instance.to_dict() -# create an instance of TestSuiteMetadataBase from a dict -test_suite_metadata_base_form_dict = test_suite_metadata_base.from_dict(test_suite_metadata_base_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/UtilsApi.md b/th_cli/api_lib_autogen/docs/UtilsApi.md deleted file mode 100644 index ef372eb..0000000 --- a/th_cli/api_lib_autogen/docs/UtilsApi.md +++ /dev/null @@ -1,77 +0,0 @@ -# api_lib_autogen.UtilsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**test_email_api_v1_utils_test_email_post**](UtilsApi.md#test_email_api_v1_utils_test_email_post) | **POST** /api/v1/utils/test-email/ | Test Email - - -# **test_email_api_v1_utils_test_email_post** -> Msg test_email_api_v1_utils_test_email_post(email_to) - -Test Email - -Test emails. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.msg import Msg -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.UtilsApi(api_client) - email_to = 'email_to_example' # str | - - try: - # Test Email - api_response = api_instance.test_email_api_v1_utils_test_email_post(email_to) - print("The response of UtilsApi->test_email_api_v1_utils_test_email_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UtilsApi->test_email_api_v1_utils_test_email_post: %s\n" % e) -``` - - - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **email_to** | **str**| | - -### Return type - -[**Msg**](Msg.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**201** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/docs/ValidationError.md b/th_cli/api_lib_autogen/docs/ValidationError.md deleted file mode 100644 index 30a7c01..0000000 --- a/th_cli/api_lib_autogen/docs/ValidationError.md +++ /dev/null @@ -1,30 +0,0 @@ -# ValidationError - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**loc** | [**List[LocationInner]**](LocationInner.md) | | -**msg** | **str** | | -**type** | **str** | | - -## Example - -```python -from api_lib_autogen.models.validation_error import ValidationError - -# TODO update the JSON string below -json = "{}" -# create an instance of ValidationError from a JSON string -validation_error_instance = ValidationError.from_json(json) -# print the JSON string representation of the object -print ValidationError.to_json() - -# convert the object into a dict -validation_error_dict = validation_error_instance.to_dict() -# create an instance of ValidationError from a dict -validation_error_form_dict = validation_error.from_dict(validation_error_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/th_cli/api_lib_autogen/docs/VersionApi.md b/th_cli/api_lib_autogen/docs/VersionApi.md deleted file mode 100644 index 739bcca..0000000 --- a/th_cli/api_lib_autogen/docs/VersionApi.md +++ /dev/null @@ -1,72 +0,0 @@ -# api_lib_autogen.VersionApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**get_test_harness_backend_version_api_v1_version_get**](VersionApi.md#get_test_harness_backend_version_api_v1_version_get) | **GET** /api/v1/version | Get Test Harness Backend Version - - -# **get_test_harness_backend_version_api_v1_version_get** -> TestHarnessBackendVersion get_test_harness_backend_version_api_v1_version_get() - -Get Test Harness Backend Version - -Retrieve version of the Test Engine. - -### Example - -```python -import time -import os -import api_lib_autogen -from api_lib_autogen.models.test_harness_backend_version import TestHarnessBackendVersion -from api_lib_autogen.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = api_lib_autogen.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with api_lib_autogen.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = api_lib_autogen.VersionApi(api_client) - - try: - # Get Test Harness Backend Version - api_response = api_instance.get_test_harness_backend_version_api_v1_version_get() - print("The response of VersionApi->get_test_harness_backend_version_api_v1_version_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling VersionApi->get_test_harness_backend_version_api_v1_version_get: %s\n" % e) -``` - - - -### Parameters -This endpoint does not need any parameter. - -### Return type - -[**TestHarnessBackendVersion**](TestHarnessBackendVersion.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/th_cli/api_lib_autogen/exceptions.py b/th_cli/api_lib_autogen/exceptions.py index 4393629..ca3e7d7 100644 --- a/th_cli/api_lib_autogen/exceptions.py +++ b/th_cli/api_lib_autogen/exceptions.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023-2026 Project CHIP Authors +# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,49 +13,38 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import json -from typing import Any, Dict, Optional +from typing import Any -from httpx import Headers, Response - -MAX_CONTENT = 200 +from httpx import Response class ApiException(Exception): - """Base class""" + """Base exception for API client errors.""" + + pass + + +class ResponseHandlingException(ApiException): + """Exception raised when response handling fails.""" + + def __init__(self, error: Exception): + self.error = error + super().__init__(f"Error handling response: {error}") class UnexpectedResponse(ApiException): - def __init__(self, status_code: Optional[int], reason_phrase: str, content: bytes, headers: Headers) -> None: + """Exception raised when response status is unexpected.""" + + def __init__(self, status_code: int, content: Any): self.status_code = status_code - self.reason_phrase = reason_phrase self.content = content - self.headers = headers - - @staticmethod - def for_response(response: Response) -> "ApiException": - return UnexpectedResponse( - status_code=response.status_code, - reason_phrase=response.reason_phrase, - content=response.content, - headers=response.headers, - ) - - def __str__(self) -> str: - status_code_str = f"{self.status_code}" if self.status_code is not None else "" - if self.reason_phrase == "" and self.status_code is not None: - reason_phrase_str = "(Unrecognized Status Code)" - else: - reason_phrase_str = f"({self.reason_phrase})" - status_str = f"{status_code_str} {reason_phrase_str}".strip() - short_content = self.content if len(self.content) <= MAX_CONTENT else self.content[: MAX_CONTENT - 3] + b" ..." - raw_content_str = f"Raw response content:\n{short_content!r}" - return f"Unexpected Response: {status_str}\n{raw_content_str}" - - def structured(self) -> Dict[str, Any]: - return json.loads(self.content) - - -class ResponseHandlingException(ApiException): - def __init__(self, source: Exception): - self.source = source + super().__init__(f"Unexpected response status: {status_code}") + + @classmethod + def for_response(cls, response: Response) -> "UnexpectedResponse": + """Create exception from httpx Response.""" + try: + content = response.json() + except Exception: + content = response.text + return cls(response.status_code, content) diff --git a/th_cli/api_lib_autogen/models.py b/th_cli/api_lib_autogen/models.py index 3c80138..1ecdb69 100644 --- a/th_cli/api_lib_autogen/models.py +++ b/th_cli/api_lib_autogen/models.py @@ -1,417 +1,465 @@ +# generated by datamodel-codegen: +# filename: openapi.json +# timestamp: 2026-02-13T18:03:04+00:00 + +from __future__ import annotations + from datetime import datetime from enum import Enum -from typing import Any # noqa -from typing import Dict, List, Optional +from typing import Annotated, Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, RootModel -class BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost(BaseModel): - test_run_execution_in: "TestRunExecutionCreate" = Field(..., alias="test_run_execution_in") - selected_tests: "Dict[str, Dict[str, Dict[str, int]]]" = Field(..., alias="selected_tests") - config: "Optional[Any]" = Field(None, alias="config") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - pics: "Optional[Any]" = Field(None, alias="pics") +class ImportFile(RootModel[bytes]): + root: Annotated[bytes, Field(title="Import File")] -class BodyCreateTestRunExecutionApiV1TestRunExecutionsPost(BaseModel): - test_run_execution_in: "TestRunExecutionCreate" = Field(..., alias="test_run_execution_in") - selected_tests: "Dict[str, Dict[str, Dict[str, int]]]" = Field(..., alias="selected_tests") +class BodyImportTestRunExecutionApiV1TestRunExecutionsImportPost(BaseModel): + import_file: Annotated[bytes, Field(title="Import File")] -class ChipServerInfo(BaseModel): - node_id: "int" = Field(..., alias="node_id") - node_id_hex: "str" = Field(..., alias="node_id_hex") - manual_pairing_code: "Optional[str]" = Field(None, alias="manual_pairing_code") +class BodyImportprojectConfigApiV1ProjectsImportPost(BodyImportTestRunExecutionApiV1TestRunExecutionsImportPost): + pass -class ExportedTestRunExecution(BaseModel): - db_revision: "str" = Field(..., alias="db_revision") - test_run_execution: "TestRunExecutionToExport" = Field(..., alias="test_run_execution") +class File(RootModel[bytes]): + root: Annotated[bytes, Field(title="File")] -class HTTPValidationError(BaseModel): - detail: "Optional[List[ValidationError]]" = Field(None, alias="detail") +class BodyUploadFileApiV1TestRunExecutionsFileUploadPost(BaseModel): + file: Annotated[bytes, Field(title="File")] -class LocationInner(BaseModel): +class BodyUploadPicsApiV1ProjectsIdUploadPicsPut(BodyUploadFileApiV1TestRunExecutionsFileUploadPost): pass +class ChipServerInfo(BaseModel): + node_id: Annotated[int, Field(title="Node Id")] + node_id_hex: Annotated[str, Field(title="Node Id Hex")] + manual_pairing_code: Annotated[str | None, Field(title="Manual Pairing Code")] = None + + class Msg(BaseModel): - msg: "str" = Field(..., alias="msg") + msg: Annotated[str, Field(title="Msg")] -class Operator(BaseModel): - name: "str" = Field(..., alias="name") - id: "int" = Field(..., alias="id") +class Name(RootModel[str]): + root: Annotated[str, Field(title="Name")] -class OperatorCreate(BaseModel): - name: "str" = Field(..., alias="name") +class Id(RootModel[int]): + root: Annotated[int, Field(title="Id")] -class OperatorToExport(BaseModel): - name: "str" = Field(..., alias="name") +class Operator(BaseModel): + name: Annotated[str, Field(title="Name")] + id: Annotated[int, Field(title="Id")] -class OperatorUpdate(BaseModel): - name: "Optional[str]" = Field(None, alias="name") +class OperatorCreate(BaseModel): + name: Annotated[str, Field(title="Name")] -class PICS(BaseModel): - clusters: "Optional[Dict[str, PICSCluster]]" = Field(None, alias="clusters") +class OperatorToExport(OperatorCreate): + pass -class PICSApplicableTestCases(BaseModel): - test_cases: "List[str]" = Field(..., alias="test_cases") +class OperatorUpdate(BaseModel): + name: Annotated[str | None, Field(title="Name")] = None -class PICSCluster(BaseModel): - name: "str" = Field(..., alias="name") - items: "Optional[Dict[str, PICSItem]]" = Field(None, alias="items") +class PICSApplicableTestCases(BaseModel): + test_cases: Annotated[list[str], Field(title="Test Cases")] class PICSItem(BaseModel): - number: "str" = Field(..., alias="number") - enabled: "bool" = Field(..., alias="enabled") + number: Annotated[str, Field(title="Number")] + enabled: Annotated[bool, Field(title="Enabled")] -class Project(BaseModel): - name: "str" = Field(..., alias="name") - config: "Optional[Any]" = Field(None, alias="config") - pics: "Any" = Field({}, alias="pics") - id: "int" = Field(..., alias="id") - created_at: "datetime" = Field(..., alias="created_at") - updated_at: "datetime" = Field(..., alias="updated_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") +class PublicId(RootModel[str]): + root: Annotated[str, Field(title="Public Id")] -class ProjectCreate(BaseModel): - name: "str" = Field(..., alias="name") - config: "Optional[Any]" = Field(None, alias="config") - pics: "Any" = Field({}, alias="pics") +class Title(RootModel[str]): + root: Annotated[str, Field(title="Title")] -class ProjectUpdate(BaseModel): - name: "Optional[str]" = Field(None, alias="name") - config: "Optional[Any]" = Field(None, alias="config") - pics: "Optional[PICS]" = Field(None, alias="pics") +class Description(RootModel[str]): + root: Annotated[str, Field(title="Description")] -class ResponseDefaultConfigApiV1ProjectsDefaultConfigGet(BaseModel): - test_parameters: "Optional[Any]" = Field(None, alias="test_parameters") +class Version(RootModel[str]): + root: Annotated[str, Field(title="Version")] -class TestCase(BaseModel): - metadata: "TestMetadata" = Field(..., alias="metadata") +class SourceHash(RootModel[str]): + root: Annotated[str, Field(title="Source Hash")] -class TestCaseExecution(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - public_id: "str" = Field(..., alias="public_id") - execution_index: "int" = Field(..., alias="execution_index") - id: "int" = Field(..., alias="id") - test_suite_execution_id: "int" = Field(..., alias="test_suite_execution_id") - test_case_metadata_id: "int" = Field(..., alias="test_case_metadata_id") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - test_case_metadata: "TestCaseMetadata" = Field(..., alias="test_case_metadata") - test_step_executions: "List[TestStepExecution]" = Field(..., alias="test_step_executions") - - -class TestCaseExecutionToExport(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - public_id: "str" = Field(..., alias="public_id") - execution_index: "int" = Field(..., alias="execution_index") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - test_case_metadata: "TestCaseMetadataBase" = Field(..., alias="test_case_metadata") - test_step_executions: "List[TestStepExecutionToExport]" = Field(..., alias="test_step_executions") - created_at: "datetime" = Field(..., alias="created_at") +class Mandatory(RootModel[bool]): + root: Annotated[bool, Field(title="Mandatory")] = False class TestCaseMetadata(BaseModel): - public_id: "str" = Field(..., alias="public_id") - title: "str" = Field(..., alias="title") - description: "str" = Field(..., alias="description") - version: "str" = Field(..., alias="version") - source_hash: "str" = Field(..., alias="source_hash") - mandatory: "bool" = Field(False, alias="mandatory") - id: "int" = Field(..., alias="id") + public_id: Annotated[str, Field(title="Public Id")] + title: Annotated[str, Field(title="Title")] + description: Annotated[str, Field(title="Description")] + version: Annotated[str, Field(title="Version")] + source_hash: Annotated[str, Field(title="Source Hash")] + mandatory: Annotated[bool | None, Field(title="Mandatory")] = False + id: Annotated[int, Field(title="Id")] class TestCaseMetadataBase(BaseModel): - public_id: "str" = Field(..., alias="public_id") - title: "str" = Field(..., alias="title") - description: "str" = Field(..., alias="description") - version: "str" = Field(..., alias="version") - source_hash: "str" = Field(..., alias="source_hash") - mandatory: "bool" = Field(False, alias="mandatory") - - -class TestCollection(BaseModel): - name: "str" = Field(..., alias="name") - path: "str" = Field(..., alias="path") - test_suites: "Dict[str, TestSuite]" = Field(..., alias="test_suites") - - -class TestCollections(BaseModel): - test_collections: "Dict[str, TestCollection]" = Field(..., alias="test_collections") + public_id: Annotated[str, Field(title="Public Id")] + title: Annotated[str, Field(title="Title")] + description: Annotated[str, Field(title="Description")] + version: Annotated[str, Field(title="Version")] + source_hash: Annotated[str, Field(title="Source Hash")] + mandatory: Annotated[bool | None, Field(title="Mandatory")] = False class TestEnvironmentConfig(BaseModel): - test_parameters: "Optional[Any]" = Field(None, alias="test_parameters") + test_parameters: Annotated[dict[str, Any] | None, Field(title="Test Parameters")] = None class TestHarnessBackendVersion(BaseModel): - version: "str" = Field(..., alias="version") - sha: "str" = Field(..., alias="sha") - sdk_sha: "str" = Field(..., alias="sdk_sha") - sdk_docker_tag: "str" = Field(..., alias="sdk_docker_tag") - db_revision: "str" = Field(..., alias="db_revision") + version: Annotated[str, Field(title="Version")] + sha: Annotated[str, Field(title="Sha")] + sdk_sha: Annotated[str, Field(title="Sdk Sha")] + sdk_docker_tag: Annotated[str, Field(title="Sdk Docker Tag")] + db_revision: Annotated[str, Field(title="Db Revision")] class TestMetadata(BaseModel): - public_id: "str" = Field(..., alias="public_id") - version: "str" = Field(..., alias="version") - title: "str" = Field(..., alias="title") - description: "str" = Field(..., alias="description") - mandatory: "bool" = Field(False, alias="mandatory") + public_id: Annotated[str, Field(title="Public Id")] + version: Annotated[str, Field(title="Version")] + title: Annotated[str, Field(title="Title")] + description: Annotated[str, Field(title="Description")] + mandatory: Annotated[bool | None, Field(title="Mandatory")] = False class TestRunConfig(BaseModel): - name: "str" = Field(..., alias="name") - dut_name: "str" = Field(..., alias="dut_name") - selected_tests: "Optional[Dict[str, Dict[str, Dict[str, int]]]]" = Field(None, alias="selected_tests") - id: "int" = Field(..., alias="id") + name: Annotated[str, Field(title="Name")] + dut_name: Annotated[str, Field(title="Dut Name")] + selected_tests: Annotated[dict[str, dict[str, dict[str, int]]] | None, Field(title="Selected Tests")] = {} + id: Annotated[int, Field(title="Id")] class TestRunConfigCreate(BaseModel): - name: "str" = Field(..., alias="name") - dut_name: "str" = Field(..., alias="dut_name") - selected_tests: "Optional[Dict[str, Dict[str, Dict[str, int]]]]" = Field(None, alias="selected_tests") + name: Annotated[str, Field(title="Name")] + dut_name: Annotated[str, Field(title="Dut Name")] + selected_tests: Annotated[dict[str, dict[str, dict[str, int]]] | None, Field(title="Selected Tests")] = {} class TestRunConfigToExport(BaseModel): - name: "str" = Field(..., alias="name") - dut_name: "str" = Field(..., alias="dut_name") - selected_tests: "Optional[Dict[str, Dict[str, Dict[str, int]]]]" = Field(None, alias="selected_tests") - created_at: "datetime" = Field(..., alias="created_at") + name: Annotated[str, Field(title="Name")] + dut_name: Annotated[str, Field(title="Dut Name")] + selected_tests: Annotated[dict[str, dict[str, dict[str, int]]] | None, Field(title="Selected Tests")] = {} + created_at: Annotated[datetime, Field(title="Created At")] -class TestRunConfigUpdate(BaseModel): - name: "str" = Field(..., alias="name") +class TestRunConfigUpdate(OperatorCreate): + pass -class TestRunExecution(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - test_run_config_id: "Optional[int]" = Field(None, alias="test_run_config_id") - project_id: "Optional[int]" = Field(None, alias="project_id") - id: "int" = Field(..., alias="id") - state: "TestStateEnum" = Field(..., alias="state") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - imported_at: "Optional[datetime]" = Field(None, alias="imported_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") - operator: "Optional[Operator]" = Field(None, alias="operator") +class TestRunExecutionCreate(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + test_run_config_id: Annotated[int | None, Field(title="Test Run Config Id")] = None + project_id: Annotated[int | None, Field(title="Project Id")] = None + operator_id: Annotated[int | None, Field(title="Operator Id")] = None -class TestRunExecutionCreate(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - test_run_config_id: "Optional[int]" = Field(None, alias="test_run_config_id") - project_id: "Optional[int]" = Field(None, alias="project_id") - operator_id: "Optional[int]" = Field(None, alias="operator_id") +class TestRunExecutionStats(BaseModel): + test_case_count: Annotated[int | None, Field(title="Test Case Count")] = 0 + states: Annotated[dict[str, int] | None, Field(title="States")] = {} -class TestRunExecutionInDBBase(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - test_run_config_id: "Optional[int]" = Field(None, alias="test_run_config_id") - project_id: "Optional[int]" = Field(None, alias="project_id") - id: "int" = Field(..., alias="id") - state: "TestStateEnum" = Field(..., alias="state") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - imported_at: "Optional[datetime]" = Field(None, alias="imported_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") +class TestRunLogEntry(BaseModel): + level: Annotated[str, Field(title="Level")] + timestamp: Annotated[float, Field(title="Timestamp")] + message: Annotated[str, Field(title="Message")] + test_suite_execution_index: Annotated[int | None, Field(title="Test Suite Execution Index")] = None + test_case_execution_index: Annotated[int | None, Field(title="Test Case Execution Index")] = None + test_step_execution_index: Annotated[int | None, Field(title="Test Step Execution Index")] = None -class TestRunExecutionStats(BaseModel): - test_case_count: "int" = Field(0, alias="test_case_count") - states: "Optional[Dict[str, int]]" = Field(None, alias="states") +class TestRunnerState(Enum): + idle = "idle" + loading = "loading" + ready = "ready" + running = "running" -class TestRunExecutionToExport(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - state: "TestStateEnum" = Field(..., alias="state") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") - test_suite_executions: "Optional[List[TestSuiteExecutionToExport]]" = Field(None, alias="test_suite_executions") - created_at: "datetime" = Field(..., alias="created_at") - log: "List[TestRunLogEntry]" = Field(..., alias="log") - operator: "Optional[OperatorToExport]" = Field(None, alias="operator") - test_run_config: "Optional[TestRunConfigToExport]" = Field(None, alias="test_run_config") +class TestRunnerStatus(BaseModel): + state: TestRunnerState + test_run_execution_id: Annotated[int | None, Field(title="Test Run Execution Id")] = None -class TestRunExecutionWithChildren(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - test_run_config_id: "Optional[int]" = Field(None, alias="test_run_config_id") - project_id: "Optional[int]" = Field(None, alias="project_id") - id: "int" = Field(..., alias="id") - state: "TestStateEnum" = Field(..., alias="state") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - imported_at: "Optional[datetime]" = Field(None, alias="imported_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") - operator: "Optional[Operator]" = Field(None, alias="operator") - test_suite_executions: "Optional[List[TestSuiteExecution]]" = Field(None, alias="test_suite_executions") +class TestStateEnum(Enum): + pending = "pending" + executing = "executing" + pending_actuation = "pending_actuation" + passed = "passed" + failed = "failed" + error = "error" + not_applicable = "not_applicable" + cancelled = "cancelled" -class TestRunExecutionWithStats(BaseModel): - title: "str" = Field(..., alias="title") - description: "Optional[str]" = Field(None, alias="description") - execution_config: "Optional[Any]" = Field(None, alias="execution_config") - certification_mode: "bool" = Field(False, alias="certification_mode") - test_run_config_id: "Optional[int]" = Field(None, alias="test_run_config_id") - project_id: "Optional[int]" = Field(None, alias="project_id") - id: "int" = Field(..., alias="id") - state: "TestStateEnum" = Field(..., alias="state") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - imported_at: "Optional[datetime]" = Field(None, alias="imported_at") - archived_at: "Optional[datetime]" = Field(None, alias="archived_at") - operator: "Optional[Operator]" = Field(None, alias="operator") - test_case_stats: "TestRunExecutionStats" = Field(..., alias="test_case_stats") +class TestStepExecution(BaseModel): + state: TestStateEnum + title: Annotated[str, Field(title="Title")] + execution_index: Annotated[int, Field(title="Execution Index")] + id: Annotated[int, Field(title="Id")] + test_case_execution_id: Annotated[int, Field(title="Test Case Execution Id")] + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + failures: Annotated[list[str] | None, Field(title="Failures")] = None -class TestRunLogEntry(BaseModel): - level: "str" = Field(..., alias="level") - timestamp: "float" = Field(..., alias="timestamp") - message: "str" = Field(..., alias="message") - test_suite_execution_index: "Optional[int]" = Field(None, alias="test_suite_execution_index") - test_case_execution_index: "Optional[int]" = Field(None, alias="test_case_execution_index") - test_step_execution_index: "Optional[int]" = Field(None, alias="test_step_execution_index") +class TestStepExecutionToExport(BaseModel): + state: TestStateEnum + title: Annotated[str, Field(title="Title")] + execution_index: Annotated[int, Field(title="Execution Index")] + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + failures: Annotated[list[str] | None, Field(title="Failures")] = None + created_at: Annotated[datetime, Field(title="Created At")] -class TestRunnerState(str, Enum): - IDLE = "idle" - LOADING = "loading" - READY = "ready" - RUNNING = "running" +class TestSuiteMetadata(TestCaseMetadata): + pass -class TestRunnerStatus(BaseModel): - state: "TestRunnerState" = Field(..., alias="state") - test_run_execution_id: "Optional[int]" = Field(None, alias="test_run_execution_id") +class TestSuiteMetadataBase(TestCaseMetadataBase): + pass -class TestStateEnum(str, Enum): - PENDING = "pending" - EXECUTING = "executing" - PENDING_ACTUATION = "pending_actuation" - PASSED = "passed" - FAILED = "failed" - ERROR = "error" - NOT_APPLICABLE = "not_applicable" - CANCELLED = "cancelled" +class ValidationError(BaseModel): + loc: Annotated[list[str | int], Field(title="Location")] + msg: Annotated[str, Field(title="Message")] + type: Annotated[str, Field(title="Error Type")] -class TestStepExecution(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - title: "str" = Field(..., alias="title") - execution_index: "int" = Field(..., alias="execution_index") - id: "int" = Field(..., alias="id") - test_case_execution_id: "int" = Field(..., alias="test_case_execution_id") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - failures: "Optional[List[str]]" = Field(None, alias="failures") +class BodyCreateCliTestRunExecutionApiV1TestRunExecutionsCliPost(BaseModel): + test_run_execution_in: TestRunExecutionCreate + selected_tests: Annotated[dict[str, dict[str, dict[str, int]]], Field(title="Selected Tests")] + config: Annotated[dict[str, Any] | None, Field(title="Config")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + pics: Annotated[dict[str, Any] | None, Field(title="Pics")] = {} -class TestStepExecutionToExport(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - title: "str" = Field(..., alias="title") - execution_index: "int" = Field(..., alias="execution_index") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - failures: "Optional[List[str]]" = Field(None, alias="failures") - created_at: "datetime" = Field(..., alias="created_at") +class BodyCreateTestRunExecutionApiV1TestRunExecutionsPost(BaseModel): + test_run_execution_in: TestRunExecutionCreate + selected_tests: Annotated[dict[str, dict[str, dict[str, int]]], Field(title="Selected Tests")] + + +class HTTPValidationError(BaseModel): + detail: Annotated[list[ValidationError] | None, Field(title="Detail")] = None + + +class PICSCluster(BaseModel): + name: Annotated[str, Field(title="Name")] + items: Annotated[ + dict[str, PICSItem] | None, Field(default_factory=lambda: PICSItem.model_validate({}), title="Items") + ] + + +class TestCase(BaseModel): + metadata: TestMetadata + + +class TestCaseExecution(BaseModel): + state: TestStateEnum + public_id: Annotated[str, Field(title="Public Id")] + execution_index: Annotated[int, Field(title="Execution Index")] + id: Annotated[int, Field(title="Id")] + test_suite_execution_id: Annotated[int, Field(title="Test Suite Execution Id")] + test_case_metadata_id: Annotated[int, Field(title="Test Case Metadata Id")] + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + test_case_metadata: TestCaseMetadata + test_step_executions: Annotated[list[TestStepExecution], Field(title="Test Step Executions")] + + +class TestCaseExecutionToExport(BaseModel): + state: TestStateEnum + public_id: Annotated[str, Field(title="Public Id")] + execution_index: Annotated[int, Field(title="Execution Index")] + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + test_case_metadata: TestCaseMetadataBase + test_step_executions: Annotated[list[TestStepExecutionToExport], Field(title="Test Step Executions")] + created_at: Annotated[datetime, Field(title="Created At")] + + +class TestRunExecution(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + test_run_config_id: Annotated[int | None, Field(title="Test Run Config Id")] = None + project_id: Annotated[int | None, Field(title="Project Id")] = None + id: Annotated[int, Field(title="Id")] + state: TestStateEnum + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + imported_at: Annotated[datetime | None, Field(title="Imported At")] = None + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + operator: Operator | None = None + + +class TestRunExecutionInDBBase(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + test_run_config_id: Annotated[int | None, Field(title="Test Run Config Id")] = None + project_id: Annotated[int | None, Field(title="Project Id")] = None + id: Annotated[int, Field(title="Id")] + state: TestStateEnum + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + imported_at: Annotated[datetime | None, Field(title="Imported At")] = None + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + + +class TestRunExecutionWithStats(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + test_run_config_id: Annotated[int | None, Field(title="Test Run Config Id")] = None + project_id: Annotated[int | None, Field(title="Project Id")] = None + id: Annotated[int, Field(title="Id")] + state: TestStateEnum + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + imported_at: Annotated[datetime | None, Field(title="Imported At")] = None + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + operator: Operator | None = None + test_case_stats: TestRunExecutionStats class TestSuite(BaseModel): - metadata: "TestMetadata" = Field(..., alias="metadata") - test_cases: "Dict[str, TestCase]" = Field(..., alias="test_cases") + metadata: TestMetadata + test_cases: Annotated[dict[str, TestCase], Field(title="Test Cases")] class TestSuiteExecution(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - public_id: "str" = Field(..., alias="public_id") - execution_index: "int" = Field(..., alias="execution_index") - collection_id: "str" = Field(..., alias="collection_id") - mandatory: "bool" = Field(False, alias="mandatory") - id: "int" = Field(..., alias="id") - test_run_execution_id: "int" = Field(..., alias="test_run_execution_id") - test_suite_metadata_id: "int" = Field(..., alias="test_suite_metadata_id") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - test_case_executions: "List[TestCaseExecution]" = Field(..., alias="test_case_executions") - test_suite_metadata: "TestSuiteMetadata" = Field(..., alias="test_suite_metadata") + state: TestStateEnum + public_id: Annotated[str, Field(title="Public Id")] + execution_index: Annotated[int, Field(title="Execution Index")] + collection_id: Annotated[str, Field(title="Collection Id")] + mandatory: Annotated[bool | None, Field(title="Mandatory")] = False + id: Annotated[int, Field(title="Id")] + test_run_execution_id: Annotated[int, Field(title="Test Run Execution Id")] + test_suite_metadata_id: Annotated[int, Field(title="Test Suite Metadata Id")] + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + test_case_executions: Annotated[list[TestCaseExecution], Field(title="Test Case Executions")] + test_suite_metadata: TestSuiteMetadata class TestSuiteExecutionToExport(BaseModel): - state: "TestStateEnum" = Field(..., alias="state") - public_id: "str" = Field(..., alias="public_id") - execution_index: "int" = Field(..., alias="execution_index") - collection_id: "str" = Field(..., alias="collection_id") - mandatory: "bool" = Field(False, alias="mandatory") - started_at: "Optional[datetime]" = Field(None, alias="started_at") - completed_at: "Optional[datetime]" = Field(None, alias="completed_at") - errors: "Optional[List[str]]" = Field(None, alias="errors") - test_case_executions: "List[TestCaseExecutionToExport]" = Field(..., alias="test_case_executions") - test_suite_metadata: "TestSuiteMetadataBase" = Field(..., alias="test_suite_metadata") - created_at: "datetime" = Field(..., alias="created_at") - - -class TestSuiteMetadata(BaseModel): - public_id: "str" = Field(..., alias="public_id") - title: "str" = Field(..., alias="title") - description: "str" = Field(..., alias="description") - version: "str" = Field(..., alias="version") - source_hash: "str" = Field(..., alias="source_hash") - mandatory: "bool" = Field(False, alias="mandatory") - id: "int" = Field(..., alias="id") - - -class TestSuiteMetadataBase(BaseModel): - public_id: "str" = Field(..., alias="public_id") - title: "str" = Field(..., alias="title") - description: "str" = Field(..., alias="description") - version: "str" = Field(..., alias="version") - source_hash: "str" = Field(..., alias="source_hash") - mandatory: "bool" = Field(False, alias="mandatory") + state: TestStateEnum + public_id: Annotated[str, Field(title="Public Id")] + execution_index: Annotated[int, Field(title="Execution Index")] + collection_id: Annotated[str, Field(title="Collection Id")] + mandatory: Annotated[bool | None, Field(title="Mandatory")] = False + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + errors: Annotated[list[str] | None, Field(title="Errors")] = None + test_case_executions: Annotated[list[TestCaseExecutionToExport], Field(title="Test Case Executions")] + test_suite_metadata: TestSuiteMetadataBase + created_at: Annotated[datetime, Field(title="Created At")] -class ValidationError(BaseModel): - loc: "List[LocationInner]" = Field(..., alias="loc") - msg: "str" = Field(..., alias="msg") - type: "str" = Field(..., alias="type") +class PICS(BaseModel): + clusters: Annotated[ + dict[str, PICSCluster] | None, Field(default_factory=lambda: PICSCluster.model_validate({}), title="Clusters") + ] + + +class Project(BaseModel): + name: Annotated[str, Field(title="Name")] + config: Annotated[dict[str, Any] | None, Field(title="Config")] = None + pics: Annotated[PICS | None, Field(default_factory=lambda: PICS.model_validate({"clusters": {}}), title="Pics")] + id: Annotated[int, Field(title="Id")] + created_at: Annotated[datetime, Field(title="Created At")] + updated_at: Annotated[datetime, Field(title="Updated At")] + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + + +class ProjectCreate(BaseModel): + name: Annotated[str, Field(title="Name")] + config: Annotated[dict[str, Any] | None, Field(title="Config")] = None + pics: Annotated[PICS | None, Field(default_factory=lambda: PICS.model_validate({"clusters": {}}), title="Pics")] + + +class ProjectUpdate(BaseModel): + name: Annotated[str | None, Field(title="Name")] = None + config: Annotated[dict[str, Any] | None, Field(title="Config")] = None + pics: PICS | None = None + + +class TestCollection(BaseModel): + name: Annotated[str, Field(title="Name")] + path: Annotated[str, Field(title="Path")] + test_suites: Annotated[dict[str, TestSuite], Field(title="Test Suites")] + + +class TestCollections(BaseModel): + test_collections: Annotated[dict[str, TestCollection], Field(title="Test Collections")] + + +class TestRunExecutionToExport(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + state: TestStateEnum + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + test_suite_executions: Annotated[ + list[TestSuiteExecutionToExport] | None, Field(title="Test Suite Executions") + ] = None + created_at: Annotated[datetime, Field(title="Created At")] + log: Annotated[list[TestRunLogEntry], Field(title="Log")] + operator: OperatorToExport | None = None + test_run_config: TestRunConfigToExport | None = None + + +class TestRunExecutionWithChildren(BaseModel): + title: Annotated[str, Field(title="Title")] + description: Annotated[str | None, Field(title="Description")] = None + execution_config: Annotated[dict[str, Any] | None, Field(title="Execution Config")] = None + certification_mode: Annotated[bool | None, Field(title="Certification Mode")] = False + test_run_config_id: Annotated[int | None, Field(title="Test Run Config Id")] = None + project_id: Annotated[int | None, Field(title="Project Id")] = None + id: Annotated[int, Field(title="Id")] + state: TestStateEnum + started_at: Annotated[datetime | None, Field(title="Started At")] = None + completed_at: Annotated[datetime | None, Field(title="Completed At")] = None + imported_at: Annotated[datetime | None, Field(title="Imported At")] = None + archived_at: Annotated[datetime | None, Field(title="Archived At")] = None + operator: Operator | None = None + test_suite_executions: Annotated[list[TestSuiteExecution] | None, Field(title="Test Suite Executions")] = None + + +class ExportedTestRunExecution(BaseModel): + db_revision: Annotated[str, Field(title="Db Revision")] + test_run_execution: TestRunExecutionToExport diff --git a/th_cli/colorize.py b/th_cli/colorize.py index a0490c2..fdd754e 100644 --- a/th_cli/colorize.py +++ b/th_cli/colorize.py @@ -45,21 +45,21 @@ class ColorConfig: # Default color mapping for different test states DEFAULT_STATE_COLORS: dict[str, str] = { - TestStateEnum.PASSED.value: "green", - TestStateEnum.FAILED.value: "red", - TestStateEnum.ERROR.value: "red", - TestStateEnum.CANCELLED.value: "bright_red", - TestStateEnum.EXECUTING.value: "yellow", - TestStateEnum.PENDING.value: "bright_white", - TestStateEnum.PENDING_ACTUATION.value: "bright_white", - TestStateEnum.NOT_APPLICABLE.value: "bright_black", + TestStateEnum.passed.value: "green", + TestStateEnum.failed.value: "red", + TestStateEnum.error.value: "red", + TestStateEnum.cancelled.value: "bright_red", + TestStateEnum.executing.value: "yellow", + TestStateEnum.pending.value: "bright_white", + TestStateEnum.pending_actuation.value: "bright_white", + TestStateEnum.not_applicable.value: "bright_black", } RUNNER_STATE_COLORS: dict[str, str] = { - TestRunnerState.IDLE.value: "bright_black", - TestRunnerState.READY.value: "green", - TestRunnerState.LOADING.value: "yellow", - TestRunnerState.RUNNING.value: "red", + TestRunnerState.idle.value: "bright_black", + TestRunnerState.ready.value: "green", + TestRunnerState.loading.value: "yellow", + TestRunnerState.running.value: "red", } # Hierarchy colors for different levels of test organization @@ -161,7 +161,7 @@ def colorize_runner_state(runner_state_name: str) -> str: Returns: Colored string if colors are enabled, plain string otherwise """ - blink = runner_state_name.lower() == TestRunnerState.RUNNING.value + blink = runner_state_name.lower() == TestRunnerState.running state_text = f"{runner_state_name.upper()}" if not color_config.colors_enabled: diff --git a/th_cli/commands/available_tests.py b/th_cli/commands/available_tests.py index cd56617..3100c2d 100644 --- a/th_cli/commands/available_tests.py +++ b/th_cli/commands/available_tests.py @@ -89,7 +89,7 @@ def available_tests( try: client = get_client() sync_apis: SyncApis = SyncApis(client) - test_collections = sync_apis.test_collections_api.read_test_collections_api_v1_test_collections_get() + test_collections = sync_apis.test_collections_api.read_test_collections_api_v1_test_collections__get() if test_collections is None: raise CLIError("Server did not return test_collection") diff --git a/th_cli/commands/project.py b/th_cli/commands/project.py index 32afc3c..bd1075b 100644 --- a/th_cli/commands/project.py +++ b/th_cli/commands/project.py @@ -21,7 +21,7 @@ from th_cli.api_lib_autogen.api_client import SyncApis from th_cli.api_lib_autogen.exceptions import UnexpectedResponse -from th_cli.api_lib_autogen.models import Project, ProjectCreate, ProjectUpdate, TestEnvironmentConfig +from th_cli.api_lib_autogen.models import Project, ProjectCreate, ProjectUpdate from th_cli.client import get_client from th_cli.colorize import colorize_cmd_help, colorize_error, colorize_header, colorize_help, colorize_success, italic from th_cli.exceptions import CLIError, handle_api_error, handle_file_error @@ -30,11 +30,6 @@ TABLE_FORMAT = "{:<5} {:25} {:28}" -def _abort_if_false(ctx, param, value): - if not value: - ctx.abort() - - @click.command( short_help=colorize_help("Manage projects"), help=colorize_cmd_help("project", "Create, list, update, or delete projects"), @@ -157,7 +152,7 @@ def _create_project(sync_apis: SyncApis, name: str, config: str | None) -> None: try: with open(config, "r") as f: config_dict = json.load(f) - test_environment_config = TestEnvironmentConfig(**config_dict) + test_environment_config = config_dict except FileNotFoundError as e: handle_file_error(e, "config file") except json.JSONDecodeError as e: @@ -169,7 +164,7 @@ def _create_project(sync_apis: SyncApis, name: str, config: str | None) -> None: project_create = ProjectCreate(name=name, config=test_environment_config) try: - response = sync_apis.projects_api.create_project_api_v1_projects_post(project_create=project_create) + response = sync_apis.projects_api.create_project_api_v1_projects__post(body=project_create) click.echo(colorize_success(f"Project '{response.name}' created with ID {response.id}")) except UnexpectedResponse as e: handle_api_error(e, f"create project '{name}'") @@ -187,13 +182,13 @@ def _list_projects( def __list_project_by_id(id: int) -> Project: try: - return sync_apis.projects_api.read_project_api_v1_projects_id_get(id=id) + return sync_apis.projects_api.read_project_api_v1_projects__id__get(id=id) except UnexpectedResponse as e: handle_api_error(e, f"list project with id '{id}'") def __list_project_by_batch(archived: bool, skip: int | None = None, limit: int | None = None) -> list[Project]: try: - return sync_apis.projects_api.read_projects_api_v1_projects_get(archived=archived, skip=skip, limit=limit) + return sync_apis.projects_api.read_projects_api_v1_projects__get(archived=archived, skip=skip, limit=limit) except UnexpectedResponse as e: handle_api_error(e, "list projects") @@ -202,10 +197,10 @@ def __print_table(projects: Any) -> None: if isinstance(projects, list): for item in projects: - __print_project(item.dict()) + __print_project(item.model_dump()) if isinstance(projects, Project): - __print_project(projects.dict()) + __print_project(projects.model_dump()) click.echo(italic("\nFor more information, please use --json\n")) @@ -235,10 +230,20 @@ def __print_project(project: dict) -> None: def _update_project(sync_apis: SyncApis, id: int, config: str) -> None: """Update an existing project""" try: + # Get existing project to preserve its name and other fields + existing_project = sync_apis.projects_api.read_project_api_v1_projects__id__get(id=id) + + # Load the new config with open(config, "r") as f: config_dict = json.load(f) - project_update = ProjectUpdate(**config_dict) - response = sync_apis.projects_api.update_project_api_v1_projects_id_put(id=id, project_update=project_update) + + project_update = ProjectUpdate( + name=existing_project.name, + config=config_dict, + pics=existing_project.pics, + ) + + response = sync_apis.projects_api.update_project_api_v1_projects__id__put(id=id, body=project_update) click.echo(colorize_success(f"Project {response.name} is updated with the new config.")) except json.JSONDecodeError as e: raise CLIError(f"Failed to parse JSON parameter: {e.msg}") @@ -247,13 +252,17 @@ def _update_project(sync_apis: SyncApis, id: int, config: str) -> None: except ValidationError as e: raise CLIError(f"Invalid configuration: {e}") except UnexpectedResponse as e: - handle_api_error(e, f"update project with '{id}'") + # Handle error when fetching existing project + if "read_project" in str(e): + handle_api_error(e, f"fetch project with ID '{id}'") + else: + handle_api_error(e, f"update project with '{id}'") def _delete_project(sync_apis: SyncApis, id: int) -> None: """Delete a project""" try: - sync_apis.projects_api.delete_project_api_v1_projects_id_delete(id=id) + sync_apis.projects_api.delete_project_api_v1_projects__id__delete(id=id) click.echo(colorize_success(f"Project {id} was deleted.")) except UnexpectedResponse as e: handle_api_error(e, f"delete project ID '{id}'") diff --git a/th_cli/commands/run_tests.py b/th_cli/commands/run_tests.py index 12778fe..c0c4db1 100644 --- a/th_cli/commands/run_tests.py +++ b/th_cli/commands/run_tests.py @@ -178,7 +178,7 @@ async def run_tests( click.echo(colorize_key_value("PICS Used", json.dumps(pics, indent=JSON_INDENT))) # Retrieve available test collections to build test selection - test_collections = await test_collections_api.read_test_collections_api_v1_test_collections_get() + test_collections = await test_collections_api.read_test_collections_api_v1_test_collections__get() selected_tests_dict = build_test_selection(test_collections, validated_test_ids) click.echo(colorize_key_value("Selected tests", json.dumps(selected_tests_dict, indent=JSON_INDENT))) @@ -207,7 +207,7 @@ async def run_tests( await client.aclose() -async def _get_project_config(async_apis: AsyncApis, project_id: int | None = None) -> m.TestEnvironmentConfig: +async def _get_project_config(async_apis: AsyncApis, project_id: int | None = None) -> dict[str, Any]: """Retrieve project configuration for given project ID or default configuration. Args: @@ -215,7 +215,7 @@ async def _get_project_config(async_apis: AsyncApis, project_id: int | None = No project_id: Optional project ID to retrieve configuration from Returns: - TestEnvironmentConfig object containing project configuration + Dictionary containing project configuration Raises: May raise API-related exceptions if default config retrieval fails @@ -224,7 +224,7 @@ async def _get_project_config(async_apis: AsyncApis, project_id: int | None = No if project_id is not None: try: - project = await projects_api.read_project_api_v1_projects_id_get(id=project_id) + project = await projects_api.read_project_api_v1_projects__id__get(id=project_id) return project.config except UnexpectedResponse as e: msg = ( @@ -353,7 +353,7 @@ async def _start_test_run( click.echo(f"{header}:\n- {title}\n- {test_run_id}\n") try: - return await test_run_executions_api.start_test_run_execution_api_v1_test_run_executions_id_start_post( + return await test_run_executions_api.start_test_run_execution_api_v1_test_run_executions__id__start_post( id=test_run.id ) except UnexpectedResponse as e: diff --git a/th_cli/commands/test_run_execution.py b/th_cli/commands/test_run_execution.py index 2a87b13..5e37e59 100644 --- a/th_cli/commands/test_run_execution.py +++ b/th_cli/commands/test_run_execution.py @@ -142,11 +142,11 @@ def test_run_execution( def __test_run_execution_by_id(sync_apis: SyncApis, id: int, json: bool) -> None: try: test_run_execution_api = sync_apis.test_run_executions_api - test_run_execution = test_run_execution_api.read_test_run_execution_api_v1_test_run_executions_id_get(id=id) + test_run_execution = test_run_execution_api.read_test_run_execution_api_v1_test_run_executions__id__get(id=id) if json: __print_json(test_run_execution) else: - __print_table_test_execution(test_run_execution.dict()) + __print_table_test_execution(test_run_execution.model_dump()) except UnexpectedResponse as e: handle_api_error(e, "get test run execution") @@ -201,7 +201,7 @@ def __test_run_execution_batch( # When --all is used, set limit to 0 to get all results effective_limit = 0 if show_all else limit - test_run_executions = test_run_execution_api.read_test_run_executions_api_v1_test_run_executions_get( + test_run_executions = test_run_execution_api.read_test_run_executions_api_v1_test_run_executions__get( skip=skip, limit=effective_limit, sort_order=sort_order, project_id=project_id ) @@ -260,7 +260,7 @@ def __test_run_execution_batch( def __fetch_test_run_execution_log(sync_apis: SyncApis, id: int) -> None: try: test_run_execution_api = sync_apis.test_run_executions_api - log_content = test_run_execution_api.download_log_api_v1_test_run_executions_id_log_get( + log_content = test_run_execution_api.download_log_api_v1_test_run_executions__id__log_get( id=id, json_entries=False, download=False ) @@ -277,7 +277,7 @@ def __print_table_test_executions(test_execution: list) -> None: __print_table_header() if isinstance(test_execution, list): for item_dict in test_execution: - __print_table_test_execution(item_dict.dict(), print_header=False) + __print_table_test_execution(item_dict.model_dump(), print_header=False) def __print_table_test_execution(item: dict, print_header=True) -> None: diff --git a/th_cli/commands/test_runner_status.py b/th_cli/commands/test_runner_status.py index cea3e0f..bda847e 100644 --- a/th_cli/commands/test_runner_status.py +++ b/th_cli/commands/test_runner_status.py @@ -43,7 +43,7 @@ def test_runner_status(json: bool | None) -> None: if json: __print_json(test_runner_status) else: - __print_status_table(test_runner_status.dict()) + __print_status_table(test_runner_status.model_dump()) except CLIError: raise # Re-raise CLI Errors as-is finally: diff --git a/th_cli/config.py b/th_cli/config.py index 683b9c4..1b31331 100644 --- a/th_cli/config.py +++ b/th_cli/config.py @@ -81,8 +81,8 @@ def get_config_search_paths() -> list[Path]: class LogConfig(BaseModel): - output_log_path = "./run_logs" - format = "{level: <8} | {time:YYYY-MM-DD HH:mm:ss.SSS} | {message}" + output_log_path: str = "./run_logs" + format: str = "{level: <8} | {time:YYYY-MM-DD HH:mm:ss.SSS} | {message}" class Config(BaseModel): @@ -109,14 +109,14 @@ def load_config(): search_paths = get_config_search_paths() # Try different possible locations for config files - possible_locations = [] + possible_locations: list[Path] = [] for path in search_paths: possible_locations.append(path / "config.json") for config_path in possible_locations: if config_path.exists(): try: - return Config.parse_file(config_path) + return Config.model_validate_json(config_path.read_text(encoding="utf-8")) except Exception as e: CLIError(f"Could not load config from {config_path}: {e}") continue diff --git a/th_cli/default_config.json b/th_cli/default_config.json index 7337f76..9a786d1 100644 --- a/th_cli/default_config.json +++ b/th_cli/default_config.json @@ -2,15 +2,18 @@ "network": { "fabric_id": 0, "thread": { - "channel": 15, - "panid": "0x1234", - "extpanid": "1111111122222222", - "networkkey": "00112233445566778899aabbccddeeff", - "networkname": "DEMO", "rcp_serial_path": "/dev/ttyACM0", "rcp_baudrate": 115200, "on_mesh_prefix": "fd11:22::/64", - "network_interface": "eth0" + "network_interface": "eth0", + "dataset": { + "channel": 15, + "panid": "0x1234", + "extpanid": "1111111122222222", + "networkkey": "00112233445566778899aabbccddeeff", + "networkname": "DEMO" + }, + "otbr_docker_image": null }, "wifi": { "ssid": "testharness", diff --git a/th_cli/test_run/prompt_manager.py b/th_cli/test_run/prompt_manager.py index d4fc76a..e8c5f63 100644 --- a/th_cli/test_run/prompt_manager.py +++ b/th_cli/test_run/prompt_manager.py @@ -547,7 +547,7 @@ async def _send_prompt_response( ) payload_dict = { MessageKeysEnum.TYPE: "prompt_response", - MessageKeysEnum.PAYLOAD: response_obj.dict(), + MessageKeysEnum.PAYLOAD: response_obj.model_dump(), } payload = json.dumps(payload_dict) await socket.send(payload) diff --git a/th_cli/test_run/socket_schemas.py b/th_cli/test_run/socket_schemas.py index 4fd4351..828fcfc 100644 --- a/th_cli/test_run/socket_schemas.py +++ b/th_cli/test_run/socket_schemas.py @@ -34,8 +34,8 @@ class UserResponseStatusEnum(IntEnum): class TestUpdateBase(BaseModel): state: TestStateEnum - errors: list[str] | None - failures: list[str] | None + errors: list[str] | None = None + failures: list[str] | None = None class TestRunUpdate(TestUpdateBase): @@ -65,10 +65,11 @@ class TimeOutNotification(BaseModel): class TestLogRecord(BaseModel): level: str - timestamp: str + timestamp: float | str message: str - test_suite_execution_id: int | None - test_case_execution_id: int | None + test_suite_execution_index: int | None = None + test_case_execution_index: int | None = None + test_step_execution_index: int | None = None class PromptRequest(BaseModel): @@ -82,9 +83,9 @@ class OptionsSelectPromptRequest(PromptRequest): class TextInputPromptRequest(PromptRequest): - placeholder_text: str | None - default_value: str | None - regex_pattern: str | None + placeholder_text: str | None = None + default_value: str | None = None + regex_pattern: str | None = None class MessagePromptRequest(PromptRequest): diff --git a/th_cli/test_run/websocket.py b/th_cli/test_run/websocket.py index 203c985..cea4ffe 100644 --- a/th_cli/test_run/websocket.py +++ b/th_cli/test_run/websocket.py @@ -99,7 +99,7 @@ async def connect_websocket(self) -> None: ) continue try: - message_obj = SocketMessage.parse_raw(message) + message_obj = SocketMessage.model_validate_json(message) await self.__handle_incoming_socket_message(socket=socket, message=message_obj) except ValidationError as e: click.echo(colorize_error(f"Received invalid socket message: {message}"), err=True) diff --git a/th_cli/utils.py b/th_cli/utils.py index 1f3cbce..260229e 100644 --- a/th_cli/utils.py +++ b/th_cli/utils.py @@ -42,9 +42,9 @@ def __json_string(object: Any) -> str: if object is None: return "None" if isinstance(object, list): - return json.dumps([item.dict() for item in object], indent=4, default=str) + return json.dumps([item.model_dump() for item in object], indent=4, default=str) else: - return json.dumps(object.dict(), indent=4, default=str) + return json.dumps(object.model_dump(), indent=4, default=str) def build_test_selection(test_collections, tests_list) -> dict: @@ -426,8 +426,8 @@ def get_versions() -> dict: try: client = get_client() sync_apis = SyncApis(client) - versions_api = sync_apis.versions_api - versions_info = versions_api.get_versions_api_v1_versions_get() + version_api = sync_apis.version_api + versions_info = version_api.get_test_harness_backend_version_api_v1_version_get() return versions_info except CLIError: raise # Re-raise CLI Errors as-is