From 2c5e91f1f3043a57e168d29b5003dc8c4358c730 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 06:28:52 +0000 Subject: [PATCH] Update SDK to version v4.24.0 - Generated from OpenAPI spec version v4.24.0 - Auto-generated by GitHub Actions --- .sdk-version | 2 +- README.md | 3 + docs/AnalysesCoreApi.md | 96 ++++++ docs/AnalysisBasicInfoOutputBody.md | 1 + docs/AnalysisRecordBody.md | 1 + docs/ExtractionFailure.md | 30 ++ docs/ResultBody.md | 2 +- docs/UpgradeAnalysisModelOutputBody.md | 31 ++ revengai/__init__.py | 6 +- revengai/api/analyses_core_api.py | 278 ++++++++++++++++++ revengai/api_client.py | 2 +- revengai/configuration.py | 4 +- revengai/models/__init__.py | 2 + .../models/analysis_basic_info_output_body.py | 4 +- revengai/models/analysis_record_body.py | 4 +- revengai/models/error_body.py | 4 +- revengai/models/extraction_failure.py | 101 +++++++ revengai/models/result_body.py | 21 +- revengai/models/status.py | 4 +- .../upgrade_analysis_model_output_body.py | 103 +++++++ 20 files changed, 683 insertions(+), 16 deletions(-) create mode 100644 docs/ExtractionFailure.md create mode 100644 docs/UpgradeAnalysisModelOutputBody.md create mode 100644 revengai/models/extraction_failure.py create mode 100644 revengai/models/upgrade_analysis_model_output_body.py diff --git a/.sdk-version b/.sdk-version index 1beef590..56008fbc 100644 --- a/.sdk-version +++ b/.sdk-version @@ -1 +1 @@ -v4.20.0 +v4.24.0 diff --git a/README.md b/README.md index ea4af387..ed0e560a 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Class | Method | HTTP request | Description *AnalysesCoreApi* | [**v3_get_analysis_strings_status**](docs/AnalysesCoreApi.md#v3_get_analysis_strings_status) | **GET** /v3/analyses/{analysis_id}/functions/strings/status | Get the string-extraction status for an analysis. *AnalysesCoreApi* | [**v3_list_analyses**](docs/AnalysesCoreApi.md#v3_list_analyses) | **GET** /v3/analyses | List analyses *AnalysesCoreApi* | [**v3_list_example_analyses**](docs/AnalysesCoreApi.md#v3_list_example_analyses) | **GET** /v3/analyses/examples | List example analyses +*AnalysesCoreApi* | [**v3_upgrade_analysis_model**](docs/AnalysesCoreApi.md#v3_upgrade_analysis_model) | **POST** /v3/analyses/{analysis_id}/upgrade-model | Re-analyse on the latest model *AnalysesResultsMetadataApi* | [**get_analysis_functions_paginated**](docs/AnalysesResultsMetadataApi.md#get_analysis_functions_paginated) | **GET** /v2/analyses/{analysis_id}/functions | Get functions from analysis *AnalysesResultsMetadataApi* | [**get_capabilities**](docs/AnalysesResultsMetadataApi.md#get_capabilities) | **GET** /v2/analyses/{analysis_id}/capabilities | Gets the capabilities from the analysis *AnalysesResultsMetadataApi* | [**get_functions_list**](docs/AnalysesResultsMetadataApi.md#get_functions_list) | **GET** /v2/analyses/{analysis_id}/functions/list | Gets functions from analysis @@ -494,6 +495,7 @@ Class | Method | HTTP request | Description - [ExternalResponse](docs/ExternalResponse.md) - [ExtractedBinary](docs/ExtractedBinary.md) - [ExtractedURL](docs/ExtractedURL.md) + - [ExtractionFailure](docs/ExtractionFailure.md) - [FileActivityEntry](docs/FileActivityEntry.md) - [FileFormat](docs/FileFormat.md) - [FileHashes](docs/FileHashes.md) @@ -766,6 +768,7 @@ Class | Method | HTTP request | Description - [UpdateUserCreditsInputBody](docs/UpdateUserCreditsInputBody.md) - [UpdateUserInputBody](docs/UpdateUserInputBody.md) - [UpdateUserPasswordInputBody](docs/UpdateUserPasswordInputBody.md) + - [UpgradeAnalysisModelOutputBody](docs/UpgradeAnalysisModelOutputBody.md) - [UploadFileType](docs/UploadFileType.md) - [UploadResponse](docs/UploadResponse.md) - [UpsertAiDecomplationRatingRequest](docs/UpsertAiDecomplationRatingRequest.md) diff --git a/docs/AnalysesCoreApi.md b/docs/AnalysesCoreApi.md index 37dea083..5e64ec93 100644 --- a/docs/AnalysesCoreApi.md +++ b/docs/AnalysesCoreApi.md @@ -33,6 +33,7 @@ Method | HTTP request | Description [**v3_get_analysis_strings_status**](AnalysesCoreApi.md#v3_get_analysis_strings_status) | **GET** /v3/analyses/{analysis_id}/functions/strings/status | Get the string-extraction status for an analysis. [**v3_list_analyses**](AnalysesCoreApi.md#v3_list_analyses) | **GET** /v3/analyses | List analyses [**v3_list_example_analyses**](AnalysesCoreApi.md#v3_list_example_analyses) | **GET** /v3/analyses/examples | List example analyses +[**v3_upgrade_analysis_model**](AnalysesCoreApi.md#v3_upgrade_analysis_model) | **POST** /v3/analyses/{analysis_id}/upgrade-model | Re-analyse on the latest model # **add_user_string_to_analysis** @@ -2716,3 +2717,98 @@ This endpoint does not need any parameter. [[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) +# **v3_upgrade_analysis_model** +> UpgradeAnalysisModelOutputBody v3_upgrade_analysis_model(analysis_id) + +Re-analyse on the latest model + +Re-runs an analysis created on an older model against the current unified model, in place — the analysis ID does not change. No credits are consumed. Only the owner may call it, and only once the analysis has settled: the pipeline clears the binary's functions, names, data types and signatures before re-running. Returns 409 if the analysis is already on the latest model, or is still running. Poll `GET /v3/analyses/{analysis_id}/basic` for status, as with any other run. + +**Error codes:** +- `404` [`NOT_FOUND`](/errors/NOT_FOUND) — Not Found +- `403` [`ACCESS_DENIED`](/errors/ACCESS_DENIED) — Access Denied +- `409` [`CONFLICT`](/errors/CONFLICT) — Conflict + +### Example + +* Api Key Authentication (APIKey): +* Bearer Authentication (bearerAuth): + +```python +import revengai +from revengai.models.upgrade_analysis_model_output_body import UpgradeAnalysisModelOutputBody +from revengai.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.reveng.ai +# See configuration.py for a list of all supported configuration parameters. +configuration = revengai.Configuration( + host = "https://api.reveng.ai" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: APIKey +configuration.api_key['APIKey'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['APIKey'] = 'Bearer' + +# Configure Bearer authorization: bearerAuth +configuration = revengai.Configuration( + access_token = os.environ["BEARER_TOKEN"] +) + +# Enter a context with an instance of the API client +with revengai.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = revengai.AnalysesCoreApi(api_client) + analysis_id = 56 # int | Analysis ID + + try: + # Re-analyse on the latest model + api_response = api_instance.v3_upgrade_analysis_model(analysis_id) + print("The response of AnalysesCoreApi->v3_upgrade_analysis_model:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AnalysesCoreApi->v3_upgrade_analysis_model: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **analysis_id** | **int**| Analysis ID | + +### Return type + +[**UpgradeAnalysisModelOutputBody**](UpgradeAnalysisModelOutputBody.md) + +### Authorization + +[APIKey](../README.md#APIKey), [bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**201** | Created | - | +**403** | Forbidden | - | +**404** | Not Found | - | +**409** | Conflict | - | +**422** | Unprocessable Entity | - | +**500** | Internal Server 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/docs/AnalysisBasicInfoOutputBody.md b/docs/AnalysisBasicInfoOutputBody.md index 9904d4ab..be988dd9 100644 --- a/docs/AnalysisBasicInfoOutputBody.md +++ b/docs/AnalysisBasicInfoOutputBody.md @@ -22,6 +22,7 @@ Name | Type | Description | Notes **is_system** | **bool** | True when the analysis is owned by a system user | **model_id** | **int** | Model ID | **model_name** | **str** | Model used for analysis | +**model_upgrade_available** | **bool** | True when the analysis ran on a model older than the current one, so its owner can re-analyse it on the latest. Describes the analysis, not the caller's rights — only the owner may act on it | **owner_username** | **str** | Username of the analysis owner | **sequencer_version** | **str** | Sequencer version, omitted when not set | [optional] **sha_256_hash** | **str** | SHA-256 hash of the binary | diff --git a/docs/AnalysisRecordBody.md b/docs/AnalysisRecordBody.md index 0c05318f..d9c0d782 100644 --- a/docs/AnalysisRecordBody.md +++ b/docs/AnalysisRecordBody.md @@ -19,6 +19,7 @@ Name | Type | Description | Notes **is_owner** | **bool** | True when the caller owns the analysis | **model_id** | **int** | Model ID | **model_name** | **str** | Model name | +**model_upgrade_available** | **bool** | True when the analysis ran on a model older than the current one, so its owner can re-analyse it on the latest. Describes the analysis, not the caller's rights — only the owner may act on it | **sha_256_hash** | **str** | SHA-256 hash of the binary | **status** | **str** | Analysis status | **supplied_architecture** | **str** | User-supplied instruction-set architecture; \"AUTO\" when not overridden | diff --git a/docs/ExtractionFailure.md b/docs/ExtractionFailure.md new file mode 100644 index 00000000..093b2d55 --- /dev/null +++ b/docs/ExtractionFailure.md @@ -0,0 +1,30 @@ +# ExtractionFailure + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**message** | **str** | Why this file failed to extract. | +**retryable** | **bool** | Whether re-submitting the extraction might resolve this failure. | + +## Example + +```python +from revengai.models.extraction_failure import ExtractionFailure + +# TODO update the JSON string below +json = "{}" +# create an instance of ExtractionFailure from a JSON string +extraction_failure_instance = ExtractionFailure.from_json(json) +# print the JSON string representation of the object +print(ExtractionFailure.to_json()) + +# convert the object into a dict +extraction_failure_dict = extraction_failure_instance.to_dict() +# create an instance of ExtractionFailure from a dict +extraction_failure_from_dict = ExtractionFailure.from_dict(extraction_failure_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/docs/ResultBody.md b/docs/ResultBody.md index d8ca5020..123e9fb0 100644 --- a/docs/ResultBody.md +++ b/docs/ResultBody.md @@ -7,7 +7,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **binaries** | [**List[ExtractedBinary]**](ExtractedBinary.md) | Child binaries recovered from the extraction. | **extraction_depth** | **int** | Number of nested-archive extraction passes taken. | -**filename_to_extraction_failure** | **Dict[str, str]** | Per-file extraction failures, keyed by filename. | +**filename_to_failure** | [**Dict[str, ExtractionFailure]**](ExtractionFailure.md) | Per-file extraction failures, keyed by filename. | **skipped_files** | **int** | Files skipped because they were not recognised as binaries. | ## Example diff --git a/docs/UpgradeAnalysisModelOutputBody.md b/docs/UpgradeAnalysisModelOutputBody.md new file mode 100644 index 00000000..15ed1dd2 --- /dev/null +++ b/docs/UpgradeAnalysisModelOutputBody.md @@ -0,0 +1,31 @@ +# UpgradeAnalysisModelOutputBody + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**analysis_id** | **int** | ID of the re-queued analysis. Unchanged — the upgrade moves the existing analysis rather than creating a new one. | +**binary_id** | **int** | ID of the binary the analysis belongs to | +**model_id** | **int** | Model the analysis is now queued against | + +## Example + +```python +from revengai.models.upgrade_analysis_model_output_body import UpgradeAnalysisModelOutputBody + +# TODO update the JSON string below +json = "{}" +# create an instance of UpgradeAnalysisModelOutputBody from a JSON string +upgrade_analysis_model_output_body_instance = UpgradeAnalysisModelOutputBody.from_json(json) +# print the JSON string representation of the object +print(UpgradeAnalysisModelOutputBody.to_json()) + +# convert the object into a dict +upgrade_analysis_model_output_body_dict = upgrade_analysis_model_output_body_instance.to_dict() +# create an instance of UpgradeAnalysisModelOutputBody from a dict +upgrade_analysis_model_output_body_from_dict = UpgradeAnalysisModelOutputBody.from_dict(upgrade_analysis_model_output_body_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/revengai/__init__.py b/revengai/__init__.py index f4331fab..74893d4f 100644 --- a/revengai/__init__.py +++ b/revengai/__init__.py @@ -13,7 +13,7 @@ """ # noqa: E501 -__version__ = "v4.20.0" +__version__ = "v4.24.0" # Define package exports __all__ = [ @@ -323,6 +323,7 @@ "ExternalResponse", "ExtractedBinary", "ExtractedURL", + "ExtractionFailure", "FileActivityEntry", "FileFormat", "FileHashes", @@ -595,6 +596,7 @@ "UpdateUserCreditsInputBody", "UpdateUserInputBody", "UpdateUserPasswordInputBody", + "UpgradeAnalysisModelOutputBody", "UploadFileType", "UploadResponse", "UpsertAiDecomplationRatingRequest", @@ -924,6 +926,7 @@ from revengai.models.external_response import ExternalResponse as ExternalResponse from revengai.models.extracted_binary import ExtractedBinary as ExtractedBinary from revengai.models.extracted_url import ExtractedURL as ExtractedURL +from revengai.models.extraction_failure import ExtractionFailure as ExtractionFailure from revengai.models.file_activity_entry import FileActivityEntry as FileActivityEntry from revengai.models.file_format import FileFormat as FileFormat from revengai.models.file_hashes import FileHashes as FileHashes @@ -1196,6 +1199,7 @@ from revengai.models.update_user_credits_input_body import UpdateUserCreditsInputBody as UpdateUserCreditsInputBody from revengai.models.update_user_input_body import UpdateUserInputBody as UpdateUserInputBody from revengai.models.update_user_password_input_body import UpdateUserPasswordInputBody as UpdateUserPasswordInputBody +from revengai.models.upgrade_analysis_model_output_body import UpgradeAnalysisModelOutputBody as UpgradeAnalysisModelOutputBody from revengai.models.upload_file_type import UploadFileType as UploadFileType from revengai.models.upload_response import UploadResponse as UploadResponse from revengai.models.upsert_ai_decomplation_rating_request import UpsertAiDecomplationRatingRequest as UpsertAiDecomplationRatingRequest diff --git a/revengai/api/analyses_core_api.py b/revengai/api/analyses_core_api.py index 3efa719c..ac056961 100644 --- a/revengai/api/analyses_core_api.py +++ b/revengai/api/analyses_core_api.py @@ -56,6 +56,7 @@ from revengai.models.start_matching_for_analysis_input_body import StartMatchingForAnalysisInputBody from revengai.models.start_matching_output_body import StartMatchingOutputBody from revengai.models.status_input import StatusInput +from revengai.models.upgrade_analysis_model_output_body import UpgradeAnalysisModelOutputBody from revengai.models.upload_file_type import UploadFileType from revengai.models.workspace import Workspace @@ -8690,3 +8691,280 @@ def _v3_list_example_analyses_serialize( ) + + + @validate_call + def v3_upgrade_analysis_model( + self, + analysis_id: Annotated[int, Field(strict=True, ge=1, description="Analysis ID")], + _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, + ) -> UpgradeAnalysisModelOutputBody: + """Re-analyse on the latest model + + Re-runs an analysis created on an older model against the current unified model, in place — the analysis ID does not change. No credits are consumed. Only the owner may call it, and only once the analysis has settled: the pipeline clears the binary's functions, names, data types and signatures before re-running. Returns 409 if the analysis is already on the latest model, or is still running. Poll `GET /v3/analyses/{analysis_id}/basic` for status, as with any other run. **Error codes:** - `404` [`NOT_FOUND`](/errors/NOT_FOUND) — Not Found - `403` [`ACCESS_DENIED`](/errors/ACCESS_DENIED) — Access Denied - `409` [`CONFLICT`](/errors/CONFLICT) — Conflict + + :param analysis_id: Analysis ID (required) + :type analysis_id: int + :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._v3_upgrade_analysis_model_serialize( + analysis_id=analysis_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UpgradeAnalysisModelOutputBody", + '403': "APIError", + '404': "APIError", + '409': "APIError", + '422': "APIError", + '500': "APIError", + } + 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 v3_upgrade_analysis_model_with_http_info( + self, + analysis_id: Annotated[int, Field(strict=True, ge=1, description="Analysis ID")], + _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[UpgradeAnalysisModelOutputBody]: + """Re-analyse on the latest model + + Re-runs an analysis created on an older model against the current unified model, in place — the analysis ID does not change. No credits are consumed. Only the owner may call it, and only once the analysis has settled: the pipeline clears the binary's functions, names, data types and signatures before re-running. Returns 409 if the analysis is already on the latest model, or is still running. Poll `GET /v3/analyses/{analysis_id}/basic` for status, as with any other run. **Error codes:** - `404` [`NOT_FOUND`](/errors/NOT_FOUND) — Not Found - `403` [`ACCESS_DENIED`](/errors/ACCESS_DENIED) — Access Denied - `409` [`CONFLICT`](/errors/CONFLICT) — Conflict + + :param analysis_id: Analysis ID (required) + :type analysis_id: int + :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._v3_upgrade_analysis_model_serialize( + analysis_id=analysis_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UpgradeAnalysisModelOutputBody", + '403': "APIError", + '404': "APIError", + '409': "APIError", + '422': "APIError", + '500': "APIError", + } + 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 v3_upgrade_analysis_model_without_preload_content( + self, + analysis_id: Annotated[int, Field(strict=True, ge=1, description="Analysis ID")], + _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: + """Re-analyse on the latest model + + Re-runs an analysis created on an older model against the current unified model, in place — the analysis ID does not change. No credits are consumed. Only the owner may call it, and only once the analysis has settled: the pipeline clears the binary's functions, names, data types and signatures before re-running. Returns 409 if the analysis is already on the latest model, or is still running. Poll `GET /v3/analyses/{analysis_id}/basic` for status, as with any other run. **Error codes:** - `404` [`NOT_FOUND`](/errors/NOT_FOUND) — Not Found - `403` [`ACCESS_DENIED`](/errors/ACCESS_DENIED) — Access Denied - `409` [`CONFLICT`](/errors/CONFLICT) — Conflict + + :param analysis_id: Analysis ID (required) + :type analysis_id: int + :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._v3_upgrade_analysis_model_serialize( + analysis_id=analysis_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "UpgradeAnalysisModelOutputBody", + '403': "APIError", + '404': "APIError", + '409': "APIError", + '422': "APIError", + '500': "APIError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _v3_upgrade_analysis_model_serialize( + self, + analysis_id, + _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, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if analysis_id is not None: + _path_params['analysis_id'] = analysis_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'APIKey', + 'bearerAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v3/analyses/{analysis_id}/upgrade-model', + 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 + ) + + diff --git a/revengai/api_client.py b/revengai/api_client.py index 6bd4cb74..06ab425c 100644 --- a/revengai/api_client.py +++ b/revengai/api_client.py @@ -90,7 +90,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/v4.20.0/python' + self.user_agent = 'OpenAPI-Generator/v4.24.0/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/revengai/configuration.py b/revengai/configuration.py index f6483978..868492ed 100644 --- a/revengai/configuration.py +++ b/revengai/configuration.py @@ -541,8 +541,8 @@ def to_debug_report(self) -> str: return "Python SDK Debug Report:\n"\ "OS: {env}\n"\ "Python Version: {pyversion}\n"\ - "Version of the API: v4.20.0\n"\ - "SDK Package Version: v4.20.0".\ + "Version of the API: v4.24.0\n"\ + "SDK Package Version: v4.24.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: diff --git a/revengai/models/__init__.py b/revengai/models/__init__.py index 8d091c46..a5bb40f3 100644 --- a/revengai/models/__init__.py +++ b/revengai/models/__init__.py @@ -289,6 +289,7 @@ from revengai.models.external_response import ExternalResponse from revengai.models.extracted_binary import ExtractedBinary from revengai.models.extracted_url import ExtractedURL +from revengai.models.extraction_failure import ExtractionFailure from revengai.models.file_activity_entry import FileActivityEntry from revengai.models.file_format import FileFormat from revengai.models.file_hashes import FileHashes @@ -561,6 +562,7 @@ from revengai.models.update_user_credits_input_body import UpdateUserCreditsInputBody from revengai.models.update_user_input_body import UpdateUserInputBody from revengai.models.update_user_password_input_body import UpdateUserPasswordInputBody +from revengai.models.upgrade_analysis_model_output_body import UpgradeAnalysisModelOutputBody from revengai.models.upload_file_type import UploadFileType from revengai.models.upload_response import UploadResponse from revengai.models.upsert_ai_decomplation_rating_request import UpsertAiDecomplationRatingRequest diff --git a/revengai/models/analysis_basic_info_output_body.py b/revengai/models/analysis_basic_info_output_body.py index 0f66cc7e..34c214fb 100644 --- a/revengai/models/analysis_basic_info_output_body.py +++ b/revengai/models/analysis_basic_info_output_body.py @@ -43,6 +43,7 @@ class AnalysisBasicInfoOutputBody(BaseModel): is_system: StrictBool = Field(description="True when the analysis is owned by a system user") model_id: StrictInt = Field(description="Model ID") model_name: StrictStr = Field(description="Model used for analysis") + model_upgrade_available: StrictBool = Field(description="True when the analysis ran on a model older than the current one, so its owner can re-analyse it on the latest. Describes the analysis, not the caller's rights — only the owner may act on it") owner_username: StrictStr = Field(description="Username of the analysis owner") sequencer_version: Optional[StrictStr] = Field(default=None, description="Sequencer version, omitted when not set") sha_256_hash: StrictStr = Field(description="SHA-256 hash of the binary") @@ -51,7 +52,7 @@ class AnalysisBasicInfoOutputBody(BaseModel): supplied_binary_type: StrictStr = Field(description="User-supplied operating-system platform; \"AUTO\" when not overridden") team_id: StrictInt = Field(description="Team ID of the analysis") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "binary_uuid", "creation", "debug", "detected_architecture", "detected_binary_format", "detected_binary_type", "function_count", "is_advanced", "is_owner", "is_system", "model_id", "model_name", "owner_username", "sequencer_version", "sha_256_hash", "supplied_architecture", "supplied_binary_format", "supplied_binary_type", "team_id"] + __properties: ClassVar[List[str]] = ["analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "binary_uuid", "creation", "debug", "detected_architecture", "detected_binary_format", "detected_binary_type", "function_count", "is_advanced", "is_owner", "is_system", "model_id", "model_name", "model_upgrade_available", "owner_username", "sequencer_version", "sha_256_hash", "supplied_architecture", "supplied_binary_format", "supplied_binary_type", "team_id"] @field_validator('analysis_scope') def analysis_scope_validate_enum(cls, value): @@ -140,6 +141,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "is_system": obj.get("is_system"), "model_id": obj.get("model_id"), "model_name": obj.get("model_name"), + "model_upgrade_available": obj.get("model_upgrade_available"), "owner_username": obj.get("owner_username"), "sequencer_version": obj.get("sequencer_version"), "sha_256_hash": obj.get("sha_256_hash"), diff --git a/revengai/models/analysis_record_body.py b/revengai/models/analysis_record_body.py index 2b2902b4..ab4cde42 100644 --- a/revengai/models/analysis_record_body.py +++ b/revengai/models/analysis_record_body.py @@ -41,6 +41,7 @@ class AnalysisRecordBody(BaseModel): is_owner: StrictBool = Field(description="True when the caller owns the analysis") model_id: StrictInt = Field(description="Model ID") model_name: StrictStr = Field(description="Model name") + model_upgrade_available: StrictBool = Field(description="True when the analysis ran on a model older than the current one, so its owner can re-analyse it on the latest. Describes the analysis, not the caller's rights — only the owner may act on it") sha_256_hash: StrictStr = Field(description="SHA-256 hash of the binary") status: StrictStr = Field(description="Analysis status") supplied_architecture: StrictStr = Field(description="User-supplied instruction-set architecture; \"AUTO\" when not overridden") @@ -49,7 +50,7 @@ class AnalysisRecordBody(BaseModel): tags: Optional[List[AnalysisTagBody]] = Field(description="Tags associated with the binary") username: StrictStr = Field(description="Username of the analysis owner") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["analysis_id", "analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "creation", "detected_architecture", "detected_binary_format", "detected_binary_type", "function_boundaries_hash", "is_owner", "model_id", "model_name", "sha_256_hash", "status", "supplied_architecture", "supplied_binary_format", "supplied_binary_type", "tags", "username"] + __properties: ClassVar[List[str]] = ["analysis_id", "analysis_scope", "base_address", "binary_id", "binary_name", "binary_size", "creation", "detected_architecture", "detected_binary_format", "detected_binary_type", "function_boundaries_hash", "is_owner", "model_id", "model_name", "model_upgrade_available", "sha_256_hash", "status", "supplied_architecture", "supplied_binary_format", "supplied_binary_type", "tags", "username"] @field_validator('analysis_scope') def analysis_scope_validate_enum(cls, value): @@ -142,6 +143,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "is_owner": obj.get("is_owner"), "model_id": obj.get("model_id"), "model_name": obj.get("model_name"), + "model_upgrade_available": obj.get("model_upgrade_available"), "sha_256_hash": obj.get("sha_256_hash"), "status": obj.get("status"), "supplied_architecture": obj.get("supplied_architecture"), diff --git a/revengai/models/error_body.py b/revengai/models/error_body.py index e08b612e..08ec1c0a 100644 --- a/revengai/models/error_body.py +++ b/revengai/models/error_body.py @@ -36,8 +36,8 @@ class ErrorBody(BaseModel): @field_validator('code') def code_validate_enum(cls, value): """Validates the enum""" - if value not in set(['ACCESS_DENIED', 'AGENT_BUDGET_EXCEEDED', 'AGENT_DEFINITION_NOT_FOUND', 'AGENT_INVALID_STARTING_INPUT', 'AGENT_MEMORY_INVALID_SCOPE', 'AGENT_MEMORY_NOT_FOUND', 'AGENT_MEMORY_VERSION_CONFLICT', 'AGENT_NO_PENDING_QUESTION', 'AGENT_RUN_NOT_FOUND', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api']): - raise ValueError("must be one of enum values ('ACCESS_DENIED', 'AGENT_BUDGET_EXCEEDED', 'AGENT_DEFINITION_NOT_FOUND', 'AGENT_INVALID_STARTING_INPUT', 'AGENT_MEMORY_INVALID_SCOPE', 'AGENT_MEMORY_NOT_FOUND', 'AGENT_MEMORY_VERSION_CONFLICT', 'AGENT_NO_PENDING_QUESTION', 'AGENT_RUN_NOT_FOUND', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api')") + if value not in set(['ACCESS_DENIED', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api']): + raise ValueError("must be one of enum values ('ACCESS_DENIED', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api')") return value model_config = ConfigDict( diff --git a/revengai/models/extraction_failure.py b/revengai/models/extraction_failure.py new file mode 100644 index 00000000..c3b00750 --- /dev/null +++ b/revengai/models/extraction_failure.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + RevEng.AI API + + RevEng.AI is an AI-powered binary analysis platform for reverse engineering and malware analysis. It provides similarity search across executable binaries and functions, AI-driven decompilation, dynamic execution analysis, firmware unpacking, and integration with external threat intelligence sources like VirusTotal. + + 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, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class ExtractionFailure(BaseModel): + """ + ExtractionFailure + """ # noqa: E501 + message: StrictStr = Field(description="Why this file failed to extract.") + retryable: StrictBool = Field(description="Whether re-submitting the extraction might resolve this failure.") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["message", "retryable"] + + 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 ExtractionFailure 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. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ExtractionFailure from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "message": obj.get("message"), + "retryable": obj.get("retryable") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/revengai/models/result_body.py b/revengai/models/result_body.py index f7c70a58..e9877936 100644 --- a/revengai/models/result_body.py +++ b/revengai/models/result_body.py @@ -16,9 +16,10 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictInt from typing import Any, ClassVar, Dict, List, Optional from revengai.models.extracted_binary import ExtractedBinary +from revengai.models.extraction_failure import ExtractionFailure from typing import Optional, Set from typing_extensions import Self @@ -28,10 +29,10 @@ class ResultBody(BaseModel): """ # noqa: E501 binaries: Optional[List[ExtractedBinary]] = Field(description="Child binaries recovered from the extraction.") extraction_depth: StrictInt = Field(description="Number of nested-archive extraction passes taken.") - filename_to_extraction_failure: Dict[str, StrictStr] = Field(description="Per-file extraction failures, keyed by filename.") + filename_to_failure: Dict[str, ExtractionFailure] = Field(description="Per-file extraction failures, keyed by filename.") skipped_files: StrictInt = Field(description="Files skipped because they were not recognised as binaries.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["binaries", "extraction_depth", "filename_to_extraction_failure", "skipped_files"] + __properties: ClassVar[List[str]] = ["binaries", "extraction_depth", "filename_to_failure", "skipped_files"] model_config = ConfigDict( populate_by_name=True, @@ -81,6 +82,13 @@ def to_dict(self) -> Dict[str, Any]: if _item_binaries: _items.append(_item_binaries.to_dict()) _dict['binaries'] = _items + # override the default output from pydantic by calling `to_dict()` of each value in filename_to_failure (dict) + _field_dict = {} + if self.filename_to_failure: + for _key_filename_to_failure in self.filename_to_failure: + if self.filename_to_failure[_key_filename_to_failure]: + _field_dict[_key_filename_to_failure] = self.filename_to_failure[_key_filename_to_failure].to_dict() + _dict['filename_to_failure'] = _field_dict # puts key-value pairs in additional_properties in the top level if self.additional_properties is not None: for _key, _value in self.additional_properties.items(): @@ -105,7 +113,12 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "binaries": [ExtractedBinary.from_dict(_item) for _item in obj["binaries"]] if obj.get("binaries") is not None else None, "extraction_depth": obj.get("extraction_depth"), - "filename_to_extraction_failure": obj.get("filename_to_extraction_failure"), + "filename_to_failure": dict( + (_k, ExtractionFailure.from_dict(_v)) + for _k, _v in obj["filename_to_failure"].items() + ) + if obj.get("filename_to_failure") is not None + else None, "skipped_files": obj.get("skipped_files") }) # store additional fields in additional_properties diff --git a/revengai/models/status.py b/revengai/models/status.py index ead5677d..70d8a870 100644 --- a/revengai/models/status.py +++ b/revengai/models/status.py @@ -35,8 +35,8 @@ class Status(BaseModel): @field_validator('code') def code_validate_enum(cls, value): """Validates the enum""" - if value not in set(['ACCESS_DENIED', 'AGENT_BUDGET_EXCEEDED', 'AGENT_DEFINITION_NOT_FOUND', 'AGENT_INVALID_STARTING_INPUT', 'AGENT_MEMORY_INVALID_SCOPE', 'AGENT_MEMORY_NOT_FOUND', 'AGENT_MEMORY_VERSION_CONFLICT', 'AGENT_NO_PENDING_QUESTION', 'AGENT_RUN_NOT_FOUND', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api']): - raise ValueError("must be one of enum values ('ACCESS_DENIED', 'AGENT_BUDGET_EXCEEDED', 'AGENT_DEFINITION_NOT_FOUND', 'AGENT_INVALID_STARTING_INPUT', 'AGENT_MEMORY_INVALID_SCOPE', 'AGENT_MEMORY_NOT_FOUND', 'AGENT_MEMORY_VERSION_CONFLICT', 'AGENT_NO_PENDING_QUESTION', 'AGENT_RUN_NOT_FOUND', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api')") + if value not in set(['ACCESS_DENIED', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api']): + raise ValueError("must be one of enum values ('ACCESS_DENIED', 'ALREADY_EXISTS', 'ANALYSIS_NOT_READY', 'BAD_REQUEST', 'CLIENT_CLOSED_REQUEST', 'CONFLICT', 'CONVERSATION_NOT_FOUND', 'DOMAIN_ALREADY_CLAIMED', 'DOMAIN_VERIFICATION_PENDING', 'DYNAMIC_EXECUTION_INCOMPLETE', 'EMAIL_NOT_VERIFIED', 'EXTERNAL_USER', 'FORBIDDEN', 'GATEWAY_TIMEOUT', 'GROUP_HAS_MEMBERS', 'INSUFFICIENT_CREDITS', 'INTERNAL_ERROR', 'INTERNAL_ISSUER', 'INVALID_CONVERSATION_ID', 'INVALID_CREDENTIALS', 'INVALID_INVITE_CODE', 'INVALID_RESET_CODE', 'LAST_ORG_OWNER', 'LAST_TEAM_ADMIN', 'LAST_TEAM_MEMBER', 'LINKED_TO_ORG', 'METHOD_NOT_ALLOWED', 'NOT_ACCEPTABLE', 'NOT_FOUND', 'NO_ACTIVE_RUN', 'NO_PENDING_CONFIRMATION', 'OIDC_DISCOVERY_FAILED', 'PASSWORD_RESET_REQUIRED', 'PAYMENT_REQUIRED', 'REPORT_RENDER_FAILED', 'REQUEST_ENTITY_TOO_LARGE', 'RUN_ALREADY_ACTIVE', 'SELF_DELETION_NOT_ALLOWED', 'SERVICE_UNAVAILABLE', 'TOKEN_EXPIRED', 'TOKEN_REUSED', 'TOO_MANY_REQUESTS', 'UNAUTHORIZED', 'UNSUPPORTED_MEDIA_TYPE', 'VALIDATION_FAILED', 'VERIFICATION_EXPIRED', 'VERIFICATION_NOT_FOUND', 'unknown_default_open_api')") return value model_config = ConfigDict( diff --git a/revengai/models/upgrade_analysis_model_output_body.py b/revengai/models/upgrade_analysis_model_output_body.py new file mode 100644 index 00000000..aa924a36 --- /dev/null +++ b/revengai/models/upgrade_analysis_model_output_body.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + RevEng.AI API + + RevEng.AI is an AI-powered binary analysis platform for reverse engineering and malware analysis. It provides similarity search across executable binaries and functions, AI-driven decompilation, dynamic execution analysis, firmware unpacking, and integration with external threat intelligence sources like VirusTotal. + + 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, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class UpgradeAnalysisModelOutputBody(BaseModel): + """ + UpgradeAnalysisModelOutputBody + """ # noqa: E501 + analysis_id: StrictInt = Field(description="ID of the re-queued analysis. Unchanged — the upgrade moves the existing analysis rather than creating a new one.") + binary_id: StrictInt = Field(description="ID of the binary the analysis belongs to") + model_id: StrictInt = Field(description="Model the analysis is now queued against") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["analysis_id", "binary_id", "model_id"] + + 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 UpgradeAnalysisModelOutputBody 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. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpgradeAnalysisModelOutputBody from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "analysis_id": obj.get("analysis_id"), + "binary_id": obj.get("binary_id"), + "model_id": obj.get("model_id") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + +