From 780c725c441deab12131d60236da70fb3369149a Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Wed, 8 Mar 2023 13:29:44 -0600 Subject: [PATCH 01/20] Initial model classes and route --- docs/api_reference/dataframe.rst | 1 + .../clients/dataframe/_data_frame_client.py | 19 ++++++++++ .../clients/dataframe/models/__init__.py | 6 ++- .../dataframe/models/_column_filter.py | 37 +++++++++++++++++++ .../dataframe/models/_column_order_by.py | 11 ++++++ .../models/_export_table_data_request.py | 37 +++++++++++++++++++ .../models/_query_table_data_base.py | 36 +----------------- .../models/_query_table_data_request.py | 12 +----- tests/integration/dataframe/test_dataframe.py | 2 + 9 files changed, 113 insertions(+), 48 deletions(-) create mode 100644 nisystemlink/clients/dataframe/models/_column_filter.py create mode 100644 nisystemlink/clients/dataframe/models/_column_order_by.py create mode 100644 nisystemlink/clients/dataframe/models/_export_table_data_request.py diff --git a/docs/api_reference/dataframe.rst b/docs/api_reference/dataframe.rst index f2cb538..156cf0d 100644 --- a/docs/api_reference/dataframe.rst +++ b/docs/api_reference/dataframe.rst @@ -20,6 +20,7 @@ nisystemlink.clients.dataframe .. automethod:: append_table_data .. automethod:: query_table_data .. automethod:: query_decimated_data + .. automethod:: export_data .. automodule:: nisystemlink.clients.dataframe.models :members: diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index e4f6aae..a1a7f62 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -286,3 +286,22 @@ def query_decimated_data( or provided an invalid argument. """ ... + + @post("tables/{id}/export-data", args=[Path, Body]) + def export_table_data( + self, id: str, query: models.ExportTableDataRequest + ): + """Exports rows of data that match a filter from the table identified by its ID. + + Args: + id: Unique ID of a DataFrame table. + query: The filtering and sorting to apply when exporting data. + + Returns: + The table data. + + Raises: + ApiException: if unable to communicate with the Data Frame service + or provided an invalid argument. + """ + ... diff --git a/nisystemlink/clients/dataframe/models/__init__.py b/nisystemlink/clients/dataframe/models/__init__.py index ccd2aa0..d9c67cb 100644 --- a/nisystemlink/clients/dataframe/models/__init__.py +++ b/nisystemlink/clients/dataframe/models/__init__.py @@ -2,10 +2,13 @@ from ._api_info import ApiInfo, Operation, OperationsV1 from ._create_table_request import CreateTableRequest from ._column import Column +from ._column_filter import FilterOperation, ColumnFilter +from ._column_order_by import ColumnOrderBy from ._column_type import ColumnType from ._data_frame import DataFrame from ._data_type import DataType from ._delete_tables_partial_success import DeleteTablesPartialSuccess +from ._export_table_data_request import ExportTableDataRequest, ExportFormat from ._modify_tables_partial_success import ModifyTablesPartialSuccess from ._modify_table_request import ColumnMetadataPatch, ModifyTableRequest from ._modify_tables_request import ModifyTablesRequest, TableMetdataModification @@ -17,8 +20,7 @@ DecimationOptions, QueryDecimatedDataRequest, ) -from ._query_table_data_base import ColumnFilter, FilterOperation -from ._query_table_data_request import ColumnOrderBy, QueryTableDataRequest +from ._query_table_data_request import QueryTableDataRequest from ._query_tables_request import QueryTablesRequest from ._table_metadata import TableMetadata from ._table_rows import TableRows diff --git a/nisystemlink/clients/dataframe/models/_column_filter.py b/nisystemlink/clients/dataframe/models/_column_filter.py new file mode 100644 index 0000000..f2f9650 --- /dev/null +++ b/nisystemlink/clients/dataframe/models/_column_filter.py @@ -0,0 +1,37 @@ +from enum import Enum +from typing import List, Optional + +from nisystemlink.clients.core._uplink._json_model import JsonModel + +class FilterOperation(str, Enum): + """Represents the different operations that can be used in a filter.""" + + Equals = "EQUALS" + NotEquals = "NOT_EQUALS" + LessThan = "LESS_THAN" + LessThanEquals = "LESS_THAN_EQUALS" + GreaterThan = "GREATER_THAN" + GreaterThanEquals = "GREATER_THAN_EQUALS" + Contains = "CONTAINS" + NotContains = "NOT_CONTAINS" + + +class ColumnFilter(JsonModel): + """A filter to apply to the table data.""" + + column: str + """The name of the column to use for filtering.""" + + operation: FilterOperation + """How to compare the column's value with the specified value. + + An error is returned if the column's data type does not support the specified operation: + * String columns only support ``EQUALS``, ``NOT_EQUALS``, ``CONTAINS``, and ``NOT_CONTAINS``. + * Non-string columns do not support ``CONTAINS`` or ``NOT_CONTAINS``. + * When ``value`` is ``None``, the operation must be ``EQUALS`` or ``NOT_EQUALS``. + * When ``value`` is ``NaN`` for a floating-point column, the operation must be ``NOT_EQUALS``. + """ + + value: Optional[str] + """The comparison value to use for filtering. An error will be returned if + the value cannot be converted to the column's data type.""" \ No newline at end of file diff --git a/nisystemlink/clients/dataframe/models/_column_order_by.py b/nisystemlink/clients/dataframe/models/_column_order_by.py new file mode 100644 index 0000000..1f4adcf --- /dev/null +++ b/nisystemlink/clients/dataframe/models/_column_order_by.py @@ -0,0 +1,11 @@ +from typing import Optional +from nisystemlink.clients.core._uplink._json_model import JsonModel + +class ColumnOrderBy(JsonModel): + """Specifies a column to order by and the ordering direction.""" + + column: str + """The name of the column to order by.""" + + descending: Optional[bool] = None + """Whether the ordering should be in descending order.""" \ No newline at end of file diff --git a/nisystemlink/clients/dataframe/models/_export_table_data_request.py b/nisystemlink/clients/dataframe/models/_export_table_data_request.py new file mode 100644 index 0000000..fc34312 --- /dev/null +++ b/nisystemlink/clients/dataframe/models/_export_table_data_request.py @@ -0,0 +1,37 @@ +from enum import Enum +from typing import List, Optional + +from nisystemlink.clients.core._uplink._json_model import JsonModel +from._column_order_by import ColumnOrderBy +from._column_filter import ColumnFilter + +class ExportFormat(str, Enum): + """The format of the exported data.""" + + CSV = 'CSV' + """Comma-separated values.""" + +class ExportTableDataRequest(JsonModel): + """Specifies the parameters for a data export with ordering and filtering.""" + + columns: Optional[List[str]] = None + """The names of columns to include in the export. The export will + include the columns in the same order specified in this parameter. All + columns are included in the order specified at table creation if this + property is excluded.""" + + orderBy: Optional[List[ColumnOrderBy]] = None + """A list of columns to order the results by. Multiple columns may be + specified to order rows that have the same value for prior columns. The + columns used for sorting do not need to be included in the columns list, in + which case they are not included in the export.""" + + filters: Optional[List[ColumnFilter]] = None + """A list of columns to filter by. Only rows whose columns contain values + matching all of the specified filters are returned. The columns used for + filtering do not need to be included in the columns list, in which case + they are not included in the export.""" + + responseFormat: ExportFormat = None + """The format of the exported data. The only response format + currently supported is ``CSV``.""" \ No newline at end of file diff --git a/nisystemlink/clients/dataframe/models/_query_table_data_base.py b/nisystemlink/clients/dataframe/models/_query_table_data_base.py index d890fe0..12d2693 100644 --- a/nisystemlink/clients/dataframe/models/_query_table_data_base.py +++ b/nisystemlink/clients/dataframe/models/_query_table_data_base.py @@ -1,42 +1,8 @@ -from enum import Enum from typing import List, Optional from nisystemlink.clients.core._uplink._json_model import JsonModel - -class FilterOperation(str, Enum): - """Represents the different operations that can be used in a filter.""" - - Equals = "EQUALS" - NotEquals = "NOT_EQUALS" - LessThan = "LESS_THAN" - LessThanEquals = "LESS_THAN_EQUALS" - GreaterThan = "GREATER_THAN" - GreaterThanEquals = "GREATER_THAN_EQUALS" - Contains = "CONTAINS" - NotContains = "NOT_CONTAINS" - - -class ColumnFilter(JsonModel): - """A filter to apply to the table data.""" - - column: str - """The name of the column to use for filtering.""" - - operation: FilterOperation - """How to compare the column's value with the specified value. - - An error is returned if the column's data type does not support the specified operation: - * String columns only support ``EQUALS``, ``NOT_EQUALS``, ``CONTAINS``, and ``NOT_CONTAINS``. - * Non-string columns do not support ``CONTAINS`` or ``NOT_CONTAINS``. - * When ``value`` is ``None``, the operation must be ``EQUALS`` or ``NOT_EQUALS``. - * When ``value`` is ``NaN`` for a floating-point column, the operation must be ``NOT_EQUALS``. - """ - - value: Optional[str] - """The comparison value to use for filtering. An error will be returned if - the value cannot be converted to the column's data type.""" - +from._column_filter import ColumnFilter class QueryTableDataBase(JsonModel): """Contains the common set of options when querying table data.""" diff --git a/nisystemlink/clients/dataframe/models/_query_table_data_request.py b/nisystemlink/clients/dataframe/models/_query_table_data_request.py index 16245fb..b31436f 100644 --- a/nisystemlink/clients/dataframe/models/_query_table_data_request.py +++ b/nisystemlink/clients/dataframe/models/_query_table_data_request.py @@ -4,17 +4,7 @@ from nisystemlink.clients.core._uplink._with_paging import WithPaging from ._query_table_data_base import QueryTableDataBase - - -class ColumnOrderBy(JsonModel): - """Specifies a column to order by and the ordering direction.""" - - column: str - """The name of the column to order by.""" - - descending: Optional[bool] = None - """Whether the ordering should be in descending order.""" - +from._column_order_by import ColumnOrderBy class QueryTableDataRequest(QueryTableDataBase, WithPaging): """Contains the filtering and sorting options to use when querying table data.""" diff --git a/tests/integration/dataframe/test_dataframe.py b/tests/integration/dataframe/test_dataframe.py index 8c8a09a..db473a8 100644 --- a/tests/integration/dataframe/test_dataframe.py +++ b/tests/integration/dataframe/test_dataframe.py @@ -18,6 +18,8 @@ DataType, DecimationMethod, DecimationOptions, + ExportFormat, + ExportTableDataRequest, FilterOperation, ModifyTableRequest, ModifyTablesRequest, From 0de1eca0d4f79eaa6fdd13e3fc1a4b2224cbcccd Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Wed, 15 Mar 2023 17:42:12 -0500 Subject: [PATCH 02/20] Implement export and lint --- docs/getting_started.rst | 17 ++++-- examples/dataframe/export_data.py | 33 ++++++++++++ .../core/helpers/generator_file_like.py | 26 +++++++++ .../clients/dataframe/_data_frame_client.py | 43 ++++++++------- .../dataframe/models/_column_filter.py | 5 +- .../dataframe/models/_column_order_by.py | 4 +- .../models/_export_table_data_request.py | 13 +++-- .../models/_query_table_data_base.py | 3 +- .../models/_query_table_data_request.py | 4 +- tests/core/__init__.py | 1 + tests/core/test_generator_file_like.py | 35 ++++++++++++ tests/integration/dataframe/test_dataframe.py | 53 +++++++++++++++++-- 12 files changed, 199 insertions(+), 38 deletions(-) create mode 100644 examples/dataframe/export_data.py create mode 100644 nisystemlink/clients/core/helpers/generator_file_like.py create mode 100644 tests/core/__init__.py create mode 100644 tests/core/test_generator_file_like.py diff --git a/docs/getting_started.rst b/docs/getting_started.rst index ad2a1b9..83ae355 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -76,13 +76,13 @@ Subscribe to tag changes :language: python :linenos: -Data Frame API +DataFrame API ------- Overview ~~~~~~~~ -The :class:`.DataFrameClient` class is the primary entry point of the Data Frame API. +The :class:`.DataFrameClient` class is the primary entry point of the DataFrame API. When constructing a :class:`.DataFrameClient`, you can pass an :class:`.HttpConfiguration` (like one retrieved from the @@ -91,11 +91,15 @@ default connection. The default connection depends on your environment. With a :class:`.DataFrameClient` object, you can: -* Create and delete Data Frame Tables. +* Create and delete data tables. * Modify table metadata and query for tables by their metadata. -* Append rows of data to a table, query for rows of data from a table, and decimate table data. +* Append rows of data to a table, query for rows of data from a table, and + decimate table data. + +* Export table data as a comma-separated values (CSV) file to view the data in a + spreadsheet editor. Examples ~~~~~~~~ @@ -111,3 +115,8 @@ Query and read data from a table .. literalinclude:: ../examples/dataframe/query_read_data.py :language: python :linenos: + +Export data from a table +.. literalinclude:: ../examples/dataframe/export_data.py + :language: python + :linenos: \ No newline at end of file diff --git a/examples/dataframe/export_data.py b/examples/dataframe/export_data.py new file mode 100644 index 0000000..af851d0 --- /dev/null +++ b/examples/dataframe/export_data.py @@ -0,0 +1,33 @@ +from shutil import copyfileobj + +import pandas as pd +from nisystemlink.clients.dataframe import DataFrameClient +from nisystemlink.clients.dataframe.models import ( + ColumnFilter, + ColumnOrderBy, + ExportFormat, + ExportTableDataRequest, + FilterOperation, +) + +client = DataFrameClient() + +# List a table +response = client.list_tables(take=1) +table = response.tables[0] + +# Export table data with query options +request = ExportTableDataRequest( + columns=['col1'], + order_by=[ColumnOrderBy('col2', descending=True)], + filters=[ColumnFilter(column='col1', operation=FilterOperation.NotEquals, value=0)], + response_format=ExportFormat.CSV) + +data = client.export_table_data(id=table.id, query=request) + +# Write the export data to a file +with open(f'{table.name}.csv', 'wb') as f: + copyfileobj(response, f) + +# Alternatively, load the export data into a pandas dataframe +df = pd.read_csv(data) diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py new file mode 100644 index 0000000..e8b7648 --- /dev/null +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -0,0 +1,26 @@ +"""A class that wraps a GeneratorType in a file-like object.""" + + +class GeneratorFileLike: + def __init__(self, generator): + self._generator = generator + self._buffer = b'' + + def read(self, size=-1): + """Read data from the generator. Store any data in a buffer for the + next call to readline. If size is negative, read all data until the + generator is exhausted. + """ + while size < 0 or len(self._buffer) < size: + try: + chunk = next(self._generator) + self._buffer += chunk + except StopIteration: + break + if size < 0: + data = self._buffer + self._buffer = b'' + else: + data = self._buffer[:size] + self._buffer = self._buffer[size:] + return data diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index a1a7f62..1f46a31 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -1,11 +1,13 @@ """Implementation of DataFrameClient.""" + from typing import List, Optional from nisystemlink.clients import core from nisystemlink.clients.core._uplink._base_client import BaseClient from nisystemlink.clients.core._uplink._methods import delete, get, patch, post -from uplink import Body, Field, Path, Query +from nisystemlink.clients.core.helpers.generator_file_like import GeneratorFileLike +from uplink import Body, Field, Path, Query, response_handler from . import models @@ -21,7 +23,7 @@ def __init__(self, configuration: Optional[core.HttpConfiguration] = None): is used. Raises: - ApiException: if unable to communicate with the Data Frame service. + ApiException: if unable to communicate with the DataFrame Service. """ if configuration is None: configuration = core.JupyterHttpConfiguration() @@ -36,7 +38,7 @@ def api_info(self) -> models.ApiInfo: Information about available API operations. Raises: - ApiException: if unable to communicate with the Data Frame service. + ApiException: if unable to communicate with the DataFrame Service. """ ... @@ -74,7 +76,7 @@ def list_tables( The list of tables with a continuation token. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -90,7 +92,7 @@ def create_table(self, table: models.CreateTableRequest) -> str: The ID of the newly created table. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -106,7 +108,7 @@ def query_tables(self, query: models.QueryTablesRequest) -> models.PagedTables: The list of tables with a continuation token. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -122,7 +124,7 @@ def get_table_metadata(self, id: str) -> models.TableMetadata: The metadata for the table. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -136,7 +138,7 @@ def modify_table(self, id: str, update: models.ModifyTableRequest) -> None: update: The metadata to update. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -149,7 +151,7 @@ def delete_table(self, id: str) -> None: id (str): Unique ID of a DataFrame table. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -168,7 +170,7 @@ def delete_tables( tables were deleted successfully. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -187,7 +189,7 @@ def modify_tables( tables were modified successfully. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -230,7 +232,7 @@ def get_table_data( The table data and total number of rows with a continuation token. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -244,7 +246,7 @@ def append_table_data(self, id: str, data: models.AppendTableDataRequest) -> Non data: The rows of data to append and any additional options. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -263,7 +265,7 @@ def query_table_data( The table data and total number of rows with a continuation token. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... @@ -282,11 +284,16 @@ def query_decimated_data( The decimated table data. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... + @response_handler() + def iter_content_filelike_wrapper(response): + return GeneratorFileLike(response.iter_content(chunk_size=4096)) + + @iter_content_filelike_wrapper @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest @@ -295,13 +302,13 @@ def export_table_data( Args: id: Unique ID of a DataFrame table. - query: The filtering and sorting to apply when exporting data. + query: The filtering, sorting, and export format to apply when exporting data. Returns: - The table data. + A file-like object for reading the exported data. Raises: - ApiException: if unable to communicate with the Data Frame service + ApiException: if unable to communicate with the DataFrame Service or provided an invalid argument. """ ... diff --git a/nisystemlink/clients/dataframe/models/_column_filter.py b/nisystemlink/clients/dataframe/models/_column_filter.py index f2f9650..64324c1 100644 --- a/nisystemlink/clients/dataframe/models/_column_filter.py +++ b/nisystemlink/clients/dataframe/models/_column_filter.py @@ -1,8 +1,9 @@ from enum import Enum -from typing import List, Optional +from typing import Optional from nisystemlink.clients.core._uplink._json_model import JsonModel + class FilterOperation(str, Enum): """Represents the different operations that can be used in a filter.""" @@ -34,4 +35,4 @@ class ColumnFilter(JsonModel): value: Optional[str] """The comparison value to use for filtering. An error will be returned if - the value cannot be converted to the column's data type.""" \ No newline at end of file + the value cannot be converted to the column's data type.""" diff --git a/nisystemlink/clients/dataframe/models/_column_order_by.py b/nisystemlink/clients/dataframe/models/_column_order_by.py index 1f4adcf..b13911f 100644 --- a/nisystemlink/clients/dataframe/models/_column_order_by.py +++ b/nisystemlink/clients/dataframe/models/_column_order_by.py @@ -1,6 +1,8 @@ from typing import Optional + from nisystemlink.clients.core._uplink._json_model import JsonModel + class ColumnOrderBy(JsonModel): """Specifies a column to order by and the ordering direction.""" @@ -8,4 +10,4 @@ class ColumnOrderBy(JsonModel): """The name of the column to order by.""" descending: Optional[bool] = None - """Whether the ordering should be in descending order.""" \ No newline at end of file + """Whether the ordering should be in descending order.""" diff --git a/nisystemlink/clients/dataframe/models/_export_table_data_request.py b/nisystemlink/clients/dataframe/models/_export_table_data_request.py index fc34312..4ed52e0 100644 --- a/nisystemlink/clients/dataframe/models/_export_table_data_request.py +++ b/nisystemlink/clients/dataframe/models/_export_table_data_request.py @@ -2,8 +2,10 @@ from typing import List, Optional from nisystemlink.clients.core._uplink._json_model import JsonModel -from._column_order_by import ColumnOrderBy -from._column_filter import ColumnFilter + +from ._column_filter import ColumnFilter +from ._column_order_by import ColumnOrderBy + class ExportFormat(str, Enum): """The format of the exported data.""" @@ -11,6 +13,7 @@ class ExportFormat(str, Enum): CSV = 'CSV' """Comma-separated values.""" + class ExportTableDataRequest(JsonModel): """Specifies the parameters for a data export with ordering and filtering.""" @@ -20,7 +23,7 @@ class ExportTableDataRequest(JsonModel): columns are included in the order specified at table creation if this property is excluded.""" - orderBy: Optional[List[ColumnOrderBy]] = None + order_by: Optional[List[ColumnOrderBy]] = None """A list of columns to order the results by. Multiple columns may be specified to order rows that have the same value for prior columns. The columns used for sorting do not need to be included in the columns list, in @@ -32,6 +35,6 @@ class ExportTableDataRequest(JsonModel): filtering do not need to be included in the columns list, in which case they are not included in the export.""" - responseFormat: ExportFormat = None + response_format: ExportFormat = None """The format of the exported data. The only response format - currently supported is ``CSV``.""" \ No newline at end of file + currently supported is ``CSV``.""" diff --git a/nisystemlink/clients/dataframe/models/_query_table_data_base.py b/nisystemlink/clients/dataframe/models/_query_table_data_base.py index 12d2693..f04d8db 100644 --- a/nisystemlink/clients/dataframe/models/_query_table_data_base.py +++ b/nisystemlink/clients/dataframe/models/_query_table_data_base.py @@ -2,7 +2,8 @@ from nisystemlink.clients.core._uplink._json_model import JsonModel -from._column_filter import ColumnFilter +from ._column_filter import ColumnFilter + class QueryTableDataBase(JsonModel): """Contains the common set of options when querying table data.""" diff --git a/nisystemlink/clients/dataframe/models/_query_table_data_request.py b/nisystemlink/clients/dataframe/models/_query_table_data_request.py index b31436f..a417e3f 100644 --- a/nisystemlink/clients/dataframe/models/_query_table_data_request.py +++ b/nisystemlink/clients/dataframe/models/_query_table_data_request.py @@ -1,10 +1,10 @@ from typing import List, Optional -from nisystemlink.clients.core._uplink._json_model import JsonModel from nisystemlink.clients.core._uplink._with_paging import WithPaging +from ._column_order_by import ColumnOrderBy from ._query_table_data_base import QueryTableDataBase -from._column_order_by import ColumnOrderBy + class QueryTableDataRequest(QueryTableDataBase, WithPaging): """Contains the filtering and sorting options to use when querying table data.""" diff --git a/tests/core/__init__.py b/tests/core/__init__.py new file mode 100644 index 0000000..9c0fa90 --- /dev/null +++ b/tests/core/__init__.py @@ -0,0 +1 @@ +# flake8: noqa diff --git a/tests/core/test_generator_file_like.py b/tests/core/test_generator_file_like.py new file mode 100644 index 0000000..3a0c4c6 --- /dev/null +++ b/tests/core/test_generator_file_like.py @@ -0,0 +1,35 @@ + +from nisystemlink.clients.core.helpers.generator_file_like import GeneratorFileLike + + +class TestGeneratorFileLike: + def test__negative_size__read__reads_all_data(self): + def generate_data(): + yield b'123' + yield b'456' + yield b'789' + + generator_file_like = GeneratorFileLike(generate_data()) + + assert generator_file_like.read(-1) == b'123456789' + + def test__size_smaller_than_chunk__read__reads_to_size(self): + def generate_data(): + yield b'1234' + + generator_file_like = GeneratorFileLike(generate_data()) + + assert generator_file_like.read(1) == b'1' + assert generator_file_like.read(2) == b'23' + + def test__size_larger_than_chunk__read__reads_to_size(self): + def generate_data(): + yield b'123' + yield b'456789' + yield b'abcde' + + generator_file_like = GeneratorFileLike(generate_data()) + + assert generator_file_like.read(4) == b'1234' + assert generator_file_like.read(6) == b'56789a' + assert generator_file_like.read(6) == b'bcde' diff --git a/tests/integration/dataframe/test_dataframe.py b/tests/integration/dataframe/test_dataframe.py index db473a8..466f1a6 100644 --- a/tests/integration/dataframe/test_dataframe.py +++ b/tests/integration/dataframe/test_dataframe.py @@ -368,7 +368,7 @@ def test__query_table_data__sorts(self, client: DataFrameClient, create_table): ) frame = DataFrame( - data=[["1", "1.5", "5.5"], ["2", "2.5", "6.5"], ["3", "2.5", "7.5"]], + data=[["1", "2.5", "6.5"], ["2", "1.5", "5.5"], ["3", "2.5", "7.5"]], ) client.append_table_data( @@ -384,9 +384,9 @@ def test__query_table_data__sorts(self, client: DataFrameClient, create_table): "frame": { "columns": ["index", "col1", "col2"], "data": [ - ["1", "1.5", "5.5"], + ["2", "1.5", "5.5"], ["3", "2.5", "7.5"], - ["2", "2.5", "6.5"], + ["1", "2.5", "6.5"], ], }, "totalRowCount": 3, @@ -416,9 +416,9 @@ def test__query_table_data__sorts(self, client: DataFrameClient, create_table): assert response.total_row_count == 3 assert response.frame.data == [ - ["1", "1.5", "5.5"], + ["2", "1.5", "5.5"], ["3", "2.5", "7.5"], - ["2", "2.5", "6.5"], + ["1", "2.5", "6.5"], ] def test__query_table_data__filters(self, client: DataFrameClient, create_table): @@ -575,3 +575,46 @@ def test__query_decimated_data__works(self, client: DataFrameClient, create_tabl ) assert response.frame.data == [["1", "1.5", "3.5"], ["4", "4.5", "4.5"]] + + def test__export_table_data__works(self, client: DataFrameClient, create_table): + id = create_table( + CreateTableRequest( + columns=[ + int_index_column, + Column(name="col1", data_type=DataType.Float64), + Column(name="col2", data_type=DataType.Float64), + ] + ) + ) + + frame = DataFrame( + data=[["1", "2.5", "6.5"], ["2", "1.5", "5.5"], ["3", "2.5", "7.5"]], + ) + + client.append_table_data( + id, AppendTableDataRequest(frame=frame, end_of_data=True) + ) + + # TODO: Remove mock when service supports flushing + with responses.RequestsMock() as rsps: + rsps.add( + responses.POST, + f"{client.session.base_url}tables/{id}/export-data", + body=b'1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5', + match=[ + matchers.json_params_matcher( + { + "responseFormat": "CSV" + } + ) + ], + ) + + response = client.export_table_data( + id, + ExportTableDataRequest( + response_format=ExportFormat.CSV + ), + ) + + assert response.read() == b'1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5' From 19e2a25ea3ea32181ffcd3f9d654627ba64dd673 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Wed, 15 Mar 2023 17:59:52 -0500 Subject: [PATCH 03/20] Minor cleanup --- docs/api_reference/dataframe.rst | 2 +- docs/getting_started.rst | 3 +-- nisystemlink/clients/core/helpers/generator_file_like.py | 9 +++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api_reference/dataframe.rst b/docs/api_reference/dataframe.rst index 156cf0d..780ccdd 100644 --- a/docs/api_reference/dataframe.rst +++ b/docs/api_reference/dataframe.rst @@ -20,7 +20,7 @@ nisystemlink.clients.dataframe .. automethod:: append_table_data .. automethod:: query_table_data .. automethod:: query_decimated_data - .. automethod:: export_data + .. automethod:: export_table_data .. automodule:: nisystemlink.clients.dataframe.models :members: diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 83ae355..358fea5 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -98,8 +98,7 @@ With a :class:`.DataFrameClient` object, you can: * Append rows of data to a table, query for rows of data from a table, and decimate table data. -* Export table data as a comma-separated values (CSV) file to view the data in a - spreadsheet editor. +* Export table data as a comma-separated values (CSV) file. Examples ~~~~~~~~ diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py index e8b7648..4d987e0 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -1,4 +1,5 @@ -"""A class that wraps a GeneratorType in a file-like object.""" +"""A file-like object adapter that wraps a python generator, providing a way to +iterate over the generator as if it was a file.""" class GeneratorFileLike: @@ -7,9 +8,9 @@ def __init__(self, generator): self._buffer = b'' def read(self, size=-1): - """Read data from the generator. Store any data in a buffer for the - next call to readline. If size is negative, read all data until the - generator is exhausted. + """Read data from the generator. Store any data in a buffer for the next + call to read. If size is negative, read all data until the generator is + exhausted. """ while size < 0 or len(self._buffer) < size: try: From ebe86dfafa2b7aa0abf56640db76d5c7f2a38df9 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 08:00:13 -0500 Subject: [PATCH 04/20] Cleanup --- docs/getting_started.rst | 2 +- nisystemlink/clients/core/helpers/generator_file_like.py | 3 ++- nisystemlink/clients/dataframe/_data_frame_client.py | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 358fea5..3b2d977 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -98,7 +98,7 @@ With a :class:`.DataFrameClient` object, you can: * Append rows of data to a table, query for rows of data from a table, and decimate table data. -* Export table data as a comma-separated values (CSV) file. +* Export table data in a comma-separated values (CSV) format. Examples ~~~~~~~~ diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py index 4d987e0..96ac88a 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -1,5 +1,6 @@ """A file-like object adapter that wraps a python generator, providing a way to -iterate over the generator as if it was a file.""" +iterate over the generator as if it was a file. +""" class GeneratorFileLike: diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index 1f46a31..d1e79ae 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -1,6 +1,5 @@ """Implementation of DataFrameClient.""" - from typing import List, Optional from nisystemlink.clients import core From ba72ff2c757c3ad2a9e00cb5c38c97ccda8dc3b6 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 08:13:38 -0500 Subject: [PATCH 05/20] Clarify docs on generator file-like --- nisystemlink/clients/core/helpers/generator_file_like.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py index 96ac88a..aa0369f 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -9,10 +9,9 @@ def __init__(self, generator): self._buffer = b'' def read(self, size=-1): - """Read data from the generator. Store any data in a buffer for the next - call to read. If size is negative, read all data until the generator is - exhausted. - """ + """Read at most `size` bytes from the file-like object. If `size` is not + specified or is negative, read until the generator is exhausted and + returns all bytes or characters read. """ while size < 0 or len(self._buffer) < size: try: chunk = next(self._generator) From 0153a76a32a448472850b5470ea722519c31b104 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 08:14:22 -0500 Subject: [PATCH 06/20] lint --- nisystemlink/clients/core/helpers/generator_file_like.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py index aa0369f..77c285d 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -11,7 +11,8 @@ def __init__(self, generator): def read(self, size=-1): """Read at most `size` bytes from the file-like object. If `size` is not specified or is negative, read until the generator is exhausted and - returns all bytes or characters read. """ + returns all bytes or characters read. + """ while size < 0 or len(self._buffer) < size: try: chunk = next(self._generator) From 444dc9552615bd2eae7991c8ea9d9338b3e0c30d Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 08:39:26 -0500 Subject: [PATCH 07/20] Doc updates plus adding Operation --- .../clients/dataframe/_data_frame_client.py | 18 +++++++++--------- .../clients/dataframe/models/_api_info.py | 5 ++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index d1e79ae..27a11f0 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -117,7 +117,7 @@ def get_table_metadata(self, id: str) -> models.TableMetadata: """Retrieves the metadata and column information for a single table identified by its ID. Args: - id (str): Unique ID of a DataFrame table. + id (str): Unique ID of a data table. Returns: The metadata for the table. @@ -133,7 +133,7 @@ def modify_table(self, id: str, update: models.ModifyTableRequest) -> None: """Modify properties of a table or its columns. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. update: The metadata to update. Raises: @@ -147,7 +147,7 @@ def delete_table(self, id: str) -> None: """Deletes a table. Args: - id (str): Unique ID of a DataFrame table. + id (str): Unique ID of a data table. Raises: ApiException: if unable to communicate with the DataFrame Service @@ -162,7 +162,7 @@ def delete_tables( """Deletes multiple tables. Args: - ids (List[str]): List of unique IDs of DataFrame tables. + ids (List[str]): List of unique IDs of data tables. Returns: A partial success if any tables failed to delete, or None if all @@ -216,7 +216,7 @@ def get_table_data( """Reads raw data from the table identified by its ID. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. columns: Columns to include in the response. Data will be returned in the same order as the columns. If not specified, all columns are returned. order_by: List of columns to sort by. Multiple columns may be specified to order rows @@ -241,7 +241,7 @@ def append_table_data(self, id: str, data: models.AppendTableDataRequest) -> Non """Appends one or more rows of data to the table identified by its ID. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. data: The rows of data to append and any additional options. Raises: @@ -257,7 +257,7 @@ def query_table_data( """Reads rows of data that match a filter from the table identified by its ID. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. query: The filtering and sorting to apply when reading data. Returns: @@ -276,7 +276,7 @@ def query_decimated_data( """Reads decimated rows of data from the table identified by its ID. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. query: The filtering and decimation options to apply when reading data. Returns: @@ -300,7 +300,7 @@ def export_table_data( """Exports rows of data that match a filter from the table identified by its ID. Args: - id: Unique ID of a DataFrame table. + id: Unique ID of a data table. query: The filtering, sorting, and export format to apply when exporting data. Returns: diff --git a/nisystemlink/clients/dataframe/models/_api_info.py b/nisystemlink/clients/dataframe/models/_api_info.py index 38006bf..2ab4d3e 100644 --- a/nisystemlink/clients/dataframe/models/_api_info.py +++ b/nisystemlink/clients/dataframe/models/_api_info.py @@ -15,7 +15,7 @@ class OperationsV1(JsonModel): """The operations available in the routes provided by the v1 HTTP API.""" create_tables: Operation - """The ability to create new DataFrame tables.""" + """The ability to create new data tables.""" delete_tables: Operation """The ability to delete tables and all of their data.""" @@ -32,6 +32,9 @@ class OperationsV1(JsonModel): write_data: Operation """The ability to append rows of data to tables.""" + export_data: Operation + """The ability to export data from tables.""" + class ApiInfo(JsonModel): """Information about the available API operations.""" From 3cd1cfef6a6f3e9d732a95e408ddf17747be4d2a Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 08:47:02 -0500 Subject: [PATCH 08/20] update api_info --- nisystemlink/clients/dataframe/models/_api_info.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/nisystemlink/clients/dataframe/models/_api_info.py b/nisystemlink/clients/dataframe/models/_api_info.py index 2ab4d3e..0d7d7a2 100644 --- a/nisystemlink/clients/dataframe/models/_api_info.py +++ b/nisystemlink/clients/dataframe/models/_api_info.py @@ -32,9 +32,6 @@ class OperationsV1(JsonModel): write_data: Operation """The ability to append rows of data to tables.""" - export_data: Operation - """The ability to export data from tables.""" - class ApiInfo(JsonModel): """Information about the available API operations.""" From 941bf86cfaa6b39a3d0bff144836025b78c2336f Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 09:22:53 -0500 Subject: [PATCH 09/20] poetry run poe black --- examples/dataframe/export_data.py | 11 ++++---- .../core/helpers/generator_file_like.py | 4 +-- .../clients/dataframe/_data_frame_client.py | 4 +-- .../models/_export_table_data_request.py | 4 +-- tests/core/test_generator_file_like.py | 27 +++++++++---------- tests/integration/dataframe/test_dataframe.py | 16 +++-------- 6 files changed, 29 insertions(+), 37 deletions(-) diff --git a/examples/dataframe/export_data.py b/examples/dataframe/export_data.py index af851d0..bfff8ac 100644 --- a/examples/dataframe/export_data.py +++ b/examples/dataframe/export_data.py @@ -18,15 +18,16 @@ # Export table data with query options request = ExportTableDataRequest( - columns=['col1'], - order_by=[ColumnOrderBy('col2', descending=True)], - filters=[ColumnFilter(column='col1', operation=FilterOperation.NotEquals, value=0)], - response_format=ExportFormat.CSV) + columns=["col1"], + order_by=[ColumnOrderBy(column="col2", descending=True)], + filters=[ColumnFilter(column="col1", operation=FilterOperation.NotEquals, value=0)], + response_format=ExportFormat.CSV, +) data = client.export_table_data(id=table.id, query=request) # Write the export data to a file -with open(f'{table.name}.csv', 'wb') as f: +with open(f"{table.name}.csv", "wb") as f: copyfileobj(response, f) # Alternatively, load the export data into a pandas dataframe diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/generator_file_like.py index 77c285d..2c64ae9 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/generator_file_like.py @@ -6,7 +6,7 @@ class GeneratorFileLike: def __init__(self, generator): self._generator = generator - self._buffer = b'' + self._buffer = b"" def read(self, size=-1): """Read at most `size` bytes from the file-like object. If `size` is not @@ -21,7 +21,7 @@ def read(self, size=-1): break if size < 0: data = self._buffer - self._buffer = b'' + self._buffer = b"" else: data = self._buffer[:size] self._buffer = self._buffer[size:] diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index 27a11f0..76bdbc6 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -289,14 +289,14 @@ def query_decimated_data( ... @response_handler() - def iter_content_filelike_wrapper(response): + def iter_content_filelike_wrapper(response) -> GeneratorFileLike: return GeneratorFileLike(response.iter_content(chunk_size=4096)) @iter_content_filelike_wrapper @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest - ): + ) -> GeneratorFileLike: """Exports rows of data that match a filter from the table identified by its ID. Args: diff --git a/nisystemlink/clients/dataframe/models/_export_table_data_request.py b/nisystemlink/clients/dataframe/models/_export_table_data_request.py index 4ed52e0..df6153d 100644 --- a/nisystemlink/clients/dataframe/models/_export_table_data_request.py +++ b/nisystemlink/clients/dataframe/models/_export_table_data_request.py @@ -10,7 +10,7 @@ class ExportFormat(str, Enum): """The format of the exported data.""" - CSV = 'CSV' + CSV = "CSV" """Comma-separated values.""" @@ -35,6 +35,6 @@ class ExportTableDataRequest(JsonModel): filtering do not need to be included in the columns list, in which case they are not included in the export.""" - response_format: ExportFormat = None + response_format: ExportFormat """The format of the exported data. The only response format currently supported is ``CSV``.""" diff --git a/tests/core/test_generator_file_like.py b/tests/core/test_generator_file_like.py index 3a0c4c6..e2b4fbe 100644 --- a/tests/core/test_generator_file_like.py +++ b/tests/core/test_generator_file_like.py @@ -1,35 +1,34 @@ - from nisystemlink.clients.core.helpers.generator_file_like import GeneratorFileLike class TestGeneratorFileLike: def test__negative_size__read__reads_all_data(self): def generate_data(): - yield b'123' - yield b'456' - yield b'789' + yield b"123" + yield b"456" + yield b"789" generator_file_like = GeneratorFileLike(generate_data()) - assert generator_file_like.read(-1) == b'123456789' + assert generator_file_like.read(-1) == b"123456789" def test__size_smaller_than_chunk__read__reads_to_size(self): def generate_data(): - yield b'1234' + yield b"1234" generator_file_like = GeneratorFileLike(generate_data()) - assert generator_file_like.read(1) == b'1' - assert generator_file_like.read(2) == b'23' + assert generator_file_like.read(1) == b"1" + assert generator_file_like.read(2) == b"23" def test__size_larger_than_chunk__read__reads_to_size(self): def generate_data(): - yield b'123' - yield b'456789' - yield b'abcde' + yield b"123" + yield b"456789" + yield b"abcde" generator_file_like = GeneratorFileLike(generate_data()) - assert generator_file_like.read(4) == b'1234' - assert generator_file_like.read(6) == b'56789a' - assert generator_file_like.read(6) == b'bcde' + assert generator_file_like.read(4) == b"1234" + assert generator_file_like.read(6) == b"56789a" + assert generator_file_like.read(6) == b"bcde" diff --git a/tests/integration/dataframe/test_dataframe.py b/tests/integration/dataframe/test_dataframe.py index 466f1a6..a54e4b4 100644 --- a/tests/integration/dataframe/test_dataframe.py +++ b/tests/integration/dataframe/test_dataframe.py @@ -600,21 +600,13 @@ def test__export_table_data__works(self, client: DataFrameClient, create_table): rsps.add( responses.POST, f"{client.session.base_url}tables/{id}/export-data", - body=b'1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5', - match=[ - matchers.json_params_matcher( - { - "responseFormat": "CSV" - } - ) - ], + body=b"1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5", + match=[matchers.json_params_matcher({"responseFormat": "CSV"})], ) response = client.export_table_data( id, - ExportTableDataRequest( - response_format=ExportFormat.CSV - ), + ExportTableDataRequest(response_format=ExportFormat.CSV), ) - assert response.read() == b'1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5' + assert response.read() == b"1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5" From 46a1bbd8aa40732a3a083aa1c8555e5b680fee7b Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 10:28:08 -0500 Subject: [PATCH 10/20] typo in example --- examples/dataframe/export_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dataframe/export_data.py b/examples/dataframe/export_data.py index bfff8ac..7039089 100644 --- a/examples/dataframe/export_data.py +++ b/examples/dataframe/export_data.py @@ -28,7 +28,7 @@ # Write the export data to a file with open(f"{table.name}.csv", "wb") as f: - copyfileobj(response, f) + copyfileobj(data, f) # Alternatively, load the export data into a pandas dataframe df = pd.read_csv(data) From 451655b8963fe8546aad4b4472b11e938c9ceddc Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 10:47:55 -0500 Subject: [PATCH 11/20] fix missing pandas for mypy --- poetry.lock | 860 ++++++++++++++++++++++++++++++------------------- pyproject.toml | 4 +- 2 files changed, 526 insertions(+), 338 deletions(-) diff --git a/poetry.lock b/poetry.lock index d0832cb..1127b19 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. + [[package]] name = "aenum" version = "3.1.11" @@ -5,6 +7,11 @@ description = "Advanced Enumerations (compatible with Python's stdlib Enum), Nam category = "main" optional = false python-versions = "*" +files = [ + {file = "aenum-3.1.11-py2-none-any.whl", hash = "sha256:525b4870a27d0b471c265bda692bc657f1e0dd7597ad4186d072c59f9db666f6"}, + {file = "aenum-3.1.11-py3-none-any.whl", hash = "sha256:12ae89967f2e25c0ce28c293955d643f891603488bc3d9946158ba2b35203638"}, + {file = "aenum-3.1.11.tar.gz", hash = "sha256:aed2c273547ae72a0d5ee869719c02a643da16bf507c80958faadc7e038e3f73"}, +] [[package]] name = "anyio" @@ -13,6 +20,10 @@ description = "High level compatibility layer for multiple asynchronous event lo category = "main" optional = false python-versions = ">=3.6.2" +files = [ + {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, + {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, +] [package.dependencies] idna = ">=2.8" @@ -25,25 +36,44 @@ trio = ["trio (>=0.16,<0.22)"] [[package]] name = "attrs" -version = "22.1.0" +version = "22.2.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" +files = [ + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, +] [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "black" -version = "22.10.0" +version = "22.12.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, + {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, + {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"}, + {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"}, + {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"}, + {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"}, + {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"}, + {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"}, + {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"}, + {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"}, + {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"}, + {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"}, +] [package.dependencies] click = ">=8.0.0" @@ -66,17 +96,95 @@ description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, +] [[package]] name = "charset-normalizer" -version = "2.1.1" +version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = ">=3.6.0" - -[package.extras] -unicode-backport = ["unicodedata2"] +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] [[package]] name = "click" @@ -85,6 +193,10 @@ description = "Composable command line interface toolkit" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -96,6 +208,10 @@ description = "Cross-platform colored terminal text." category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "events" @@ -104,14 +220,21 @@ description = "Bringing the elegance of C# EventHandler to Python" category = "main" optional = false python-versions = "*" +files = [ + {file = "Events-0.4.tar.gz", hash = "sha256:01d9dd2a061f908d74a89fa5c8f07baa694f02a2a5974983663faaf7a97180f5"}, +] [[package]] name = "exceptiongroup" -version = "1.0.4" +version = "1.1.1" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, +] [package.extras] test = ["pytest (>=6)"] @@ -123,6 +246,10 @@ description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, +] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" @@ -131,11 +258,15 @@ pyflakes = ">=2.5.0,<2.6.0" [[package]] name = "flake8-docstrings" -version = "1.6.0" +version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, + {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, +] [package.dependencies] flake8 = ">=3" @@ -148,6 +279,10 @@ description = "Flake8 and pylama plugin that checks the ordering of import state category = "dev" optional = false python-versions = "*" +files = [ + {file = "flake8-import-order-0.18.2.tar.gz", hash = "sha256:e23941f892da3e0c09d711babbb0c73bc735242e9b216b726616758a920d900e"}, + {file = "flake8_import_order-0.18.2-py2.py3-none-any.whl", hash = "sha256:82ed59f1083b629b030ee9d3928d9e06b6213eb196fe745b3a7d4af2168130df"}, +] [package.dependencies] pycodestyle = "*" @@ -160,14 +295,22 @@ description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] [[package]] name = "httpcore" -version = "0.16.2" +version = "0.16.3" description = "A minimal low-level HTTP client." category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"}, + {file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"}, +] [package.dependencies] anyio = ">=3.0,<5.0" @@ -181,11 +324,15 @@ socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" -version = "0.23.1" +version = "0.23.3" description = "The next generation HTTP client." category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpx-0.23.3-py3-none-any.whl", hash = "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"}, + {file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"}, +] [package.dependencies] certifi = "*" @@ -206,14 +353,22 @@ description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] [[package]] name = "mccabe" @@ -222,6 +377,10 @@ description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] name = "mypy" @@ -230,6 +389,32 @@ description = "Optional static typing for Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, + {file = "mypy-0.982-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:41fd1cf9bc0e1c19b9af13a6580ccb66c381a5ee2cf63ee5ebab747a4badeba3"}, + {file = "mypy-0.982-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f793e3dd95e166b66d50e7b63e69e58e88643d80a3dcc3bcd81368e0478b089c"}, + {file = "mypy-0.982-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ebe67adf4d021b28c3f547da6aa2cce660b57f0432617af2cca932d4d378a6"}, + {file = "mypy-0.982-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:175f292f649a3af7082fe36620369ffc4661a71005aa9f8297ea473df5772046"}, + {file = "mypy-0.982-cp310-cp310-win_amd64.whl", hash = "sha256:8ee8c2472e96beb1045e9081de8e92f295b89ac10c4109afdf3a23ad6e644f3e"}, + {file = "mypy-0.982-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58f27ebafe726a8e5ccb58d896451dd9a662a511a3188ff6a8a6a919142ecc20"}, + {file = "mypy-0.982-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6af646bd46f10d53834a8e8983e130e47d8ab2d4b7a97363e35b24e1d588947"}, + {file = "mypy-0.982-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7aeaa763c7ab86d5b66ff27f68493d672e44c8099af636d433a7f3fa5596d40"}, + {file = "mypy-0.982-cp37-cp37m-win_amd64.whl", hash = "sha256:724d36be56444f569c20a629d1d4ee0cb0ad666078d59bb84f8f887952511ca1"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14d53cdd4cf93765aa747a7399f0961a365bcddf7855d9cef6306fa41de01c24"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ae64555d480ad4b32a267d10cab7aec92ff44de35a7cd95b2b7cb8e64ebe3e"}, + {file = "mypy-0.982-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6389af3e204975d6658de4fb8ac16f58c14e1bacc6142fee86d1b5b26aa52bda"}, + {file = "mypy-0.982-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b35ce03a289480d6544aac85fa3674f493f323d80ea7226410ed065cd46f206"}, + {file = "mypy-0.982-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6e564f035d25c99fd2b863e13049744d96bd1947e3d3d2f16f5828864506763"}, + {file = "mypy-0.982-cp38-cp38-win_amd64.whl", hash = "sha256:cebca7fd333f90b61b3ef7f217ff75ce2e287482206ef4a8b18f32b49927b1a2"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a705a93670c8b74769496280d2fe6cd59961506c64f329bb179970ff1d24f9f8"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75838c649290d83a2b83a88288c1eb60fe7a05b36d46cbea9d22efc790002146"}, + {file = "mypy-0.982-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:91781eff1f3f2607519c8b0e8518aad8498af1419e8442d5d0afb108059881fc"}, + {file = "mypy-0.982-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa97b9ddd1dd9901a22a879491dbb951b5dec75c3b90032e2baa7336777363b"}, + {file = "mypy-0.982-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a692a8e7d07abe5f4b2dd32d731812a0175626a90a223d4b58f10f458747dd8a"}, + {file = "mypy-0.982-cp39-cp39-win_amd64.whl", hash = "sha256:eb7a068e503be3543c4bd329c994103874fa543c1727ba5288393c21d912d795"}, + {file = "mypy-0.982-py3-none-any.whl", hash = "sha256:1021c241e8b6e1ca5a47e4d52601274ac078a89845cfde66c6d5f769819ffa1d"}, + {file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"}, +] [package.dependencies] mypy-extensions = ">=0.4.3" @@ -243,22 +428,129 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "numpy" +version = "1.24.2" +description = "Fundamental package for array computing in Python" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"}, + {file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"}, + {file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"}, + {file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"}, + {file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"}, + {file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"}, + {file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"}, + {file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"}, + {file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"}, + {file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"}, + {file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"}, +] [[package]] name = "packaging" -version = "21.3" +version = "23.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, +] + +[[package]] +name = "pandas" +version = "1.5.3" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, + {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, + {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, + {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, + {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, + {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, + {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, + {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + +[[package]] +name = "pandas-stubs" +version = "1.5.3.230304" +description = "Type annotations for pandas" +category = "dev" +optional = false +python-versions = ">=3.8,<3.12" +files = [ + {file = "pandas_stubs-1.5.3.230304-py3-none-any.whl", hash = "sha256:ebb545329109e98510cdf6357074497dfbdf62f173d8ec8b5430486716360639"}, + {file = "pandas_stubs-1.5.3.230304.tar.gz", hash = "sha256:853174ea5aac1ee2001b3ae708dea9780c60d546ee490abb5eeb7c37ed57d255"}, +] [package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +types-pytz = ">=2022.1.1" [[package]] name = "pastel" @@ -267,26 +559,38 @@ description = "Bring colors to your terminal." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] [[package]] name = "pathspec" -version = "0.10.2" +version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, +] [[package]] name = "platformdirs" -version = "2.5.4" +version = "3.1.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, + {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, +] [package.extras] -docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] -test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -295,6 +599,10 @@ description = "plugin and hook calling mechanisms for python" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] [package.extras] dev = ["pre-commit", "tox"] @@ -307,6 +615,10 @@ description = "A task runner that works well with poetry." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "poethepoet-0.16.5-py3-none-any.whl", hash = "sha256:493d5d47b4cb0894dde6a69d14129ba39ef3f124fabda1f83ebb39bbf737a40e"}, + {file = "poethepoet-0.16.5.tar.gz", hash = "sha256:3c958792ce488661ba09df67ba832a1b3141aa640236505ee60c23f4b1db4dbc"}, +] [package.dependencies] pastel = ">=0.2.1,<0.3.0" @@ -322,17 +634,59 @@ description = "Python style guide checker" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, +] [[package]] name = "pydantic" -version = "1.10.2" +version = "1.10.6" description = "Data validation and settings management using python type hints" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9289065611c48147c1dd1fd344e9d57ab45f1d99b0fb26c51f1cf72cd9bcd31"}, + {file = "pydantic-1.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c32b6bba301490d9bb2bf5f631907803135e8085b6aa3e5fe5a770d46dd0160"}, + {file = "pydantic-1.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd9b9e98068fa1068edfc9eabde70a7132017bdd4f362f8b4fd0abed79c33083"}, + {file = "pydantic-1.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c84583b9df62522829cbc46e2b22e0ec11445625b5acd70c5681ce09c9b11c4"}, + {file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b41822064585fea56d0116aa431fbd5137ce69dfe837b599e310034171996084"}, + {file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61f1f08adfaa9cc02e0cbc94f478140385cbd52d5b3c5a657c2fceb15de8d1fb"}, + {file = "pydantic-1.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:32937835e525d92c98a1512218db4eed9ddc8f4ee2a78382d77f54341972c0e7"}, + {file = "pydantic-1.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbd5c531b22928e63d0cb1868dee76123456e1de2f1cb45879e9e7a3f3f1779b"}, + {file = "pydantic-1.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e277bd18339177daa62a294256869bbe84df1fb592be2716ec62627bb8d7c81d"}, + {file = "pydantic-1.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f15277d720aa57e173954d237628a8d304896364b9de745dcb722f584812c7"}, + {file = "pydantic-1.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b243b564cea2576725e77aeeda54e3e0229a168bc587d536cd69941e6797543d"}, + {file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3ce13a558b484c9ae48a6a7c184b1ba0e5588c5525482681db418268e5f86186"}, + {file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3ac1cd4deed871dfe0c5f63721e29debf03e2deefa41b3ed5eb5f5df287c7b70"}, + {file = "pydantic-1.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:b1eb6610330a1dfba9ce142ada792f26bbef1255b75f538196a39e9e90388bf4"}, + {file = "pydantic-1.10.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4ca83739c1263a044ec8b79df4eefc34bbac87191f0a513d00dd47d46e307a65"}, + {file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea4e2a7cb409951988e79a469f609bba998a576e6d7b9791ae5d1e0619e1c0f2"}, + {file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53de12b4608290992a943801d7756f18a37b7aee284b9ffa794ee8ea8153f8e2"}, + {file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:60184e80aac3b56933c71c48d6181e630b0fbc61ae455a63322a66a23c14731a"}, + {file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:415a3f719ce518e95a92effc7ee30118a25c3d032455d13e121e3840985f2efd"}, + {file = "pydantic-1.10.6-cp37-cp37m-win_amd64.whl", hash = "sha256:72cb30894a34d3a7ab6d959b45a70abac8a2a93b6480fc5a7bfbd9c935bdc4fb"}, + {file = "pydantic-1.10.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3091d2eaeda25391405e36c2fc2ed102b48bac4b384d42b2267310abae350ca6"}, + {file = "pydantic-1.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:751f008cd2afe812a781fd6aa2fb66c620ca2e1a13b6a2152b1ad51553cb4b77"}, + {file = "pydantic-1.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12e837fd320dd30bd625be1b101e3b62edc096a49835392dcf418f1a5ac2b832"}, + {file = "pydantic-1.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d92831d0115874d766b1f5fddcdde0c5b6c60f8c6111a394078ec227fca6d"}, + {file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:476f6674303ae7965730a382a8e8d7fae18b8004b7b69a56c3d8fa93968aa21c"}, + {file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3a2be0a0f32c83265fd71a45027201e1278beaa82ea88ea5b345eea6afa9ac7f"}, + {file = "pydantic-1.10.6-cp38-cp38-win_amd64.whl", hash = "sha256:0abd9c60eee6201b853b6c4be104edfba4f8f6c5f3623f8e1dba90634d63eb35"}, + {file = "pydantic-1.10.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6195ca908045054dd2d57eb9c39a5fe86409968b8040de8c2240186da0769da7"}, + {file = "pydantic-1.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43cdeca8d30de9a897440e3fb8866f827c4c31f6c73838e3a01a14b03b067b1d"}, + {file = "pydantic-1.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c19eb5163167489cb1e0161ae9220dadd4fc609a42649e7e84a8fa8fff7a80f"}, + {file = "pydantic-1.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:012c99a9c0d18cfde7469aa1ebff922e24b0c706d03ead96940f5465f2c9cf62"}, + {file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:528dcf7ec49fb5a84bf6fe346c1cc3c55b0e7603c2123881996ca3ad79db5bfc"}, + {file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:163e79386c3547c49366e959d01e37fc30252285a70619ffc1b10ede4758250a"}, + {file = "pydantic-1.10.6-cp39-cp39-win_amd64.whl", hash = "sha256:189318051c3d57821f7233ecc94708767dd67687a614a4e8f92b4a020d4ffd06"}, + {file = "pydantic-1.10.6-py3-none-any.whl", hash = "sha256:acc6783751ac9c9bc4680379edd6d286468a1dc8d7d9906cd6f1186ed682b2b0"}, + {file = "pydantic-1.10.6.tar.gz", hash = "sha256:cf95adb0d1671fc38d8c43dd921ad5814a735e7d9b4d9e437c088002863854fd"}, +] [package.dependencies] -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.2.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] @@ -340,17 +694,21 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pydocstyle" -version = "6.1.1" +version = "6.3.0" description = "Python docstring style checker" category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, +] [package.dependencies] -snowballstemmer = "*" +snowballstemmer = ">=2.2.0" [package.extras] -toml = ["toml"] +toml = ["tomli (>=1.2.3)"] [[package]] name = "pyflakes" @@ -359,25 +717,22 @@ description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=3.6" - -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" -optional = false -python-versions = ">=3.6.8" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +files = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] [[package]] name = "pytest" -version = "7.2.0" +version = "7.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-7.2.2-py3-none-any.whl", hash = "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"}, + {file = "pytest-7.2.2.tar.gz", hash = "sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"}, +] [package.dependencies] attrs = ">=19.2.0" @@ -393,29 +748,65 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. [[package]] name = "pytest-asyncio" -version = "0.20.2" +version = "0.20.3" description = "Pytest support for asyncio" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-asyncio-0.20.3.tar.gz", hash = "sha256:83cbf01169ce3e8eb71c6c278ccb0574d1a7a3bb8eaaf5e50e0ad342afb33b36"}, + {file = "pytest_asyncio-0.20.3-py3-none-any.whl", hash = "sha256:f129998b209d04fcc65c96fc85c11e5316738358909a8399e93be553d7656442"}, +] [package.dependencies] pytest = ">=6.1.0" [package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2022.7.1" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, +] + [[package]] name = "requests" -version = "2.28.1" +version = "2.28.2" description = "Python HTTP for Humans." category = "main" optional = false python-versions = ">=3.7, <4" +files = [ + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, +] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" +charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" @@ -430,6 +821,10 @@ description = "A utility library for mocking out the `requests` Python library." category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "responses-0.22.0-py3-none-any.whl", hash = "sha256:dcf294d204d14c436fddcc74caefdbc5764795a40ff4e6a7740ed8ddbf3294be"}, + {file = "responses-0.22.0.tar.gz", hash = "sha256:396acb2a13d25297789a5866b4881cf4e46ffd49cc26c43ab1117f40b973102e"}, +] [package.dependencies] requests = ">=2.22.0,<3.0" @@ -447,6 +842,10 @@ description = "Validating URI References per RFC 3986" category = "main" optional = false python-versions = "*" +files = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] [package.dependencies] idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} @@ -456,14 +855,18 @@ idna2008 = ["idna"] [[package]] name = "setuptools" -version = "65.6.3" +version = "67.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"}, + {file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"}, +] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] @@ -474,6 +877,10 @@ description = "Python 2 and 3 compatibility utilities" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] [[package]] name = "sniffio" @@ -482,6 +889,10 @@ description = "Sniff out which async library your code is running under" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] [[package]] name = "snowballstemmer" @@ -490,6 +901,10 @@ description = "This package provides 29 stemmers for 28 languages generated from category = "dev" optional = false python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] [[package]] name = "toml" @@ -498,6 +913,10 @@ description = "Python Library for Tom's Obvious, Minimal Language" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] [[package]] name = "tomli" @@ -506,41 +925,73 @@ description = "A lil' TOML parser" category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "types-pytz" +version = "2022.7.1.2" +description = "Typing stubs for pytz" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-pytz-2022.7.1.2.tar.gz", hash = "sha256:487d3e8e9f4071eec8081746d53fa982bbc05812e719dcbf2ebf3d55a1a4cd28"}, + {file = "types_pytz-2022.7.1.2-py3-none-any.whl", hash = "sha256:40ca448a928d566f7d44ddfde0066e384f7ffbd4da2778e42a4570eaca572446"}, +] [[package]] name = "types-requests" -version = "2.28.11.5" +version = "2.28.11.15" description = "Typing stubs for requests" category = "dev" optional = false python-versions = "*" +files = [ + {file = "types-requests-2.28.11.15.tar.gz", hash = "sha256:fc8eaa09cc014699c6b63c60c2e3add0c8b09a410c818b5ac6e65f92a26dde09"}, + {file = "types_requests-2.28.11.15-py3-none-any.whl", hash = "sha256:a05e4c7bc967518fba5789c341ea8b0c942776ee474c7873129a61161978e586"}, +] [package.dependencies] types-urllib3 = "<1.27" [[package]] name = "types-toml" -version = "0.10.8.1" +version = "0.10.8.5" description = "Typing stubs for toml" category = "dev" optional = false python-versions = "*" +files = [ + {file = "types-toml-0.10.8.5.tar.gz", hash = "sha256:bf80fce7d2d74be91148f47b88d9ae5adeb1024abef22aa2fdbabc036d6b8b3c"}, + {file = "types_toml-0.10.8.5-py3-none-any.whl", hash = "sha256:2432017febe43174af0f3c65f03116e3d3cf43e7e1406b8200e106da8cf98992"}, +] [[package]] name = "types-urllib3" -version = "1.26.25.4" +version = "1.26.25.8" description = "Typing stubs for urllib3" category = "dev" optional = false python-versions = "*" +files = [ + {file = "types-urllib3-1.26.25.8.tar.gz", hash = "sha256:ecf43c42d8ee439d732a1110b4901e9017a79a38daca26f08e42c8460069392c"}, + {file = "types_urllib3-1.26.25.8-py3-none-any.whl", hash = "sha256:95ea847fbf0bf675f50c8ae19a665baedcf07e6b4641662c4c3c72e7b2edf1a9"}, +] [[package]] name = "typing-extensions" -version = "4.4.0" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, +] [[package]] name = "uplink" @@ -549,6 +1000,10 @@ description = "A Declarative HTTP Client for Python." category = "main" optional = false python-versions = "*" +files = [ + {file = "uplink-0.9.7-py2.py3-none-any.whl", hash = "sha256:4b50be0bb657ffd1c48e2c20bdf8538d512fe4b9f0520247d46249912ed19d15"}, + {file = "uplink-0.9.7.tar.gz", hash = "sha256:8d5bff42fedfc1bec1c2959b7a15fc1354e1a32ead33facaeadfa76f7c5d68a2"}, +] [package.dependencies] requests = ">=2.18.0" @@ -570,14 +1025,22 @@ description = "Implementation of RFC 6570 URI Templates" category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, + {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, +] [[package]] name = "urllib3" -version = "1.26.13" +version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, +] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] @@ -585,283 +1048,6 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "p socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [metadata] -lock-version = "1.1" -python-versions = "^3.8" -content-hash = "6497fc0d588477e74b42201860dfa2055b4fe5b37188385f62d50cddeac68fd5" - -[metadata.files] -aenum = [ - {file = "aenum-3.1.11-py2-none-any.whl", hash = "sha256:525b4870a27d0b471c265bda692bc657f1e0dd7597ad4186d072c59f9db666f6"}, - {file = "aenum-3.1.11-py3-none-any.whl", hash = "sha256:12ae89967f2e25c0ce28c293955d643f891603488bc3d9946158ba2b35203638"}, - {file = "aenum-3.1.11.tar.gz", hash = "sha256:aed2c273547ae72a0d5ee869719c02a643da16bf507c80958faadc7e038e3f73"}, -] -anyio = [ - {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, - {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, -] -attrs = [ - {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, - {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, -] -black = [ - {file = "black-22.10.0-1fixedarch-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa"}, - {file = "black-22.10.0-1fixedarch-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef"}, - {file = "black-22.10.0-1fixedarch-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6"}, - {file = "black-22.10.0-1fixedarch-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d"}, - {file = "black-22.10.0-1fixedarch-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4"}, - {file = "black-22.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb"}, - {file = "black-22.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7"}, - {file = "black-22.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66"}, - {file = "black-22.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae"}, - {file = "black-22.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b"}, - {file = "black-22.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d"}, - {file = "black-22.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650"}, - {file = "black-22.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d"}, - {file = "black-22.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"}, - {file = "black-22.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87"}, - {file = "black-22.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395"}, - {file = "black-22.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0"}, - {file = "black-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383"}, - {file = "black-22.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de"}, - {file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, - {file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, -] -certifi = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, - {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, -] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -colorama = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -events = [ - {file = "Events-0.4.tar.gz", hash = "sha256:01d9dd2a061f908d74a89fa5c8f07baa694f02a2a5974983663faaf7a97180f5"}, -] -exceptiongroup = [ - {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, - {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, -] -flake8 = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, -] -flake8-docstrings = [ - {file = "flake8-docstrings-1.6.0.tar.gz", hash = "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b"}, - {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"}, -] -flake8-import-order = [ - {file = "flake8-import-order-0.18.2.tar.gz", hash = "sha256:e23941f892da3e0c09d711babbb0c73bc735242e9b216b726616758a920d900e"}, - {file = "flake8_import_order-0.18.2-py2.py3-none-any.whl", hash = "sha256:82ed59f1083b629b030ee9d3928d9e06b6213eb196fe745b3a7d4af2168130df"}, -] -h11 = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] -httpcore = [ - {file = "httpcore-0.16.2-py3-none-any.whl", hash = "sha256:52c79095197178856724541e845f2db86d5f1527640d9254b5b8f6f6cebfdee6"}, - {file = "httpcore-0.16.2.tar.gz", hash = "sha256:c35c5176dc82db732acfd90b581a3062c999a72305df30c0fc8fafd8e4aca068"}, -] -httpx = [ - {file = "httpx-0.23.1-py3-none-any.whl", hash = "sha256:0b9b1f0ee18b9978d637b0776bfd7f54e2ca278e063e3586d8f01cda89e042a8"}, - {file = "httpx-0.23.1.tar.gz", hash = "sha256:202ae15319be24efe9a8bd4ed4360e68fde7b38bcc2ce87088d416f026667d19"}, -] -idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -mccabe = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] -mypy = [ - {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, - {file = "mypy-0.982-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:41fd1cf9bc0e1c19b9af13a6580ccb66c381a5ee2cf63ee5ebab747a4badeba3"}, - {file = "mypy-0.982-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f793e3dd95e166b66d50e7b63e69e58e88643d80a3dcc3bcd81368e0478b089c"}, - {file = "mypy-0.982-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ebe67adf4d021b28c3f547da6aa2cce660b57f0432617af2cca932d4d378a6"}, - {file = "mypy-0.982-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:175f292f649a3af7082fe36620369ffc4661a71005aa9f8297ea473df5772046"}, - {file = "mypy-0.982-cp310-cp310-win_amd64.whl", hash = "sha256:8ee8c2472e96beb1045e9081de8e92f295b89ac10c4109afdf3a23ad6e644f3e"}, - {file = "mypy-0.982-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58f27ebafe726a8e5ccb58d896451dd9a662a511a3188ff6a8a6a919142ecc20"}, - {file = "mypy-0.982-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6af646bd46f10d53834a8e8983e130e47d8ab2d4b7a97363e35b24e1d588947"}, - {file = "mypy-0.982-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7aeaa763c7ab86d5b66ff27f68493d672e44c8099af636d433a7f3fa5596d40"}, - {file = "mypy-0.982-cp37-cp37m-win_amd64.whl", hash = "sha256:724d36be56444f569c20a629d1d4ee0cb0ad666078d59bb84f8f887952511ca1"}, - {file = "mypy-0.982-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14d53cdd4cf93765aa747a7399f0961a365bcddf7855d9cef6306fa41de01c24"}, - {file = "mypy-0.982-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ae64555d480ad4b32a267d10cab7aec92ff44de35a7cd95b2b7cb8e64ebe3e"}, - {file = "mypy-0.982-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6389af3e204975d6658de4fb8ac16f58c14e1bacc6142fee86d1b5b26aa52bda"}, - {file = "mypy-0.982-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b35ce03a289480d6544aac85fa3674f493f323d80ea7226410ed065cd46f206"}, - {file = "mypy-0.982-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6e564f035d25c99fd2b863e13049744d96bd1947e3d3d2f16f5828864506763"}, - {file = "mypy-0.982-cp38-cp38-win_amd64.whl", hash = "sha256:cebca7fd333f90b61b3ef7f217ff75ce2e287482206ef4a8b18f32b49927b1a2"}, - {file = "mypy-0.982-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a705a93670c8b74769496280d2fe6cd59961506c64f329bb179970ff1d24f9f8"}, - {file = "mypy-0.982-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75838c649290d83a2b83a88288c1eb60fe7a05b36d46cbea9d22efc790002146"}, - {file = "mypy-0.982-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:91781eff1f3f2607519c8b0e8518aad8498af1419e8442d5d0afb108059881fc"}, - {file = "mypy-0.982-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa97b9ddd1dd9901a22a879491dbb951b5dec75c3b90032e2baa7336777363b"}, - {file = "mypy-0.982-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a692a8e7d07abe5f4b2dd32d731812a0175626a90a223d4b58f10f458747dd8a"}, - {file = "mypy-0.982-cp39-cp39-win_amd64.whl", hash = "sha256:eb7a068e503be3543c4bd329c994103874fa543c1727ba5288393c21d912d795"}, - {file = "mypy-0.982-py3-none-any.whl", hash = "sha256:1021c241e8b6e1ca5a47e4d52601274ac078a89845cfde66c6d5f769819ffa1d"}, - {file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -pastel = [ - {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, - {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, -] -pathspec = [ - {file = "pathspec-0.10.2-py3-none-any.whl", hash = "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5"}, - {file = "pathspec-0.10.2.tar.gz", hash = "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0"}, -] -platformdirs = [ - {file = "platformdirs-2.5.4-py3-none-any.whl", hash = "sha256:af0276409f9a02373d540bf8480021a048711d572745aef4b7842dad245eba10"}, - {file = "platformdirs-2.5.4.tar.gz", hash = "sha256:1006647646d80f16130f052404c6b901e80ee4ed6bef6792e1f238a8969106f7"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -poethepoet = [ - {file = "poethepoet-0.16.5-py3-none-any.whl", hash = "sha256:493d5d47b4cb0894dde6a69d14129ba39ef3f124fabda1f83ebb39bbf737a40e"}, - {file = "poethepoet-0.16.5.tar.gz", hash = "sha256:3c958792ce488661ba09df67ba832a1b3141aa640236505ee60c23f4b1db4dbc"}, -] -pycodestyle = [ - {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, - {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, -] -pydantic = [ - {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, - {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"}, - {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"}, - {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"}, - {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"}, - {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"}, - {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"}, - {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"}, - {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, - {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, -] -pydocstyle = [ - {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, - {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, -] -pyflakes = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, -] -pyparsing = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] -pytest = [ - {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, - {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, -] -pytest-asyncio = [ - {file = "pytest-asyncio-0.20.2.tar.gz", hash = "sha256:32a87a9836298a881c0ec637ebcc952cfe23a56436bdc0d09d1511941dd8a812"}, - {file = "pytest_asyncio-0.20.2-py3-none-any.whl", hash = "sha256:07e0abf9e6e6b95894a39f688a4a875d63c2128f76c02d03d16ccbc35bcc0f8a"}, -] -requests = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, -] -responses = [ - {file = "responses-0.22.0-py3-none-any.whl", hash = "sha256:dcf294d204d14c436fddcc74caefdbc5764795a40ff4e6a7740ed8ddbf3294be"}, - {file = "responses-0.22.0.tar.gz", hash = "sha256:396acb2a13d25297789a5866b4881cf4e46ffd49cc26c43ab1117f40b973102e"}, -] -rfc3986 = [ - {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, - {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, -] -setuptools = [ - {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, - {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -sniffio = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, -] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -types-requests = [ - {file = "types-requests-2.28.11.5.tar.gz", hash = "sha256:a7df37cc6fb6187a84097da951f8e21d335448aa2501a6b0a39cbd1d7ca9ee2a"}, - {file = "types_requests-2.28.11.5-py3-none-any.whl", hash = "sha256:091d4a5a33c1b4f20d8b1b952aa8fa27a6e767c44c3cf65e56580df0b05fd8a9"}, -] -types-toml = [ - {file = "types-toml-0.10.8.1.tar.gz", hash = "sha256:171bdb3163d79a520560f24ba916a9fc9bff81659c5448a9fea89240923722be"}, - {file = "types_toml-0.10.8.1-py3-none-any.whl", hash = "sha256:b7b5c4977f96ab7b5ac06d8a6590d17c0bf252a96efc03b109c2711fb3e0eafd"}, -] -types-urllib3 = [ - {file = "types-urllib3-1.26.25.4.tar.gz", hash = "sha256:eec5556428eec862b1ac578fb69aab3877995a99ffec9e5a12cf7fbd0cc9daee"}, - {file = "types_urllib3-1.26.25.4-py3-none-any.whl", hash = "sha256:ed6b9e8a8be488796f72306889a06a3fc3cb1aa99af02ab8afb50144d7317e49"}, -] -typing-extensions = [ - {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, - {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, -] -uplink = [ - {file = "uplink-0.9.7-py2.py3-none-any.whl", hash = "sha256:4b50be0bb657ffd1c48e2c20bdf8538d512fe4b9f0520247d46249912ed19d15"}, - {file = "uplink-0.9.7.tar.gz", hash = "sha256:8d5bff42fedfc1bec1c2959b7a15fc1354e1a32ead33facaeadfa76f7c5d68a2"}, -] -uritemplate = [ - {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, - {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, -] -urllib3 = [ - {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, - {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, -] +lock-version = "2.0" +python-versions = ">=3.8,<3.12" +content-hash = "e86d6b2ec28d156137117e4d6c74ea7b13c365c5df991dd5f8477cc10c8aa5fc" diff --git a/pyproject.toml b/pyproject.toml index 1696c03..2acda20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ classifiers = [ ] [tool.poetry.dependencies] -python = "^3.8" +python = ">=3.8,<3.12" aenum = "^3.1.11" Events = "^0.4" httpx = "^0.23.0" @@ -44,6 +44,8 @@ flake8-import-order = "^0.18.1" pytest = "^7.2.0" pytest-asyncio = "^0.20.1" mypy = "^0.982" +pandas = "^1.5.3" +pandas-stubs = "^1.5.3" flake8-docstrings = "^1.6.0" poethepoet = "^0.16.4" types-requests = "^2.28.11.4" From 3ec27648f917869f4a1a407f34d117576f747c10 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 11:09:02 -0500 Subject: [PATCH 12/20] Rename generator -> iterator, fix type errors --- nisystemlink/clients/core/helpers/__init__.py | 3 +++ ...tor_file_like.py => iterator_file_like.py} | 18 ++++++++------- .../clients/dataframe/_data_frame_client.py | 8 +++---- tests/core/test_generator_file_like.py | 22 +++++++++---------- 4 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 nisystemlink/clients/core/helpers/__init__.py rename nisystemlink/clients/core/helpers/{generator_file_like.py => iterator_file_like.py} (55%) diff --git a/nisystemlink/clients/core/helpers/__init__.py b/nisystemlink/clients/core/helpers/__init__.py new file mode 100644 index 0000000..b252ebf --- /dev/null +++ b/nisystemlink/clients/core/helpers/__init__.py @@ -0,0 +1,3 @@ +from .iterator_file_like import IteratorFileLike + +# flake8: noqa diff --git a/nisystemlink/clients/core/helpers/generator_file_like.py b/nisystemlink/clients/core/helpers/iterator_file_like.py similarity index 55% rename from nisystemlink/clients/core/helpers/generator_file_like.py rename to nisystemlink/clients/core/helpers/iterator_file_like.py index 2c64ae9..af07c65 100644 --- a/nisystemlink/clients/core/helpers/generator_file_like.py +++ b/nisystemlink/clients/core/helpers/iterator_file_like.py @@ -1,21 +1,23 @@ -"""A file-like object adapter that wraps a python generator, providing a way to -iterate over the generator as if it was a file. +"""A file-like object adapter that wraps a python iterator, providing a way to +read from the iterator as if it was a file. """ +from typing import Any, Iterator -class GeneratorFileLike: - def __init__(self, generator): - self._generator = generator + +class iteratorFileLike: + def __init__(self, iterator: Iterator[Any]) -> None: + self._iterator = iterator self._buffer = b"" - def read(self, size=-1): + def read(self, size: int = -1) -> bytes: """Read at most `size` bytes from the file-like object. If `size` is not - specified or is negative, read until the generator is exhausted and + specified or is negative, read until the iterator is exhausted and returns all bytes or characters read. """ while size < 0 or len(self._buffer) < size: try: - chunk = next(self._generator) + chunk = next(self._iterator) self._buffer += chunk except StopIteration: break diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index 76bdbc6..d871822 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -5,7 +5,7 @@ from nisystemlink.clients import core from nisystemlink.clients.core._uplink._base_client import BaseClient from nisystemlink.clients.core._uplink._methods import delete, get, patch, post -from nisystemlink.clients.core.helpers.generator_file_like import GeneratorFileLike +from nisystemlink.clients.core.helpers.iterator_file_like import IteratorFileLike from uplink import Body, Field, Path, Query, response_handler from . import models @@ -289,14 +289,14 @@ def query_decimated_data( ... @response_handler() - def iter_content_filelike_wrapper(response) -> GeneratorFileLike: - return GeneratorFileLike(response.iter_content(chunk_size=4096)) + def iter_content_filelike_wrapper(response) -> IteratorFileLike: + return IteratorFileLike(response.iter_content(chunk_size=4096)) @iter_content_filelike_wrapper @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest - ) -> GeneratorFileLike: + ) -> IteratorFileLike: """Exports rows of data that match a filter from the table identified by its ID. Args: diff --git a/tests/core/test_generator_file_like.py b/tests/core/test_generator_file_like.py index e2b4fbe..4a192ea 100644 --- a/tests/core/test_generator_file_like.py +++ b/tests/core/test_generator_file_like.py @@ -1,25 +1,25 @@ -from nisystemlink.clients.core.helpers.generator_file_like import GeneratorFileLike +from nisystemlink.clients.core.helpers.iterator_file_like import IteratorFileLike -class TestGeneratorFileLike: +class TestIteratorFileLike: def test__negative_size__read__reads_all_data(self): def generate_data(): yield b"123" yield b"456" yield b"789" - generator_file_like = GeneratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(generate_data()) - assert generator_file_like.read(-1) == b"123456789" + assert iterator_file_like.read(-1) == b"123456789" def test__size_smaller_than_chunk__read__reads_to_size(self): def generate_data(): yield b"1234" - generator_file_like = GeneratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(generate_data()) - assert generator_file_like.read(1) == b"1" - assert generator_file_like.read(2) == b"23" + assert iterator_file_like.read(1) == b"1" + assert iterator_file_like.read(2) == b"23" def test__size_larger_than_chunk__read__reads_to_size(self): def generate_data(): @@ -27,8 +27,8 @@ def generate_data(): yield b"456789" yield b"abcde" - generator_file_like = GeneratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(generate_data()) - assert generator_file_like.read(4) == b"1234" - assert generator_file_like.read(6) == b"56789a" - assert generator_file_like.read(6) == b"bcde" + assert iterator_file_like.read(4) == b"1234" + assert iterator_file_like.read(6) == b"56789a" + assert iterator_file_like.read(6) == b"bcde" From f18f37829a8a46be1e53315e57731544e67d7175 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 11:13:45 -0500 Subject: [PATCH 13/20] typo --- nisystemlink/clients/core/helpers/iterator_file_like.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nisystemlink/clients/core/helpers/iterator_file_like.py b/nisystemlink/clients/core/helpers/iterator_file_like.py index af07c65..5688fe0 100644 --- a/nisystemlink/clients/core/helpers/iterator_file_like.py +++ b/nisystemlink/clients/core/helpers/iterator_file_like.py @@ -5,7 +5,7 @@ from typing import Any, Iterator -class iteratorFileLike: +class IteratorFileLike: def __init__(self, iterator: Iterator[Any]) -> None: self._iterator = iterator self._buffer = b"" From 6e0e40e7358711cbb2a215d2439e5f116fe4a752 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 16 Mar 2023 11:51:43 -0500 Subject: [PATCH 14/20] try to address untyped decorator error --- nisystemlink/clients/dataframe/_data_frame_client.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index d871822..5f64ece 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -6,6 +6,7 @@ from nisystemlink.clients.core._uplink._base_client import BaseClient from nisystemlink.clients.core._uplink._methods import delete, get, patch, post from nisystemlink.clients.core.helpers.iterator_file_like import IteratorFileLike +from requests.models import Response from uplink import Body, Field, Path, Query, response_handler from . import models @@ -288,11 +289,11 @@ def query_decimated_data( """ ... - @response_handler() - def iter_content_filelike_wrapper(response) -> IteratorFileLike: + @response_handler() # type: ignore + def iter_content_filelike_wrapper(response: Response) -> IteratorFileLike: return IteratorFileLike(response.iter_content(chunk_size=4096)) - @iter_content_filelike_wrapper + @iter_content_filelike_wrapper # type: ignore @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest From 5de9e39006b41a8eaa08ac65f5f2217606c68023 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Fri, 24 Mar 2023 14:12:13 -0500 Subject: [PATCH 15/20] PR comment fixes --- docs/api_reference/core.rst | 4 ++++ docs/api_reference/dataframe.rst | 2 +- docs/getting_started.rst | 3 ++- examples/dataframe/export_data.py | 4 +++- nisystemlink/clients/core/helpers/__init__.py | 2 +- .../{iterator_file_like.py => _iterator_file_like.py} | 10 +++++----- nisystemlink/clients/dataframe/_data_frame_client.py | 7 ++++--- tests/core/test_generator_file_like.py | 2 +- tests/integration/dataframe/test_dataframe.py | 8 ++++++-- 9 files changed, 27 insertions(+), 15 deletions(-) rename nisystemlink/clients/core/helpers/{iterator_file_like.py => _iterator_file_like.py} (80%) diff --git a/docs/api_reference/core.rst b/docs/api_reference/core.rst index 54a2794..d58d793 100644 --- a/docs/api_reference/core.rst +++ b/docs/api_reference/core.rst @@ -7,3 +7,7 @@ nisystemlink.clients.core :members: :inherited-members: :imported-members: + +.. automodule:: nisystemlink.clients.core.helpers + :members: + :imported-members: diff --git a/docs/api_reference/dataframe.rst b/docs/api_reference/dataframe.rst index 780ccdd..27dd7ab 100644 --- a/docs/api_reference/dataframe.rst +++ b/docs/api_reference/dataframe.rst @@ -19,8 +19,8 @@ nisystemlink.clients.dataframe .. automethod:: get_table_data .. automethod:: append_table_data .. automethod:: query_table_data - .. automethod:: query_decimated_data .. automethod:: export_table_data + .. automethod:: query_decimated_data .. automodule:: nisystemlink.clients.dataframe.models :members: diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 3b2d977..2f74e64 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -116,6 +116,7 @@ Query and read data from a table :linenos: Export data from a table + .. literalinclude:: ../examples/dataframe/export_data.py :language: python - :linenos: \ No newline at end of file + :linenos: diff --git a/examples/dataframe/export_data.py b/examples/dataframe/export_data.py index 7039089..8fc784d 100644 --- a/examples/dataframe/export_data.py +++ b/examples/dataframe/export_data.py @@ -20,7 +20,9 @@ request = ExportTableDataRequest( columns=["col1"], order_by=[ColumnOrderBy(column="col2", descending=True)], - filters=[ColumnFilter(column="col1", operation=FilterOperation.NotEquals, value=0)], + filters=[ + ColumnFilter(column="col1", operation=FilterOperation.NotEquals, value="0") + ], response_format=ExportFormat.CSV, ) diff --git a/nisystemlink/clients/core/helpers/__init__.py b/nisystemlink/clients/core/helpers/__init__.py index b252ebf..ebc3bb9 100644 --- a/nisystemlink/clients/core/helpers/__init__.py +++ b/nisystemlink/clients/core/helpers/__init__.py @@ -1,3 +1,3 @@ -from .iterator_file_like import IteratorFileLike +from ._iterator_file_like import IteratorFileLike # flake8: noqa diff --git a/nisystemlink/clients/core/helpers/iterator_file_like.py b/nisystemlink/clients/core/helpers/_iterator_file_like.py similarity index 80% rename from nisystemlink/clients/core/helpers/iterator_file_like.py rename to nisystemlink/clients/core/helpers/_iterator_file_like.py index 5688fe0..a5d05dc 100644 --- a/nisystemlink/clients/core/helpers/iterator_file_like.py +++ b/nisystemlink/clients/core/helpers/_iterator_file_like.py @@ -1,12 +1,12 @@ -"""A file-like object adapter that wraps a python iterator, providing a way to -read from the iterator as if it was a file. -""" - from typing import Any, Iterator class IteratorFileLike: - def __init__(self, iterator: Iterator[Any]) -> None: + """A file-like object adapter that wraps a python iterator, providing a way to + read from the iterator as if it was a file. + """ + + def __init__(self, iterator: Iterator[Any]): self._iterator = iterator self._buffer = b"" diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index 5f64ece..628a618 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -5,7 +5,7 @@ from nisystemlink.clients import core from nisystemlink.clients.core._uplink._base_client import BaseClient from nisystemlink.clients.core._uplink._methods import delete, get, patch, post -from nisystemlink.clients.core.helpers.iterator_file_like import IteratorFileLike +from nisystemlink.clients.core.helpers import IteratorFileLike from requests.models import Response from uplink import Body, Field, Path, Query, response_handler @@ -289,11 +289,12 @@ def query_decimated_data( """ ... + # Suppress type checking because we can't add typing to uplink.response_handler @response_handler() # type: ignore - def iter_content_filelike_wrapper(response: Response) -> IteratorFileLike: + def _iter_content_filelike_wrapper(response: Response) -> IteratorFileLike: return IteratorFileLike(response.iter_content(chunk_size=4096)) - @iter_content_filelike_wrapper # type: ignore + @_iter_content_filelike_wrapper # type: ignore @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest diff --git a/tests/core/test_generator_file_like.py b/tests/core/test_generator_file_like.py index 4a192ea..84c856e 100644 --- a/tests/core/test_generator_file_like.py +++ b/tests/core/test_generator_file_like.py @@ -1,4 +1,4 @@ -from nisystemlink.clients.core.helpers.iterator_file_like import IteratorFileLike +from nisystemlink.clients.core.helpers import IteratorFileLike class TestIteratorFileLike: diff --git a/tests/integration/dataframe/test_dataframe.py b/tests/integration/dataframe/test_dataframe.py index a54e4b4..623294b 100644 --- a/tests/integration/dataframe/test_dataframe.py +++ b/tests/integration/dataframe/test_dataframe.py @@ -583,6 +583,7 @@ def test__export_table_data__works(self, client: DataFrameClient, create_table): int_index_column, Column(name="col1", data_type=DataType.Float64), Column(name="col2", data_type=DataType.Float64), + Column(name="col3", data_type=DataType.Float64), ] ) ) @@ -600,7 +601,7 @@ def test__export_table_data__works(self, client: DataFrameClient, create_table): rsps.add( responses.POST, f"{client.session.base_url}tables/{id}/export-data", - body=b"1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5", + body=b'"col1","col2","col3"\r\n1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5', match=[matchers.json_params_matcher({"responseFormat": "CSV"})], ) @@ -609,4 +610,7 @@ def test__export_table_data__works(self, client: DataFrameClient, create_table): ExportTableDataRequest(response_format=ExportFormat.CSV), ) - assert response.read() == b"1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5" + assert ( + response.read() + == b'"col1","col2","col3"\r\n1,2.5,6.5\r\n2,1.5,5.5\r\n3,2.5,7.5' + ) From 8cab889bca8498aed03848851e687e0e5da413d8 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Fri, 24 Mar 2023 14:25:07 -0500 Subject: [PATCH 16/20] fix broken test --- tests/integration/dataframe/test_dataframe.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/dataframe/test_dataframe.py b/tests/integration/dataframe/test_dataframe.py index 623294b..aa9c252 100644 --- a/tests/integration/dataframe/test_dataframe.py +++ b/tests/integration/dataframe/test_dataframe.py @@ -583,7 +583,6 @@ def test__export_table_data__works(self, client: DataFrameClient, create_table): int_index_column, Column(name="col1", data_type=DataType.Float64), Column(name="col2", data_type=DataType.Float64), - Column(name="col3", data_type=DataType.Float64), ] ) ) From 0fcdc215d50d6e25b0d81dd704c259cc3de3a27b Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 6 Apr 2023 09:55:20 -0500 Subject: [PATCH 17/20] review comments, pt 1 --- mypy.ini | 3 +++ .../clients/dataframe/_data_frame_client.py | 5 ++--- pyproject.toml | 4 +--- ...ile_like.py => test_iterator_file_like.py} | 19 +++---------------- 4 files changed, 9 insertions(+), 22 deletions(-) rename tests/core/{test_generator_file_like.py => test_iterator_file_like.py} (56%) diff --git a/mypy.ini b/mypy.ini index 80cd27f..844a92e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -11,6 +11,9 @@ disallow_untyped_decorators=True strict_equality=True +[mypy-pandas.*] +ignore_missing_imports = True + [mypy-tests.*] disallow_untyped_calls=True disallow_untyped_decorators=True diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index 628a618..b92272d 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -289,12 +289,11 @@ def query_decimated_data( """ ... - # Suppress type checking because we can't add typing to uplink.response_handler - @response_handler() # type: ignore def _iter_content_filelike_wrapper(response: Response) -> IteratorFileLike: return IteratorFileLike(response.iter_content(chunk_size=4096)) - @_iter_content_filelike_wrapper # type: ignore + # Suppress type checking because we can't add typing to uplink.response_handler + @response_handler(_iter_content_filelike_wrapper) # type: ignore @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest diff --git a/pyproject.toml b/pyproject.toml index 2acda20..fe0d12e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ classifiers = [ ] [tool.poetry.dependencies] -python = ">=3.8,<3.12" +python = "^3.8" aenum = "^3.1.11" Events = "^0.4" httpx = "^0.23.0" @@ -44,8 +44,6 @@ flake8-import-order = "^0.18.1" pytest = "^7.2.0" pytest-asyncio = "^0.20.1" mypy = "^0.982" -pandas = "^1.5.3" -pandas-stubs = "^1.5.3" flake8-docstrings = "^1.6.0" poethepoet = "^0.16.4" types-requests = "^2.28.11.4" diff --git a/tests/core/test_generator_file_like.py b/tests/core/test_iterator_file_like.py similarity index 56% rename from tests/core/test_generator_file_like.py rename to tests/core/test_iterator_file_like.py index 84c856e..b277ae4 100644 --- a/tests/core/test_generator_file_like.py +++ b/tests/core/test_iterator_file_like.py @@ -3,31 +3,18 @@ class TestIteratorFileLike: def test__negative_size__read__reads_all_data(self): - def generate_data(): - yield b"123" - yield b"456" - yield b"789" - - iterator_file_like = IteratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(iter([b"123", b"456", b"789"])) assert iterator_file_like.read(-1) == b"123456789" def test__size_smaller_than_chunk__read__reads_to_size(self): - def generate_data(): - yield b"1234" - - iterator_file_like = IteratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(iter([b"1234"])) assert iterator_file_like.read(1) == b"1" assert iterator_file_like.read(2) == b"23" def test__size_larger_than_chunk__read__reads_to_size(self): - def generate_data(): - yield b"123" - yield b"456789" - yield b"abcde" - - iterator_file_like = IteratorFileLike(generate_data()) + iterator_file_like = IteratorFileLike(iter([b"123", b"456789", b"abcde"])) assert iterator_file_like.read(4) == b"1234" assert iterator_file_like.read(6) == b"56789a" From 8712de562e42c1e5ab2a7316902b697115eeb60b Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 6 Apr 2023 10:42:26 -0500 Subject: [PATCH 18/20] Avoid type error in client --- examples/dataframe/export_data.py | 4 ++-- mypy.ini | 2 +- nisystemlink/clients/core/_uplink/_methods.py | 19 ++++++++++++++++++- .../clients/dataframe/_data_frame_client.py | 13 +++++++++---- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/examples/dataframe/export_data.py b/examples/dataframe/export_data.py index 8fc784d..da76b48 100644 --- a/examples/dataframe/export_data.py +++ b/examples/dataframe/export_data.py @@ -1,6 +1,5 @@ from shutil import copyfileobj -import pandas as pd from nisystemlink.clients.dataframe import DataFrameClient from nisystemlink.clients.dataframe.models import ( ColumnFilter, @@ -33,4 +32,5 @@ copyfileobj(data, f) # Alternatively, load the export data into a pandas dataframe -df = pd.read_csv(data) +# import pandas as pd +# df = pd.read_csv(data) diff --git a/mypy.ini b/mypy.ini index 844a92e..e45cbfd 100644 --- a/mypy.ini +++ b/mypy.ini @@ -12,7 +12,7 @@ disallow_untyped_decorators=True strict_equality=True [mypy-pandas.*] -ignore_missing_imports = True +ignore_missing_imports=True [mypy-tests.*] disallow_untyped_calls=True diff --git a/nisystemlink/clients/core/_uplink/_methods.py b/nisystemlink/clients/core/_uplink/_methods.py index ea47564..a888067 100644 --- a/nisystemlink/clients/core/_uplink/_methods.py +++ b/nisystemlink/clients/core/_uplink/_methods.py @@ -2,7 +2,13 @@ from typing import Any, Callable, Optional, Sequence, Tuple, TypeVar, Union -from uplink import Body, commands, json, returns +from uplink import ( + Body, + commands, + json, + returns, + response_handler as uplink_response_handler, +) F = TypeVar("F", bound=Callable[..., Any]) @@ -50,3 +56,14 @@ def decorator(func: F) -> F: return commands.delete(path, args=args)(func) # type: ignore return decorator + + +def response_handler( + handler: Any, requires_consumer: Optional[bool] = False +) -> Callable[[F], F]: + """Annotation for creating custom response handlers.""" + + def decorator(func: F) -> F: + return uplink_response_handler(handler, requires_consumer)(func) # type: ignore + + return decorator diff --git a/nisystemlink/clients/dataframe/_data_frame_client.py b/nisystemlink/clients/dataframe/_data_frame_client.py index b92272d..de1b7b1 100644 --- a/nisystemlink/clients/dataframe/_data_frame_client.py +++ b/nisystemlink/clients/dataframe/_data_frame_client.py @@ -4,10 +4,16 @@ from nisystemlink.clients import core from nisystemlink.clients.core._uplink._base_client import BaseClient -from nisystemlink.clients.core._uplink._methods import delete, get, patch, post +from nisystemlink.clients.core._uplink._methods import ( + delete, + get, + patch, + post, + response_handler, +) from nisystemlink.clients.core.helpers import IteratorFileLike from requests.models import Response -from uplink import Body, Field, Path, Query, response_handler +from uplink import Body, Field, Path, Query from . import models @@ -292,8 +298,7 @@ def query_decimated_data( def _iter_content_filelike_wrapper(response: Response) -> IteratorFileLike: return IteratorFileLike(response.iter_content(chunk_size=4096)) - # Suppress type checking because we can't add typing to uplink.response_handler - @response_handler(_iter_content_filelike_wrapper) # type: ignore + @response_handler(_iter_content_filelike_wrapper) @post("tables/{id}/export-data", args=[Path, Body]) def export_table_data( self, id: str, query: models.ExportTableDataRequest From d9e32e17ffc75cb6b226dca8cf8ff294ad699ae6 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 6 Apr 2023 11:12:55 -0500 Subject: [PATCH 19/20] reorder imports --- nisystemlink/clients/core/_uplink/_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nisystemlink/clients/core/_uplink/_methods.py b/nisystemlink/clients/core/_uplink/_methods.py index a888067..bed0470 100644 --- a/nisystemlink/clients/core/_uplink/_methods.py +++ b/nisystemlink/clients/core/_uplink/_methods.py @@ -6,8 +6,8 @@ Body, commands, json, - returns, response_handler as uplink_response_handler, + returns, ) F = TypeVar("F", bound=Callable[..., Any]) From 0147f542f166827b69ad8b82c9c09b448185ab59 Mon Sep 17 00:00:00 2001 From: Kelsey Johnson Date: Thu, 6 Apr 2023 14:33:42 -0500 Subject: [PATCH 20/20] remove mypy suppression for pandas --- mypy.ini | 3 --- 1 file changed, 3 deletions(-) diff --git a/mypy.ini b/mypy.ini index e45cbfd..80cd27f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -11,9 +11,6 @@ disallow_untyped_decorators=True strict_equality=True -[mypy-pandas.*] -ignore_missing_imports=True - [mypy-tests.*] disallow_untyped_calls=True disallow_untyped_decorators=True