From e975f1f3cfa30f7b0beb9ee3214d8eac5166aa7a Mon Sep 17 00:00:00 2001 From: blundski Date: Fri, 5 May 2023 15:35:40 +0200 Subject: [PATCH] Fix broken test data + minor changes (#145) --- exabel_data_sdk/client/api/export_api.py | 2 +- exabel_data_sdk/client/api/time_series_api.py | 1 - exabel_data_sdk/client/user_login.py | 4 ++-- .../scripts/create_entity_mapping_from_csv.py | 2 -- .../services/sql/sql_reader_configuration.py | 2 ++ .../v1/prediction_model_messages_pb2.pyi | 14 +++++++------- .../api/management/v1/folder_messages_pb2.py | 6 +++--- .../api/management/v1/folder_messages_pb2.pyi | 8 ++++---- .../tests/resources/data/corrupt_dates_1.xlsx | Bin 20530 -> 19586 bytes .../test_create_entity_mapping_from_csv.py | 5 ----- exabel_data_sdk/util/deprecate_arguments.py | 1 + 11 files changed, 20 insertions(+), 25 deletions(-) diff --git a/exabel_data_sdk/client/api/export_api.py b/exabel_data_sdk/client/api/export_api.py index 09eca9f..fea6f6c 100644 --- a/exabel_data_sdk/client/api/export_api.py +++ b/exabel_data_sdk/client/api/export_api.py @@ -81,7 +81,7 @@ def run_query_bytes(self, query: Union[str, Query], file_format: str) -> bytes: if error_message.startswith('"') and error_message.endswith('"'): error_message = error_message[1:-1] error_message = f"{response.status_code}: {error_message}" - raise Exception(error_message) + raise ValueError(error_message) def run_query(self, query: Union[str, Query]) -> pd.DataFrame: """ diff --git a/exabel_data_sdk/client/api/time_series_api.py b/exabel_data_sdk/client/api/time_series_api.py index 3e6403e..10aad4b 100644 --- a/exabel_data_sdk/client/api/time_series_api.py +++ b/exabel_data_sdk/client/api/time_series_api.py @@ -460,7 +460,6 @@ def bulk_upsert_time_series( """ def import_func(ts_sequence: Sequence[pd.Series]) -> Sequence[ResourceCreationResult]: - result = self.import_time_series( parent="signals/-", series=ts_sequence, diff --git a/exabel_data_sdk/client/user_login.py b/exabel_data_sdk/client/user_login.py index 442b336..8ce28ee 100644 --- a/exabel_data_sdk/client/user_login.py +++ b/exabel_data_sdk/client/user_login.py @@ -142,7 +142,7 @@ def start_http_server(self) -> HTTPServer: if error.errno != errno.EADDRINUSE: raise error if httpd is None: - raise Exception("Cannot start a local HTTP server to receive the login token.") + raise ValueError("Cannot start a local HTTP server to receive the login token.") thread = threading.Thread(target=httpd.serve_forever, daemon=True) thread.start() @@ -288,7 +288,7 @@ def auth_headers(self) -> Dict[str, str]: def get_auth_headers(self) -> Dict[str, str]: """Log in and get the authentication headers for HTTPS requests to the Exabel API.""" if not self.log_in(): - raise Exception("Failed to log in.") + raise ValueError("Failed to log in.") return self.auth_headers diff --git a/exabel_data_sdk/scripts/create_entity_mapping_from_csv.py b/exabel_data_sdk/scripts/create_entity_mapping_from_csv.py index 747efd7..7abe849 100644 --- a/exabel_data_sdk/scripts/create_entity_mapping_from_csv.py +++ b/exabel_data_sdk/scripts/create_entity_mapping_from_csv.py @@ -84,7 +84,6 @@ def __init__(self, argv: Sequence[str], description: str): def get_entity_mapping( self, client: ExabelClient, args: argparse.Namespace, mapping_input: pd.DataFrame ) -> pd.DataFrame: - """ Find the entity type we are creating mapping for. @@ -222,7 +221,6 @@ def get_markets(self, market: str) -> List[str]: return markets def run_script(self, client: ExabelClient, args: argparse.Namespace) -> None: - mapping_input = CsvReader.read_file( args.filename_input, separator=args.sep, string_columns=[0], keep_default_na=True ) diff --git a/exabel_data_sdk/services/sql/sql_reader_configuration.py b/exabel_data_sdk/services/sql/sql_reader_configuration.py index db2061e..5089f12 100644 --- a/exabel_data_sdk/services/sql/sql_reader_configuration.py +++ b/exabel_data_sdk/services/sql/sql_reader_configuration.py @@ -1,5 +1,6 @@ import abc import argparse +from dataclasses import dataclass from typing import Any, Mapping, NamedTuple, NewType ConnectionString = NewType("ConnectionString", str) @@ -12,6 +13,7 @@ class EngineArgs(NamedTuple): kwargs: Mapping[str, Any] +@dataclass class SqlReaderConfiguration(abc.ABC): """Base class for SQL reader configurations.""" diff --git a/exabel_data_sdk/stubs/exabel/api/analytics/v1/prediction_model_messages_pb2.pyi b/exabel_data_sdk/stubs/exabel/api/analytics/v1/prediction_model_messages_pb2.pyi index d6ba7fa..375af87 100644 --- a/exabel_data_sdk/stubs/exabel/api/analytics/v1/prediction_model_messages_pb2.pyi +++ b/exabel_data_sdk/stubs/exabel/api/analytics/v1/prediction_model_messages_pb2.pyi @@ -21,24 +21,24 @@ class _ModelConfiguration: class _ModelConfigurationEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ModelConfiguration.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor MODEL_CONFIGURATION_NOT_SPECIFIED: _ModelConfiguration.ValueType - 'Not specified.' + 'Not specified - defaults to use the latest configuration.' LATEST: _ModelConfiguration.ValueType 'Latest configuration.' ACTIVE: _ModelConfiguration.ValueType - 'Configuration of the active run.' + 'Configuration of the active run. A specific run may be activated from the prediction model user interface.' SPECIFIC_RUN: _ModelConfiguration.ValueType - 'Configuration of a specific run.' + 'Configuration of a specific run. The run number must be specified as well.' class ModelConfiguration(_ModelConfiguration, metaclass=_ModelConfigurationEnumTypeWrapper): """Specifies which model configuration to use.""" MODEL_CONFIGURATION_NOT_SPECIFIED: ModelConfiguration.ValueType -'Not specified.' +'Not specified - defaults to use the latest configuration.' LATEST: ModelConfiguration.ValueType 'Latest configuration.' ACTIVE: ModelConfiguration.ValueType -'Configuration of the active run.' +'Configuration of the active run. A specific run may be activated from the prediction model user interface.' SPECIFIC_RUN: ModelConfiguration.ValueType -'Configuration of a specific run.' +'Configuration of a specific run. The run number must be specified as well.' global___ModelConfiguration = ModelConfiguration @typing_extensions.final @@ -57,7 +57,7 @@ class PredictionModelRun(google.protobuf.message.Message): configuration: global___ModelConfiguration.ValueType 'Which model configuration to use.\n If not specified, the latest model configuration is used.\n ' configuration_source: builtins.int - 'Specifies a prediction model run from which model configuration should be retrieved.\n Only relevant when `configuration` is set to `ModelConfiguration.SPECIFIC_RUN`.\n ' + 'Prediction model run number from which model configuration should be retrieved, e.g. `1`.\n Only relevant when `configuration` is set to `ModelConfiguration.SPECIFIC_RUN`.\n ' auto_activate: builtins.bool 'Whether to automatically set this run as active once it completes.\n The run will not be activated if it fails for any of the entities in the model.\n ' diff --git a/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.py b/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.py index 8231289..bc17cf9 100644 --- a/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.py +++ b/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.py @@ -8,7 +8,7 @@ from google.api import field_behavior_pb2 as google_dot_api_dot_field__behavior__pb2 from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 from .....protoc_gen_openapiv2.options import annotations_pb2 as protoc__gen__openapiv2_dot_options_dot_annotations__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.exabel/api/management/v1/folder_messages.proto\x12\x18exabel.api.management.v1\x1a,exabel/api/management/v1/user_messages.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc_gen_openapiv2/options/annotations.proto"\xf3\x01\n\x06Folder\x120\n\x04name\x18\x01 \x01(\tB"\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName\x120\n\x0cdisplay_name\x18\x02 \x01(\tB\x1a\xe0A\x02\x92A\x14J\x12"My shared folder"\x12\x12\n\x05write\x18\x03 \x01(\x08B\x03\xe0A\x03\x12;\n\x05items\x18\x04 \x03(\x0b2$.exabel.api.management.v1.FolderItemB\x06\xe0A\x06\xe0A\x03\x124\n\x0bdescription\x18\x05 \x01(\tB\x1f\x92A\x1cJ\x1a"This is my shared folder""\xf0\x02\n\nFolderItem\x122\n\x06parent\x18\x01 \x01(\tB"\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName\x12*\n\x04name\x18\x02 \x01(\tB\x1c\xe0A\x03\x92A\x16J\x14"derivedSignals/123"\x12&\n\x0cdisplay_name\x18\x03 \x01(\tB\x10\x92A\rJ\x0b"my_signal"\x12\x13\n\x0bdescription\x18\t \x01(\t\x12;\n\titem_type\x18\x04 \x01(\x0e2(.exabel.api.management.v1.FolderItemType\x12/\n\x0bcreate_time\x18\x05 \x01(\x0b2\x1a.google.protobuf.Timestamp\x12/\n\x0bupdate_time\x18\x06 \x01(\x0b2\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12\x12\n\nupdated_by\x18\x08 \x01(\t"O\n\x0eFolderAccessor\x12.\n\x05group\x18\x01 \x01(\x0b2\x1f.exabel.api.management.v1.Group\x12\r\n\x05write\x18\x02 \x01(\x08"B\n\x0cSearchResult\x122\n\x04item\x18\x01 \x01(\x0b2$.exabel.api.management.v1.FolderItem*\xc4\x01\n\x0eFolderItemType\x12\x1c\n\x18FOLDER_ITEM_TYPE_INVALID\x10\x00\x12\x12\n\x0eDERIVED_SIGNAL\x10\x01\x12\x14\n\x10PREDICTION_MODEL\x10\x02\x12\x16\n\x12PORTFOLIO_STRATEGY\x10\x03\x12\r\n\tDASHBOARD\x10\x04\x12\x0e\n\nDRILL_DOWN\x10\x05\x12\x07\n\x03TAG\x10\x06\x12\n\n\x06SCREEN\x10\x07\x12\x13\n\x0fFINANCIAL_MODEL\x10\x08\x12\t\n\x05CHART\x10\tBS\n\x1ccom.exabel.api.management.v1B\x13FolderMessagesProtoP\x01Z\x1cexabel.com/api/management/v1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.exabel/api/management/v1/folder_messages.proto\x12\x18exabel.api.management.v1\x1a,exabel/api/management/v1/user_messages.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc_gen_openapiv2/options/annotations.proto"\xf3\x01\n\x06Folder\x120\n\x04name\x18\x01 \x01(\tB"\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName\x120\n\x0cdisplay_name\x18\x02 \x01(\tB\x1a\xe0A\x02\x92A\x14J\x12"My shared folder"\x124\n\x0bdescription\x18\x05 \x01(\tB\x1f\x92A\x1cJ\x1a"This is my shared folder"\x12\x12\n\x05write\x18\x03 \x01(\x08B\x03\xe0A\x03\x12;\n\x05items\x18\x04 \x03(\x0b2$.exabel.api.management.v1.FolderItemB\x06\xe0A\x06\xe0A\x03"\xf0\x02\n\nFolderItem\x122\n\x06parent\x18\x01 \x01(\tB"\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName\x12*\n\x04name\x18\x02 \x01(\tB\x1c\xe0A\x03\x92A\x16J\x14"derivedSignals/123"\x12&\n\x0cdisplay_name\x18\x03 \x01(\tB\x10\x92A\rJ\x0b"my_signal"\x12\x13\n\x0bdescription\x18\t \x01(\t\x12;\n\titem_type\x18\x04 \x01(\x0e2(.exabel.api.management.v1.FolderItemType\x12/\n\x0bcreate_time\x18\x05 \x01(\x0b2\x1a.google.protobuf.Timestamp\x12/\n\x0bupdate_time\x18\x06 \x01(\x0b2\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12\x12\n\nupdated_by\x18\x08 \x01(\t"O\n\x0eFolderAccessor\x12.\n\x05group\x18\x01 \x01(\x0b2\x1f.exabel.api.management.v1.Group\x12\r\n\x05write\x18\x02 \x01(\x08"B\n\x0cSearchResult\x122\n\x04item\x18\x01 \x01(\x0b2$.exabel.api.management.v1.FolderItem*\xc4\x01\n\x0eFolderItemType\x12\x1c\n\x18FOLDER_ITEM_TYPE_INVALID\x10\x00\x12\x12\n\x0eDERIVED_SIGNAL\x10\x01\x12\x14\n\x10PREDICTION_MODEL\x10\x02\x12\x16\n\x12PORTFOLIO_STRATEGY\x10\x03\x12\r\n\tDASHBOARD\x10\x04\x12\x0e\n\nDRILL_DOWN\x10\x05\x12\x07\n\x03TAG\x10\x06\x12\n\n\x06SCREEN\x10\x07\x12\x13\n\x0fFINANCIAL_MODEL\x10\x08\x12\t\n\x05CHART\x10\tBS\n\x1ccom.exabel.api.management.v1B\x13FolderMessagesProtoP\x01Z\x1cexabel.com/api/management/v1b\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'exabel.api.management.v1.folder_messages_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: @@ -18,12 +18,12 @@ _FOLDER.fields_by_name['name']._serialized_options = b'\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName' _FOLDER.fields_by_name['display_name']._options = None _FOLDER.fields_by_name['display_name']._serialized_options = b'\xe0A\x02\x92A\x14J\x12"My shared folder"' + _FOLDER.fields_by_name['description']._options = None + _FOLDER.fields_by_name['description']._serialized_options = b'\x92A\x1cJ\x1a"This is my shared folder"' _FOLDER.fields_by_name['write']._options = None _FOLDER.fields_by_name['write']._serialized_options = b'\xe0A\x03' _FOLDER.fields_by_name['items']._options = None _FOLDER.fields_by_name['items']._serialized_options = b'\xe0A\x06\xe0A\x03' - _FOLDER.fields_by_name['description']._options = None - _FOLDER.fields_by_name['description']._serialized_options = b'\x92A\x1cJ\x1a"This is my shared folder"' _FOLDERITEM.fields_by_name['parent']._options = None _FOLDERITEM.fields_by_name['parent']._serialized_options = b'\x92A\x1fJ\r"folders/123"\xca>\r\xfa\x02\nfolderName' _FOLDERITEM.fields_by_name['name']._options = None diff --git a/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.pyi b/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.pyi index a602eb1..c68baf0 100644 --- a/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.pyi +++ b/exabel_data_sdk/stubs/exabel/api/management/v1/folder_messages_pb2.pyi @@ -75,23 +75,23 @@ class Folder(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor NAME_FIELD_NUMBER: builtins.int DISPLAY_NAME_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int WRITE_FIELD_NUMBER: builtins.int ITEMS_FIELD_NUMBER: builtins.int - DESCRIPTION_FIELD_NUMBER: builtins.int name: builtins.str 'Unique resource name of the folder, e.g. `folders/123`. In the "Create folder" method, this is\n ignored and may be left empty.\n ' display_name: builtins.str 'Appears in the Exabel Library in the list of folders.' + description: builtins.str + 'The description of the folder.' write: builtins.bool 'Whether the API caller has write access to the folder.' @property def items(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FolderItem]: """List of items in the folder. To add or remove folder items, use the "Move folder items" method.""" - description: builtins.str - 'The description of the folder.' - def __init__(self, *, name: builtins.str | None=..., display_name: builtins.str | None=..., write: builtins.bool | None=..., items: collections.abc.Iterable[global___FolderItem] | None=..., description: builtins.str | None=...) -> None: + def __init__(self, *, name: builtins.str | None=..., display_name: builtins.str | None=..., description: builtins.str | None=..., write: builtins.bool | None=..., items: collections.abc.Iterable[global___FolderItem] | None=...) -> None: ... def ClearField(self, field_name: typing_extensions.Literal['description', b'description', 'display_name', b'display_name', 'items', b'items', 'name', b'name', 'write', b'write']) -> None: diff --git a/exabel_data_sdk/tests/resources/data/corrupt_dates_1.xlsx b/exabel_data_sdk/tests/resources/data/corrupt_dates_1.xlsx index 08b8d55eec745a3dcef941463fd8029b6e4bb7b8..5300cab86cf3ab6210162d5d4390c9a449fb23fe 100644 GIT binary patch literal 19586 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 diff --git a/exabel_data_sdk/tests/scripts/test_create_entity_mapping_from_csv.py b/exabel_data_sdk/tests/scripts/test_create_entity_mapping_from_csv.py index eddd1c2..353847d 100644 --- a/exabel_data_sdk/tests/scripts/test_create_entity_mapping_from_csv.py +++ b/exabel_data_sdk/tests/scripts/test_create_entity_mapping_from_csv.py @@ -17,7 +17,6 @@ def tearDown(self): self.temp_file.close() def test_create_mapping_ticker(self): - args = [ "script-name", "--filename-input", @@ -77,7 +76,6 @@ def test_create_mapping_ticker(self): ) def test_create_mapping_isin(self): - args = [ "script-name", "--filename-input", @@ -101,7 +99,6 @@ def test_create_mapping_isin(self): ) def test_create_mapping_factset_identifier(self): - args = [ "script-name", "--filename-input", @@ -134,7 +131,6 @@ def test_create_mapping_factset_identifier(self): ) def test_create_mapping_bloomberg_ticker(self): - args = [ "script-name", "--filename-input", @@ -167,7 +163,6 @@ def test_create_mapping_bloomberg_ticker(self): ) def test_create_mapping_figi(self): - args = [ "script-name", "--filename-input", diff --git a/exabel_data_sdk/util/deprecate_arguments.py b/exabel_data_sdk/util/deprecate_arguments.py index 4f1610f..04f7560 100644 --- a/exabel_data_sdk/util/deprecate_arguments.py +++ b/exabel_data_sdk/util/deprecate_arguments.py @@ -6,6 +6,7 @@ FunctionT = TypeVar("FunctionT", bound=Callable[..., Any]) + # Pylint flags '__func' as an invalid argument name, but we want the '__' prefix to make Mypy # interpret it as a positional-only argument. Therefore, we disable the check for this argument. @overload