From e64ec95bc51e312bbe521a3841f22b6ffe8a1446 Mon Sep 17 00:00:00 2001 From: "blues-hub-automation[bot]" Date: Wed, 8 Apr 2026 16:05:56 +0000 Subject: [PATCH 1/3] feat: Update OpenAPI file replicated from Notehub commit 07a3c60 --- openapi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi.yaml b/openapi.yaml index 2f796c0..2455b09 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -194,7 +194,7 @@ paths: '/v1/billing-accounts/{billingAccountUID}/balance-history': get: operationId: GetBillingAccountBalanceHistory - description: 'Get Billing Account Balance history, only enterprise supported' + description: Get Billing Account Balance history parameters: - $ref: '#/components/parameters/billingAccountUIDParam' - $ref: '#/components/parameters/startDateParam' From dcad4baa8e640fd7ee4dce26a4d4e76e74aa9193 Mon Sep 17 00:00:00 2001 From: "blues-hub-automation[bot]" Date: Wed, 15 Apr 2026 14:15:35 +0000 Subject: [PATCH 2/3] feat: Update OpenAPI file replicated from Notehub commit 781834f --- openapi.yaml | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/openapi.yaml b/openapi.yaml index 2455b09..aed060c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1607,6 +1607,33 @@ paths: tags: - project '/v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename}': + delete: + operationId: DeleteFirmware + description: | + Delete a host firmware binary. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + parameters: + - $ref: '#/components/parameters/projectOrProductUIDParam' + - name: firmwareType + in: path + required: true + schema: + type: string + enum: + - host + - name: filename + in: path + required: true + schema: + type: string + responses: + '204': + description: Firmware deleted successfully + default: + $ref: '#/components/responses/ErrorResponse' + security: + - personalAccessToken: [] + tags: + - project get: operationId: DownloadFirmware description: Download firmware binary @@ -1632,6 +1659,44 @@ paths: - personalAccessToken: [] tags: - project + post: + operationId: UpdateFirmware + description: | + Update the metadata of an existing host firmware entry. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + parameters: + - $ref: '#/components/parameters/projectOrProductUIDParam' + - name: firmwareType + in: path + required: true + schema: + type: string + enum: + - host + - name: filename + in: path + required: true + schema: + type: string + requestBody: + description: Firmware metadata fields to update. All fields are optional; only provided fields will be updated. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateHostFirmwareRequest' + responses: + '200': + description: Update successful + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareInfo' + default: + $ref: '#/components/responses/ErrorResponse' + security: + - personalAccessToken: [] + tags: + - project put: operationId: UploadFirmware description: Upload firmware binary @@ -5994,6 +6059,21 @@ components: to: type: string additionalProperties: false + UpdateHostFirmwareRequest: + description: | + Request body for updating host firmware metadata. All fields are optional; only provided fields will be updated. + type: object + properties: + info: + description: Arbitrary JSON metadata associated with this firmware entry. + type: object + additionalProperties: true + notes: + description: Notes describing this firmware version. + type: string + version: + description: The firmware version string. + type: string UploadMetadata: type: object properties: From 7951a4d43df71f2f62898c1bc2cb38dc1c76126d Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 23 Apr 2026 15:25:31 -0400 Subject: [PATCH 3/3] 6.2.0 --- config.json | 2 +- openapi_filtered.yaml | 92 ++- src/.openapi-generator/FILES | 3 + src/README.md | 5 +- src/docs/BillingAccountApi.md | 2 +- src/docs/ProjectApi.md | 115 ++++ src/docs/UpdateHostFirmwareRequest.md | 33 + src/notehub_py/__init__.py | 3 +- src/notehub_py/api/billing_account_api.py | 6 +- src/notehub_py/api/project_api.py | 579 ++++++++++++++++++ src/notehub_py/api_client.py | 2 +- src/notehub_py/configuration.py | 2 +- src/notehub_py/models/__init__.py | 1 + .../models/update_host_firmware_request.py | 99 +++ src/pyproject.toml | 2 +- src/setup.py | 2 +- src/test/test_update_host_firmware_request.py | 56 ++ 17 files changed, 992 insertions(+), 12 deletions(-) create mode 100644 src/docs/UpdateHostFirmwareRequest.md create mode 100644 src/notehub_py/models/update_host_firmware_request.py create mode 100644 src/test/test_update_host_firmware_request.py diff --git a/config.json b/config.json index 5cf8783..fb1c50a 100644 --- a/config.json +++ b/config.json @@ -2,5 +2,5 @@ "packageName": "notehub_py", "packageUrl": "https://github.com/blues/notehub-py", "projectName": "notehub-py", - "packageVersion": "6.1.0" + "packageVersion": "6.2.0" } diff --git a/openapi_filtered.yaml b/openapi_filtered.yaml index 65d0783..792c693 100644 --- a/openapi_filtered.yaml +++ b/openapi_filtered.yaml @@ -197,7 +197,7 @@ paths: /v1/billing-accounts/{billingAccountUID}/balance-history: get: operationId: GetBillingAccountBalanceHistory - description: Get Billing Account Balance history, only enterprise supported + description: Get Billing Account Balance history parameters: - $ref: '#/components/parameters/billingAccountUIDParam' - $ref: '#/components/parameters/startDateParam' @@ -1632,6 +1632,36 @@ paths: tags: - project /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename}: + delete: + operationId: DeleteFirmware + description: 'Delete a host firmware binary. The filename must be the full stored + filename including the timestamp suffix (e.g. test$20260324190911.bin) as + returned by the firmware upload or list endpoints. + + ' + parameters: + - $ref: '#/components/parameters/projectOrProductUIDParam' + - name: firmwareType + in: path + required: true + schema: + type: string + enum: + - host + - name: filename + in: path + required: true + schema: + type: string + responses: + '204': + description: Firmware deleted successfully + default: + $ref: '#/components/responses/ErrorResponse' + security: + - personalAccessToken: [] + tags: + - project get: operationId: DownloadFirmware description: Download firmware binary @@ -1657,6 +1687,49 @@ paths: - personalAccessToken: [] tags: - project + post: + operationId: UpdateFirmware + description: 'Update the metadata of an existing host firmware entry. The filename + must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) + as returned by the firmware upload or list endpoints. + + ' + parameters: + - $ref: '#/components/parameters/projectOrProductUIDParam' + - name: firmwareType + in: path + required: true + schema: + type: string + enum: + - host + - name: filename + in: path + required: true + schema: + type: string + requestBody: + description: Firmware metadata fields to update. All fields are optional; + only provided fields will be updated. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateHostFirmwareRequest' + properties: {} + responses: + '200': + description: Update successful + content: + application/json: + schema: + $ref: '#/components/schemas/FirmwareInfo' + default: + $ref: '#/components/responses/ErrorResponse' + security: + - personalAccessToken: [] + tags: + - project put: operationId: UploadFirmware description: Upload firmware binary @@ -6074,6 +6147,23 @@ components: to: type: string additionalProperties: false + UpdateHostFirmwareRequest: + description: 'Request body for updating host firmware metadata. All fields are + optional; only provided fields will be updated. + + ' + type: object + properties: + info: + description: Arbitrary JSON metadata associated with this firmware entry. + type: object + additionalProperties: true + notes: + description: Notes describing this firmware version. + type: string + version: + description: The firmware version string. + type: string UploadMetadata: type: object properties: diff --git a/src/.openapi-generator/FILES b/src/.openapi-generator/FILES index 72777a7..805aae5 100644 --- a/src/.openapi-generator/FILES +++ b/src/.openapi-generator/FILES @@ -147,6 +147,7 @@ docs/ThingworxRoute.md docs/TowerLocation.md docs/TwilioRoute.md docs/UpdateFleetRequest.md +docs/UpdateHostFirmwareRequest.md docs/UploadMetadata.md docs/UsageApi.md docs/UsageData.md @@ -313,6 +314,7 @@ notehub_py/models/thingworx_route.py notehub_py/models/tower_location.py notehub_py/models/twilio_route.py notehub_py/models/update_fleet_request.py +notehub_py/models/update_host_firmware_request.py notehub_py/models/upload_metadata.py notehub_py/models/usage_data.py notehub_py/models/usage_events_data.py @@ -331,4 +333,5 @@ setup.cfg setup.py test-requirements.txt test/__init__.py +test/test_update_host_firmware_request.py tox.ini diff --git a/src/README.md b/src/README.md index 01d8391..ef83476 100644 --- a/src/README.md +++ b/src/README.md @@ -5,7 +5,7 @@ The OpenAPI definition for the Notehub.io API. This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - API version: 1.2.0 -- Package version: 6.1.0 +- Package version: 6.2.0 - Generator version: 7.5.0 - Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit [https://dev.blues.io/support/](https://dev.blues.io/support/) @@ -155,6 +155,7 @@ Class | Method | HTTP request | Description *ProjectApi* | [**create_product**](docs/ProjectApi.md#create_product) | **POST** /v1/projects/{projectOrProductUID}/products | *ProjectApi* | [**create_project**](docs/ProjectApi.md#create_project) | **POST** /v1/projects | *ProjectApi* | [**delete_device_from_fleets**](docs/ProjectApi.md#delete_device_from_fleets) | **DELETE** /v1/projects/{projectOrProductUID}/devices/{deviceUID}/fleets | +*ProjectApi* | [**delete_firmware**](docs/ProjectApi.md#delete_firmware) | **DELETE** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | *ProjectApi* | [**delete_fleet**](docs/ProjectApi.md#delete_fleet) | **DELETE** /v1/projects/{projectOrProductUID}/fleets/{fleetUID} | *ProjectApi* | [**delete_fleet_environment_variable**](docs/ProjectApi.md#delete_fleet_environment_variable) | **DELETE** /v1/projects/{projectOrProductUID}/fleets/{fleetUID}/environment_variables/{key} | *ProjectApi* | [**delete_product**](docs/ProjectApi.md#delete_product) | **DELETE** /v1/projects/{projectOrProductUID}/products/{productUID} | @@ -186,6 +187,7 @@ Class | Method | HTTP request | Description *ProjectApi* | [**set_fleet_environment_variables**](docs/ProjectApi.md#set_fleet_environment_variables) | **PUT** /v1/projects/{projectOrProductUID}/fleets/{fleetUID}/environment_variables | *ProjectApi* | [**set_global_event_transformation**](docs/ProjectApi.md#set_global_event_transformation) | **POST** /v1/projects/{projectOrProductUID}/global-transformation | *ProjectApi* | [**set_project_environment_variables**](docs/ProjectApi.md#set_project_environment_variables) | **PUT** /v1/projects/{projectOrProductUID}/environment_variables | +*ProjectApi* | [**update_firmware**](docs/ProjectApi.md#update_firmware) | **POST** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | *ProjectApi* | [**update_fleet**](docs/ProjectApi.md#update_fleet) | **PUT** /v1/projects/{projectOrProductUID}/fleets/{fleetUID} | *ProjectApi* | [**upload_firmware**](docs/ProjectApi.md#upload_firmware) | **PUT** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | *RouteApi* | [**create_route**](docs/RouteApi.md#create_route) | **POST** /v1/projects/{projectOrProductUID}/routes | @@ -341,6 +343,7 @@ Class | Method | HTTP request | Description - [TowerLocation](docs/TowerLocation.md) - [TwilioRoute](docs/TwilioRoute.md) - [UpdateFleetRequest](docs/UpdateFleetRequest.md) + - [UpdateHostFirmwareRequest](docs/UpdateHostFirmwareRequest.md) - [UploadMetadata](docs/UploadMetadata.md) - [UsageData](docs/UsageData.md) - [UsageEventsData](docs/UsageEventsData.md) diff --git a/src/docs/BillingAccountApi.md b/src/docs/BillingAccountApi.md index f45b4cd..e661169 100644 --- a/src/docs/BillingAccountApi.md +++ b/src/docs/BillingAccountApi.md @@ -63,7 +63,7 @@ with notehub_py.ApiClient(configuration) as api_client: > GetBillingAccountBalanceHistory200Response get_billing_account_balance_history(billing_account_uid, start_date=start_date, end_date=end_date) -Get Billing Account Balance history, only enterprise supported +Get Billing Account Balance history ### Example diff --git a/src/docs/ProjectApi.md b/src/docs/ProjectApi.md index 72da14a..721bc82 100644 --- a/src/docs/ProjectApi.md +++ b/src/docs/ProjectApi.md @@ -10,6 +10,7 @@ All URIs are relative to *https://api.notefile.net* | [**create_product**](ProjectApi.md#create_product) | **POST** /v1/projects/{projectOrProductUID}/products | | [**create_project**](ProjectApi.md#create_project) | **POST** /v1/projects | | [**delete_device_from_fleets**](ProjectApi.md#delete_device_from_fleets) | **DELETE** /v1/projects/{projectOrProductUID}/devices/{deviceUID}/fleets | +| [**delete_firmware**](ProjectApi.md#delete_firmware) | **DELETE** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | | [**delete_fleet**](ProjectApi.md#delete_fleet) | **DELETE** /v1/projects/{projectOrProductUID}/fleets/{fleetUID} | | [**delete_fleet_environment_variable**](ProjectApi.md#delete_fleet_environment_variable) | **DELETE** /v1/projects/{projectOrProductUID}/fleets/{fleetUID}/environment_variables/{key} | | [**delete_product**](ProjectApi.md#delete_product) | **DELETE** /v1/projects/{projectOrProductUID}/products/{productUID} | @@ -41,6 +42,7 @@ All URIs are relative to *https://api.notefile.net* | [**set_fleet_environment_variables**](ProjectApi.md#set_fleet_environment_variables) | **PUT** /v1/projects/{projectOrProductUID}/fleets/{fleetUID}/environment_variables | | [**set_global_event_transformation**](ProjectApi.md#set_global_event_transformation) | **POST** /v1/projects/{projectOrProductUID}/global-transformation | | [**set_project_environment_variables**](ProjectApi.md#set_project_environment_variables) | **PUT** /v1/projects/{projectOrProductUID}/environment_variables | +| [**update_firmware**](ProjectApi.md#update_firmware) | **POST** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | | [**update_fleet**](ProjectApi.md#update_fleet) | **PUT** /v1/projects/{projectOrProductUID}/fleets/{fleetUID} | | [**upload_firmware**](ProjectApi.md#upload_firmware) | **PUT** /v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename} | @@ -382,6 +384,56 @@ with notehub_py.ApiClient(configuration) as api_client: - **Content-Type**: application/json - **Accept**: application/json +## delete_firmware + +> delete_firmware(project_or_product_uid, firmware_type, filename) + +Delete a host firmware binary. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + +### Example + +```python +import notehub_py +from notehub_py.rest import ApiException +from pprint import pprint + +configuration = notehub_py.Configuration(access_token="PERSONAL_ACCESS_TOKEN") + +# Enter a context with an instance of the API client +with notehub_py.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = notehub_py.ProjectApi(api_client) + project_or_product_uid = "app:2606f411-dea6-44a0-9743-1130f57d77d8" # str | + firmware_type = "firmware_type_example" # str | + filename = "filename_example" # str | + + try: + api_instance.delete_firmware(project_or_product_uid, firmware_type, filename) + except Exception as e: + print("Exception when calling ProjectApi->delete_firmware: %s\n" % e) +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------------------------- | ------- | ----------- | ----- | +| **project_or_product_uid** | **str** | | +| **firmware_type** | **str** | | +| **filename** | **str** | | + +### Return type + +void (empty response body) + +### Authorization + +[personalAccessToken](../README.md#personalAccessToken) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + ## delete_fleet > delete_fleet(project_or_product_uid, fleet_uid) @@ -2158,6 +2210,69 @@ with notehub_py.ApiClient(configuration) as api_client: - **Content-Type**: application/json - **Accept**: application/json +## update_firmware + +> FirmwareInfo update_firmware(project_or_product_uid, firmware_type, filename, update_host_firmware_request) + +Update the metadata of an existing host firmware entry. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + +### Example + +```python +import notehub_py +from notehub_py.models.firmware_info import FirmwareInfo +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest +from notehub_py.rest import ApiException +from pprint import pprint + +configuration = notehub_py.Configuration(access_token="PERSONAL_ACCESS_TOKEN") + +# Enter a context with an instance of the API client +with notehub_py.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = notehub_py.ProjectApi(api_client) + project_or_product_uid = "app:2606f411-dea6-44a0-9743-1130f57d77d8" # str | + firmware_type = "firmware_type_example" # str | + filename = "filename_example" # str | + update_host_firmware_request = ( + notehub_py.UpdateHostFirmwareRequest() + ) # UpdateHostFirmwareRequest | Firmware metadata fields to update. All fields are optional; only provided fields will be updated. + + try: + api_response = api_instance.update_firmware( + project_or_product_uid, + firmware_type, + filename, + update_host_firmware_request, + ) + print("The response of ProjectApi->update_firmware:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling ProjectApi->update_firmware: %s\n" % e) +``` + +### Parameters + +| Name | Type | Description | Notes | +| -------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ----- | +| **project_or_product_uid** | **str** | | +| **firmware_type** | **str** | | +| **filename** | **str** | | +| **update_host_firmware_request** | [**UpdateHostFirmwareRequest**](UpdateHostFirmwareRequest.md) | Firmware metadata fields to update. All fields are optional; only provided fields will be updated. | + +### Return type + +[**FirmwareInfo**](FirmwareInfo.md) + +### Authorization + +[personalAccessToken](../README.md#personalAccessToken) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + ## update_fleet > Fleet update_fleet(project_or_product_uid, fleet_uid, update_fleet_request) diff --git a/src/docs/UpdateHostFirmwareRequest.md b/src/docs/UpdateHostFirmwareRequest.md new file mode 100644 index 0000000..9a40592 --- /dev/null +++ b/src/docs/UpdateHostFirmwareRequest.md @@ -0,0 +1,33 @@ +# UpdateHostFirmwareRequest + +Request body for updating host firmware metadata. All fields are optional; only provided fields will be updated. + +## Properties + +| Name | Type | Description | Notes | +| ----------- | --------------------- | ------------------------------------------------------------ | ---------- | +| **info** | **Dict[str, object]** | Arbitrary JSON metadata associated with this firmware entry. | [optional] | +| **notes** | **str** | Notes describing this firmware version. | [optional] | +| **version** | **str** | The firmware version string. | [optional] | + +## Example + +```python +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateHostFirmwareRequest from a JSON string +update_host_firmware_request_instance = UpdateHostFirmwareRequest.from_json(json) +# print the JSON string representation of the object +print(UpdateHostFirmwareRequest.to_json()) + +# convert the object into a dict +update_host_firmware_request_dict = update_host_firmware_request_instance.to_dict() +# create an instance of UpdateHostFirmwareRequest from a dict +update_host_firmware_request_from_dict = UpdateHostFirmwareRequest.from_dict( + update_host_firmware_request_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/src/notehub_py/__init__.py b/src/notehub_py/__init__.py index 20f59b2..160a6cf 100644 --- a/src/notehub_py/__init__.py +++ b/src/notehub_py/__init__.py @@ -15,7 +15,7 @@ """ # noqa: E501 -__version__ = "6.1.0" +__version__ = "6.2.0" # import apis into sdk package from notehub_py.api.alert_api import AlertApi @@ -215,6 +215,7 @@ from notehub_py.models.tower_location import TowerLocation from notehub_py.models.twilio_route import TwilioRoute from notehub_py.models.update_fleet_request import UpdateFleetRequest +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest from notehub_py.models.upload_metadata import UploadMetadata from notehub_py.models.usage_data import UsageData from notehub_py.models.usage_events_data import UsageEventsData diff --git a/src/notehub_py/api/billing_account_api.py b/src/notehub_py/api/billing_account_api.py index b008d87..cbbf4b7 100644 --- a/src/notehub_py/api/billing_account_api.py +++ b/src/notehub_py/api/billing_account_api.py @@ -316,7 +316,7 @@ def get_billing_account_balance_history( ) -> GetBillingAccountBalanceHistory200Response: """get_billing_account_balance_history - Get Billing Account Balance history, only enterprise supported + Get Billing Account Balance history :param billing_account_uid: (required) :type billing_account_uid: str @@ -398,7 +398,7 @@ def get_billing_account_balance_history_with_http_info( ) -> ApiResponse[GetBillingAccountBalanceHistory200Response]: """get_billing_account_balance_history - Get Billing Account Balance history, only enterprise supported + Get Billing Account Balance history :param billing_account_uid: (required) :type billing_account_uid: str @@ -480,7 +480,7 @@ def get_billing_account_balance_history_without_preload_content( ) -> RESTResponseType: """get_billing_account_balance_history - Get Billing Account Balance history, only enterprise supported + Get Billing Account Balance history :param billing_account_uid: (required) :type billing_account_uid: str diff --git a/src/notehub_py/api/project_api.py b/src/notehub_py/api/project_api.py index 648663e..f45d10a 100644 --- a/src/notehub_py/api/project_api.py +++ b/src/notehub_py/api/project_api.py @@ -48,6 +48,7 @@ from notehub_py.models.product import Product from notehub_py.models.project import Project from notehub_py.models.update_fleet_request import UpdateFleetRequest +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest from notehub_py.api_client import ApiClient, RequestSerialized from notehub_py.api_response import ApiResponse @@ -1719,6 +1720,275 @@ def _delete_device_from_fleets_serialize( _request_auth=_request_auth, ) + @validate_call + def delete_firmware( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """delete_firmware + + Delete a host firmware binary. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "204": None, + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def delete_firmware_with_http_info( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """delete_firmware + + Delete a host firmware binary. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "204": None, + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def delete_firmware_without_preload_content( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """delete_firmware + + Delete a host firmware binary. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "204": None, + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + return response_data.response + + def _delete_firmware_serialize( + self, + project_or_product_uid, + firmware_type, + filename, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_or_product_uid is not None: + _path_params["projectOrProductUID"] = project_or_product_uid + if firmware_type is not None: + _path_params["firmwareType"] = firmware_type + if filename is not None: + _path_params["filename"] = filename + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) + + # authentication setting + _auth_settings: List[str] = ["personalAccessToken"] + + return self.api_client.param_serialize( + method="DELETE", + resource_path="/v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename}", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + @validate_call def delete_fleet( self, @@ -10477,6 +10747,315 @@ def _set_project_environment_variables_serialize( _request_auth=_request_auth, ) + @validate_call + def update_firmware( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + update_host_firmware_request: Annotated[ + UpdateHostFirmwareRequest, + Field( + description="Firmware metadata fields to update. All fields are optional; only provided fields will be updated." + ), + ], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> FirmwareInfo: + """update_firmware + + Update the metadata of an existing host firmware entry. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param update_host_firmware_request: Firmware metadata fields to update. All fields are optional; only provided fields will be updated. (required) + :type update_host_firmware_request: UpdateHostFirmwareRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + update_host_firmware_request=update_host_firmware_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "FirmwareInfo", + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + @validate_call + def update_firmware_with_http_info( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + update_host_firmware_request: Annotated[ + UpdateHostFirmwareRequest, + Field( + description="Firmware metadata fields to update. All fields are optional; only provided fields will be updated." + ), + ], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[FirmwareInfo]: + """update_firmware + + Update the metadata of an existing host firmware entry. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param update_host_firmware_request: Firmware metadata fields to update. All fields are optional; only provided fields will be updated. (required) + :type update_host_firmware_request: UpdateHostFirmwareRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + update_host_firmware_request=update_host_firmware_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "FirmwareInfo", + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + @validate_call + def update_firmware_without_preload_content( + self, + project_or_product_uid: StrictStr, + firmware_type: StrictStr, + filename: StrictStr, + update_host_firmware_request: Annotated[ + UpdateHostFirmwareRequest, + Field( + description="Firmware metadata fields to update. All fields are optional; only provided fields will be updated." + ), + ], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)] + ], + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """update_firmware + + Update the metadata of an existing host firmware entry. The filename must be the full stored filename including the timestamp suffix (e.g. test$20260324190911.bin) as returned by the firmware upload or list endpoints. + + :param project_or_product_uid: (required) + :type project_or_product_uid: str + :param firmware_type: (required) + :type firmware_type: str + :param filename: (required) + :type filename: str + :param update_host_firmware_request: Firmware metadata fields to update. All fields are optional; only provided fields will be updated. (required) + :type update_host_firmware_request: UpdateHostFirmwareRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_firmware_serialize( + project_or_product_uid=project_or_product_uid, + firmware_type=firmware_type, + filename=filename, + update_host_firmware_request=update_host_firmware_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index, + ) + + _response_types_map: Dict[str, Optional[str]] = { + "200": "FirmwareInfo", + } + response_data = self.api_client.call_api( + *_param, _request_timeout=_request_timeout + ) + return response_data.response + + def _update_firmware_serialize( + self, + project_or_product_uid, + firmware_type, + filename, + update_host_firmware_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = {} + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, Union[str, bytes]] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_or_product_uid is not None: + _path_params["projectOrProductUID"] = project_or_product_uid + if firmware_type is not None: + _path_params["firmwareType"] = firmware_type + if filename is not None: + _path_params["filename"] = filename + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_host_firmware_request is not None: + _body_params = update_host_firmware_request + + # set the HTTP header `Accept` + _header_params["Accept"] = self.api_client.select_header_accept( + ["application/json"] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params["Content-Type"] = _content_type + else: + _default_content_type = self.api_client.select_header_content_type( + ["application/json"] + ) + if _default_content_type is not None: + _header_params["Content-Type"] = _default_content_type + + # authentication setting + _auth_settings: List[str] = ["personalAccessToken"] + + return self.api_client.param_serialize( + method="POST", + resource_path="/v1/projects/{projectOrProductUID}/firmware/{firmwareType}/{filename}", + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth, + ) + @validate_call def update_fleet( self, diff --git a/src/notehub_py/api_client.py b/src/notehub_py/api_client.py index 2c47d63..fc2187a 100644 --- a/src/notehub_py/api_client.py +++ b/src/notehub_py/api_client.py @@ -86,7 +86,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = "OpenAPI-Generator/6.1.0/python" + self.user_agent = "OpenAPI-Generator/6.2.0/python" self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/src/notehub_py/configuration.py b/src/notehub_py/configuration.py index 40186fd..39f1328 100644 --- a/src/notehub_py/configuration.py +++ b/src/notehub_py/configuration.py @@ -395,7 +395,7 @@ def to_debug_report(self): "OS: {env}\n" "Python Version: {pyversion}\n" "Version of the API: 1.2.0\n" - "SDK Package Version: 6.1.0".format(env=sys.platform, pyversion=sys.version) + "SDK Package Version: 6.2.0".format(env=sys.platform, pyversion=sys.version) ) def get_host_settings(self): diff --git a/src/notehub_py/models/__init__.py b/src/notehub_py/models/__init__.py index 0098e0f..d88a6ef 100644 --- a/src/notehub_py/models/__init__.py +++ b/src/notehub_py/models/__init__.py @@ -187,6 +187,7 @@ from notehub_py.models.tower_location import TowerLocation from notehub_py.models.twilio_route import TwilioRoute from notehub_py.models.update_fleet_request import UpdateFleetRequest +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest from notehub_py.models.upload_metadata import UploadMetadata from notehub_py.models.usage_data import UsageData from notehub_py.models.usage_events_data import UsageEventsData diff --git a/src/notehub_py/models/update_host_firmware_request.py b/src/notehub_py/models/update_host_firmware_request.py new file mode 100644 index 0000000..257d029 --- /dev/null +++ b/src/notehub_py/models/update_host_firmware_request.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" +Notehub API + +The OpenAPI definition for the Notehub.io API. + +The version of the OpenAPI document: 1.2.0 +Contact: engineering@blues.io +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + + +class UpdateHostFirmwareRequest(BaseModel): + """ + Request body for updating host firmware metadata. All fields are optional; only provided fields will be updated. + """ # noqa: E501 + + info: Optional[Dict[str, Any]] = Field( + default=None, + description="Arbitrary JSON metadata associated with this firmware entry.", + ) + notes: Optional[StrictStr] = Field( + default=None, description="Notes describing this firmware version." + ) + version: Optional[StrictStr] = Field( + default=None, description="The firmware version string." + ) + __properties: ClassVar[List[str]] = ["info", "notes", "version"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateHostFirmwareRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateHostFirmwareRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate( + { + "info": obj.get("info"), + "notes": obj.get("notes"), + "version": obj.get("version"), + } + ) + return _obj diff --git a/src/pyproject.toml b/src/pyproject.toml index f577609..bf91336 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "notehub_py" -version = "6.1.0" +version = "6.2.0" description = "Notehub API" authors = ["Blues Engineering "] license = "MIT" diff --git a/src/setup.py b/src/setup.py index 28cdebb..7693316 100644 --- a/src/setup.py +++ b/src/setup.py @@ -25,7 +25,7 @@ # prerequisite: setuptools # http://pypi.python.org/pypi/setuptools NAME = "notehub-py" -VERSION = "6.1.0" +VERSION = "6.2.0" PYTHON_REQUIRES = ">=3.10" REQUIRES = [ "urllib3 >= 2.5.0", diff --git a/src/test/test_update_host_firmware_request.py b/src/test/test_update_host_firmware_request.py new file mode 100644 index 0000000..71f1c98 --- /dev/null +++ b/src/test/test_update_host_firmware_request.py @@ -0,0 +1,56 @@ +# coding: utf-8 + +""" +Notehub API + +The OpenAPI definition for the Notehub.io API. + +The version of the OpenAPI document: 1.2.0 +Contact: engineering@blues.io +Generated by OpenAPI Generator (https://openapi-generator.tech) + +Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from notehub_py.models.update_host_firmware_request import UpdateHostFirmwareRequest + + +class TestUpdateHostFirmwareRequest(unittest.TestCase): + """UpdateHostFirmwareRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateHostFirmwareRequest: + """Test UpdateHostFirmwareRequest + include_option is a boolean, when False only required + params are included, when True both required and + optional params are included""" + # uncomment below to create an instance of `UpdateHostFirmwareRequest` + """ + model = UpdateHostFirmwareRequest() + if include_optional: + return UpdateHostFirmwareRequest( + info = { }, + notes = '', + version = '' + ) + else: + return UpdateHostFirmwareRequest( + ) + """ + + def testUpdateHostFirmwareRequest(self): + """Test UpdateHostFirmwareRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + + +if __name__ == "__main__": + unittest.main()