From 4f30a6587d8c8aa197e56a8ffd5d74383851aca2 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 5 Apr 2024 21:31:54 -0600 Subject: [PATCH 01/30] Updating for usage in ingest cookiecutter --- pyproject.toml | 2 +- src/koza/app.py | 7 ---- src/koza/cli_runner.py | 13 ++++--- src/koza/io/reader/__init__.py | 2 -- src/koza/io/reader/csv_reader.py | 12 ++----- src/koza/main.py | 19 ++++------ src/koza/model/config/source_config.py | 50 +++++++++++--------------- src/koza/model/config/sssom_config.py | 1 - src/koza/model/curie_cleaner.py | 1 - src/koza/model/source.py | 13 ++++--- 10 files changed, 44 insertions(+), 76 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b2dcee6..854222f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "koza" -version = "0.5.4" +version = "0.5.5" description = "Data transformation framework for LinkML data models" authors = [ "The Monarch Initiative ", diff --git a/src/koza/app.py b/src/koza/app.py index 10e4640..2f3d158 100644 --- a/src/koza/app.py +++ b/src/koza/app.py @@ -214,13 +214,6 @@ def _load_map(self, map_file: Source): @staticmethod def _map_sniffer(depends_on: str): """ - TODO a utility function to determine if a depends_on string - is a path to a map config file, a yaml file that should be - interpreted as a dictionary, or a json file that should be - interpreted as a dictionary - - See https://github.com/monarch-initiative/koza/issues/39 - :param depends_on: """ pass diff --git a/src/koza/cli_runner.py b/src/koza/cli_runner.py index f45cd2f..ab4a76e 100644 --- a/src/koza/cli_runner.py +++ b/src/koza/cli_runner.py @@ -29,7 +29,7 @@ def get_koza_app(source_name) -> Optional[KozaApp]: """ try: return koza_apps[source_name] - except: + except KeyError: raise KeyError(f"{source_name} was not found in KozaApp dictionary") @@ -63,13 +63,18 @@ def transform_source( with open(source, 'r') as source_fh: source_config = PrimaryFileConfig(**yaml.load(source_fh, Loader=UniqueIncludeLoader)) - + + # TODO: Try moving this to source_config class if not source_config.name: source_config.name = Path(source).stem if not source_config.transform_code: - # look for it alongside the source conf as a .py file - source_config.transform_code = str(Path(source).parent / Path(source).stem) + '.py' + filename = f"{Path(source).parent / Path(source).stem}.py" + if not Path(filename).exists(): + filename = Path(source).parent / "transform.py" + if not Path(filename).exists(): + raise FileNotFoundError(f"Could not find transform file for {source}") + source_config.transform_code = filename koza_source = Source(source_config, row_limit) logger.debug(f"Source created: {koza_source.config.name}") diff --git a/src/koza/io/reader/__init__.py b/src/koza/io/reader/__init__.py index 8011370..1becdbc 100644 --- a/src/koza/io/reader/__init__.py +++ b/src/koza/io/reader/__init__.py @@ -1,5 +1,3 @@ """ Readers - csv, json, jsonl - -TODO implement XML reader """ diff --git a/src/koza/io/reader/csv_reader.py b/src/koza/io/reader/csv_reader.py index a7d97f0..101ab3b 100644 --- a/src/koza/io/reader/csv_reader.py +++ b/src/koza/io/reader/csv_reader.py @@ -38,8 +38,6 @@ class CSVReader: - Potentially will add support a multivalued field DSL, eg List[str][';'] would convert a semicolon delimited multivalued field to a list of strings - - TODO handle cases when delimiter is >1 character """ def __init__( @@ -137,11 +135,6 @@ def __next__(self) -> Dict[str, Any]: row = next(self.reader) # Check row length discrepancies for each row - # TODO currently varying line lengths will raise an exception - # and hard fail, we should probably make these warnings and report - # out which lines vary - # Could also create a custom exception and allow the client code - # to determine what to do here fields_len = len(self._header) row_len = len(row) stripped_row = [val.strip() for val in row] @@ -154,9 +147,8 @@ def __next__(self) -> Dict[str, Any]: elif fields_len < row_len: logger.warning(f"CSV file {self.name} has {row_len - fields_len} extra columns at {self.reader.line_num}") - # Not sure if this would serve a purpose - # - # if not 'extra_cols' in self.field_type_map: + # # Not sure if this would serve a purpose: + # if 'extra_cols' not in self.field_type_map: # # Create a type map for extra columns # self.field_type_map['extra_cols'] = FieldType.str # field_map['extra_cols'] = row[fields_len:] diff --git a/src/koza/main.py b/src/koza/main.py index 7e1beb9..74bc55b 100755 --- a/src/koza/main.py +++ b/src/koza/main.py @@ -24,14 +24,14 @@ def callback(version: Optional[bool] = typer.Option(None, "--version", is_eager= @typer_app.command() def transform( source: str = typer.Option(..., help="Source metadata file"), - output_dir: str = typer.Option('./output', help="Path to output directory"), + output_dir: str = typer.Option("./output", help="Path to output directory"), output_format: OutputFormat = typer.Option("tsv", help="Output format"), global_table: str = typer.Option(None, help="Path to global translation table"), local_table: str = typer.Option(None, help="Path to local translation table"), - schema: str = typer.Option(None, help='Path to schema YAML for validation in writer'), + schema: str = typer.Option(None, help="Path to schema YAML for validation in writer"), row_limit: int = typer.Option(None, help="Number of rows to process (if skipped, processes entire source file)"), verbose: Optional[bool] = typer.Option(None, "--debug/--quiet"), - log: bool = typer.Option(False, help='Optional log mode - set true to save output to ./logs'), + log: bool = typer.Option(False, help="Optional log mode - set true to save output to ./logs"), ) -> None: """Transform a source file""" @@ -49,7 +49,7 @@ def transform( def validate( file: str = typer.Option(..., help="Path or url to the source file"), format: FormatType = FormatType.csv, - delimiter: str = ',', + delimiter: str = ",", header_delimiter: str = None, skip_blank_lines: bool = True, ) -> None: @@ -57,12 +57,5 @@ def validate( validate_file(file, format, delimiter, header_delimiter, skip_blank_lines) -# @typer_app.command() -# def create(): -# """ -# TODO -# Create a new koza project -# """ - -# if __name__ == "__main__": -# typer_app() +if __name__ == "__main__": + typer_app() diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index 39aa016..42e94dd 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -57,7 +57,7 @@ class FormatType(str, Enum): jsonl = "jsonl" json = "json" yaml = "yaml" - xml = "xml" # TODO + # xml = "xml" # Not yet supported class HeaderMode(str, Enum): @@ -120,14 +120,14 @@ class DatasetDescription: than documentation """ - id: Optional[str] = None # TODO constrain to a curie? + id: Optional[str] = None name: Optional[str] = None # If empty use source name - ingest_title: Optional[str] = None # Map to biolink name - ingest_url: Optional[str] = None # Maps to biolink iri + ingest_title: Optional[str] = None # Title of source of data, map to biolink name + ingest_url: Optional[str] = None # URL to source of data, Maps to biolink iri description: Optional[str] = None source: Optional[str] = None provided_by: Optional[str] = None - license: Optional[str] = None + # license: Optional[str] = None # Possibly redundant, same as rights rights: Optional[str] = None @@ -143,16 +143,17 @@ class SourceConfig: file_archive: str (optional) - path to a file archive containing files to process format: FormatType (optional) - format of the data file(s) sssom_config: SSSOMConfig (optional) - SSSOM config options - metadata: DatasetDescription (optional) - metadata for the source columns: List[str] (optional) - list of columns to include + field_type_map: dict (optional) - dict of field names and their type (using the FieldType enum) + filters: List[ColumnFilter] (optional) - list of filters to apply required_properties: List[str] (optional) - list of properties which must be in json data files + metadata: DatasetDescription (optional) - metadata for the source delimiter: str (optional) - delimiter for csv files header: int (optional) - header row index header_delimiter: str (optional) - delimiter for header in csv files header_prefix: str (optional) - prefix for header in csv files comment_char: str (optional) - comment character for csv files skip_blank_lines: bool (optional) - skip blank lines in csv files - filters: List[ColumnFilter] (optional) - list of filters to apply json_path: List[str] (optional) - path within JSON object containing data to process transform_code: str (optional) - path to a python file to transform the data transform_mode: TransformMode (optional) - how to process the transform file @@ -167,6 +168,7 @@ class SourceConfig: sssom_config: Optional[SSSOMConfig] = None columns: Optional[List[Union[str, Dict[str, FieldType]]]] = None field_type_map: Optional[dict] = None + filters: List[ColumnFilter] = field(default_factory=list) required_properties: Optional[List[str]] = None metadata: Optional[Union[DatasetDescription, str]] = None delimiter: Optional[str] = None @@ -175,7 +177,6 @@ class SourceConfig: header_prefix: Optional[str] = None comment_char: str = "#" skip_blank_lines: bool = True - filters: List[ColumnFilter] = field(default_factory=list) json_path: Optional[List[Union[StrictStr, StrictInt]]] = None transform_code: Optional[str] = None transform_mode: TransformMode = TransformMode.flat @@ -196,11 +197,7 @@ def extract_archive(self): return files def __post_init__(self): - """ - TO DO figure out why we're using object.__setattr__(self, ...) - here and document it. - Is this a workaround for a pydantic bug? - """ + # Get files as paths, or extract them from an archive if self.file_archive: files = self.extract_archive() else: @@ -213,22 +210,20 @@ def __post_init__(self): else: files_as_paths.append(file) object.__setattr__(self, "files", files_as_paths) - # self.files = files_as_paths <---- is this equivalent to the above? + # If metadata looks like a file path attempt to load it from the yaml if self.metadata and isinstance(self.metadata, str): - # If this looks like a file path attempt to load it from the yaml - # TODO enforce that this is imported via an include? - # See https://github.com/monarch-initiative/koza/issues/46 try: with open(self.metadata, "r") as meta: object.__setattr__(self, "metadata", DatasetDescription(**yaml.safe_load(meta))) except Exception as e: - # TODO check for more explicit exceptions raise ValueError(f"Unable to load metadata from {self.metadata}: {e}") + # Format tab as delimiter if self.delimiter in ["tab", "\\t"]: object.__setattr__(self, "delimiter", "\t") + # Filter columns filtered_columns = [column_filter.column for column_filter in self.filters] all_columns = [] @@ -249,9 +244,6 @@ def __post_init__(self): for column_filter in self.filters: if column_filter.filter_code in ["lt", "gt", "lte", "gte"]: - # TODO determine if this should raise an exception - # or instead try to type coerce the string to a float - # type coercion is probably the best thing to do here if not isinstance(column_filter.value, (int, float)): raise ValueError(f"Filter value must be int or float for operator {column_filter.filter_code}") elif column_filter.filter_code == "eq": @@ -263,24 +255,24 @@ def __post_init__(self): if not isinstance(column_filter.value, List): raise ValueError(f"Filter value must be List for operator {column_filter.filter_code}") + # Check for conflicting configurations if self.format == FormatType.csv and self.required_properties: raise ValueError( "CSV specified but required properties have been configured\n" - "either set format to jsonl or change properties to columns in the config" + "Either set format to jsonl or change properties to columns in the config" ) - if self.columns and self.format != FormatType.csv: raise ValueError( - "columns have been configured but format is not csv\n" - "either set format to csv or change columns to properties in the config" + "Columns have been configured but format is not csv\n" + "Either set format to csv or change columns to properties in the config" ) - if self.json_path and self.format != FormatType.json: raise ValueError( "iterate_over has been configured but format is not json\n" - "either set format to json or remove iterate_over in the configuration" + "Either set format to json or remove iterate_over in the configuration" ) + # Create a field_type_map if columns are supplied if self.columns: field_type_map = {} for field in self.columns: @@ -288,12 +280,10 @@ def __post_init__(self): field_type_map[field] = FieldType.str else: if len(field) != 1: - # TODO expand this exception msg raise ValueError("Field type map contains more than one key") for key, val in field.items(): field_type_map[key] = val - # print(f"FIELD TYPE MAP: {field_type_map}") - self.field_type_map = field_type_map + object.__setattr__(self, "field_type_map", field_type_map) @dataclass(config=PYDANTIC_CONFIG) diff --git a/src/koza/model/config/sssom_config.py b/src/koza/model/config/sssom_config.py index 6590931..2cd8d68 100644 --- a/src/koza/model/config/sssom_config.py +++ b/src/koza/model/config/sssom_config.py @@ -76,7 +76,6 @@ def _merge_and_filter_sssom(self): def _build_sssom_lut(self) -> Dict: """Build a lookup table from SSSOM mapping dataframe.""" - # TODO add narrow and broad match mappings sssom_lut = {} for _, row in self.df.iterrows(): subject_id = row["subject_id"] diff --git a/src/koza/model/curie_cleaner.py b/src/koza/model/curie_cleaner.py index cf75b91..d401c62 100644 --- a/src/koza/model/curie_cleaner.py +++ b/src/koza/model/curie_cleaner.py @@ -3,7 +3,6 @@ class CurieCleaner: def __init__(self): - # TODO: these belong in yaml, might already exist somewhere self.mappings = {"taxon": "NCBITaxon", "NCBI_Gene": "NCBIGene"} def clean(self, curie: str) -> str: diff --git a/src/koza/model/source.py b/src/koza/model/source.py index 294c643..d2ba711 100644 --- a/src/koza/model/source.py +++ b/src/koza/model/source.py @@ -19,8 +19,8 @@ class Source: and adds filter support to the readers in io.reader config: Source config - reader: An iterator that takes in an IO[str] as its first argument - and yields a dictionary + row_limit: Number of rows to process + reader: An iterator that takes in an IO[str] and yields a dictionary """ def __init__(self, config: Union[PrimaryFileConfig, MapFileConfig], row_limit: Optional[int] = None): @@ -33,7 +33,7 @@ def __init__(self, config: Union[PrimaryFileConfig, MapFileConfig], row_limit: O for file in config.files: resource_io = open_resource(file) - if self.config.format == 'csv': + if self.config.format == "csv": self._readers.append( CSVReader( resource_io, @@ -47,7 +47,7 @@ def __init__(self, config: Union[PrimaryFileConfig, MapFileConfig], row_limit: O row_limit=self.row_limit, ) ) - elif self.config.format == 'jsonl': + elif self.config.format == "jsonl": self._readers.append( JSONLReader( resource_io, @@ -56,14 +56,14 @@ def __init__(self, config: Union[PrimaryFileConfig, MapFileConfig], row_limit: O row_limit=self.row_limit, ) ) - elif self.config.format == 'json' or self.config.format == 'yaml': + elif self.config.format == "json" or self.config.format == "yaml": self._readers.append( JSONReader( resource_io, name=config.name, json_path=config.json_path, required_properties=config.required_properties, - is_yaml=(self.config.format == 'yaml'), + is_yaml=(self.config.format == "yaml"), row_limit=self.row_limit, ) ) @@ -90,7 +90,6 @@ def _get_row(self): if self._filter: row = next(self._reader) while not self._filter.include_row(row): - # TODO log filtered out lines row = next(self._reader) else: row = next(self._reader) From 72bcd3a9d3d4321832bd39c163376a589fb594c8 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 19 Apr 2024 16:30:33 -0600 Subject: [PATCH 02/30] update documentation some more --- docs/Ingests/index.md | 12 ++ docs/Ingests/mapping.md | 62 +++++++++++ docs/Ingests/source_config.md | 74 +++++++++++++ docs/Ingests/transform.md | 59 ++++++++++ docs/Usage/ingests.md | 200 ---------------------------------- docs/index.md | 9 +- mkdocs.yaml | 6 +- 7 files changed, 218 insertions(+), 204 deletions(-) create mode 100644 docs/Ingests/index.md create mode 100644 docs/Ingests/mapping.md create mode 100644 docs/Ingests/source_config.md create mode 100644 docs/Ingests/transform.md delete mode 100644 docs/Usage/ingests.md diff --git a/docs/Ingests/index.md b/docs/Ingests/index.md new file mode 100644 index 0000000..8c1eb77 --- /dev/null +++ b/docs/Ingests/index.md @@ -0,0 +1,12 @@ + +(For CLI usage, see the [CLI commands](./CLI.md) page.) + + +Koza is designed to process and transform existing data into a target csv/json/jsonl format. + +This process is internally known as an **ingest**. Ingests are defined by: + +1. [Source config yaml](./source_config.md): Ingest configuration, including: + - metadata, formats, required columns, any SSSOM files, etc. +1. [Map config yaml](./mapping.md): (Optional) configures creation of mapping dictionary +1. [Transform code](./transform.md): a Python script, with specific transform instructions diff --git a/docs/Ingests/mapping.md b/docs/Ingests/mapping.md new file mode 100644 index 0000000..5c18aee --- /dev/null +++ b/docs/Ingests/mapping.md @@ -0,0 +1,62 @@ + +Mapping with Koza is optional, but can be done in two ways: + +- Automated mapping with SSSOM files +- Manual mapping with a map config yaml + +### SSSOM Mapping + +Koza supports mapping with SSSOM files (Semantic Similarity of Source and Target Ontology Mappings). +Simply add the path to the SSSOM file to your source config, the desired target prefixes, +and any prefixes you want to use to filter the SSSOM file. +Koza will automatically create a mapping lookup table which will automatically +attempt to map any values in the source file to an ID with the target prefix. + +```yaml +sssom_config: + sssom_file: './path/to/your_mapping_file.sssom.tsv' + filter_prefixes: + - 'SOMEPREFIX' + - 'OTHERPREFIX' + target_prefixes: + - 'OTHERPREFIX' + use_match: + - 'exact' +``` + +**Note:** Currently, only the `exact` match type is supported (`narrow` and `broad` match types will be added in the future). + +### Manual Mapping / Additional Data + +The map config yaml allows you to include data from other sources in your ingests, +which may have different columns or formats. + +If you don't have an SSSOM file, or you want to manually map some values, you can use a map config yaml. +You can then add this map to your source config yaml in the `depends_on` property. + +Koza will then create a nested dictionary with the specified key and values. +For example, the following map config yaml maps values from the `STRING` column to the `entrez` and `NCBI taxid` columns. + +```yaml +# koza/examples/maps/entrez-2-string.yaml +name: ... +files: ... + +columns: +- 'NCBI taxid' +- 'entrez' +- 'STRING' + +key: 'STRING' + +values: +- 'entrez' +- 'NCBI taxid' +``` + + +The mapping dict will be available in your transform script from the `koza_app` object (see the Transform Code section below). + +--- + +**Next Steps: [Transform Code](./transform.md)** \ No newline at end of file diff --git a/docs/Ingests/source_config.md b/docs/Ingests/source_config.md new file mode 100644 index 0000000..999070a --- /dev/null +++ b/docs/Ingests/source_config.md @@ -0,0 +1,74 @@ +This YAML file sets properties for the ingest of a single file type from a within a Source. + +!!! tip "Paths are relative to the directory from which you execute Koza." + +## Source Configuration Properties + +| **Required properties** | | +| ------------------------------------ | --------------------------------------------------------------------------------------------------- | +| `name` | Name of the source | +| `files` | List of files to process | +| | | +| **Optional properties** | | +| `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | +| `format` | Format of the data file(s) (CSV or JSON) | +| `sssom_config` | Configures usage of SSSOM mapping files | +| `depends_on` | List of map config files to use | +| `metadata` | Metadata for the source, either a list of properties,
or path to a `metadata.yaml` | +| `transform_code` | Path to a python file to transform the data | +| `transform_mode` | How to process the transform file | +| `global_table` | Path to a global translation table file | +| `local_table` | Path to a local translation table file | +| `field_type_map` | Dict of field names and their type (using the FieldType enum) | +| `filters` | List of filters to apply | +| `json_path` | Path within JSON object containing data to process | +| `required_properties` | List of properties that must be present in output (JSON only) | +| | | +| **Optional CSV Specific Properties** | | +| `columns` | List of columns to include in output (CSV only) | +| `delimiter` | Delimiter for csv files | +| `header` | Header row index for csv files | +| `header_delimiter` | Delimiter for header in csv files | +| `header_prefix` | Prefix for header in csv files | +| `comment_char` | Comment character for csv files | +| `skip_blank_lines` | Skip blank lines in csv files | + +## Metadata Properties + +Metadata is optional, and can be defined as a list of properties and values, or as a path to a `metadata.yaml` file, +for example - `metadata: "./path/to/metadata.yaml"`. +Remember that the path is relative to the directory from which you execute Koza. + +| **Metadata Properties** | | +| ----------------------- | -------------------------------------------- | +| id | TBD | +| name | If empty, uses source name | +| ingest_title | Title of source of data, map to biolink name | +| ingest_url | URL to source of data, Maps to biolink iri | +| description | Description of ingest | +| source | Source of data being transformed | +| provided_by | TBD | +| rights | TBD | + +### Composing Configuration from Multiple Yaml Files + +Koza's custom YAML Loader supports importing/including other yaml files with an `!include` tag. + +For example, if you had a file named `standard-columns.yaml`: + +```yaml +- "column_1" +- "column_2" +- "column_3" +- "column_4": "int" +``` + +Then in any ingests you wish to use these columns, you can simply `!include` them: + +```yaml +columns: !include "./path/to/standard-columns.yaml" +``` + +--- + +**Next Steps: [Mapping and Additional Data](./mapping.md)** diff --git a/docs/Ingests/transform.md b/docs/Ingests/transform.md new file mode 100644 index 0000000..ede359f --- /dev/null +++ b/docs/Ingests/transform.md @@ -0,0 +1,59 @@ +This Python script is where you'll define the specific steps of your data transformation. +Koza will load this script and execute it for each row of data in your source file, +applying any filters and mapping as defined in your source config yaml, +and outputting the transformed data to the target csv/json/jsonl file. + +When Koza is called, either by command-line or as a library using `transform_source()`, +it creates a `KozaApp` object for the specified ingest. +This KozaApp will be your entry point to Koza: + +```python +from koza.cli_runner import get_koza_app +koza_app = get_koza_app('your-source-name') +``` + +The KozaApp object has the following methods: + +| Method | Description | +| --- | --- | +| `get_row()` | Returns the next row of data from the source file | +| `get_map(map_name)` | Returns the mapping dict for the specified map | +| `get_global_table()` | Returns the global translation table | +| `get_local_table()` | Returns the local translation table | + +??? tldr "Example Python Transform Script" + + ```python + # other imports, eg. uuid, pydantic, etc. + import uuid + from biolink.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction + + # Koza imports + from koza.cli_runner import get_koza_app + + # This is the name of the ingest you want to run + source_name = 'map-protein-links-detailed' + koza_app = get_koza_app(source_name) + + # If your ingest depends_on a mapping file, you can access it like this: + map_name = 'entrez-2-string' + koza_map = koza_app.get_map(map_name) + + # This grabs the first/next row from the source data + # Koza will reload this script and return the next row until it reaches EOF or row-limit + while (row := koza_app.get_row()) is not None: + # Now you can lay out your actual transformations, and define your output: + + gene_a = Gene(id='NCBIGene:' + koza_map[row['protein1']]['entrez']) + gene_b = Gene(id='NCBIGene:' + koza_map[row['protein2']]['entrez']) + + pairwise_gene_to_gene_interaction = PairwiseGeneToGeneInteraction( + id="uuid:" + str(uuid.uuid1()), + subject=gene_a.id, + object=gene_b.id, + predicate="biolink:interacts_with" + ) + + # Finally, write the transformed row to the target file + koza_app.write(gene_a, gene_b, pairwise_gene_to_gene_interaction) + ``` \ No newline at end of file diff --git a/docs/Usage/ingests.md b/docs/Usage/ingests.md deleted file mode 100644 index dfa8a32..0000000 --- a/docs/Usage/ingests.md +++ /dev/null @@ -1,200 +0,0 @@ -# Ingests - - -(For CLI usage, see the [CLI commands](./CLI.md) page.) - - -!!! tip "Ingest Overview" - Koza is designed to process and transform existing data into a target csv/json/jsonl format. - - This process is internally known as an **ingest**. Ingests are defined by: - - - **Source config yaml**: Ingest configuration, including: - - metadata, formats, required columns, any SSSOM files, etc. - - **Map config yaml**: (Optional) configures creation of mapping dictionary - - **Transform code**: a Python script, with specific transform instructions - ------ - -Let's say you have some data, and you want to save certain bits of that data, -with maybe some changes or translations along the way. -Creating this ingest will require three things: - -!!! list "" - ## 1. Source Config File - - This YAML file sets properties for the ingest of a single file type from a within a Source. - - !!! tip "Paths are relative to the directory from which you execute Koza." - - | __Required properties__ | | - | --- | --- | - | `name` | Name of the source | - | `files` | List of files to process | - ||| - | __Optional properties__ | | - | `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | - | `format` | Format of the data file(s) (CSV or JSON) | - | `sssom_config` | Configures usage of SSSOM mapping files | - | `depends_on` | List of map config files to use | - | `metadata` | Metadata for the source | - | `transform_code` | Path to a python file to transform the data | - | `transform_mode` | How to process the transform file | - | `global_table` | Path to a global translation table file | - | `local_table` | Path to a local translation table file | - | `filters` | List of filters to apply | - | `json_path` | Path within JSON object containing data to process | - | `required_properties` | List of properties that must be present in output (JSON only) | - ||| - | __Optional CSV Specific Properties__ | | - | `columns` | List of columns to include in output (CSV only) | - | `delimiter` | Delimiter for csv files | - | `header` | Header row index for csv files | - | `header_delimiter` | Delimiter for header in csv files | - | `header_prefix` | Prefix for header in csv files | - | `comment_char` | Comment character for csv files | - | `skip_blank_lines` | Skip blank lines in csv files | - - - ### Composing Configuration from Multiple Yaml Files - - The Koza yaml loader supports importing/including other yaml files with an `!include` tag. - - For example, if you had a file named `standard-columns.yaml`: - ```yaml - - 'column_1' - - 'column_2' - - 'column_3' - - 'column_4' : 'int' - ``` - - Then in any ingests you wish to use these columns, you can simply `!include` them: - ```yaml - columns: !include './path/to/standard-columns.yaml' - ``` - -!!! list "" - ## 2. Mapping and Additional Data - - Mapping with Koza can be done in two ways: - - - Automated mapping with SSSOM files - - Manual mapping with a map config yaml - - ### SSSOM Mapping - - Koza supports mapping with SSSOM files (Semantic Similarity of Source and Target Ontology Mappings). - Simply add the path to the SSSOM file to your source config, the desired target prefixes, - and any prefixes you want to use to filter the SSSOM file. - Koza will automatically create a mapping lookup table which will automatically - attempt to map any values in the source file to an ID with the target prefix. - - ```yaml - sssom_config: - sssom_file: './path/to/your_mapping_file.sssom.tsv' - filter_prefixes: - - 'SOMEPREFIX' - - 'OTHERPREFIX' - target_prefixes: - - 'OTHERPREFIX' - use_match: - - 'exact' - ``` - - **Note:** Currently, only the `exact` match type is supported (`narrow` and `broad` match types will be added in the future). - - ### Manual Mapping / Additional Data - - The map config yaml allows you to include data from other sources in your ingests, - which may have different columns or formats. - - If you don't have an SSSOM file, or you want to manually map some values, you can use a map config yaml. - You can then add this map to your source config yaml in the `depends_on` property. - - Koza will then create a nested dictionary with the specified key and values. - For example, the following map config yaml maps values from the `STRING` column to the `entrez` and `NCBI taxid` columns. - - ```yaml - # koza/examples/maps/entrez-2-string.yaml - name: ... - files: ... - - columns: - - 'NCBI taxid' - - 'entrez' - - 'STRING' - - key: 'STRING' - - values: - - 'entrez' - - 'NCBI taxid' - ``` - - - The mapping dict will be available in your transform script from the `koza_app` object (see the Transform Code section below). - - -!!! list "" - ## 3. Transform Code - - This Python script is where you'll define the specific steps of your data transformation. - Koza will load this script and execute it for each row of data in your source file, - applying any filters and mapping as defined in your source config yaml, - and outputting the transformed data to the target csv/json/jsonl file. - - When Koza is called, either by command-line or as a library using `transform_source()`, - it creates a `KozaApp` object for the specified ingest. - This KozaApp will be your entry point to Koza: - - ```python - from koza.cli_runner import get_koza_app - koza_app = get_koza_app('your-source-name') - ``` - - The KozaApp object has the following methods: - - | Method | Description | - | --- | --- | - | `get_row()` | Returns the next row of data from the source file | - | `get_map(map_name)` | Returns the mapping dict for the specified map | - | `get_global_table()` | Returns the global translation table | - | `get_local_table()` | Returns the local translation table | - - ??? tldr "Example Python Transform Script" - - ```python - # other imports, eg. uuid, pydantic, etc. - import uuid - from biolink.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction - - # Koza imports - from koza.cli_runner import get_koza_app - - # This is the name of the ingest you want to run - source_name = 'map-protein-links-detailed' - koza_app = get_koza_app(source_name) - - # If your ingest depends_on a mapping file, you can access it like this: - map_name = 'entrez-2-string' - koza_map = koza_app.get_map(map_name) - - # This grabs the first/next row from the source data - # Koza will reload this script and return the next row until it reaches EOF or row-limit - row = koza_app.get_row() - - # Now you can lay out your actual transformations, and define your output: - - gene_a = Gene(id='NCBIGene:' + koza_map[row['protein1']]['entrez']) - gene_b = Gene(id='NCBIGene:' + koza_map[row['protein2']]['entrez']) - - pairwise_gene_to_gene_interaction = PairwiseGeneToGeneInteraction( - id="uuid:" + str(uuid.uuid1()), - subject=gene_a.id, - object=gene_b.id, - predicate="biolink:interacts_with" - ) - - # Finally, write the transformed row to the target file - koza_app.write(gene_a, gene_b, pairwise_gene_to_gene_interaction) - ``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 19c6ab8..ba7844c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,6 @@ -# Koza - a data transformation framework +# Koza + +### A data transformation framework in Python ## Overview @@ -19,7 +21,7 @@ pip install koza ## Usage -See the [Ingests](./Usage/ingests.md) page for information on how to configure ingests for koza to use. +See the [Ingests](./Ingests/index.md) page for information on how to configure ingests for koza to use. Koza can be used as a Python library, or via the command line. [CLI commands](./Usage/CLI.md) are available for validating and transforming data. @@ -63,7 +65,8 @@ Koza also includes some examples to help you get started (see `koza/examples`). **Note**: Koza expects a directory structure as described in the above example - with the source config file and transform code in the same directory: + with the source config file and transform code in the same directory + (these files can also simply be named `transform.yaml` and `transform.py`, as is default): ``` . ├── ... diff --git a/mkdocs.yaml b/mkdocs.yaml index 69f0493..c751d0e 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -7,7 +7,11 @@ repo_url: 'https://github.com/monarch-initiative/koza' nav: - Welcome: 'index.md' - - Ingests: 'Usage/ingests.md' + - Ingests: + - Configuring an Ingest: 'Ingests/index.md' + - Source Config: 'Ingests/source_config.md' + - Mapping: 'Ingests/mapping.md' + - Transform Code: 'Ingests/transform.md' - CLI: 'Usage/CLI.md' - API: 'Usage/API.md' From 8bfd87fcebe8be3b286d4397e25e8e5c5197b3ce Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 22 Apr 2024 17:13:58 -0600 Subject: [PATCH 03/30] update docs, examples/tests, and biolink and typer versions --- docs/Ingests/source_config.md | 28 +- docs/Ingests/transform.md | 32 +- docs/Usage/{API.md => Module.md} | 0 .../declarative-protein-links-detailed.py | 10 +- .../custom-map-protein-links-detailed.py | 17 +- .../map-protein-links-detailed.py | 17 +- examples/string/protein-links-detailed.py | 4 +- mkdocs.yaml | 2 +- poetry.lock | 850 +++++++++--------- pyproject.toml | 5 +- src/koza/app.py | 6 +- src/koza/converter/biolink_converter.py | 2 +- src/koza/io/writer/tsv_writer.py | 14 +- src/koza/model/config/source_config.py | 24 +- tests/unit/test_kgx_converter.py | 4 +- tests/unit/test_tsvwriter_node_and_edge.py | 20 +- tests/unit/test_tsvwriter_node_only.py | 2 +- 17 files changed, 529 insertions(+), 508 deletions(-) rename docs/Usage/{API.md => Module.md} (100%) diff --git a/docs/Ingests/source_config.md b/docs/Ingests/source_config.md index 999070a..4958dc0 100644 --- a/docs/Ingests/source_config.md +++ b/docs/Ingests/source_config.md @@ -6,7 +6,7 @@ This YAML file sets properties for the ingest of a single file type from a withi | **Required properties** | | | ------------------------------------ | --------------------------------------------------------------------------------------------------- | -| `name` | Name of the source | +| `name` | Name of the data ingest, as `_`,
ex. `hpoa_gene_to_disease` | | `files` | List of files to process | | | | | **Optional properties** | | @@ -24,7 +24,7 @@ This YAML file sets properties for the ingest of a single file type from a withi | `json_path` | Path within JSON object containing data to process | | `required_properties` | List of properties that must be present in output (JSON only) | | | | -| **Optional CSV Specific Properties** | | +| **Optional CSV-Specific Properties** | | | `columns` | List of columns to include in output (CSV only) | | `delimiter` | Delimiter for csv files | | `header` | Header row index for csv files | @@ -35,22 +35,22 @@ This YAML file sets properties for the ingest of a single file type from a withi ## Metadata Properties -Metadata is optional, and can be defined as a list of properties and values, or as a path to a `metadata.yaml` file, +Metadata is optional, and can be defined as a list of properties and values, or as a path to a `metadata.yaml` file, for example - `metadata: "./path/to/metadata.yaml"`. Remember that the path is relative to the directory from which you execute Koza. -| **Metadata Properties** | | -| ----------------------- | -------------------------------------------- | -| id | TBD | -| name | If empty, uses source name | -| ingest_title | Title of source of data, map to biolink name | -| ingest_url | URL to source of data, Maps to biolink iri | -| description | Description of ingest | -| source | Source of data being transformed | -| provided_by | TBD | -| rights | TBD | +| **Metadata Properties** | | +| ----------------------- | ---------------------------------------------------------------------------------------- | +| name | Name of data source, ex. "FlyBase" | +| description | Description of data/ingest | +| ingest_title | \*Title of source of data, map to biolink name | +| ingest_url | \*URL to source of data, Maps to biolink iri | +| provided_by | `_`, ex. `hpoa_gene_to_disease` (see config propery "name") | +| rights | Link to license information for the data source | -### Composing Configuration from Multiple Yaml Files +**\*Note**: For more information on `ingest_title` and `ingest_url`, see the [infores catalog](https://biolink.github.io/information-resource-registry/infores_catalog.yaml) + +## Composing Configuration from Multiple Yaml Files Koza's custom YAML Loader supports importing/including other yaml files with an `!include` tag. diff --git a/docs/Ingests/transform.md b/docs/Ingests/transform.md index ede359f..c8d6ece 100644 --- a/docs/Ingests/transform.md +++ b/docs/Ingests/transform.md @@ -1,4 +1,4 @@ -This Python script is where you'll define the specific steps of your data transformation. +This Python script is where you'll define the specific steps of your data transformation. Koza will load this script and execute it for each row of data in your source file, applying any filters and mapping as defined in your source config yaml, and outputting the transformed data to the target csv/json/jsonl file. @@ -12,29 +12,34 @@ from koza.cli_runner import get_koza_app koza_app = get_koza_app('your-source-name') ``` -The KozaApp object has the following methods: +The KozaApp object has the following methods which can be used in your transform code: -| Method | Description | -| --- | --- | -| `get_row()` | Returns the next row of data from the source file | -| `get_map(map_name)` | Returns the mapping dict for the specified map | -| `get_global_table()` | Returns the global translation table | -| `get_local_table()` | Returns the local translation table | +| Method | Description | +| ------------------- | ------------------------------------------------- | +| `get_row()` | Returns the next row of data from the source file | +| `next_row()` | Skip to the next row in the data file | +| `get_map(map_name)` | Returns the mapping dict for the specified map | +| `process_sources()` | TBD | +| `process_maps()` | Initializes the KozaApp's map cache | +| `write(*args)` | Writes the transformed data to the target file | + +Once you have processed a row of data, and created a biolink entity node or edge object (or both), +you can pass these to `koza_app.write()` to output the transformed data to the target file. ??? tldr "Example Python Transform Script" ```python # other imports, eg. uuid, pydantic, etc. import uuid - from biolink.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction - + from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction + # Koza imports from koza.cli_runner import get_koza_app # This is the name of the ingest you want to run source_name = 'map-protein-links-detailed' koza_app = get_koza_app(source_name) - + # If your ingest depends_on a mapping file, you can access it like this: map_name = 'entrez-2-string' koza_map = koza_app.get_map(map_name) @@ -56,4 +61,7 @@ The KozaApp object has the following methods: # Finally, write the transformed row to the target file koza_app.write(gene_a, gene_b, pairwise_gene_to_gene_interaction) - ``` \ No newline at end of file + ``` + + If you pass nodes, as well as edges, to `koza_app.write()`, Koza will automatically create a node file and an edge file. + If you pass only nodes, Koza will create only a node file, and if you pass only edges, Koza will create only an edge file. diff --git a/docs/Usage/API.md b/docs/Usage/Module.md similarity index 100% rename from docs/Usage/API.md rename to docs/Usage/Module.md diff --git a/examples/string-declarative/declarative-protein-links-detailed.py b/examples/string-declarative/declarative-protein-links-detailed.py index f5b48b3..a3e52f6 100644 --- a/examples/string-declarative/declarative-protein-links-detailed.py +++ b/examples/string-declarative/declarative-protein-links-detailed.py @@ -1,22 +1,24 @@ import re import uuid -from biolink.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein +from biolink_model.datamodel.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein from koza.cli_runner import get_koza_app -koza_app = get_koza_app('declarative-protein-links-detailed') +koza_app = get_koza_app("declarative-protein-links-detailed") row = koza_app.get_row() -protein_a = Protein(id='ENSEMBL:' + re.sub(r'\d+\.', '', row['protein1'])) -protein_b = Protein(id='ENSEMBL:' + re.sub(r'\d+\.', '', row['protein2'])) +protein_a = Protein(id="ENSEMBL:" + re.sub(r"\d+\.", "", row["protein1"])) +protein_b = Protein(id="ENSEMBL:" + re.sub(r"\d+\.", "", row["protein2"])) pairwise_gene_to_gene_interaction = PairwiseGeneToGeneInteraction( id="uuid:" + str(uuid.uuid1()), subject=protein_a.id, object=protein_b.id, predicate="biolink:interacts_with", + knowledge_level="not_provided", + agent_type="not_provided", ) koza_app.write(protein_a, protein_b, pairwise_gene_to_gene_interaction) diff --git a/examples/string-w-custom-map/custom-map-protein-links-detailed.py b/examples/string-w-custom-map/custom-map-protein-links-detailed.py index ec8da60..30af763 100644 --- a/examples/string-w-custom-map/custom-map-protein-links-detailed.py +++ b/examples/string-w-custom-map/custom-map-protein-links-detailed.py @@ -1,19 +1,24 @@ import uuid -from biolink.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction +from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction from koza.cli_runner import get_koza_app -source_name = 'custom-map-protein-links-detailed' +source_name = "custom-map-protein-links-detailed" koza_app = get_koza_app(source_name) row = koza_app.get_row() -entrez_2_string = koza_app.get_map('custom-entrez-2-string') +entrez_2_string = koza_app.get_map("custom-entrez-2-string") -gene_a = Gene(id='NCBIGene:' + entrez_2_string[row['protein1']]['entrez']) -gene_b = Gene(id='NCBIGene:' + entrez_2_string[row['protein2']]['entrez']) +gene_a = Gene(id="NCBIGene:" + entrez_2_string[row["protein1"]]["entrez"]) +gene_b = Gene(id="NCBIGene:" + entrez_2_string[row["protein2"]]["entrez"]) pairwise_gene_to_gene_interaction = PairwiseGeneToGeneInteraction( - id="uuid:" + str(uuid.uuid1()), subject=gene_a.id, object=gene_b.id, predicate="biolink:interacts_with" + id="uuid:" + str(uuid.uuid1()), + subject=gene_a.id, + object=gene_b.id, + predicate="biolink:interacts_with", + knowledge_level="not_provided", + agent_type="not_provided", ) koza_app.write(gene_a, gene_b, pairwise_gene_to_gene_interaction) diff --git a/examples/string-w-map/map-protein-links-detailed.py b/examples/string-w-map/map-protein-links-detailed.py index ffd1f6f..0ad4ee6 100644 --- a/examples/string-w-map/map-protein-links-detailed.py +++ b/examples/string-w-map/map-protein-links-detailed.py @@ -1,11 +1,11 @@ import uuid -from biolink.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction +from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction from koza.cli_runner import get_koza_app -source_name = 'map-protein-links-detailed' -map_name = 'entrez-2-string' +source_name = "map-protein-links-detailed" +map_name = "entrez-2-string" koza_app = get_koza_app(source_name) row = koza_app.get_row() @@ -15,11 +15,16 @@ logger.info(koza_map) -gene_a = Gene(id='NCBIGene:' + koza_map[row['protein1']]['entrez']) -gene_b = Gene(id='NCBIGene:' + koza_map[row['protein2']]['entrez']) +gene_a = Gene(id="NCBIGene:" + koza_map[row["protein1"]]["entrez"]) +gene_b = Gene(id="NCBIGene:" + koza_map[row["protein2"]]["entrez"]) pairwise_gene_to_gene_interaction = PairwiseGeneToGeneInteraction( - id="uuid:" + str(uuid.uuid1()), subject=gene_a.id, object=gene_b.id, predicate="biolink:interacts_with" + id="uuid:" + str(uuid.uuid1()), + subject=gene_a.id, + object=gene_b.id, + predicate="biolink:interacts_with", + knowledge_level="not_provided", + agent_type="not_provided", ) koza_app.write(gene_a, gene_b, pairwise_gene_to_gene_interaction) diff --git a/examples/string/protein-links-detailed.py b/examples/string/protein-links-detailed.py index b7e526f..1cf6778 100644 --- a/examples/string/protein-links-detailed.py +++ b/examples/string/protein-links-detailed.py @@ -1,7 +1,7 @@ import re import uuid -from biolink.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein +from biolink_model.datamodel.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein from koza.cli_runner import get_koza_app @@ -16,6 +16,8 @@ subject=protein_a.id, object=protein_b.id, predicate="biolink:interacts_with", + knowledge_level="not_provided", + agent_type="not_provided", ) koza_app.write(protein_a, protein_b, pairwise_gene_to_gene_interaction) diff --git a/mkdocs.yaml b/mkdocs.yaml index c751d0e..d6bfce2 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -13,7 +13,7 @@ nav: - Mapping: 'Ingests/mapping.md' - Transform Code: 'Ingests/transform.md' - CLI: 'Usage/CLI.md' - - API: 'Usage/API.md' + - Module: 'Usage/Module.md' theme: diff --git a/poetry.lock b/poetry.lock index c632737..5fdeff7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -96,19 +96,23 @@ lxml = ["lxml"] [[package]] name = "biolink-model" -version = "3.6.0" -description = "'A high level datamodel of biological entities and associations'" +version = "4.2.0" +description = "The Biolink Model is a high-level data model designed to standardize types and relationships in biological knowledgebases." optional = false -python-versions = ">=3.9" +python-versions = "<4.0,>=3.9" files = [ - {file = "biolink-model-3.6.0.tar.gz", hash = "sha256:8fd3dc3d3364fa9714775e73857aff97cc72a3809ecd2916826d6c39c5a70ee4"}, - {file = "biolink_model-3.6.0-py3-none-any.whl", hash = "sha256:78cc0827bb6657ea4712d5be439dddd4307daddb51d38b03e6b53f884417d60f"}, + {file = "biolink_model-4.2.0-py3-none-any.whl", hash = "sha256:de9af717285a5faf798c53c570e58b000e36c480d25584bdd79944a2ccefb929"}, + {file = "biolink_model-4.2.0.tar.gz", hash = "sha256:e11ff4678173d6a5d4a75e18bbb6d7474654226698de1a155be35443a48c35a1"}, ] [package.dependencies] -curies = "*" -linkml = "*" -prefixmaps = "*" +beautifulsoup4 = ">=4.0.0" +curies = ">=0.7.4,<0.8.0" +prefixmaps = ">=0.2.3,<0.3.0" +pytest = ">=8.1.1,<9.0.0" +pyyaml = ">=6.0.1,<7.0.0" +stringcase = ">=1.2.0,<2.0.0" +yamllint = ">=1.35.1,<2.0.0" [[package]] name = "black" @@ -328,13 +332,13 @@ files = [ [[package]] name = "curies" -version = "0.7.8" +version = "0.7.9" description = "Idiomatic conversion between URIs and compact URIs (CURIEs)." optional = false python-versions = ">=3.8" files = [ - {file = "curies-0.7.8-py3-none-any.whl", hash = "sha256:a60b2559f08557176b0a3df1f7c47ec7cd8ae4e0695f23fc6574825d2ccd17eb"}, - {file = "curies-0.7.8.tar.gz", hash = "sha256:d208ad40b5e40b532285c917f116001f9e887a48dda54e6eedd10e514ea6aa1a"}, + {file = "curies-0.7.9-py3-none-any.whl", hash = "sha256:e4c5beb91642376953c94db0ee2fb5d2b011c3b16749516436114ba61442f260"}, + {file = "curies-0.7.9.tar.gz", hash = "sha256:3b63c5fea7b0e967629a3a384b1a8c59b56c503487c1dcbacddeab59e25db4d8"}, ] [package.dependencies] @@ -352,13 +356,13 @@ tests = ["coverage", "pytest"] [[package]] name = "dask" -version = "2024.3.1" +version = "2024.4.2" description = "Parallel PyData with Task Scheduling" optional = false python-versions = ">=3.9" files = [ - {file = "dask-2024.3.1-py3-none-any.whl", hash = "sha256:1ac260b8716b1a9fc144c0d7f958336812cfc3ef542a3742c9ae02387189b32b"}, - {file = "dask-2024.3.1.tar.gz", hash = "sha256:78bee2ffd735514e572adaa669fc2a437ec256aecb6bec036a1f5b8dd36b2e60"}, + {file = "dask-2024.4.2-py3-none-any.whl", hash = "sha256:56fbe92472e3b323ab7beaf2dc8437d48066ac21aa9c2c17ac40d2b6f7b4c414"}, + {file = "dask-2024.4.2.tar.gz", hash = "sha256:3d7a516468d96e72581b84c7bb00172366f30d24c689ea4e9bd1334ab6d98f8a"}, ] [package.dependencies] @@ -376,7 +380,7 @@ array = ["numpy (>=1.21)"] complete = ["dask[array,dataframe,diagnostics,distributed]", "lz4 (>=4.3.2)", "pyarrow (>=7.0)", "pyarrow-hotfix"] dataframe = ["dask-expr (>=1.0,<1.1)", "dask[array]", "pandas (>=1.3)"] diagnostics = ["bokeh (>=2.4.2)", "jinja2 (>=2.10.3)"] -distributed = ["distributed (==2024.3.1)"] +distributed = ["distributed (==2024.4.2)"] test = ["pandas[test]", "pre-commit", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-timeout", "pytest-xdist"] [[package]] @@ -410,16 +414,6 @@ files = [ [package.dependencies] packaging = "*" -[[package]] -name = "editorconfig" -version = "0.12.4" -description = "EditorConfig File Locator and Interpreter for Python" -optional = false -python-versions = "*" -files = [ - {file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"}, -] - [[package]] name = "et-xmlfile" version = "1.1.0" @@ -433,13 +427,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -597,13 +591,13 @@ test = ["objgraph", "psutil"] [[package]] name = "griffe" -version = "0.42.1" +version = "0.44.0" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." optional = false python-versions = ">=3.8" files = [ - {file = "griffe-0.42.1-py3-none-any.whl", hash = "sha256:7e805e35617601355edcac0d3511cedc1ed0cb1f7645e2d336ae4b05bbae7b3b"}, - {file = "griffe-0.42.1.tar.gz", hash = "sha256:57046131384043ed078692b85d86b76568a686266cc036b9b56b704466f803ce"}, + {file = "griffe-0.44.0-py3-none-any.whl", hash = "sha256:8a4471c469ba980b87c843f1168850ce39d0c1d0c7be140dca2480f76c8e5446"}, + {file = "griffe-0.44.0.tar.gz", hash = "sha256:34aee1571042f9bf00529bc715de4516fb6f482b164e90d030300601009e0223"}, ] [package.dependencies] @@ -622,13 +616,13 @@ files = [ [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -724,20 +718,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jsbeautifier" -version = "1.15.1" -description = "JavaScript unobfuscator and beautifier." -optional = false -python-versions = "*" -files = [ - {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"}, -] - -[package.dependencies] -editorconfig = ">=0.12.2" -six = ">=1.13.0" - [[package]] name = "json-flattener" version = "0.1.9" @@ -862,13 +842,13 @@ referencing = ">=0.31.0" [[package]] name = "linkml" -version = "1.7.7" +version = "1.7.8" description = "Linked Open Data Modeling Language" optional = false python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "linkml-1.7.7-py3-none-any.whl", hash = "sha256:3f17bcaf77458dd2aaecd4c7f9a6545e8422aa3260513868f395b4f3d4b36571"}, - {file = "linkml-1.7.7.tar.gz", hash = "sha256:d89c6b793dba01bb2e53e4929fab70c4b2d498d7b2141f7f1985f8cf9f570537"}, + {file = "linkml-1.7.8-py3-none-any.whl", hash = "sha256:4b8ebe33b422517b08ca01802dc2899ac133c502a71d811c58fa6f4263130709"}, + {file = "linkml-1.7.8.tar.gz", hash = "sha256:af48ee1ad6751c8d20de2832dbeefe225da9be5f39a7f8ea7821a691cf7c0148"}, ] [package.dependencies] @@ -922,13 +902,13 @@ linkml-runtime = ">=1.1.6" [[package]] name = "linkml-runtime" -version = "1.7.4" +version = "1.7.5" description = "Runtime environment for LinkML, the Linked open data modeling language" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "linkml_runtime-1.7.4-py3-none-any.whl", hash = "sha256:6808e752a95b709b0fbc66841df7707bb0011b09286fe71b4169d4b885ee27a7"}, - {file = "linkml_runtime-1.7.4.tar.gz", hash = "sha256:b5578c3b82b08d50d45f4a6b858004839dbb5c81150f9057a54e79ef78f3d04e"}, + {file = "linkml_runtime-1.7.5-py3-none-any.whl", hash = "sha256:c58000c7c68fa97b7d76c50421a85a64e25f07eec5bcac464bc00c4cd79007a6"}, + {file = "linkml_runtime-1.7.5.tar.gz", hash = "sha256:b31197a5398359441ae1ed43470c54377a1d08db961366dda670300dddcd71d7"}, ] [package.dependencies] @@ -993,6 +973,30 @@ importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.5" @@ -1062,6 +1066,17 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mergedeep" version = "1.3.4" @@ -1122,13 +1137,13 @@ mkdocs = ">=1.1" [[package]] name = "mkdocs-material" -version = "9.5.15" +version = "9.5.18" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.15-py3-none-any.whl", hash = "sha256:e5c96dec3d19491de49ca643fc1dbb92b278e43cdb816c775bc47db77d9b62fb"}, - {file = "mkdocs_material-9.5.15.tar.gz", hash = "sha256:39f03cca45e82bf54eb7456b5a18bd252eabfdd67f237a229471484a0a4d4635"}, + {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, + {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, ] [package.dependencies] @@ -1160,36 +1175,15 @@ files = [ {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] -[[package]] -name = "mkdocs-mermaid2-plugin" -version = "0.6.0" -description = "A MkDocs plugin for including mermaid graphs in markdown sources" -optional = false -python-versions = ">=3.5" -files = [ - {file = "mkdocs-mermaid2-plugin-0.6.0.tar.gz", hash = "sha256:99cca6db7c6b4a954a701dcb6b507191bc32a7b0b47eacf2885c1bacf77d1af1"}, - {file = "mkdocs_mermaid2_plugin-0.6.0-py3-none-any.whl", hash = "sha256:ffbe8a7daa7ed718cb800c44c5ce4c0ff413caebf7b8b63d9c4a998dfd78a64d"}, -] - -[package.dependencies] -beautifulsoup4 = ">=4.6.3" -jsbeautifier = "*" -mkdocs = ">=1.0.4" -mkdocs-material = "*" -pymdown-extensions = ">=8.0" -pyyaml = "*" -requests = "*" -setuptools = ">=18.5" - [[package]] name = "mkdocstrings" -version = "0.24.1" +version = "0.24.3" description = "Automatic documentation from sources, for MkDocs." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocstrings-0.24.1-py3-none-any.whl", hash = "sha256:b4206f9a2ca8a648e222d5a0ca1d36ba7dee53c88732818de183b536f9042b5d"}, - {file = "mkdocstrings-0.24.1.tar.gz", hash = "sha256:cc83f9a1c8724fc1be3c2fa071dd73d91ce902ef6a79710249ec8d0ee1064401"}, + {file = "mkdocstrings-0.24.3-py3-none-any.whl", hash = "sha256:5c9cf2a32958cd161d5428699b79c8b0988856b0d4a8c5baf8395fc1bf4087c3"}, + {file = "mkdocstrings-0.24.3.tar.gz", hash = "sha256:f327b234eb8d2551a306735436e157d0a22d45f79963c60a8b585d5f7a94c1d2"}, ] [package.dependencies] @@ -1212,18 +1206,18 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] [[package]] name = "mkdocstrings-python" -version = "1.8.0" +version = "1.10.0" description = "A Python handler for mkdocstrings." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocstrings_python-1.8.0-py3-none-any.whl", hash = "sha256:4209970cc90bec194568682a535848a8d8489516c6ed4adbe58bbc67b699ca9d"}, - {file = "mkdocstrings_python-1.8.0.tar.gz", hash = "sha256:1488bddf50ee42c07d9a488dddc197f8e8999c2899687043ec5dd1643d057192"}, + {file = "mkdocstrings_python-1.10.0-py3-none-any.whl", hash = "sha256:ba833fbd9d178a4b9d5cb2553a4df06e51dc1f51e41559a4d2398c16a6f69ecc"}, + {file = "mkdocstrings_python-1.10.0.tar.gz", hash = "sha256:71678fac657d4d2bb301eed4e4d2d91499c095fd1f8a90fa76422a87a5693828"}, ] [package.dependencies] -griffe = ">=0.37" -mkdocstrings = ">=0.20" +griffe = ">=0.44" +mkdocstrings = ">=0.24.2" [[package]] name = "mypy-extensions" @@ -1350,47 +1344,47 @@ files = [ [[package]] name = "pandas" -version = "2.2.1" +version = "2.2.2" description = "Powerful data structures for data analysis, time series, and statistics" optional = false python-versions = ">=3.9" files = [ - {file = "pandas-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8df8612be9cd1c7797c93e1c5df861b2ddda0b48b08f2c3eaa0702cf88fb5f88"}, - {file = "pandas-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0f573ab277252ed9aaf38240f3b54cfc90fff8e5cab70411ee1d03f5d51f3944"}, - {file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f02a3a6c83df4026e55b63c1f06476c9aa3ed6af3d89b4f04ea656ccdaaaa359"}, - {file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c38ce92cb22a4bea4e3929429aa1067a454dcc9c335799af93ba9be21b6beb51"}, - {file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c2ce852e1cf2509a69e98358e8458775f89599566ac3775e70419b98615f4b06"}, - {file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53680dc9b2519cbf609c62db3ed7c0b499077c7fefda564e330286e619ff0dd9"}, - {file = "pandas-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:94e714a1cca63e4f5939cdce5f29ba8d415d85166be3441165edd427dc9f6bc0"}, - {file = "pandas-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f821213d48f4ab353d20ebc24e4faf94ba40d76680642fb7ce2ea31a3ad94f9b"}, - {file = "pandas-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70e00c2d894cb230e5c15e4b1e1e6b2b478e09cf27cc593a11ef955b9ecc81a"}, - {file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97fbb5387c69209f134893abc788a6486dbf2f9e511070ca05eed4b930b1b02"}, - {file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101d0eb9c5361aa0146f500773395a03839a5e6ecde4d4b6ced88b7e5a1a6403"}, - {file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7d2ed41c319c9fb4fd454fe25372028dfa417aacb9790f68171b2e3f06eae8cd"}, - {file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af5d3c00557d657c8773ef9ee702c61dd13b9d7426794c9dfeb1dc4a0bf0ebc7"}, - {file = "pandas-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:06cf591dbaefb6da9de8472535b185cba556d0ce2e6ed28e21d919704fef1a9e"}, - {file = "pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:88ecb5c01bb9ca927ebc4098136038519aa5d66b44671861ffab754cae75102c"}, - {file = "pandas-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:04f6ec3baec203c13e3f8b139fb0f9f86cd8c0b94603ae3ae8ce9a422e9f5bee"}, - {file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a935a90a76c44fe170d01e90a3594beef9e9a6220021acfb26053d01426f7dc2"}, - {file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c391f594aae2fd9f679d419e9a4d5ba4bce5bb13f6a989195656e7dc4b95c8f0"}, - {file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9d1265545f579edf3f8f0cb6f89f234f5e44ba725a34d86535b1a1d38decbccc"}, - {file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11940e9e3056576ac3244baef2fedade891977bcc1cb7e5cc8f8cc7d603edc89"}, - {file = "pandas-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4acf681325ee1c7f950d058b05a820441075b0dd9a2adf5c4835b9bc056bf4fb"}, - {file = "pandas-2.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9bd8a40f47080825af4317d0340c656744f2bfdb6819f818e6ba3cd24c0e1397"}, - {file = "pandas-2.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df0c37ebd19e11d089ceba66eba59a168242fc6b7155cba4ffffa6eccdfb8f16"}, - {file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:739cc70eaf17d57608639e74d63387b0d8594ce02f69e7a0b046f117974b3019"}, - {file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d3558d263073ed95e46f4650becff0c5e1ffe0fc3a015de3c79283dfbdb3df"}, - {file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4aa1d8707812a658debf03824016bf5ea0d516afdea29b7dc14cf687bc4d4ec6"}, - {file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:76f27a809cda87e07f192f001d11adc2b930e93a2b0c4a236fde5429527423be"}, - {file = "pandas-2.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:1ba21b1d5c0e43416218db63037dbe1a01fc101dc6e6024bcad08123e48004ab"}, - {file = "pandas-2.2.1.tar.gz", hash = "sha256:0ab90f87093c13f3e8fa45b48ba9f39181046e8f3317d3aadb2fffbb1b978572"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, ] [package.dependencies] numpy = [ - {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -1494,13 +1488,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest- [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -1537,13 +1531,13 @@ requests = ">=2.28.1,<3.0.0" [[package]] name = "prefixmaps" -version = "0.2.2" +version = "0.2.4" description = "A python library for retrieving semantic prefix maps" optional = false -python-versions = ">=3.8,<4.0" +python-versions = "<4.0,>=3.8" files = [ - {file = "prefixmaps-0.2.2-py3-none-any.whl", hash = "sha256:4ac2bf3ddb9b27c40c978cf937e9bedb160050d24e8c679b94c9c885e1d73c72"}, - {file = "prefixmaps-0.2.2.tar.gz", hash = "sha256:a36b1554154ef465271bde82dc91cd671e2d31dc1f50c2fd08ccb0d7d5791c33"}, + {file = "prefixmaps-0.2.4-py3-none-any.whl", hash = "sha256:89bf0e6fb08c276f754f9624c42adf2e87c64ee92a3dde1f7eff01f22d85b512"}, + {file = "prefixmaps-0.2.4.tar.gz", hash = "sha256:ae86a1b31189d0516d199756d5808f75f44b39e86546c356cc78c0fe8d2078af"}, ] [package.dependencies] @@ -1552,18 +1546,18 @@ pyyaml = ">=5.3.1" [[package]] name = "pydantic" -version = "2.6.4" +version = "2.7.0" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"}, - {file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"}, + {file = "pydantic-2.7.0-py3-none-any.whl", hash = "sha256:9dee74a271705f14f9a1567671d144a851c675b072736f0a7b2608fd9e495352"}, + {file = "pydantic-2.7.0.tar.gz", hash = "sha256:b5ecdd42262ca2462e2624793551e80911a1e989f462910bb81aef974b4bb383"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.16.3" +pydantic-core = "2.18.1" typing-extensions = ">=4.6.1" [package.extras] @@ -1571,90 +1565,90 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.16.3" -description = "" +version = "2.18.1" +description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, - {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, - {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, - {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, - {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, - {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, - {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, - {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, - {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, - {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, - {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, - {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, - {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, - {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, - {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, - {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, - {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, - {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, - {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, - {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, - {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, - {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, - {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, - {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, - {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, - {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, - {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, - {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, - {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, - {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, - {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, - {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, - {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, - {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, - {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, - {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, - {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, - {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, - {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, - {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, + {file = "pydantic_core-2.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ee9cf33e7fe14243f5ca6977658eb7d1042caaa66847daacbd2117adb258b226"}, + {file = "pydantic_core-2.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6b7bbb97d82659ac8b37450c60ff2e9f97e4eb0f8a8a3645a5568b9334b08b50"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df4249b579e75094f7e9bb4bd28231acf55e308bf686b952f43100a5a0be394c"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d0491006a6ad20507aec2be72e7831a42efc93193d2402018007ff827dc62926"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ae80f72bb7a3e397ab37b53a2b49c62cc5496412e71bc4f1277620a7ce3f52b"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58aca931bef83217fca7a390e0486ae327c4af9c3e941adb75f8772f8eeb03a1"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1be91ad664fc9245404a789d60cba1e91c26b1454ba136d2a1bf0c2ac0c0505a"}, + {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:667880321e916a8920ef49f5d50e7983792cf59f3b6079f3c9dac2b88a311d17"}, + {file = "pydantic_core-2.18.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f7054fdc556f5421f01e39cbb767d5ec5c1139ea98c3e5b350e02e62201740c7"}, + {file = "pydantic_core-2.18.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:030e4f9516f9947f38179249778709a460a3adb516bf39b5eb9066fcfe43d0e6"}, + {file = "pydantic_core-2.18.1-cp310-none-win32.whl", hash = "sha256:2e91711e36e229978d92642bfc3546333a9127ecebb3f2761372e096395fc649"}, + {file = "pydantic_core-2.18.1-cp310-none-win_amd64.whl", hash = "sha256:9a29726f91c6cb390b3c2338f0df5cd3e216ad7a938762d11c994bb37552edb0"}, + {file = "pydantic_core-2.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9ece8a49696669d483d206b4474c367852c44815fca23ac4e48b72b339807f80"}, + {file = "pydantic_core-2.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a5d83efc109ceddb99abd2c1316298ced2adb4570410defe766851a804fcd5b"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7973c381283783cd1043a8c8f61ea5ce7a3a58b0369f0ee0ee975eaf2f2a1b"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:54c7375c62190a7845091f521add19b0f026bcf6ae674bdb89f296972272e86d"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd63cec4e26e790b70544ae5cc48d11b515b09e05fdd5eff12e3195f54b8a586"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:561cf62c8a3498406495cfc49eee086ed2bb186d08bcc65812b75fda42c38294"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68717c38a68e37af87c4da20e08f3e27d7e4212e99e96c3d875fbf3f4812abfc"}, + {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d5728e93d28a3c63ee513d9ffbac9c5989de8c76e049dbcb5bfe4b923a9739d"}, + {file = "pydantic_core-2.18.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f0f17814c505f07806e22b28856c59ac80cee7dd0fbb152aed273e116378f519"}, + {file = "pydantic_core-2.18.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d816f44a51ba5175394bc6c7879ca0bd2be560b2c9e9f3411ef3a4cbe644c2e9"}, + {file = "pydantic_core-2.18.1-cp311-none-win32.whl", hash = "sha256:09f03dfc0ef8c22622eaa8608caa4a1e189cfb83ce847045eca34f690895eccb"}, + {file = "pydantic_core-2.18.1-cp311-none-win_amd64.whl", hash = "sha256:27f1009dc292f3b7ca77feb3571c537276b9aad5dd4efb471ac88a8bd09024e9"}, + {file = "pydantic_core-2.18.1-cp311-none-win_arm64.whl", hash = "sha256:48dd883db92e92519201f2b01cafa881e5f7125666141a49ffba8b9facc072b0"}, + {file = "pydantic_core-2.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b6b0e4912030c6f28bcb72b9ebe4989d6dc2eebcd2a9cdc35fefc38052dd4fe8"}, + {file = "pydantic_core-2.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3202a429fe825b699c57892d4371c74cc3456d8d71b7f35d6028c96dfecad31"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3982b0a32d0a88b3907e4b0dc36809fda477f0757c59a505d4e9b455f384b8b"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25595ac311f20e5324d1941909b0d12933f1fd2171075fcff763e90f43e92a0d"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14fe73881cf8e4cbdaded8ca0aa671635b597e42447fec7060d0868b52d074e6"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca976884ce34070799e4dfc6fbd68cb1d181db1eefe4a3a94798ddfb34b8867f"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684d840d2c9ec5de9cb397fcb3f36d5ebb6fa0d94734f9886032dd796c1ead06"}, + {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:54764c083bbe0264f0f746cefcded6cb08fbbaaf1ad1d78fb8a4c30cff999a90"}, + {file = "pydantic_core-2.18.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:201713f2f462e5c015b343e86e68bd8a530a4f76609b33d8f0ec65d2b921712a"}, + {file = "pydantic_core-2.18.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fd1a9edb9dd9d79fbeac1ea1f9a8dd527a6113b18d2e9bcc0d541d308dae639b"}, + {file = "pydantic_core-2.18.1-cp312-none-win32.whl", hash = "sha256:d5e6b7155b8197b329dc787356cfd2684c9d6a6b1a197f6bbf45f5555a98d411"}, + {file = "pydantic_core-2.18.1-cp312-none-win_amd64.whl", hash = "sha256:9376d83d686ec62e8b19c0ac3bf8d28d8a5981d0df290196fb6ef24d8a26f0d6"}, + {file = "pydantic_core-2.18.1-cp312-none-win_arm64.whl", hash = "sha256:c562b49c96906b4029b5685075fe1ebd3b5cc2601dfa0b9e16c2c09d6cbce048"}, + {file = "pydantic_core-2.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3e352f0191d99fe617371096845070dee295444979efb8f27ad941227de6ad09"}, + {file = "pydantic_core-2.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0295d52b012cbe0d3059b1dba99159c3be55e632aae1999ab74ae2bd86a33d7"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56823a92075780582d1ffd4489a2e61d56fd3ebb4b40b713d63f96dd92d28144"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd3f79e17b56741b5177bcc36307750d50ea0698df6aa82f69c7db32d968c1c2"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38a5024de321d672a132b1834a66eeb7931959c59964b777e8f32dbe9523f6b1"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2ce426ee691319d4767748c8e0895cfc56593d725594e415f274059bcf3cb76"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2adaeea59849ec0939af5c5d476935f2bab4b7f0335b0110f0f069a41024278e"}, + {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9b6431559676a1079eac0f52d6d0721fb8e3c5ba43c37bc537c8c83724031feb"}, + {file = "pydantic_core-2.18.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:85233abb44bc18d16e72dc05bf13848a36f363f83757541f1a97db2f8d58cfd9"}, + {file = "pydantic_core-2.18.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:641a018af4fe48be57a2b3d7a1f0f5dbca07c1d00951d3d7463f0ac9dac66622"}, + {file = "pydantic_core-2.18.1-cp38-none-win32.whl", hash = "sha256:63d7523cd95d2fde0d28dc42968ac731b5bb1e516cc56b93a50ab293f4daeaad"}, + {file = "pydantic_core-2.18.1-cp38-none-win_amd64.whl", hash = "sha256:907a4d7720abfcb1c81619863efd47c8a85d26a257a2dbebdb87c3b847df0278"}, + {file = "pydantic_core-2.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:aad17e462f42ddbef5984d70c40bfc4146c322a2da79715932cd8976317054de"}, + {file = "pydantic_core-2.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:94b9769ba435b598b547c762184bcfc4783d0d4c7771b04a3b45775c3589ca44"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80e0e57cc704a52fb1b48f16d5b2c8818da087dbee6f98d9bf19546930dc64b5"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76b86e24039c35280ceee6dce7e62945eb93a5175d43689ba98360ab31eebc4a"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a05db5013ec0ca4a32cc6433f53faa2a014ec364031408540ba858c2172bb0"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:250ae39445cb5475e483a36b1061af1bc233de3e9ad0f4f76a71b66231b07f88"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a32204489259786a923e02990249c65b0f17235073149d0033efcebe80095570"}, + {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6395a4435fa26519fd96fdccb77e9d00ddae9dd6c742309bd0b5610609ad7fb2"}, + {file = "pydantic_core-2.18.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2533ad2883f001efa72f3d0e733fb846710c3af6dcdd544fe5bf14fa5fe2d7db"}, + {file = "pydantic_core-2.18.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b560b72ed4816aee52783c66854d96157fd8175631f01ef58e894cc57c84f0f6"}, + {file = "pydantic_core-2.18.1-cp39-none-win32.whl", hash = "sha256:582cf2cead97c9e382a7f4d3b744cf0ef1a6e815e44d3aa81af3ad98762f5a9b"}, + {file = "pydantic_core-2.18.1-cp39-none-win_amd64.whl", hash = "sha256:ca71d501629d1fa50ea7fa3b08ba884fe10cefc559f5c6c8dfe9036c16e8ae89"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e178e5b66a06ec5bf51668ec0d4ac8cfb2bdcb553b2c207d58148340efd00143"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:72722ce529a76a4637a60be18bd789d8fb871e84472490ed7ddff62d5fed620d"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe0c1ce5b129455e43f941f7a46f61f3d3861e571f2905d55cdbb8b5c6f5e2c"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4284c621f06a72ce2cb55f74ea3150113d926a6eb78ab38340c08f770eb9b4d"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a0c3e718f4e064efde68092d9d974e39572c14e56726ecfaeebbe6544521f47"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2027493cc44c23b598cfaf200936110433d9caa84e2c6cf487a83999638a96ac"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:76909849d1a6bffa5a07742294f3fa1d357dc917cb1fe7b470afbc3a7579d539"}, + {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ee7ccc7fb7e921d767f853b47814c3048c7de536663e82fbc37f5eb0d532224b"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee2794111c188548a4547eccc73a6a8527fe2af6cf25e1a4ebda2fd01cdd2e60"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a139fe9f298dc097349fb4f28c8b81cc7a202dbfba66af0e14be5cfca4ef7ce5"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d074b07a10c391fc5bbdcb37b2f16f20fcd9e51e10d01652ab298c0d07908ee2"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c69567ddbac186e8c0aadc1f324a60a564cfe25e43ef2ce81bcc4b8c3abffbae"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf1c7b78cddb5af00971ad5294a4583188bda1495b13760d9f03c9483bb6203"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2684a94fdfd1b146ff10689c6e4e815f6a01141781c493b97342cdc5b06f4d5d"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:73c1bc8a86a5c9e8721a088df234265317692d0b5cd9e86e975ce3bc3db62a59"}, + {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e60defc3c15defb70bb38dd605ff7e0fae5f6c9c7cbfe0ad7868582cb7e844a6"}, + {file = "pydantic_core-2.18.1.tar.gz", hash = "sha256:de9d3e8717560eb05e28739d1b35e4eac2e458553a52a301e51352a7ffc86a35"}, ] [package.dependencies] @@ -1692,17 +1686,17 @@ jsonasobj = ">=1.2.1" [[package]] name = "pymdown-extensions" -version = "10.7.1" +version = "10.8" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.7.1-py3-none-any.whl", hash = "sha256:f5cc7000d7ff0d1ce9395d216017fa4df3dde800afb1fb72d1c7d3fd35e710f4"}, - {file = "pymdown_extensions-10.7.1.tar.gz", hash = "sha256:c70e146bdd83c744ffc766b4671999796aba18842b268510a329f7f64700d584"}, + {file = "pymdown_extensions-10.8-py3-none-any.whl", hash = "sha256:3539003ff0d5e219ba979d2dc961d18fcad5ac259e66c764482e8347b4c0503c"}, + {file = "pymdown_extensions-10.8.tar.gz", hash = "sha256:91ca336caf414e1e5e0626feca86e145de9f85a3921a7bcbd32890b51738c428"}, ] [package.dependencies] -markdown = ">=3.5" +markdown = ">=3.6" pyyaml = "*" [package.extras] @@ -1976,104 +1970,104 @@ rpds-py = ">=0.7.0" [[package]] name = "regex" -version = "2023.12.25" +version = "2024.4.16" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.7" files = [ - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, - {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, - {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, - {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, - {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, - {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, - {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, - {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, - {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, - {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, - {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, - {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, - {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, - {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, - {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, + {file = "regex-2024.4.16-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb83cc090eac63c006871fd24db5e30a1f282faa46328572661c0a24a2323a08"}, + {file = "regex-2024.4.16-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c91e1763696c0eb66340c4df98623c2d4e77d0746b8f8f2bee2c6883fd1fe18"}, + {file = "regex-2024.4.16-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10188fe732dec829c7acca7422cdd1bf57d853c7199d5a9e96bb4d40db239c73"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:956b58d692f235cfbf5b4f3abd6d99bf102f161ccfe20d2fd0904f51c72c4c66"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a70b51f55fd954d1f194271695821dd62054d949efd6368d8be64edd37f55c86"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c02fcd2bf45162280613d2e4a1ca3ac558ff921ae4e308ecb307650d3a6ee51"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4ed75ea6892a56896d78f11006161eea52c45a14994794bcfa1654430984b22"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd727ad276bb91928879f3aa6396c9a1d34e5e180dce40578421a691eeb77f47"}, + {file = "regex-2024.4.16-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7cbc5d9e8a1781e7be17da67b92580d6ce4dcef5819c1b1b89f49d9678cc278c"}, + {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:78fddb22b9ef810b63ef341c9fcf6455232d97cfe03938cbc29e2672c436670e"}, + {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:445ca8d3c5a01309633a0c9db57150312a181146315693273e35d936472df912"}, + {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:95399831a206211d6bc40224af1c635cb8790ddd5c7493e0bd03b85711076a53"}, + {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7731728b6568fc286d86745f27f07266de49603a6fdc4d19c87e8c247be452af"}, + {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4facc913e10bdba42ec0aee76d029aedda628161a7ce4116b16680a0413f658a"}, + {file = "regex-2024.4.16-cp310-cp310-win32.whl", hash = "sha256:911742856ce98d879acbea33fcc03c1d8dc1106234c5e7d068932c945db209c0"}, + {file = "regex-2024.4.16-cp310-cp310-win_amd64.whl", hash = "sha256:e0a2df336d1135a0b3a67f3bbf78a75f69562c1199ed9935372b82215cddd6e2"}, + {file = "regex-2024.4.16-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1210365faba7c2150451eb78ec5687871c796b0f1fa701bfd2a4a25420482d26"}, + {file = "regex-2024.4.16-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ab40412f8cd6f615bfedea40c8bf0407d41bf83b96f6fc9ff34976d6b7037fd"}, + {file = "regex-2024.4.16-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd80d1280d473500d8086d104962a82d77bfbf2b118053824b7be28cd5a79ea5"}, + {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bb966fdd9217e53abf824f437a5a2d643a38d4fd5fd0ca711b9da683d452969"}, + {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20b7a68444f536365af42a75ccecb7ab41a896a04acf58432db9e206f4e525d6"}, + {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b74586dd0b039c62416034f811d7ee62810174bb70dffcca6439f5236249eb09"}, + {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8290b44d8b0af4e77048646c10c6e3aa583c1ca67f3b5ffb6e06cf0c6f0f89"}, + {file = "regex-2024.4.16-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2d80a6749724b37853ece57988b39c4e79d2b5fe2869a86e8aeae3bbeef9eb0"}, + {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3a1018e97aeb24e4f939afcd88211ace472ba566efc5bdf53fd8fd7f41fa7170"}, + {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8d015604ee6204e76569d2f44e5a210728fa917115bef0d102f4107e622b08d5"}, + {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:3d5ac5234fb5053850d79dd8eb1015cb0d7d9ed951fa37aa9e6249a19aa4f336"}, + {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0a38d151e2cdd66d16dab550c22f9521ba79761423b87c01dae0a6e9add79c0d"}, + {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:159dc4e59a159cb8e4e8f8961eb1fa5d58f93cb1acd1701d8aff38d45e1a84a6"}, + {file = "regex-2024.4.16-cp311-cp311-win32.whl", hash = "sha256:ba2336d6548dee3117520545cfe44dc28a250aa091f8281d28804aa8d707d93d"}, + {file = "regex-2024.4.16-cp311-cp311-win_amd64.whl", hash = "sha256:8f83b6fd3dc3ba94d2b22717f9c8b8512354fd95221ac661784df2769ea9bba9"}, + {file = "regex-2024.4.16-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:80b696e8972b81edf0af2a259e1b2a4a661f818fae22e5fa4fa1a995fb4a40fd"}, + {file = "regex-2024.4.16-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d61ae114d2a2311f61d90c2ef1358518e8f05eafda76eaf9c772a077e0b465ec"}, + {file = "regex-2024.4.16-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ba6745440b9a27336443b0c285d705ce73adb9ec90e2f2004c64d95ab5a7598"}, + {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295004b2dd37b0835ea5c14a33e00e8cfa3c4add4d587b77287825f3418d310"}, + {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4aba818dcc7263852aabb172ec27b71d2abca02a593b95fa79351b2774eb1d2b"}, + {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0800631e565c47520aaa04ae38b96abc5196fe8b4aa9bd864445bd2b5848a7a"}, + {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08dea89f859c3df48a440dbdcd7b7155bc675f2fa2ec8c521d02dc69e877db70"}, + {file = "regex-2024.4.16-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eeaa0b5328b785abc344acc6241cffde50dc394a0644a968add75fcefe15b9d4"}, + {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4e819a806420bc010489f4e741b3036071aba209f2e0989d4750b08b12a9343f"}, + {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c2d0e7cbb6341e830adcbfa2479fdeebbfbb328f11edd6b5675674e7a1e37730"}, + {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:91797b98f5e34b6a49f54be33f72e2fb658018ae532be2f79f7c63b4ae225145"}, + {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:d2da13568eff02b30fd54fccd1e042a70fe920d816616fda4bf54ec705668d81"}, + {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:370c68dc5570b394cbaadff50e64d705f64debed30573e5c313c360689b6aadc"}, + {file = "regex-2024.4.16-cp312-cp312-win32.whl", hash = "sha256:904c883cf10a975b02ab3478bce652f0f5346a2c28d0a8521d97bb23c323cc8b"}, + {file = "regex-2024.4.16-cp312-cp312-win_amd64.whl", hash = "sha256:785c071c982dce54d44ea0b79cd6dfafddeccdd98cfa5f7b86ef69b381b457d9"}, + {file = "regex-2024.4.16-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e2f142b45c6fed48166faeb4303b4b58c9fcd827da63f4cf0a123c3480ae11fb"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87ab229332ceb127a165612d839ab87795972102cb9830e5f12b8c9a5c1b508"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81500ed5af2090b4a9157a59dbc89873a25c33db1bb9a8cf123837dcc9765047"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b340cccad138ecb363324aa26893963dcabb02bb25e440ebdf42e30963f1a4e0"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c72608e70f053643437bd2be0608f7f1c46d4022e4104d76826f0839199347a"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a01fe2305e6232ef3e8f40bfc0f0f3a04def9aab514910fa4203bafbc0bb4682"}, + {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:03576e3a423d19dda13e55598f0fd507b5d660d42c51b02df4e0d97824fdcae3"}, + {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:549c3584993772e25f02d0656ac48abdda73169fe347263948cf2b1cead622f3"}, + {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:34422d5a69a60b7e9a07a690094e824b66f5ddc662a5fc600d65b7c174a05f04"}, + {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5f580c651a72b75c39e311343fe6875d6f58cf51c471a97f15a938d9fe4e0d37"}, + {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3399dd8a7495bbb2bacd59b84840eef9057826c664472e86c91d675d007137f5"}, + {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8d1f86f3f4e2388aa3310b50694ac44daefbd1681def26b4519bd050a398dc5a"}, + {file = "regex-2024.4.16-cp37-cp37m-win32.whl", hash = "sha256:dd5acc0a7d38fdc7a3a6fd3ad14c880819008ecb3379626e56b163165162cc46"}, + {file = "regex-2024.4.16-cp37-cp37m-win_amd64.whl", hash = "sha256:ba8122e3bb94ecda29a8de4cf889f600171424ea586847aa92c334772d200331"}, + {file = "regex-2024.4.16-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:743deffdf3b3481da32e8a96887e2aa945ec6685af1cfe2bcc292638c9ba2f48"}, + {file = "regex-2024.4.16-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7571f19f4a3fd00af9341c7801d1ad1967fc9c3f5e62402683047e7166b9f2b4"}, + {file = "regex-2024.4.16-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:df79012ebf6f4efb8d307b1328226aef24ca446b3ff8d0e30202d7ebcb977a8c"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e757d475953269fbf4b441207bb7dbdd1c43180711b6208e129b637792ac0b93"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4313ab9bf6a81206c8ac28fdfcddc0435299dc88cad12cc6305fd0e78b81f9e4"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d83c2bc678453646f1a18f8db1e927a2d3f4935031b9ad8a76e56760461105dd"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9df1bfef97db938469ef0a7354b2d591a2d438bc497b2c489471bec0e6baf7c4"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62120ed0de69b3649cc68e2965376048793f466c5a6c4370fb27c16c1beac22d"}, + {file = "regex-2024.4.16-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c2ef6f7990b6e8758fe48ad08f7e2f66c8f11dc66e24093304b87cae9037bb4a"}, + {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8fc6976a3395fe4d1fbeb984adaa8ec652a1e12f36b56ec8c236e5117b585427"}, + {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:03e68f44340528111067cecf12721c3df4811c67268b897fbe695c95f860ac42"}, + {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ec7e0043b91115f427998febaa2beb82c82df708168b35ece3accb610b91fac1"}, + {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c21fc21a4c7480479d12fd8e679b699f744f76bb05f53a1d14182b31f55aac76"}, + {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:12f6a3f2f58bb7344751919a1876ee1b976fe08b9ffccb4bbea66f26af6017b9"}, + {file = "regex-2024.4.16-cp38-cp38-win32.whl", hash = "sha256:479595a4fbe9ed8f8f72c59717e8cf222da2e4c07b6ae5b65411e6302af9708e"}, + {file = "regex-2024.4.16-cp38-cp38-win_amd64.whl", hash = "sha256:0534b034fba6101611968fae8e856c1698da97ce2efb5c2b895fc8b9e23a5834"}, + {file = "regex-2024.4.16-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7ccdd1c4a3472a7533b0a7aa9ee34c9a2bef859ba86deec07aff2ad7e0c3b94"}, + {file = "regex-2024.4.16-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f2f017c5be19984fbbf55f8af6caba25e62c71293213f044da3ada7091a4455"}, + {file = "regex-2024.4.16-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:803b8905b52de78b173d3c1e83df0efb929621e7b7c5766c0843704d5332682f"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:684008ec44ad275832a5a152f6e764bbe1914bea10968017b6feaecdad5736e0"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65436dce9fdc0aeeb0a0effe0839cb3d6a05f45aa45a4d9f9c60989beca78b9c"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea355eb43b11764cf799dda62c658c4d2fdb16af41f59bb1ccfec517b60bcb07"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c1165f3809ce7774f05cb74e5408cd3aa93ee8573ae959a97a53db3ca3180d"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cccc79a9be9b64c881f18305a7c715ba199e471a3973faeb7ba84172abb3f317"}, + {file = "regex-2024.4.16-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00169caa125f35d1bca6045d65a662af0202704489fada95346cfa092ec23f39"}, + {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6cc38067209354e16c5609b66285af17a2863a47585bcf75285cab33d4c3b8df"}, + {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:23cff1b267038501b179ccbbd74a821ac4a7192a1852d1d558e562b507d46013"}, + {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:b9d320b3bf82a39f248769fc7f188e00f93526cc0fe739cfa197868633d44701"}, + {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:89ec7f2c08937421bbbb8b48c54096fa4f88347946d4747021ad85f1b3021b3c"}, + {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4918fd5f8b43aa7ec031e0fef1ee02deb80b6afd49c85f0790be1dc4ce34cb50"}, + {file = "regex-2024.4.16-cp39-cp39-win32.whl", hash = "sha256:684e52023aec43bdf0250e843e1fdd6febbe831bd9d52da72333fa201aaa2335"}, + {file = "regex-2024.4.16-cp39-cp39-win_amd64.whl", hash = "sha256:e697e1c0238133589e00c244a8b676bc2cfc3ab4961318d902040d099fec7483"}, + {file = "regex-2024.4.16.tar.gz", hash = "sha256:fa454d26f2e87ad661c4f0c5a5fe4cf6aab1e307d1b94f16ffdfcb089ba685c0"}, ] [[package]] @@ -2122,6 +2116,24 @@ files = [ {file = "rfc3987-1.3.8.tar.gz", hash = "sha256:d3c4d257a560d544e9826b38bc81db676890c79ab9d7ac92b39c7a253d5ca733"}, ] +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "rpds-py" version = "0.18.0" @@ -2309,97 +2321,81 @@ files = [ [[package]] name = "ruff" -version = "0.3.4" +version = "0.4.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"}, - {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"}, - {file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"}, - {file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"}, - {file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"}, - {file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"}, - {file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"}, - {file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"}, - {file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"}, - {file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"}, - {file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"}, + {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2d9ef6231e3fbdc0b8c72404a1a0c46fd0dcea84efca83beb4681c318ea6a953"}, + {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9485f54a7189e6f7433e0058cf8581bee45c31a25cd69009d2a040d1bd4bfaef"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2921ac03ce1383e360e8a95442ffb0d757a6a7ddd9a5be68561a671e0e5807e"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eec8d185fe193ad053eda3a6be23069e0c8ba8c5d20bc5ace6e3b9e37d246d3f"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa27d9d72a94574d250f42b7640b3bd2edc4c58ac8ac2778a8c82374bb27984"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f1ee41580bff1a651339eb3337c20c12f4037f6110a36ae4a2d864c52e5ef954"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0926cefb57fc5fced629603fbd1a23d458b25418681d96823992ba975f050c2b"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6e37f2e3cd74496a74af9a4fa67b547ab3ca137688c484749189bf3a686ceb"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd703a5975ac1998c2cc5e9494e13b28f31e66c616b0a76e206de2562e0843c"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b92f03b4aa9fa23e1799b40f15f8b95cdc418782a567d6c43def65e1bbb7f1cf"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c859f294f8633889e7d77de228b203eb0e9a03071b72b5989d89a0cf98ee262"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b34510141e393519a47f2d7b8216fec747ea1f2c81e85f076e9f2910588d4b64"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e68d248ed688b9d69fd4d18737edcbb79c98b251bba5a2b031ce2470224bdf9"}, + {file = "ruff-0.4.1-py3-none-win32.whl", hash = "sha256:b90506f3d6d1f41f43f9b7b5ff845aeefabed6d2494307bc7b178360a8805252"}, + {file = "ruff-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c7d391e5936af5c9e252743d767c564670dc3889aff460d35c518ee76e4b26d7"}, + {file = "ruff-0.4.1-py3-none-win_arm64.whl", hash = "sha256:a1eaf03d87e6a7cd5e661d36d8c6e874693cb9bc3049d110bc9a97b350680c43"}, + {file = "ruff-0.4.1.tar.gz", hash = "sha256:d592116cdbb65f8b1b7e2a2b48297eb865f6bdc20641879aa9d7b9c11d86db79"}, ] [[package]] name = "scipy" -version = "1.12.0" +version = "1.13.0" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.9" files = [ - {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, - {file = "scipy-1.12.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5f00ebaf8de24d14b8449981a2842d404152774c1a1d880c901bf454cb8e2a1"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53958531a7c695ff66c2e7bb7b79560ffdc562e2051644c5576c39ff8efb563"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e32847e08da8d895ce09d108a494d9eb78974cf6de23063f93306a3e419960c"}, - {file = "scipy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1020cad92772bf44b8e4cdabc1df5d87376cb219742549ef69fc9fd86282dd"}, - {file = "scipy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:75ea2a144096b5e39402e2ff53a36fecfd3b960d786b7efd3c180e29c39e53f2"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}, - {file = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}, - {file = "scipy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}, - {file = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}, - {file = "scipy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:913d6e7956c3a671de3b05ccb66b11bc293f56bfdef040583a7221d9e22a2e35"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba1b0c7256ad75401c73e4b3cf09d1f176e9bd4248f0d3112170fb2ec4db067"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:730badef9b827b368f351eacae2e82da414e13cf8bd5051b4bdfd720271a5371"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6546dc2c11a9df6926afcbdd8a3edec28566e4e785b915e849348c6dd9f3f490"}, - {file = "scipy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:196ebad3a4882081f62a5bf4aeb7326aa34b110e533aab23e4374fcccb0890dc"}, - {file = "scipy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:b360f1b6b2f742781299514e99ff560d1fe9bd1bff2712894b52abe528d1fd1e"}, - {file = "scipy-1.12.0.tar.gz", hash = "sha256:4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}, -] - -[package.dependencies] -numpy = ">=1.22.4,<1.29.0" + {file = "scipy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba419578ab343a4e0a77c0ef82f088238a93eef141b2b8017e46149776dfad4d"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:22789b56a999265431c417d462e5b7f2b487e831ca7bef5edeb56efe4c93f86e"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f1432ba070e90d42d7fd836462c50bf98bd08bed0aa616c359eed8a04e3922"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8434f6f3fa49f631fae84afee424e2483289dfc30a47755b4b4e6b07b2633a4"}, + {file = "scipy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dcbb9ea49b0167de4167c40eeee6e167caeef11effb0670b554d10b1e693a8b9"}, + {file = "scipy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d2f7bb14c178f8b13ebae93f67e42b0a6b0fc50eba1cd8021c9b6e08e8fb1cd"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fbcf8abaf5aa2dc8d6400566c1a727aed338b5fe880cde64907596a89d576fa"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5e4a756355522eb60fcd61f8372ac2549073c8788f6114449b37e9e8104f15a5"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5acd8e1dbd8dbe38d0004b1497019b2dbbc3d70691e65d69615f8a7292865d7"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ff7dad5d24a8045d836671e082a490848e8639cabb3dbdacb29f943a678683d"}, + {file = "scipy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4dca18c3ffee287ddd3bc8f1dabaf45f5305c5afc9f8ab9cbfab855e70b2df5c"}, + {file = "scipy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a2f471de4d01200718b2b8927f7d76b5d9bde18047ea0fa8bd15c5ba3f26a1d6"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0de696f589681c2802f9090fff730c218f7c51ff49bf252b6a97ec4a5d19e8b"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b2a3ff461ec4756b7e8e42e1c681077349a038f0686132d623fa404c0bee2551"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf9fe63e7a4bf01d3645b13ff2aa6dea023d38993f42aaac81a18b1bda7a82a"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e7626dfd91cdea5714f343ce1176b6c4745155d234f1033584154f60ef1ff42"}, + {file = "scipy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:109d391d720fcebf2fbe008621952b08e52907cf4c8c7efc7376822151820820"}, + {file = "scipy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:8930ae3ea371d6b91c203b1032b9600d69c568e537b7988a3073dfe4d4774f21"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5407708195cb38d70fd2d6bb04b1b9dd5c92297d86e9f9daae1576bd9e06f602"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ac38c4c92951ac0f729c4c48c9e13eb3675d9986cc0c83943784d7390d540c78"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c74543c4fbeb67af6ce457f6a6a28e5d3739a87f62412e4a16e46f164f0ae5"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e286bf9ac422d6beb559bc61312c348ca9b0f0dae0d7c5afde7f722d6ea13d"}, + {file = "scipy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33fde20efc380bd23a78a4d26d59fc8704e9b5fd9b08841693eb46716ba13d86"}, + {file = "scipy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:45c08bec71d3546d606989ba6e7daa6f0992918171e2a6f7fbedfa7361c2de1e"}, + {file = "scipy-1.13.0.tar.gz", hash = "sha256:58569af537ea29d3f78e5abd18398459f195546bb3be23d16677fb26616cc11e"}, +] + +[package.dependencies] +numpy = ">=1.22.4,<2.3" [package.extras] -dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "setuptools" -version = "69.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, - {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "shellingham" -version = "1.4.0" +version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false -python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" +python-versions = ">=3.7" files = [ - {file = "shellingham-1.4.0-py2.py3-none-any.whl", hash = "sha256:536b67a0697f2e4af32ab176c00a50ac2899c5a05e0d8e2dadac8e58888283f9"}, - {file = "shellingham-1.4.0.tar.gz", hash = "sha256:4855c2458d6904829bd34c299f11fdeed7cfefbf8a2c522e4caea6cd76b3171e"}, + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, ] [[package]] @@ -2574,13 +2570,13 @@ sqlcipher = ["sqlcipher3_binary"] [[package]] name = "sssom" -version = "0.4.5" +version = "0.4.7" description = "Operations on SSSOM mapping tables" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "sssom-0.4.5-py3-none-any.whl", hash = "sha256:8fd582082b9b5e748f05d1831362f1af9f700837a01f1d5fca09361519657d54"}, - {file = "sssom-0.4.5.tar.gz", hash = "sha256:753b3481083a6a62d39f11d6dc18e6038fc0edaa27929e0881e1c7fee8f8bcbe"}, + {file = "sssom-0.4.7-py3-none-any.whl", hash = "sha256:93118cafec7f35948f3bdb17f21612cf94162a500c8f569c8a8564de36e3c040"}, + {file = "sssom-0.4.7.tar.gz", hash = "sha256:c2f8bf418f159f778e4564cdec2a859f2bfae5891a33e0b67b2d8bb56c6221b3"}, ] [package.dependencies] @@ -2588,7 +2584,7 @@ click = ">=8.1.6" curies = ">=0.7.3" deprecation = ">=2.1.0,<3.0.0" importlib-resources = ">=6.1.1,<7.0.0" -linkml-runtime = ">=1.5.5" +linkml-runtime = ">=1.7.5,<2.0.0" networkx = {version = ">=3.1", extras = ["networkx"]} pandas = ">1.0.3" pansql = {version = ">=0.0.1", extras = ["pansql"]} @@ -2596,23 +2592,32 @@ pyyaml = ">=6.0.1,<7.0.0" rdflib = ">=6.0.0" scipy = {version = "*", extras = ["scipy"]} sparqlwrapper = ">=2.0.0" -sssom-schema = ">=0.14.0" +sssom-schema = ">=0.15.2,<0.16.0" validators = ">=0.20.0" [[package]] name = "sssom-schema" -version = "0.15.0" +version = "0.15.2" description = "SSSOM is a Simple Standard for Sharing Ontology Mappings." optional = false -python-versions = ">=3.7.6,<4.0.0" +python-versions = "<4.0,>=3.8" files = [ - {file = "sssom_schema-0.15.0-py3-none-any.whl", hash = "sha256:0ba81a0fe76d28a2c65d65a99e0cd17d8dd08274f9735776a70c8d2f3734e901"}, - {file = "sssom_schema-0.15.0.tar.gz", hash = "sha256:35d56ba6d0350b1e07df2789aebac9c5c70b0888bf88ec3c0592c89e9c13d228"}, + {file = "sssom_schema-0.15.2-py3-none-any.whl", hash = "sha256:41112586160d5e57a7cfedab22dfd0c21d1e3e1a86805f7fe31918a9b664ca15"}, + {file = "sssom_schema-0.15.2.tar.gz", hash = "sha256:c759ee8f9e4a7e5e8249b58198189b2e48e297ff31a918d4af64a89ed30938da"}, ] [package.dependencies] linkml-runtime = "*" -mkdocs-mermaid2-plugin = ">=0.6.0,<0.7.0" + +[[package]] +name = "stringcase" +version = "1.2.0" +description = "String case converter." +optional = false +python-versions = "*" +files = [ + {file = "stringcase-1.2.0.tar.gz", hash = "sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008"}, +] [[package]] name = "tomli" @@ -2638,39 +2643,20 @@ files = [ [[package]] name = "typer" -version = "0.7.0" +version = "0.12.3" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false -python-versions = ">=3.6" -files = [ - {file = "typer-0.7.0-py3-none-any.whl", hash = "sha256:b5e704f4e48ec263de1c0b3a2387cd405a13767d2f907f44c1a08cbad96f606d"}, - {file = "typer-0.7.0.tar.gz", hash = "sha256:ff797846578a9f2a201b53442aedeb543319466870fbe1c701eab66dd7681165"}, -] - -[package.dependencies] -click = ">=7.1.1,<9.0.0" - -[package.extras] -all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] -dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] -doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] -test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] - -[[package]] -name = "typer-cli" -version = "0.0.13" -description = "Run Typer scripts with completion, without having to create a package, using Typer CLI." -optional = false python-versions = ">=3.7" files = [ - {file = "typer_cli-0.0.13-py3-none-any.whl", hash = "sha256:5ae0f99dce8f8f9669137a2c98eb42485cd4412e0ec225c8eb29ce8ac3378731"}, - {file = "typer_cli-0.0.13.tar.gz", hash = "sha256:f5b85764e56fb3fe835ed008ad5bc7db4961f7bcce1f1c1698ac46b6c5d9b86f"}, + {file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"}, + {file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"}, ] [package.dependencies] -colorama = ">=0.4.3,<=0.5.0" -shellingham = ">=1.3.2,<=1.4.0" -typer = ">=0.4.0,<=0.7.0" +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" [[package]] name = "types-python-dateutil" @@ -2685,13 +2671,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.11.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, ] [[package]] @@ -2738,13 +2724,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "validators" -version = "0.24.0" +version = "0.28.1" description = "Python Data Validation for Humans™" optional = false python-versions = ">=3.8" files = [ - {file = "validators-0.24.0-py3-none-any.whl", hash = "sha256:4a99eb368747e60900bae947418eb21e230ff4ff5e7b7944b9308c456d86da32"}, - {file = "validators-0.24.0.tar.gz", hash = "sha256:cd23defb36de42d14e7559cf0757f761bb46b10d9de2998e6ef805f769d859e3"}, + {file = "validators-0.28.1-py3-none-any.whl", hash = "sha256:890c98789ad884037f059af6ea915ec2d667129d509180c2c590b8009a4c4219"}, + {file = "validators-0.28.1.tar.gz", hash = "sha256:5ac88e7916c3405f0ce38ac2ac82a477fcf4d90dbbeddd04c8193171fc17f7dc"}, ] [[package]] @@ -2896,6 +2882,24 @@ files = [ {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, ] +[[package]] +name = "yamllint" +version = "1.35.1" +description = "A linter for YAML files." +optional = false +python-versions = ">=3.8" +files = [ + {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"}, + {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"}, +] + +[package.dependencies] +pathspec = ">=0.5.3" +pyyaml = "*" + +[package.extras] +dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] + [[package]] name = "zipp" version = "3.18.1" @@ -2914,4 +2918,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "24fcafa107fbce6d07560a3b1895b472ff9a02247554c830850e0d313f516491" +content-hash = "40207ecd405a86ce7b93123b9aec29588d047466ec2b630f64e3dd172cabc2f6" diff --git a/pyproject.toml b/pyproject.toml index 854222f..2da07fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,8 +21,7 @@ pydantic = "^2.4" pyyaml = ">=5.0.0" requests = "^2.24.0" ordered-set = ">=4.1.0" -typer = "^0.7.0" -typer-cli = "^0.0.13" +typer = "^0.12.3" loguru = "*" sssom = ">=0.4" @@ -30,7 +29,7 @@ sssom = ">=0.4" black = "^23.10.0" ruff = "*" pytest = ">=6.0.0" -biolink-model = ">=3.6" +biolink-model = ">=4.2" dask = ">=2022.5.2" mkdocs = ">=1.4.2" mkdocs-material = ">=9.1.16" diff --git a/src/koza/app.py b/src/koza/app.py index 2f3d158..f814192 100644 --- a/src/koza/app.py +++ b/src/koza/app.py @@ -81,7 +81,7 @@ def process_sources(self): or inferred by taking the name and path of the config file and looking for a .py file along side it (see constructor) - Intended for decoupling ingest logic into a configuration like file + Intended for decoupling ingest logic into a configuration-like file """ import sys @@ -106,10 +106,10 @@ def process_sources(self): self.logger.debug(f"{str(mie)} not found in map") except NextRowException: continue - except ValidationError as ve: + except ValidationError: if self.logger: self.logger.error(f"Validation error while processing: {self.source.last_row}") - raise ve + raise ValidationError except StopIteration: break elif self.source.config.transform_mode == 'loop': diff --git a/src/koza/converter/biolink_converter.py b/src/koza/converter/biolink_converter.py index 5f7b263..e5d6747 100644 --- a/src/koza/converter/biolink_converter.py +++ b/src/koza/converter/biolink_converter.py @@ -1,4 +1,4 @@ -from biolink.pydanticmodel_v2 import Gene +from biolink_model.datamodel.pydanticmodel_v2 import Gene from koza.cli_runner import koza_app diff --git a/src/koza/io/writer/tsv_writer.py b/src/koza/io/writer/tsv_writer.py index 77fc865..5c586bd 100644 --- a/src/koza/io/writer/tsv_writer.py +++ b/src/koza/io/writer/tsv_writer.py @@ -2,7 +2,7 @@ # NOTE - May want to rename to KGXWriter at some point, if we develop writers for other models non biolink/kgx specific from pathlib import Path -import typing as t +from typing import Dict, Iterable, List, Literal, Set, Union from ordered_set import OrderedSet @@ -15,10 +15,10 @@ class TSVWriter(KozaWriter): def __init__( self, - output_dir: t.Union[str, Path], + output_dir: Union[str, Path], source_name: str, - node_properties: t.List[str] = None, - edge_properties: t.List[str] = None, + node_properties: List[str] = None, + edge_properties: List[str] = None, sssom_config: SSSOMConfig = None, ): self.basename = source_name @@ -44,7 +44,7 @@ def __init__( self.edgeFH = open(self.edges_file_name, "w") self.edgeFH.write(self.delimiter.join(self.edge_columns) + "\n") - def write(self, entities: t.Iterable) -> None: + def write(self, entities: Iterable) -> None: """Write an entities object to separate node and edge .tsv files""" nodes, edges = self.converter.convert(entities) @@ -59,7 +59,7 @@ def write(self, entities: t.Iterable) -> None: edge = self.sssom_config.apply_mapping(edge) self.write_row(edge, record_type="edge") - def write_row(self, record: t.Dict, record_type: t.Literal["node", "edge"]) -> None: + def write_row(self, record: Dict, record_type: Literal["node", "edge"]) -> None: """Write a row to the underlying store. Args: @@ -88,7 +88,7 @@ def finalize(self): self.edgeFH.close() @staticmethod - def _order_columns(cols: t.Set, record_type: t.Literal["node", "edge"]) -> OrderedSet: + def _order_columns(cols: Set, record_type: Literal["node", "edge"]) -> OrderedSet: """Arrange node or edge columns in a defined order. Args: diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index 42e94dd..7490437 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -116,19 +116,18 @@ class DatasetDescription: These options should be treated as being in alpha, as we need to align with various efforts (hcls, translator infores) - These currently do not serve a purpose in koza other - than documentation + These currently do not serve a purpose in koza other than documentation """ - id: Optional[str] = None - name: Optional[str] = None # If empty use source name + # id: Optional[str] = None # Can uncomment when we have a standard + name: Optional[str] = None # If empty use source name ingest_title: Optional[str] = None # Title of source of data, map to biolink name - ingest_url: Optional[str] = None # URL to source of data, Maps to biolink iri - description: Optional[str] = None - source: Optional[str] = None - provided_by: Optional[str] = None - # license: Optional[str] = None # Possibly redundant, same as rights - rights: Optional[str] = None + ingest_url: Optional[str] = None # URL to source of data, maps to biolink iri + description: Optional[str] = None # Description of the data/ingest + # source: Optional[str] = None # Possibly replaced with provided_by + provided_by: Optional[str] = None # _, ex. hpoa_gene_to_disease + # license: Optional[str] = None # Possibly redundant, same as rights + rights: Optional[str] = None # License information for the data source @dataclass(config=PYDANTIC_CONFIG) @@ -194,6 +193,11 @@ def extract_archive(self): else: raise ValueError("Error extracting archive. Supported archive types: .tar.gz, .zip") files = [os.path.join(archive_path, file) for file in self.files] + # Possibly replace with this code if we want to extract all files? (not sure) + # if self.files: + # files = [os.path.join(archive_path, file) for file in self.files] + # else: + # files = [os.path.join(archive_path, file) for file in os.listdir(archive_path)] return files def __post_init__(self): diff --git a/tests/unit/test_kgx_converter.py b/tests/unit/test_kgx_converter.py index 7bf52dd..130daa2 100644 --- a/tests/unit/test_kgx_converter.py +++ b/tests/unit/test_kgx_converter.py @@ -1,5 +1,5 @@ import pytest -from biolink.pydanticmodel_v2 import Gene, GeneToGeneAssociation # , Publication +from biolink_model.datamodel.pydanticmodel_v2 import Gene, GeneToGeneAssociation # , Publication from koza.converter.kgx_converter import KGXConverter @@ -33,6 +33,8 @@ def test_association_conversion(): predicate="biolink:interacts_with", object=pax2a.id, publications=[pub], + knowledge_level="not_provided", + agent_type="not_provided", ) (_, edges) = KGXConverter().convert([fgf8a, pax2a, association]) diff --git a/tests/unit/test_tsvwriter_node_and_edge.py b/tests/unit/test_tsvwriter_node_and_edge.py index 4711fde..b0ac031 100644 --- a/tests/unit/test_tsvwriter_node_and_edge.py +++ b/tests/unit/test_tsvwriter_node_and_edge.py @@ -1,6 +1,6 @@ import os -from biolink.pydanticmodel_v2 import Disease, Gene, GeneToDiseaseAssociation +from biolink_model.datamodel.pydanticmodel_v2 import Disease, Gene, GeneToDiseaseAssociation from koza.io.writer.tsv_writer import TSVWriter @@ -15,24 +15,14 @@ def test_tsv_writer(): id="uuid:5b06e86f-d768-4cd9-ac27-abe31e95ab1e", subject=g.id, object=d.id, - # relation="RO:0003304", predicate="biolink:contributes_to", + knowledge_level="not_provided", + agent_type="not_provided", ) ent = [g, d, a] - node_properties = ['id', 'category', 'symbol', 'in_taxon', 'provided_by', 'source'] - edge_properties = [ - 'id', - 'subject', - 'predicate', - 'object', - 'category', - 'relation', - 'qualifiers', - 'publications', - 'provided_by', - 'source', - ] + node_properties = ["id", "category", "symbol", "in_taxon", "provided_by", "source"] + edge_properties = ["id", "subject", "predicate", "object", "category" "qualifiers", "publications", "provided_by"] outdir = "output/tests" outfile = "tsvwriter-node-and-edge" diff --git a/tests/unit/test_tsvwriter_node_only.py b/tests/unit/test_tsvwriter_node_only.py index 7d7b903..0fa8eb8 100644 --- a/tests/unit/test_tsvwriter_node_only.py +++ b/tests/unit/test_tsvwriter_node_only.py @@ -1,6 +1,6 @@ import os -from biolink.pydanticmodel_v2 import Disease, Gene +from biolink_model.datamodel.pydanticmodel_v2 import Disease, Gene from koza.io.writer.tsv_writer import TSVWriter From aafb61ea18b6e8c02cfcbd5e76e9112f52eb8b54 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 22 Apr 2024 17:52:34 -0600 Subject: [PATCH 04/30] update config doc, allow using all extracted files --- docs/Ingests/source_config.md | 57 +++++++++++++------------- src/koza/model/config/source_config.py | 12 +++--- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/docs/Ingests/source_config.md b/docs/Ingests/source_config.md index 4958dc0..b889b71 100644 --- a/docs/Ingests/source_config.md +++ b/docs/Ingests/source_config.md @@ -4,34 +4,35 @@ This YAML file sets properties for the ingest of a single file type from a withi ## Source Configuration Properties -| **Required properties** | | -| ------------------------------------ | --------------------------------------------------------------------------------------------------- | -| `name` | Name of the data ingest, as `_`,
ex. `hpoa_gene_to_disease` | -| `files` | List of files to process | -| | | -| **Optional properties** | | -| `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | -| `format` | Format of the data file(s) (CSV or JSON) | -| `sssom_config` | Configures usage of SSSOM mapping files | -| `depends_on` | List of map config files to use | -| `metadata` | Metadata for the source, either a list of properties,
or path to a `metadata.yaml` | -| `transform_code` | Path to a python file to transform the data | -| `transform_mode` | How to process the transform file | -| `global_table` | Path to a global translation table file | -| `local_table` | Path to a local translation table file | -| `field_type_map` | Dict of field names and their type (using the FieldType enum) | -| `filters` | List of filters to apply | -| `json_path` | Path within JSON object containing data to process | -| `required_properties` | List of properties that must be present in output (JSON only) | -| | | -| **Optional CSV-Specific Properties** | | -| `columns` | List of columns to include in output (CSV only) | -| `delimiter` | Delimiter for csv files | -| `header` | Header row index for csv files | -| `header_delimiter` | Delimiter for header in csv files | -| `header_prefix` | Prefix for header in csv files | -| `comment_char` | Comment character for csv files | -| `skip_blank_lines` | Skip blank lines in csv files | +| **Required properties** | | +| --------------------------- | --------------------------------------------------------------------------------------------------- | +| `name` | Name of the data ingest, as `_`,
ex. `hpoa_gene_to_disease` | +| `files` | List of files to process | +| | | +| **Optional properties** | | +| `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | +| `format` | Format of the data file(s) (CSV or JSON) | +| `sssom_config` | Configures usage of SSSOM mapping files | +| `depends_on` | List of map config files to use | +| `metadata` | Metadata for the source, either a list of properties,
or path to a `metadata.yaml` | +| `transform_code` | Path to a python file to transform the data | +| `transform_mode` | How to process the transform file | +| `global_table` | Path to a global translation table file | +| `local_table` | Path to a local translation table file | +| `field_type_map` | Dict of field names and their type (using the FieldType enum) | +| `filters` | List of filters to apply | +| `json_path` | Path within JSON object containing data to process | +| `required_properties` | List of properties that must be present in output (JSON only) | +| | | +| **CSV-Specific Properties** | | +| `delimiter` | Delimiter for csv files (**Required for CSV format**) | +| **Optional CSV Properties** | | +| `columns` | List of columns to include in output (CSV only) | +| `header` | Header row index for csv files | +| `header_delimiter` | Delimiter for header in csv files | +| `header_prefix` | Prefix for header in csv files | +| `comment_char` | Comment character for csv files | +| `skip_blank_lines` | Skip blank lines in csv files | ## Metadata Properties diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index 7490437..a6e63b9 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -148,7 +148,7 @@ class SourceConfig: required_properties: List[str] (optional) - list of properties which must be in json data files metadata: DatasetDescription (optional) - metadata for the source delimiter: str (optional) - delimiter for csv files - header: int (optional) - header row index + header: int (optional) - header row index (required if format is csv and header is not none) header_delimiter: str (optional) - delimiter for header in csv files header_prefix: str (optional) - prefix for header in csv files comment_char: str (optional) - comment character for csv files @@ -192,12 +192,10 @@ def extract_archive(self): archive.extractall(archive_path) else: raise ValueError("Error extracting archive. Supported archive types: .tar.gz, .zip") - files = [os.path.join(archive_path, file) for file in self.files] - # Possibly replace with this code if we want to extract all files? (not sure) - # if self.files: - # files = [os.path.join(archive_path, file) for file in self.files] - # else: - # files = [os.path.join(archive_path, file) for file in os.listdir(archive_path)] + if self.files: + files = [os.path.join(archive_path, file) for file in self.files] + else: + files = [os.path.join(archive_path, file) for file in os.listdir(archive_path)] return files def __post_init__(self): From 004332afdf7cf1bb8f10e0eee478a9f8c5a5d11e Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 22 Apr 2024 19:16:52 -0600 Subject: [PATCH 05/30] further documentation changes --- docs/Ingests/index.md | 2 +- docs/Ingests/source_config.md | 62 ++++++++++++++------------ docs/index.md | 2 +- src/koza/model/config/source_config.py | 13 +++--- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/docs/Ingests/index.md b/docs/Ingests/index.md index 8c1eb77..44cd645 100644 --- a/docs/Ingests/index.md +++ b/docs/Ingests/index.md @@ -1,5 +1,5 @@ -(For CLI usage, see the [CLI commands](./CLI.md) page.) +(For CLI usage, see the [CLI commands](../Usage/CLI.md) page.) Koza is designed to process and transform existing data into a target csv/json/jsonl format. diff --git a/docs/Ingests/source_config.md b/docs/Ingests/source_config.md index b889b71..faa7280 100644 --- a/docs/Ingests/source_config.md +++ b/docs/Ingests/source_config.md @@ -4,35 +4,39 @@ This YAML file sets properties for the ingest of a single file type from a withi ## Source Configuration Properties -| **Required properties** | | -| --------------------------- | --------------------------------------------------------------------------------------------------- | -| `name` | Name of the data ingest, as `_`,
ex. `hpoa_gene_to_disease` | -| `files` | List of files to process | -| | | -| **Optional properties** | | -| `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | -| `format` | Format of the data file(s) (CSV or JSON) | -| `sssom_config` | Configures usage of SSSOM mapping files | -| `depends_on` | List of map config files to use | -| `metadata` | Metadata for the source, either a list of properties,
or path to a `metadata.yaml` | -| `transform_code` | Path to a python file to transform the data | -| `transform_mode` | How to process the transform file | -| `global_table` | Path to a global translation table file | -| `local_table` | Path to a local translation table file | -| `field_type_map` | Dict of field names and their type (using the FieldType enum) | -| `filters` | List of filters to apply | -| `json_path` | Path within JSON object containing data to process | -| `required_properties` | List of properties that must be present in output (JSON only) | -| | | -| **CSV-Specific Properties** | | -| `delimiter` | Delimiter for csv files (**Required for CSV format**) | -| **Optional CSV Properties** | | -| `columns` | List of columns to include in output (CSV only) | -| `header` | Header row index for csv files | -| `header_delimiter` | Delimiter for header in csv files | -| `header_prefix` | Prefix for header in csv files | -| `comment_char` | Comment character for csv files | -| `skip_blank_lines` | Skip blank lines in csv files | +| **Required properties** | | +| --------------------------- | ------------------------------------------------------------------------------------------------------ | +| `name` | Name of the data ingest, as `_`,
ex. `hpoa_gene_to_disease` | +| `files` | List of files to process | +| | | +| `node_properties` | List of node properties to include in output | +| `edge_properties` | List of edge properties to include in output | +| **Note** | Either node or edge properties (or both) must be defined in the primary config yaml for your transform | +| | | +| **Optional properties** | | +| `file_archive` | Path to a file archive containing the file(s) to process
Supported archive formats: zip, gzip | +| `format` | Format of the data file(s) (CSV or JSON) | +| `sssom_config` | Configures usage of SSSOM mapping files | +| `depends_on` | List of map config files to use | +| `metadata` | Metadata for the source, either a list of properties,
or path to a `metadata.yaml` | +| `transform_code` | Path to a python file to transform the data | +| `transform_mode` | How to process the transform file | +| `global_table` | Path to a global translation table file | +| `local_table` | Path to a local translation table file | +| `field_type_map` | Dict of field names and their type (using the FieldType enum) | +| `filters` | List of filters to apply | +| `json_path` | Path within JSON object containing data to process | +| `required_properties` | List of properties that must be present in output (JSON only) | +| | | +| **CSV-Specific Properties** | | +| `delimiter` | Delimiter for csv files (**Required for CSV format**) | +| **Optional CSV Properties** | | +| `columns` | List of columns to include in output (CSV only) | +| `header` | Header row index for csv files | +| `header_delimiter` | Delimiter for header in csv files | +| `header_prefix` | Prefix for header in csv files | +| `comment_char` | Comment character for csv files | +| `skip_blank_lines` | Skip blank lines in csv files | ## Metadata Properties diff --git a/docs/index.md b/docs/index.md index ba7844c..3dbb6ca 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ See the [Ingests](./Ingests/index.md) page for information on how to configure i Koza can be used as a Python library, or via the command line. [CLI commands](./Usage/CLI.md) are available for validating and transforming data. -See the [API](./Usage/API.md) page for information on using Koza as a library. +See the [Module](./Usage/Module.md) page for information on using Koza as a library. Koza also includes some examples to help you get started (see `koza/examples`). ### Basic Examples diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index a6e63b9..c79b2ad 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -120,14 +120,14 @@ class DatasetDescription: """ # id: Optional[str] = None # Can uncomment when we have a standard - name: Optional[str] = None # If empty use source name + name: Optional[str] = None # If empty use source name ingest_title: Optional[str] = None # Title of source of data, map to biolink name - ingest_url: Optional[str] = None # URL to source of data, maps to biolink iri - description: Optional[str] = None # Description of the data/ingest + ingest_url: Optional[str] = None # URL to source of data, maps to biolink iri + description: Optional[str] = None # Description of the data/ingest # source: Optional[str] = None # Possibly replaced with provided_by - provided_by: Optional[str] = None # _, ex. hpoa_gene_to_disease + provided_by: Optional[str] = None # _, ex. hpoa_gene_to_disease # license: Optional[str] = None # Possibly redundant, same as rights - rights: Optional[str] = None # License information for the data source + rights: Optional[str] = None # License information for the data source @dataclass(config=PYDANTIC_CONFIG) @@ -291,8 +291,7 @@ def __post_init__(self): @dataclass(config=PYDANTIC_CONFIG) class PrimaryFileConfig(SourceConfig): """ - node_properties and edge_properties are used for configuring - the KGX writer + node_properties and edge_properties are used for configuring the KGX writer """ node_properties: Optional[List[str]] = None From e2fb994971d707c82e6d3161cd7d983da1acadcd Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 15:01:56 -0600 Subject: [PATCH 06/30] add testing util to mock koza, rename cli runner to cli utils --- src/koza/{cli_runner.py => cli_utils.py} | 24 +++----- src/koza/converter/biolink_converter.py | 2 +- src/koza/main.py | 2 +- src/koza/utils/testing_utils.py | 78 ++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 17 deletions(-) rename src/koza/{cli_runner.py => cli_utils.py} (92%) create mode 100644 src/koza/utils/testing_utils.py diff --git a/src/koza/cli_runner.py b/src/koza/cli_utils.py similarity index 92% rename from src/koza/cli_runner.py rename to src/koza/cli_utils.py index ab4a76e..93e87bb 100644 --- a/src/koza/cli_runner.py +++ b/src/koza/cli_utils.py @@ -36,7 +36,7 @@ def get_koza_app(source_name) -> Optional[KozaApp]: def transform_source( source: str, output_dir: str, - output_format: OutputFormat = OutputFormat('tsv'), + output_format: OutputFormat = OutputFormat("tsv"), global_table: str = None, local_table: str = None, schema: str = None, @@ -61,9 +61,9 @@ def transform_source( """ logger = get_logger(name=Path(source).name if log else None, verbose=verbose) - with open(source, 'r') as source_fh: + with open(source, "r") as source_fh: source_config = PrimaryFileConfig(**yaml.load(source_fh, Loader=UniqueIncludeLoader)) - + # TODO: Try moving this to source_config class if not source_config.name: source_config.name = Path(source).stem @@ -73,7 +73,7 @@ def transform_source( if not Path(filename).exists(): filename = Path(source).parent / "transform.py" if not Path(filename).exists(): - raise FileNotFoundError(f"Could not find transform file for {source}") + raise FileNotFoundError(f"Could not find transform file for {source}") source_config.transform_code = filename koza_source = Source(source_config, row_limit) @@ -94,7 +94,7 @@ def transform_source( def validate_file( file: str, format: FormatType = FormatType.csv, - delimiter: str = ',', + delimiter: str = ",", header_delimiter: str = None, skip_blank_lines: bool = True, ): @@ -149,14 +149,14 @@ def get_translation_table( logger.debug("No global table used for transform") else: if isinstance(global_table, str): - with open(global_table, 'r') as global_tt_fh: + with open(global_table, "r") as global_tt_fh: global_tt = yaml.safe_load(global_tt_fh) elif isinstance(global_table, Dict): global_tt = global_table if local_table: if isinstance(local_table, str): - with open(local_table, 'r') as local_tt_fh: + with open(local_table, "r") as local_tt_fh: local_tt = yaml.safe_load(local_tt_fh) elif isinstance(local_table, Dict): local_tt = local_table @@ -170,8 +170,8 @@ def get_translation_table( def _set_koza_app( source: Source, translation_table: TranslationTable = None, - output_dir: str = './output', - output_format: OutputFormat = OutputFormat('tsv'), + output_dir: str = "./output", + output_format: OutputFormat = OutputFormat("tsv"), schema: str = None, node_type: str = None, edge_type: str = None, @@ -184,9 +184,3 @@ def _set_koza_app( ) logger.debug(f"koza_apps entry created for {source.config.name}: {koza_apps[source.config.name]}") return koza_apps[source.config.name] - - -def test_koza(koza: KozaApp): - """Manually sets KozaApp (for testing)""" - global koza_app - koza_app = koza diff --git a/src/koza/converter/biolink_converter.py b/src/koza/converter/biolink_converter.py index e5d6747..af6eb60 100644 --- a/src/koza/converter/biolink_converter.py +++ b/src/koza/converter/biolink_converter.py @@ -1,6 +1,6 @@ from biolink_model.datamodel.pydanticmodel_v2 import Gene -from koza.cli_runner import koza_app +from koza.cli_utils import koza_app def gpi2gene(row: dict) -> Gene: diff --git a/src/koza/main.py b/src/koza/main.py index 74bc55b..b349a56 100755 --- a/src/koza/main.py +++ b/src/koza/main.py @@ -4,7 +4,7 @@ from pathlib import Path from typing import Optional -from koza.cli_runner import transform_source, validate_file +from koza.cli_utils import transform_source, validate_file from koza.model.config.source_config import FormatType, OutputFormat import typer diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py new file mode 100644 index 0000000..b4bf0bb --- /dev/null +++ b/src/koza/utils/testing_utils.py @@ -0,0 +1,78 @@ +import types +from typing import Iterable + +from loguru import logger + +from koza.app import KozaApp +from koza.cli_utils import get_koza_app, get_translation_table, _set_koza_app +from koza.model.config.source_config import PrimaryFileConfig +from koza.model.source import Source + +def test_koza(koza: KozaApp): + """Manually sets KozaApp for testing""" + global koza_app + koza_app = koza + +def mock_koza(): + """Mock KozaApp for testing""" + def _mock_write(self, *entities): + if hasattr(self, '_entities'): + self._entities.extend(list(entities)) + else: + self._entities = list(entities) + + def _make_mock_koza_app( + name: str, + data: Iterable, + transform_code: str, + map_cache=None, + filters=None, + global_table=None, + local_table=None, + ): + mock_source_file_config = PrimaryFileConfig( + name=name, + files=[], + transform_code=transform_code, + ) + mock_source_file = Source(mock_source_file_config) + mock_source_file._reader = data + + _set_koza_app( + source=mock_source_file, + translation_table=get_translation_table(global_table, local_table, logger), + logger=logger, + ) + koza = get_koza_app(name) + + # TODO filter mocks + koza._map_cache = map_cache + koza.write = types.MethodType(_mock_write, koza) + + return koza + + def _transform( + name: str, + data: Iterable, + transform_code: str, + map_cache=None, + filters=None, + global_table=None, + local_table=None, + ): + koza_app = _make_mock_koza_app( + name, + data, + transform_code, + map_cache=map_cache, + filters=filters, + global_table=global_table, + local_table=local_table, + ) + test_koza(koza_app) + koza_app.process_sources() + if not hasattr(koza_app, '_entities'): + koza_app._entities = [] + return koza_app._entities + + return _transform From 7dade07519afd71d0d77ab239f074ad3738045d4 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 15:04:18 -0600 Subject: [PATCH 07/30] fix imports in tests --- docs/Ingests/transform.md | 4 ++-- docs/Usage/Module.md | 2 +- examples/maps/custom-entrez-2-string.py | 2 +- .../string-declarative/declarative-protein-links-detailed.py | 2 +- .../string-w-custom-map/custom-map-protein-links-detailed.py | 2 +- examples/string-w-map/map-protein-links-detailed.py | 2 +- examples/string/protein-links-detailed.py | 2 +- tests/conftest.py | 2 +- tests/integration/test_examples.py | 2 +- tests/integration/test_parallel.py | 2 +- tests/integration/test_row_limit.py | 2 +- tests/integration/test_validator.py | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/Ingests/transform.md b/docs/Ingests/transform.md index c8d6ece..3069db9 100644 --- a/docs/Ingests/transform.md +++ b/docs/Ingests/transform.md @@ -8,7 +8,7 @@ it creates a `KozaApp` object for the specified ingest. This KozaApp will be your entry point to Koza: ```python -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app koza_app = get_koza_app('your-source-name') ``` @@ -34,7 +34,7 @@ you can pass these to `koza_app.write()` to output the transformed data to the t from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction # Koza imports - from koza.cli_runner import get_koza_app + from koza.cli_utils import get_koza_app # This is the name of the ingest you want to run source_name = 'map-protein-links-detailed' diff --git a/docs/Usage/Module.md b/docs/Usage/Module.md index 63a9567..dda763a 100644 --- a/docs/Usage/Module.md +++ b/docs/Usage/Module.md @@ -1 +1 @@ -::: src.koza.cli_runner \ No newline at end of file +::: src.koza.cli_utils \ No newline at end of file diff --git a/examples/maps/custom-entrez-2-string.py b/examples/maps/custom-entrez-2-string.py index 72ae769..de2c07a 100644 --- a/examples/maps/custom-entrez-2-string.py +++ b/examples/maps/custom-entrez-2-string.py @@ -1,4 +1,4 @@ -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app source_name = 'custom-map-protein-links-detailed' map_name = 'custom-entrez-2-string' diff --git a/examples/string-declarative/declarative-protein-links-detailed.py b/examples/string-declarative/declarative-protein-links-detailed.py index a3e52f6..e06967d 100644 --- a/examples/string-declarative/declarative-protein-links-detailed.py +++ b/examples/string-declarative/declarative-protein-links-detailed.py @@ -3,7 +3,7 @@ from biolink_model.datamodel.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app koza_app = get_koza_app("declarative-protein-links-detailed") diff --git a/examples/string-w-custom-map/custom-map-protein-links-detailed.py b/examples/string-w-custom-map/custom-map-protein-links-detailed.py index 30af763..1a3ef4f 100644 --- a/examples/string-w-custom-map/custom-map-protein-links-detailed.py +++ b/examples/string-w-custom-map/custom-map-protein-links-detailed.py @@ -2,7 +2,7 @@ from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app source_name = "custom-map-protein-links-detailed" koza_app = get_koza_app(source_name) diff --git a/examples/string-w-map/map-protein-links-detailed.py b/examples/string-w-map/map-protein-links-detailed.py index 0ad4ee6..95b87b8 100644 --- a/examples/string-w-map/map-protein-links-detailed.py +++ b/examples/string-w-map/map-protein-links-detailed.py @@ -2,7 +2,7 @@ from biolink_model.datamodel.pydanticmodel_v2 import Gene, PairwiseGeneToGeneInteraction -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app source_name = "map-protein-links-detailed" map_name = "entrez-2-string" diff --git a/examples/string/protein-links-detailed.py b/examples/string/protein-links-detailed.py index 1cf6778..9ce03ae 100644 --- a/examples/string/protein-links-detailed.py +++ b/examples/string/protein-links-detailed.py @@ -3,7 +3,7 @@ from biolink_model.datamodel.pydanticmodel_v2 import PairwiseGeneToGeneInteraction, Protein -from koza.cli_runner import get_koza_app +from koza.cli_utils import get_koza_app koza_app = get_koza_app('protein-links-detailed') diff --git a/tests/conftest.py b/tests/conftest.py index 2f92415..7e5fdb0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,7 +5,7 @@ from loguru import logger from koza.app import KozaApp -from koza.cli_runner import test_koza +from koza.utils.testing_utils import test_koza from koza.model.config.source_config import PrimaryFileConfig from koza.model.source import Source diff --git a/tests/integration/test_examples.py b/tests/integration/test_examples.py index 946e5d0..cc92ad1 100644 --- a/tests/integration/test_examples.py +++ b/tests/integration/test_examples.py @@ -6,7 +6,7 @@ import pytest -from koza.cli_runner import transform_source +from koza.cli_utils import transform_source from koza.model.config.source_config import OutputFormat diff --git a/tests/integration/test_parallel.py b/tests/integration/test_parallel.py index 9809410..9a462c4 100644 --- a/tests/integration/test_parallel.py +++ b/tests/integration/test_parallel.py @@ -4,7 +4,7 @@ # import pytest import dask -from koza.cli_runner import transform_source +from koza.cli_utils import transform_source from koza.model.config.source_config import OutputFormat diff --git a/tests/integration/test_row_limit.py b/tests/integration/test_row_limit.py index 3c9d8b7..2b8f918 100644 --- a/tests/integration/test_row_limit.py +++ b/tests/integration/test_row_limit.py @@ -8,7 +8,7 @@ import pytest -from koza.cli_runner import transform_source +from koza.cli_utils import transform_source from koza.model.config.source_config import OutputFormat diff --git a/tests/integration/test_validator.py b/tests/integration/test_validator.py index be5bb0f..21eb8a5 100644 --- a/tests/integration/test_validator.py +++ b/tests/integration/test_validator.py @@ -11,7 +11,7 @@ import pytest -from koza.cli_runner import transform_source +from koza.cli_utils import transform_source from koza.model.config.source_config import OutputFormat # pytest.skip("LinkML issue with `category` slot has `designates_type: true`", allow_module_level=True) From 8fdae5999ebf887633bb71de45bdae5861f7cfce Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 15:31:53 -0600 Subject: [PATCH 08/30] update deps --- poetry.lock | 231 +++++++++++++++++++++++++------------------------ pyproject.toml | 8 +- 2 files changed, 120 insertions(+), 119 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5fdeff7..e3b6b64 100644 --- a/poetry.lock +++ b/poetry.lock @@ -116,33 +116,33 @@ yamllint = ">=1.35.1,<2.0.0" [[package]] name = "black" -version = "23.12.1" +version = "24.4.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, + {file = "black-24.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f7749fd0d97ff9415975a1432fac7df89bf13c3833cea079e55fa004d5f28c0"}, + {file = "black-24.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:859f3cc5d2051adadf8fd504a01e02b0fd866d7549fff54bc9202d524d2e8bd7"}, + {file = "black-24.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59271c9c29dfa97f7fda51f56c7809b3f78e72fd8d2205189bbd23022a0618b6"}, + {file = "black-24.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:5ed9c34cba223149b5a0144951a0f33d65507cf82c5449cb3c35fe4b515fea9a"}, + {file = "black-24.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dae3ae59d6f2dc93700fd5034a3115434686e66fd6e63d4dcaa48d19880f2b0"}, + {file = "black-24.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5f8698974a81af83283eb47644f2711b5261138d6d9180c863fce673cbe04b13"}, + {file = "black-24.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f404b6e77043b23d0321fb7772522b876b6de737ad3cb97d6b156638d68ce81"}, + {file = "black-24.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:c94e52b766477bdcd010b872ba0714d5458536dc9d0734eff6583ba7266ffd89"}, + {file = "black-24.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:962d9e953872cdb83b97bb737ad47244ce2938054dc946685a4cad98520dab38"}, + {file = "black-24.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d8e3b2486b7dd522b1ab2ba1ec4907f0aa8f5e10a33c4271fb331d1d10b70c"}, + {file = "black-24.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed77e214b785148f57e43ca425b6e0850165144aa727d66ac604e56a70bb7825"}, + {file = "black-24.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:4ef4764437d7eba8386689cd06e1fb5341ee0ae2e9e22582b21178782de7ed94"}, + {file = "black-24.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:92b183f8eef5baf7b20a513abcf982ad616f544f593f6688bb2850d2982911f1"}, + {file = "black-24.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:945abd7b3572add997757c94295bb3e73c6ffaf3366b1f26cb2356a4bffd1dc3"}, + {file = "black-24.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db5154b9e5b478031371d8bc41ff37b33855fa223a6cfba456c9b73fb96f77d4"}, + {file = "black-24.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:afc84c33c1a9aaf3d73140cee776b4ddf73ff429ffe6b7c56dc1c9c10725856d"}, + {file = "black-24.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0889f4eb8b3bdf8b189e41a71cf0dbb8141a98346cd1a2695dea5995d416e940"}, + {file = "black-24.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5bb0143f175db45a55227eefd63e90849d96c266330ba31719e9667d0d5ec3b9"}, + {file = "black-24.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:713a04a78e78f28ef7e8df7a16fe075670ea164860fcef3885e4f3dffc0184b3"}, + {file = "black-24.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:171959bc879637a8cdbc53dc3fddae2a83e151937a28cf605fd175ce61e0e94a"}, + {file = "black-24.4.1-py3-none-any.whl", hash = "sha256:ecbab810604fe02c70b3a08afd39beb599f7cc9afd13e81f5336014133b4fe35"}, + {file = "black-24.4.1.tar.gz", hash = "sha256:5241612dc8cad5b6fd47432b8bd04db80e07cfbc53bb69e9ae18985063bcb8dd"}, ] [package.dependencies] @@ -1473,18 +1473,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, + {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" @@ -1546,18 +1547,18 @@ pyyaml = ">=5.3.1" [[package]] name = "pydantic" -version = "2.7.0" +version = "2.7.1" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.0-py3-none-any.whl", hash = "sha256:9dee74a271705f14f9a1567671d144a851c675b072736f0a7b2608fd9e495352"}, - {file = "pydantic-2.7.0.tar.gz", hash = "sha256:b5ecdd42262ca2462e2624793551e80911a1e989f462910bb81aef974b4bb383"}, + {file = "pydantic-2.7.1-py3-none-any.whl", hash = "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5"}, + {file = "pydantic-2.7.1.tar.gz", hash = "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.1" +pydantic-core = "2.18.2" typing-extensions = ">=4.6.1" [package.extras] @@ -1565,90 +1566,90 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.1" +version = "2.18.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ee9cf33e7fe14243f5ca6977658eb7d1042caaa66847daacbd2117adb258b226"}, - {file = "pydantic_core-2.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6b7bbb97d82659ac8b37450c60ff2e9f97e4eb0f8a8a3645a5568b9334b08b50"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df4249b579e75094f7e9bb4bd28231acf55e308bf686b952f43100a5a0be394c"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d0491006a6ad20507aec2be72e7831a42efc93193d2402018007ff827dc62926"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ae80f72bb7a3e397ab37b53a2b49c62cc5496412e71bc4f1277620a7ce3f52b"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58aca931bef83217fca7a390e0486ae327c4af9c3e941adb75f8772f8eeb03a1"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1be91ad664fc9245404a789d60cba1e91c26b1454ba136d2a1bf0c2ac0c0505a"}, - {file = "pydantic_core-2.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:667880321e916a8920ef49f5d50e7983792cf59f3b6079f3c9dac2b88a311d17"}, - {file = "pydantic_core-2.18.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f7054fdc556f5421f01e39cbb767d5ec5c1139ea98c3e5b350e02e62201740c7"}, - {file = "pydantic_core-2.18.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:030e4f9516f9947f38179249778709a460a3adb516bf39b5eb9066fcfe43d0e6"}, - {file = "pydantic_core-2.18.1-cp310-none-win32.whl", hash = "sha256:2e91711e36e229978d92642bfc3546333a9127ecebb3f2761372e096395fc649"}, - {file = "pydantic_core-2.18.1-cp310-none-win_amd64.whl", hash = "sha256:9a29726f91c6cb390b3c2338f0df5cd3e216ad7a938762d11c994bb37552edb0"}, - {file = "pydantic_core-2.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9ece8a49696669d483d206b4474c367852c44815fca23ac4e48b72b339807f80"}, - {file = "pydantic_core-2.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a5d83efc109ceddb99abd2c1316298ced2adb4570410defe766851a804fcd5b"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7973c381283783cd1043a8c8f61ea5ce7a3a58b0369f0ee0ee975eaf2f2a1b"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:54c7375c62190a7845091f521add19b0f026bcf6ae674bdb89f296972272e86d"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd63cec4e26e790b70544ae5cc48d11b515b09e05fdd5eff12e3195f54b8a586"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:561cf62c8a3498406495cfc49eee086ed2bb186d08bcc65812b75fda42c38294"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68717c38a68e37af87c4da20e08f3e27d7e4212e99e96c3d875fbf3f4812abfc"}, - {file = "pydantic_core-2.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d5728e93d28a3c63ee513d9ffbac9c5989de8c76e049dbcb5bfe4b923a9739d"}, - {file = "pydantic_core-2.18.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f0f17814c505f07806e22b28856c59ac80cee7dd0fbb152aed273e116378f519"}, - {file = "pydantic_core-2.18.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d816f44a51ba5175394bc6c7879ca0bd2be560b2c9e9f3411ef3a4cbe644c2e9"}, - {file = "pydantic_core-2.18.1-cp311-none-win32.whl", hash = "sha256:09f03dfc0ef8c22622eaa8608caa4a1e189cfb83ce847045eca34f690895eccb"}, - {file = "pydantic_core-2.18.1-cp311-none-win_amd64.whl", hash = "sha256:27f1009dc292f3b7ca77feb3571c537276b9aad5dd4efb471ac88a8bd09024e9"}, - {file = "pydantic_core-2.18.1-cp311-none-win_arm64.whl", hash = "sha256:48dd883db92e92519201f2b01cafa881e5f7125666141a49ffba8b9facc072b0"}, - {file = "pydantic_core-2.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b6b0e4912030c6f28bcb72b9ebe4989d6dc2eebcd2a9cdc35fefc38052dd4fe8"}, - {file = "pydantic_core-2.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3202a429fe825b699c57892d4371c74cc3456d8d71b7f35d6028c96dfecad31"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3982b0a32d0a88b3907e4b0dc36809fda477f0757c59a505d4e9b455f384b8b"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25595ac311f20e5324d1941909b0d12933f1fd2171075fcff763e90f43e92a0d"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14fe73881cf8e4cbdaded8ca0aa671635b597e42447fec7060d0868b52d074e6"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca976884ce34070799e4dfc6fbd68cb1d181db1eefe4a3a94798ddfb34b8867f"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:684d840d2c9ec5de9cb397fcb3f36d5ebb6fa0d94734f9886032dd796c1ead06"}, - {file = "pydantic_core-2.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:54764c083bbe0264f0f746cefcded6cb08fbbaaf1ad1d78fb8a4c30cff999a90"}, - {file = "pydantic_core-2.18.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:201713f2f462e5c015b343e86e68bd8a530a4f76609b33d8f0ec65d2b921712a"}, - {file = "pydantic_core-2.18.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fd1a9edb9dd9d79fbeac1ea1f9a8dd527a6113b18d2e9bcc0d541d308dae639b"}, - {file = "pydantic_core-2.18.1-cp312-none-win32.whl", hash = "sha256:d5e6b7155b8197b329dc787356cfd2684c9d6a6b1a197f6bbf45f5555a98d411"}, - {file = "pydantic_core-2.18.1-cp312-none-win_amd64.whl", hash = "sha256:9376d83d686ec62e8b19c0ac3bf8d28d8a5981d0df290196fb6ef24d8a26f0d6"}, - {file = "pydantic_core-2.18.1-cp312-none-win_arm64.whl", hash = "sha256:c562b49c96906b4029b5685075fe1ebd3b5cc2601dfa0b9e16c2c09d6cbce048"}, - {file = "pydantic_core-2.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3e352f0191d99fe617371096845070dee295444979efb8f27ad941227de6ad09"}, - {file = "pydantic_core-2.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0295d52b012cbe0d3059b1dba99159c3be55e632aae1999ab74ae2bd86a33d7"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56823a92075780582d1ffd4489a2e61d56fd3ebb4b40b713d63f96dd92d28144"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd3f79e17b56741b5177bcc36307750d50ea0698df6aa82f69c7db32d968c1c2"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38a5024de321d672a132b1834a66eeb7931959c59964b777e8f32dbe9523f6b1"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2ce426ee691319d4767748c8e0895cfc56593d725594e415f274059bcf3cb76"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2adaeea59849ec0939af5c5d476935f2bab4b7f0335b0110f0f069a41024278e"}, - {file = "pydantic_core-2.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9b6431559676a1079eac0f52d6d0721fb8e3c5ba43c37bc537c8c83724031feb"}, - {file = "pydantic_core-2.18.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:85233abb44bc18d16e72dc05bf13848a36f363f83757541f1a97db2f8d58cfd9"}, - {file = "pydantic_core-2.18.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:641a018af4fe48be57a2b3d7a1f0f5dbca07c1d00951d3d7463f0ac9dac66622"}, - {file = "pydantic_core-2.18.1-cp38-none-win32.whl", hash = "sha256:63d7523cd95d2fde0d28dc42968ac731b5bb1e516cc56b93a50ab293f4daeaad"}, - {file = "pydantic_core-2.18.1-cp38-none-win_amd64.whl", hash = "sha256:907a4d7720abfcb1c81619863efd47c8a85d26a257a2dbebdb87c3b847df0278"}, - {file = "pydantic_core-2.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:aad17e462f42ddbef5984d70c40bfc4146c322a2da79715932cd8976317054de"}, - {file = "pydantic_core-2.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:94b9769ba435b598b547c762184bcfc4783d0d4c7771b04a3b45775c3589ca44"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80e0e57cc704a52fb1b48f16d5b2c8818da087dbee6f98d9bf19546930dc64b5"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76b86e24039c35280ceee6dce7e62945eb93a5175d43689ba98360ab31eebc4a"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a05db5013ec0ca4a32cc6433f53faa2a014ec364031408540ba858c2172bb0"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:250ae39445cb5475e483a36b1061af1bc233de3e9ad0f4f76a71b66231b07f88"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a32204489259786a923e02990249c65b0f17235073149d0033efcebe80095570"}, - {file = "pydantic_core-2.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6395a4435fa26519fd96fdccb77e9d00ddae9dd6c742309bd0b5610609ad7fb2"}, - {file = "pydantic_core-2.18.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2533ad2883f001efa72f3d0e733fb846710c3af6dcdd544fe5bf14fa5fe2d7db"}, - {file = "pydantic_core-2.18.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b560b72ed4816aee52783c66854d96157fd8175631f01ef58e894cc57c84f0f6"}, - {file = "pydantic_core-2.18.1-cp39-none-win32.whl", hash = "sha256:582cf2cead97c9e382a7f4d3b744cf0ef1a6e815e44d3aa81af3ad98762f5a9b"}, - {file = "pydantic_core-2.18.1-cp39-none-win_amd64.whl", hash = "sha256:ca71d501629d1fa50ea7fa3b08ba884fe10cefc559f5c6c8dfe9036c16e8ae89"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e178e5b66a06ec5bf51668ec0d4ac8cfb2bdcb553b2c207d58148340efd00143"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:72722ce529a76a4637a60be18bd789d8fb871e84472490ed7ddff62d5fed620d"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe0c1ce5b129455e43f941f7a46f61f3d3861e571f2905d55cdbb8b5c6f5e2c"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4284c621f06a72ce2cb55f74ea3150113d926a6eb78ab38340c08f770eb9b4d"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a0c3e718f4e064efde68092d9d974e39572c14e56726ecfaeebbe6544521f47"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2027493cc44c23b598cfaf200936110433d9caa84e2c6cf487a83999638a96ac"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:76909849d1a6bffa5a07742294f3fa1d357dc917cb1fe7b470afbc3a7579d539"}, - {file = "pydantic_core-2.18.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ee7ccc7fb7e921d767f853b47814c3048c7de536663e82fbc37f5eb0d532224b"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee2794111c188548a4547eccc73a6a8527fe2af6cf25e1a4ebda2fd01cdd2e60"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a139fe9f298dc097349fb4f28c8b81cc7a202dbfba66af0e14be5cfca4ef7ce5"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d074b07a10c391fc5bbdcb37b2f16f20fcd9e51e10d01652ab298c0d07908ee2"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c69567ddbac186e8c0aadc1f324a60a564cfe25e43ef2ce81bcc4b8c3abffbae"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf1c7b78cddb5af00971ad5294a4583188bda1495b13760d9f03c9483bb6203"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2684a94fdfd1b146ff10689c6e4e815f6a01141781c493b97342cdc5b06f4d5d"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:73c1bc8a86a5c9e8721a088df234265317692d0b5cd9e86e975ce3bc3db62a59"}, - {file = "pydantic_core-2.18.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e60defc3c15defb70bb38dd605ff7e0fae5f6c9c7cbfe0ad7868582cb7e844a6"}, - {file = "pydantic_core-2.18.1.tar.gz", hash = "sha256:de9d3e8717560eb05e28739d1b35e4eac2e458553a52a301e51352a7ffc86a35"}, + {file = "pydantic_core-2.18.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81"}, + {file = "pydantic_core-2.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af"}, + {file = "pydantic_core-2.18.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857"}, + {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563"}, + {file = "pydantic_core-2.18.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38"}, + {file = "pydantic_core-2.18.2-cp310-none-win32.whl", hash = "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027"}, + {file = "pydantic_core-2.18.2-cp310-none-win_amd64.whl", hash = "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543"}, + {file = "pydantic_core-2.18.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3"}, + {file = "pydantic_core-2.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6"}, + {file = "pydantic_core-2.18.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c"}, + {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0"}, + {file = "pydantic_core-2.18.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664"}, + {file = "pydantic_core-2.18.2-cp311-none-win32.whl", hash = "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e"}, + {file = "pydantic_core-2.18.2-cp311-none-win_amd64.whl", hash = "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3"}, + {file = "pydantic_core-2.18.2-cp311-none-win_arm64.whl", hash = "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d"}, + {file = "pydantic_core-2.18.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"}, + {file = "pydantic_core-2.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72"}, + {file = "pydantic_core-2.18.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c"}, + {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241"}, + {file = "pydantic_core-2.18.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3"}, + {file = "pydantic_core-2.18.2-cp312-none-win32.whl", hash = "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038"}, + {file = "pydantic_core-2.18.2-cp312-none-win_amd64.whl", hash = "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438"}, + {file = "pydantic_core-2.18.2-cp312-none-win_arm64.whl", hash = "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec"}, + {file = "pydantic_core-2.18.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439"}, + {file = "pydantic_core-2.18.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70"}, + {file = "pydantic_core-2.18.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b"}, + {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761"}, + {file = "pydantic_core-2.18.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788"}, + {file = "pydantic_core-2.18.2-cp38-none-win32.whl", hash = "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350"}, + {file = "pydantic_core-2.18.2-cp38-none-win_amd64.whl", hash = "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e"}, + {file = "pydantic_core-2.18.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8"}, + {file = "pydantic_core-2.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0"}, + {file = "pydantic_core-2.18.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4"}, + {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399"}, + {file = "pydantic_core-2.18.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b"}, + {file = "pydantic_core-2.18.2-cp39-none-win32.whl", hash = "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e"}, + {file = "pydantic_core-2.18.2-cp39-none-win_amd64.whl", hash = "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b"}, + {file = "pydantic_core-2.18.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae"}, + {file = "pydantic_core-2.18.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374"}, + {file = "pydantic_core-2.18.2.tar.gz", hash = "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e"}, ] [package.dependencies] @@ -1955,13 +1956,13 @@ rdflib-jsonld = "0.6.1" [[package]] name = "referencing" -version = "0.34.0" +version = "0.35.0" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.34.0-py3-none-any.whl", hash = "sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4"}, - {file = "referencing-0.34.0.tar.gz", hash = "sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844"}, + {file = "referencing-0.35.0-py3-none-any.whl", hash = "sha256:8080727b30e364e5783152903672df9b6b091c926a146a759080b62ca3126cd6"}, + {file = "referencing-0.35.0.tar.gz", hash = "sha256:191e936b0c696d0af17ad7430a3dc68e88bc11be6514f4757dc890f04ab05889"}, ] [package.dependencies] @@ -2918,4 +2919,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "40207ecd405a86ce7b93123b9aec29588d047466ec2b630f64e3dd172cabc2f6" +content-hash = "20c9bbc4596f5cf803b6a53ad3184e4ebadc8ab97eaa6da867af6c7f29b3b653" diff --git a/pyproject.toml b/pyproject.toml index 2da07fc..9569db4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,18 +21,18 @@ pydantic = "^2.4" pyyaml = ">=5.0.0" requests = "^2.24.0" ordered-set = ">=4.1.0" -typer = "^0.12.3" +typer = ">=0.12.3" loguru = "*" sssom = ">=0.4" [tool.poetry.dev-dependencies] -black = "^23.10.0" +black = "^24.4" ruff = "*" pytest = ">=6.0.0" biolink-model = ">=4.2" dask = ">=2022.5.2" -mkdocs = ">=1.4.2" -mkdocs-material = ">=9.1.16" +mkdocs = ">=1.4" +mkdocs-material = ">=9.5" mkdocstrings = {extras = ["python"], version = ">=0.22.0"} [tool.poetry.scripts] From 9c4ac7829c83e424fb90816335c5cd730a6ec8f5 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 16:17:53 -0600 Subject: [PATCH 09/30] try class instead of function --- src/koza/utils/testing_utils.py | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index b4bf0bb..f71cf02 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -8,15 +8,18 @@ from koza.model.config.source_config import PrimaryFileConfig from koza.model.source import Source + def test_koza(koza: KozaApp): """Manually sets KozaApp for testing""" global koza_app koza_app = koza + def mock_koza(): """Mock KozaApp for testing""" + def _mock_write(self, *entities): - if hasattr(self, '_entities'): + if hasattr(self, "_entities"): self._entities.extend(list(entities)) else: self._entities = list(entities) @@ -71,8 +74,76 @@ def _transform( ) test_koza(koza_app) koza_app.process_sources() - if not hasattr(koza_app, '_entities'): + if not hasattr(koza_app, "_entities"): koza_app._entities = [] return koza_app._entities return _transform + + +class MockKoza: + """Mock KozaApp for testing""" + + def __init__( + self, + name: str, + data: Iterable, + transform_code: str, + map_cache=None, + filters=None, + global_table=None, + local_table=None, + ): + self.name = name + self.data = data + self.transform_code = transform_code + self.map_cache = map_cache + self.filters = filters + self.global_table = global_table + self.local_table = local_table + + # return self.transform() + + def mock_write(self, *entities): + if hasattr(self, "_entities"): + self._entities.extend(list(entities)) + else: + self._entities = list(entities) + + def make_mock_koza_app(self): + mock_source_file_config = PrimaryFileConfig( + name=self.name, + files=[], + transform_code=self.transform_code, + ) + mock_source_file = Source(mock_source_file_config) + mock_source_file._reader = self.data + + _set_koza_app( + source=mock_source_file, + translation_table=get_translation_table(self.global_table, self.local_table, logger), + logger=logger, + ) + koza = get_koza_app(self.name) + + # TODO filter mocks + koza._map_cache = self.map_cache + koza.write = types.MethodType(self._mock_write, koza) + + return koza + + def transform(self): + koza_app = self._make_mock_koza_app( + self.name, + self.data, + self.transform_code, + map_cache=self.map_cache, + filters=self.filters, + global_table=self.global_table, + local_table=self.local_table, + ) + test_koza(koza_app) + koza_app.process_sources() + if not hasattr(koza_app, "_entities"): + koza_app._entities = [] + return koza_app._entities From 8f3a3eb0e63a6f573daf41ede860cb417f70067e Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 16:19:17 -0600 Subject: [PATCH 10/30] typo --- src/koza/utils/testing_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index f71cf02..bc41ff5 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -133,7 +133,7 @@ def make_mock_koza_app(self): return koza def transform(self): - koza_app = self._make_mock_koza_app( + koza_app = self.make_mock_koza_app( self.name, self.data, self.transform_code, From c835bf3e59acd2c22e845fc27539d8b2a6dbe6d3 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 16:20:32 -0600 Subject: [PATCH 11/30] remove args from make_mock_koza_app --- src/koza/utils/testing_utils.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index bc41ff5..5ab1501 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -133,15 +133,7 @@ def make_mock_koza_app(self): return koza def transform(self): - koza_app = self.make_mock_koza_app( - self.name, - self.data, - self.transform_code, - map_cache=self.map_cache, - filters=self.filters, - global_table=self.global_table, - local_table=self.local_table, - ) + koza_app = self.make_mock_koza_app() test_koza(koza_app) koza_app.process_sources() if not hasattr(koza_app, "_entities"): From 791d654e3ca8db34ccea8df682ec43511e4a3b69 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 16:21:40 -0600 Subject: [PATCH 12/30] more typos --- src/koza/utils/testing_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index 5ab1501..b3997fe 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -106,9 +106,9 @@ def __init__( def mock_write(self, *entities): if hasattr(self, "_entities"): - self._entities.extend(list(entities)) + self.entities.extend(list(entities)) else: - self._entities = list(entities) + self.entities = list(entities) def make_mock_koza_app(self): mock_source_file_config = PrimaryFileConfig( @@ -128,7 +128,7 @@ def make_mock_koza_app(self): # TODO filter mocks koza._map_cache = self.map_cache - koza.write = types.MethodType(self._mock_write, koza) + koza.write = types.MethodType(self.mock_write, koza) return koza From 2a1545da4cf55b3629cb3ac1e29eda984624674b Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 16:33:14 -0600 Subject: [PATCH 13/30] add underscore back to entities, maybe that matters? --- src/koza/utils/testing_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index b3997fe..24ad4fa 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -106,9 +106,9 @@ def __init__( def mock_write(self, *entities): if hasattr(self, "_entities"): - self.entities.extend(list(entities)) + self._entities.extend(list(entities)) else: - self.entities = list(entities) + self._entities = list(entities) def make_mock_koza_app(self): mock_source_file_config = PrimaryFileConfig( From 7e9a5d120c968d8fad79737b132f1fb503e6f811 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 17:07:40 -0600 Subject: [PATCH 14/30] try making it a fixture --- src/koza/utils/testing_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index 24ad4fa..ec7fbf3 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -2,6 +2,7 @@ from typing import Iterable from loguru import logger +import pytest from koza.app import KozaApp from koza.cli_utils import get_koza_app, get_translation_table, _set_koza_app @@ -14,7 +15,7 @@ def test_koza(koza: KozaApp): global koza_app koza_app = koza - +@pytest.fixture(scope="package") def mock_koza(): """Mock KozaApp for testing""" From bc0c5028ec8b97effd5b072bc72a0c26d7908f54 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Wed, 24 Apr 2024 17:10:52 -0600 Subject: [PATCH 15/30] ok fixture works. removing class --- src/koza/utils/testing_utils.py | 63 ++------------------------------- 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index ec7fbf3..9d10796 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -1,8 +1,8 @@ import types from typing import Iterable -from loguru import logger import pytest +from loguru import logger from koza.app import KozaApp from koza.cli_utils import get_koza_app, get_translation_table, _set_koza_app @@ -15,6 +15,7 @@ def test_koza(koza: KozaApp): global koza_app koza_app = koza + @pytest.fixture(scope="package") def mock_koza(): """Mock KozaApp for testing""" @@ -80,63 +81,3 @@ def _transform( return koza_app._entities return _transform - - -class MockKoza: - """Mock KozaApp for testing""" - - def __init__( - self, - name: str, - data: Iterable, - transform_code: str, - map_cache=None, - filters=None, - global_table=None, - local_table=None, - ): - self.name = name - self.data = data - self.transform_code = transform_code - self.map_cache = map_cache - self.filters = filters - self.global_table = global_table - self.local_table = local_table - - # return self.transform() - - def mock_write(self, *entities): - if hasattr(self, "_entities"): - self._entities.extend(list(entities)) - else: - self._entities = list(entities) - - def make_mock_koza_app(self): - mock_source_file_config = PrimaryFileConfig( - name=self.name, - files=[], - transform_code=self.transform_code, - ) - mock_source_file = Source(mock_source_file_config) - mock_source_file._reader = self.data - - _set_koza_app( - source=mock_source_file, - translation_table=get_translation_table(self.global_table, self.local_table, logger), - logger=logger, - ) - koza = get_koza_app(self.name) - - # TODO filter mocks - koza._map_cache = self.map_cache - koza.write = types.MethodType(self.mock_write, koza) - - return koza - - def transform(self): - koza_app = self.make_mock_koza_app() - test_koza(koza_app) - koza_app.process_sources() - if not hasattr(koza_app, "_entities"): - koza_app._entities = [] - return koza_app._entities From aa99993cc36a93c6859db44f0fdb76451164bc58 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Thu, 25 Apr 2024 17:24:36 -0600 Subject: [PATCH 16/30] add testing documentation, create iterator in mock koza directly --- README.md | 2 +- docs/Ingests/testing.md | 87 ++++++++++++++++++++++++ mkdocs.yaml | 1 + pyproject.toml | 4 +- src/koza/io/reader/csv_reader.py | 2 +- src/koza/io/reader/json_reader.py | 3 +- src/koza/io/utils.py | 2 +- src/koza/model/config/pydantic_config.py | 8 +-- src/koza/model/config/source_config.py | 1 - src/koza/utils/testing_utils.py | 6 +- tests/integration/test_parallel.py | 1 + tests/integration/test_row_limit.py | 1 + tests/unit/test_config.py | 1 + tests/unit/test_custom_dict.py | 1 + tests/unit/test_filter.py | 1 + tests/unit/test_validation.py | 14 ++-- 16 files changed, 115 insertions(+), 20 deletions(-) create mode 100644 docs/Ingests/testing.md diff --git a/README.md b/README.md index 3f95a10..f43f6fd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Pyversions](https://img.shields.io/pypi/pyversions/koza.svg)](https://pypi.python.org/pypi/koza) [![PyPi](https://img.shields.io/pypi/v/koza.svg)](https://pypi.python.org/pypi/koza) -![Github Action](https://github.com/monarch-initiative/koza/actions/workflows/build.yml/badge.svg) +![Github Action](https://github.com/monarch-initiative/koza/actions/workflows/test.yaml/badge.svg) ![pupa](docs/img/pupa.png) diff --git a/docs/Ingests/testing.md b/docs/Ingests/testing.md new file mode 100644 index 0000000..42ab436 --- /dev/null +++ b/docs/Ingests/testing.md @@ -0,0 +1,87 @@ +Koza includes a `mock_koza` fixture (see `src/koza/utils/testing_utils`) that can be used to test your ingest configuration. This fixture accepts the following arguments: + +| Argument | Type | Description | +| ------------------ | ------------------------- | ------------------------------------- | +| Required Arguments | +| `name` | `str` | The name of the ingest | +| `data` | `Union[Dict, List[Dict]]` | The data to be ingested | +| `transform_code` | `str` | Path to the transform code to be used | +| Optional Arguments | +| `map_cache` | `Dict` | Map cache to be used | +| `filters` | `List(str)` | List of filters to apply to data | +| `global_table` | `str` | Path to the global table | +| `local_table` | `str` | Path to the local table | + +The `mock_koza` fixture returns a list of entities that would be generated by the ingest configuration. +This list can then be used to test the output based on the transform script. + +Here is an example of how to use the `mock_koza` fixture to test an ingest configuration: + +```python +import pytest + +from koza.utils.testing_utils import mock_koza + +# Define the source name and transform script path +INGEST_NAME = "your_ingest_name" +TRANSFORM_SCRIPT = "./src/{{cookiecutter.__project_slug}}/transform.py" + +# Define an example row to test +@pytest.fixture +def example_row(): + return { + "example_column_1": "entity_1", + "example_column_2": "entity_6", + "example_column_3": "biolink:related_to", + } + +# Or a list of rows +@pytest.fixture +def example_list_of_rows(): + return [ + { + "example_column_1": "entity_1", + "example_column_2": "entity_6", + "example_column_3": "biolink:related_to", + }, + { + "example_column_1": "entity_2", + "example_column_2": "entity_7", + "example_column_3": "biolink:related_to", + }, + ] + +# Define the mock koza transform +@pytest.fixture +def mock_transform(mock_koza, example_row): + return mock_koza( + SOURCE_NAME, + example_row, + TRANSFORM_SCRIPT, + ) + +# Or for multiple rows +@pytest.fixture +def mock_transform_multiple_rows(mock_koza, example_list_of_rows): + return mock_koza( + SOURCE_NAME, + example_list_of_rows, + TRANSFORM_SCRIPT, + ) + + +def test_example(mock_transform): + assert len(mock_transform) == 1 + entity = mock_transform[0] + assert entity + assert entity.subject == "entity_1" + + +def test_multiple_rows(mock_transform_multiple_rows): + assert len(mock_transform_multiple_rows) == 2 + entity_1 = mock_transform_multiple_rows[0] + entity_2 = mock_transform_multiple_rows[1] + assert entity_1.subject == "entity_1" + assert entity_2.subject == "entity_2" + +``` diff --git a/mkdocs.yaml b/mkdocs.yaml index d6bfce2..c42b56c 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -12,6 +12,7 @@ nav: - Source Config: 'Ingests/source_config.md' - Mapping: 'Ingests/mapping.md' - Transform Code: 'Ingests/transform.md' + - Testing: 'Ingests/testing.md' - CLI: 'Usage/CLI.md' - Module: 'Usage/Module.md' diff --git a/pyproject.toml b/pyproject.toml index 9569db4..adb4702 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,11 +43,11 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.black] -line_length = 120 +line-length = 120 skip-string-normalization = true [tool.ruff] line-length = 120 -ignore = [ +lint.ignore = [ "F541", # f-strings with no placeholders ] \ No newline at end of file diff --git a/src/koza/io/reader/csv_reader.py b/src/koza/io/reader/csv_reader.py index 101ab3b..18bbd81 100644 --- a/src/koza/io/reader/csv_reader.py +++ b/src/koza/io/reader/csv_reader.py @@ -147,7 +147,7 @@ def __next__(self) -> Dict[str, Any]: elif fields_len < row_len: logger.warning(f"CSV file {self.name} has {row_len - fields_len} extra columns at {self.reader.line_num}") - # # Not sure if this would serve a purpose: + # # Not sure if this would serve a purpose: # if 'extra_cols' not in self.field_type_map: # # Create a type map for extra columns # self.field_type_map['extra_cols'] = FieldType.str diff --git a/src/koza/io/reader/json_reader.py b/src/koza/io/reader/json_reader.py index f91bf53..4b6e8da 100644 --- a/src/koza/io/reader/json_reader.py +++ b/src/koza/io/reader/json_reader.py @@ -1,4 +1,5 @@ -import json, yaml +import json +import yaml from typing import IO, Any, Dict, Iterator, List, Union # from xmlrpc.client import Boolean diff --git a/src/koza/io/utils.py b/src/koza/io/utils.py index 8feb28f..b1b4ae3 100644 --- a/src/koza/io/utils.py +++ b/src/koza/io/utils.py @@ -61,7 +61,7 @@ def open_resource(resource: Union[str, PathLike]) -> IO[str]: # If resource is local, check for compression if is_zipfile(resource): with ZipFile(resource, 'r') as zip_file: - file = TextIOWrapper(zip_file.open(zip_file.namelist()[0], 'r'))#, encoding='utf-8') + file = TextIOWrapper(zip_file.open(zip_file.namelist()[0], 'r')) # , encoding='utf-8') # file = zip_file.read(zip_file.namelist()[0], 'r').decode('utf-8') elif str(resource).endswith('gz'): file = gzip.open(resource, 'rt') diff --git a/src/koza/model/config/pydantic_config.py b/src/koza/model/config/pydantic_config.py index 5347887..46212cb 100644 --- a/src/koza/model/config/pydantic_config.py +++ b/src/koza/model/config/pydantic_config.py @@ -6,7 +6,7 @@ from pydantic import ConfigDict PYDANTIC_CONFIG = ConfigDict( - validate_assignment = True, - validate_default = True, - extra = 'forbid', -) \ No newline at end of file + validate_assignment=True, + validate_default=True, + extra='forbid', +) diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index c79b2ad..fa4484a 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -12,7 +12,6 @@ from typing import Dict, List, Union, Optional import yaml -from loguru import logger from pydantic import StrictFloat, StrictInt, StrictStr from pydantic.dataclasses import dataclass diff --git a/src/koza/utils/testing_utils.py b/src/koza/utils/testing_utils.py index 9d10796..80af189 100644 --- a/src/koza/utils/testing_utils.py +++ b/src/koza/utils/testing_utils.py @@ -1,5 +1,5 @@ import types -from typing import Iterable +from typing import Union, List, Dict, Iterable import pytest from loguru import logger @@ -58,7 +58,7 @@ def _make_mock_koza_app( def _transform( name: str, - data: Iterable, + data: Union[Dict, List[Dict]], transform_code: str, map_cache=None, filters=None, @@ -67,7 +67,7 @@ def _transform( ): koza_app = _make_mock_koza_app( name, - data, + iter(data) if isinstance(data, list) else iter([data]), transform_code, map_cache=map_cache, filters=filters, diff --git a/tests/integration/test_parallel.py b/tests/integration/test_parallel.py index 9a462c4..ea06584 100644 --- a/tests/integration/test_parallel.py +++ b/tests/integration/test_parallel.py @@ -1,6 +1,7 @@ """ Test parallel transforms """ + # import pytest import dask diff --git a/tests/integration/test_row_limit.py b/tests/integration/test_row_limit.py index 2b8f918..d6f6e10 100644 --- a/tests/integration/test_row_limit.py +++ b/tests/integration/test_row_limit.py @@ -2,6 +2,7 @@ Test the row_limit argument for transforms Assert correct number of rows has been processed """ + # TODO: Parameterize row_limit, and test reading from JSON and JSONL # TODO: Address filter in examples/string-declarative/protein-links-detailed.yaml diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 4dc6ead..04aeb67 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -2,6 +2,7 @@ Testing the biolink config dataclasses + pydandic """ + from pathlib import Path import pytest diff --git a/tests/unit/test_custom_dict.py b/tests/unit/test_custom_dict.py index c2c5f18..d815c1f 100644 --- a/tests/unit/test_custom_dict.py +++ b/tests/unit/test_custom_dict.py @@ -1,6 +1,7 @@ """ Testing custom dictionary """ + import pytest from koza.utils.exceptions import MapItemException diff --git a/tests/unit/test_filter.py b/tests/unit/test_filter.py index e917a27..0eb446e 100644 --- a/tests/unit/test_filter.py +++ b/tests/unit/test_filter.py @@ -2,6 +2,7 @@ Testing for row filtering """ + import pytest from koza.model.config.source_config import ColumnFilter, FilterCode, FilterInclusion diff --git a/tests/unit/test_validation.py b/tests/unit/test_validation.py index 7313581..c2af0d2 100644 --- a/tests/unit/test_validation.py +++ b/tests/unit/test_validation.py @@ -17,9 +17,10 @@ } invalid_input = {"name": "Bogus Gene 98765", "type": "biolink:NamedThing"} -model_path = Path(__file__).parent.parent / 'resources' / 'test-model.yaml' -with open(model_path) as f: - model = yaml.load(f, Loader=yaml.FullLoader) +model_path = Path(__file__).parent.parent / 'resources' / 'test-model.yaml' +with open(model_path) as f: + model = yaml.load(f, Loader=yaml.FullLoader) + @pytest.mark.parametrize("entity", [valid_input]) def test_valid_input(entity): @@ -32,13 +33,14 @@ def test_invalid_input(entity): v = validate(instance=entity, target_class="Entity", schema=model) assert v.results[0].severity == "ERROR" + ################################################################################################### # Generic model test # model_path = Path(__file__).parent.parent / 'resources' / 'test-model.yaml' -# with open(model_path) as f: -# model = yaml.load(f, Loader=yaml.FullLoader) +# with open(model_path) as f: +# model = yaml.load(f, Loader=yaml.FullLoader) # valid_input = { # "id": "BOGUS:12345", @@ -66,4 +68,4 @@ def test_invalid_input(entity): # result = v.results[0] # print(f"result: {result}") # assert 1 == 2 -# assert result.severity == "ERROR" \ No newline at end of file +# assert result.severity == "ERROR" From 1e82b6c935cf0532104e33b1f5adaaac6b3196e0 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Thu, 25 Apr 2024 21:00:00 -0600 Subject: [PATCH 17/30] update testing documentation --- docs/Ingests/testing.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/Ingests/testing.md b/docs/Ingests/testing.md index 42ab436..365d247 100644 --- a/docs/Ingests/testing.md +++ b/docs/Ingests/testing.md @@ -26,7 +26,7 @@ from koza.utils.testing_utils import mock_koza INGEST_NAME = "your_ingest_name" TRANSFORM_SCRIPT = "./src/{{cookiecutter.__project_slug}}/transform.py" -# Define an example row to test +# Define an example row to test (as a dictionary) @pytest.fixture def example_row(): return { @@ -55,7 +55,7 @@ def example_list_of_rows(): @pytest.fixture def mock_transform(mock_koza, example_row): return mock_koza( - SOURCE_NAME, + INGEST_NAME, example_row, TRANSFORM_SCRIPT, ) @@ -64,13 +64,14 @@ def mock_transform(mock_koza, example_row): @pytest.fixture def mock_transform_multiple_rows(mock_koza, example_list_of_rows): return mock_koza( - SOURCE_NAME, + INGEST_NAME, example_list_of_rows, TRANSFORM_SCRIPT, ) +# Test the output of the transform -def test_example(mock_transform): +def test_single_row(mock_transform): assert len(mock_transform) == 1 entity = mock_transform[0] assert entity @@ -83,5 +84,4 @@ def test_multiple_rows(mock_transform_multiple_rows): entity_2 = mock_transform_multiple_rows[1] assert entity_1.subject == "entity_1" assert entity_2.subject == "entity_2" - ``` From e1a454abe3cdcedde6930b60e0afb9eebfa99dd2 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 29 Apr 2024 14:58:21 -0600 Subject: [PATCH 18/30] dynamic version by release --- .github/dependabot.yaml | 10 ++++++++++ .github/workflows/publish.yaml | 3 ++- pyproject.toml | 6 +++--- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..11eb345 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,10 @@ +# Set update schedule for GitHub Actions + +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index d17463b..abc4a56 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -22,7 +22,8 @@ jobs: - name: Build run: | - poetry build + poetry version $(git describe --tags --abbrev=0) + poetry build - name: Publish to PyPi env: diff --git a/pyproject.toml b/pyproject.toml index adb4702..b3d88ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "koza" -version = "0.5.5" +version = "0.0.0" description = "Data transformation framework for LinkML data models" authors = [ "The Monarch Initiative ", @@ -39,8 +39,8 @@ mkdocstrings = {extras = ["python"], version = ">=0.22.0"} koza = "koza.main:typer_app" [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["poetry-core", "poetry-dynamic-version"] +build-backend = "poetry_dynamic_versioning.backend" [tool.black] line-length = 120 From c72a6564aced9cd66ec1dfbc07694e15d4ea1313 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Tue, 30 Apr 2024 10:53:38 -0600 Subject: [PATCH 19/30] fix pyproject.toml --- poetry.lock | 387 ++++++++++++++----------- pyproject.toml | 11 +- src/koza/cli_utils.py | 7 + src/koza/main.py | 3 - src/koza/model/config/source_config.py | 17 +- 5 files changed, 253 insertions(+), 172 deletions(-) diff --git a/poetry.lock b/poetry.lock index e3b6b64..b5c7e9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -116,33 +116,33 @@ yamllint = ">=1.35.1,<2.0.0" [[package]] name = "black" -version = "24.4.1" +version = "24.4.2" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f7749fd0d97ff9415975a1432fac7df89bf13c3833cea079e55fa004d5f28c0"}, - {file = "black-24.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:859f3cc5d2051adadf8fd504a01e02b0fd866d7549fff54bc9202d524d2e8bd7"}, - {file = "black-24.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59271c9c29dfa97f7fda51f56c7809b3f78e72fd8d2205189bbd23022a0618b6"}, - {file = "black-24.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:5ed9c34cba223149b5a0144951a0f33d65507cf82c5449cb3c35fe4b515fea9a"}, - {file = "black-24.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dae3ae59d6f2dc93700fd5034a3115434686e66fd6e63d4dcaa48d19880f2b0"}, - {file = "black-24.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5f8698974a81af83283eb47644f2711b5261138d6d9180c863fce673cbe04b13"}, - {file = "black-24.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f404b6e77043b23d0321fb7772522b876b6de737ad3cb97d6b156638d68ce81"}, - {file = "black-24.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:c94e52b766477bdcd010b872ba0714d5458536dc9d0734eff6583ba7266ffd89"}, - {file = "black-24.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:962d9e953872cdb83b97bb737ad47244ce2938054dc946685a4cad98520dab38"}, - {file = "black-24.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d8e3b2486b7dd522b1ab2ba1ec4907f0aa8f5e10a33c4271fb331d1d10b70c"}, - {file = "black-24.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed77e214b785148f57e43ca425b6e0850165144aa727d66ac604e56a70bb7825"}, - {file = "black-24.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:4ef4764437d7eba8386689cd06e1fb5341ee0ae2e9e22582b21178782de7ed94"}, - {file = "black-24.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:92b183f8eef5baf7b20a513abcf982ad616f544f593f6688bb2850d2982911f1"}, - {file = "black-24.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:945abd7b3572add997757c94295bb3e73c6ffaf3366b1f26cb2356a4bffd1dc3"}, - {file = "black-24.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db5154b9e5b478031371d8bc41ff37b33855fa223a6cfba456c9b73fb96f77d4"}, - {file = "black-24.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:afc84c33c1a9aaf3d73140cee776b4ddf73ff429ffe6b7c56dc1c9c10725856d"}, - {file = "black-24.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0889f4eb8b3bdf8b189e41a71cf0dbb8141a98346cd1a2695dea5995d416e940"}, - {file = "black-24.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5bb0143f175db45a55227eefd63e90849d96c266330ba31719e9667d0d5ec3b9"}, - {file = "black-24.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:713a04a78e78f28ef7e8df7a16fe075670ea164860fcef3885e4f3dffc0184b3"}, - {file = "black-24.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:171959bc879637a8cdbc53dc3fddae2a83e151937a28cf605fd175ce61e0e94a"}, - {file = "black-24.4.1-py3-none-any.whl", hash = "sha256:ecbab810604fe02c70b3a08afd39beb599f7cc9afd13e81f5336014133b4fe35"}, - {file = "black-24.4.1.tar.gz", hash = "sha256:5241612dc8cad5b6fd47432b8bd04db80e07cfbc53bb69e9ae18985063bcb8dd"}, + {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, + {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, + {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, + {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, + {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, + {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, + {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, + {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, + {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, + {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, + {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, + {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, + {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, + {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, + {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, + {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, + {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, + {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, + {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, + {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, + {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, + {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, ] [package.dependencies] @@ -414,6 +414,62 @@ files = [ [package.dependencies] packaging = "*" +[[package]] +name = "duckdb" +version = "0.10.2" +description = "DuckDB in-process database" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3891d3ac03e12a3e5c43afa3020fe701f64060f52d25f429a1ed7b5d914368d3"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f63877651f1fb940e049dc53038eb763856616319acf4f892b1c3ed074f5ab0"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:06e3a36f04f4d98d2c0bbdd63e517cfbe114a795306e26ec855e62e076af5043"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf5f95ad5b75c8e65c6508b4df02043dd0b9d97712b9a33236ad77c388ce7861"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff62bc98278c98fecbd6eecec5d698ad41ebd654110feaadbf8ac8bb59b1ecf"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cceede13fde095c23cf9a53adf7c414c7bfb21b9a7aa6a4836014fdbecbfca70"}, + {file = "duckdb-0.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:acdfff60b7efccd7f731213a9795851256249dfacf80367074b2b2e144f716dd"}, + {file = "duckdb-0.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:4a5d5655cf0bdaf664a6f332afe465e02b08cef715548a0983bb7aef48da06a6"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a9d15842876d18763e085648656cccc7660a215d16254906db5c4471be2c7732"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c88cdcdc8452c910e4298223e7d9fca291534ff5aa36090aa49c9e6557550b13"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:364cd6f5dc8a1010d144d08c410ba9a74c521336ee5bda84fabc6616216a6d6a"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c57c11d1060296f5e9ebfb5bb7e5521e0d77912e8f9ff43c90240c3311e9de9"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:186d86b8dda8e1076170eb770bb2bb73ea88ca907d92885c9695d6515207b205"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f65b62f31c6bff21afc0261cfe28d238b8f34ec78f339546b12f4740c39552a"}, + {file = "duckdb-0.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a860d7466a5c93714cdd94559ce9e1db2ab91914f0941c25e5e93d4ebe36a5fa"}, + {file = "duckdb-0.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:33308190e9c7f05a3a0a2d46008a043effd4eae77011869d7c18fb37acdd9215"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3a8b2f1229b4aecb79cd28ffdb99032b1497f0a805d0da1136a9b6115e1afc70"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d23a6dea61963733a0f45a0d0bbb1361fb2a47410ed5ff308b4a1f869d4eeb6f"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20ee0aa27e688aa52a40b434ec41a50431d0b06edeab88edc2feaca18d82c62c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80a6d43d9044f0997a15a92e0c0ff3afd21151a1e572a92f439cc4f56b7090e1"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6934758cacd06029a5c9f54556a43bd277a86757e22bf8d0dd11ca15c1813d1c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a11e2d68bd79044eea5486b1cddb5b915115f537e5c74eeb94c768ce30f9f4b"}, + {file = "duckdb-0.10.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0bf58385c43b8e448a2fea7e8729054934bf73ea616d1d7ef8184eda07f975e2"}, + {file = "duckdb-0.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:eae75c7014597ded6e7f6dc51e32d48362a31608acd73e9f795748ee94335a54"}, + {file = "duckdb-0.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62e89deff778a7a86f651802b947a3466425f6cce41e9d7d412d39e492932943"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f87e555fd36ec6da316b727a39fb24c53124a797dfa9b451bdea87b2f20a351f"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41e8b34b1a944590ebcf82f8cc59d67b084fe99479f048892d60da6c1402c386"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c68c6dde2773774cf2371522a3959ea2716fc2b3a4891d4066f0e426455fe19"}, + {file = "duckdb-0.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ff6a8a0980d0f9398fa461deffa59465dac190d707468478011ea8a5fe1f2c81"}, + {file = "duckdb-0.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:728dd4ff0efda387a424754e5508d4f8c72a272c2d3ccb036a83286f60b46002"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c461d6b4619e80170044a9eb999bbf4097e330d3a4974ced0a7eaeb79c7c39f6"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:909351ff72eb3b50b89761251148d8a186594d8a438e12dcf5494794caff6693"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d9eeb8393d69abafd355b869669957eb85b89e4df677e420b9ef0693b7aa6cb4"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3102bcf5011e8f82ea3c2bde43108774fe5a283a410d292c0843610ea13e2237"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d64d443613e5f16caf7d67102733538c90f7715867c1a98597efd3babca068e3"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb31398826d1b7473344e5ee8e0f826370c9752549469ba1327042ace9041f80"}, + {file = "duckdb-0.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d09dcec467cd6127d5cc1fb0ce4efbd77e761882d9d772b0f64fc2f79a2a1cde"}, + {file = "duckdb-0.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:82fab1a24faf7c33d8a7afed08b57ee36e8821a3a68a2f1574cd238ea440bba0"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38607e6e6618e8ea28c8d9b67aa9e22cfd6d6d673f2e8ab328bd6e867b697f69"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb0c23bc8c09615bff38aebcf8e92e6ae74959c67b3c9e5b00edddc730bf22be"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:00576c11c78c83830ab483bad968e07cd9b5f730e7ffaf5aa5fadee5ac4f71e9"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:077db692cdda50c4684ef87dc2a68507665804caa90e539dbe819116bda722ad"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca25984ad9f9a04e46e8359f852668c11569534e3bb8424b80be711303ad2314"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a72cc40982c7b92cf555e574618fc711033b013bf258b611ba18d7654c89d8c"}, + {file = "duckdb-0.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27b9efd6e788eb561535fdc0cbc7c74aca1ff39f748b7cfc27aa49b00e22da1"}, + {file = "duckdb-0.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:4800469489bc262dda61a7f1d40acedf67cf2454874e9d8bbf07920dc2b147e6"}, + {file = "duckdb-0.10.2.tar.gz", hash = "sha256:0f609c9d5f941f1ecde810f010dd9321cd406a552c1df20318a13fa64247f67f"}, +] + [[package]] name = "et-xmlfile" version = "1.1.0" @@ -1090,34 +1146,34 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.3" +version = "1.6.0" description = "Project documentation with Markdown." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, - {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, + {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, + {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, ] [package.dependencies] click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" -markdown = ">=3.2.1" +markdown = ">=3.3.6" markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" packaging = ">=20.5" pathspec = ">=0.11.1" -platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] [[package]] name = "mkdocs-autorefs" @@ -1135,15 +1191,32 @@ Markdown = ">=3.3" markupsafe = ">=2.0.1" mkdocs = ">=1.1" +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + [[package]] name = "mkdocs-material" -version = "9.5.18" +version = "9.5.20" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, - {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, + {file = "mkdocs_material-9.5.20-py3-none-any.whl", hash = "sha256:ad0094a7597bcb5d0cc3e8e543a10927c2581f7f647b9bb4861600f583180f9b"}, + {file = "mkdocs_material-9.5.20.tar.gz", hash = "sha256:986eef0250d22f70fb06ce0f4eac64cc92bd797a589ec3892ce31fad976fe3da"}, ] [package.dependencies] @@ -1151,7 +1224,7 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<1.6.0" +mkdocs = ">=1.6,<2.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" @@ -1177,13 +1250,13 @@ files = [ [[package]] name = "mkdocstrings" -version = "0.24.3" +version = "0.25.0" description = "Automatic documentation from sources, for MkDocs." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocstrings-0.24.3-py3-none-any.whl", hash = "sha256:5c9cf2a32958cd161d5428699b79c8b0988856b0d4a8c5baf8395fc1bf4087c3"}, - {file = "mkdocstrings-0.24.3.tar.gz", hash = "sha256:f327b234eb8d2551a306735436e157d0a22d45f79963c60a8b585d5f7a94c1d2"}, + {file = "mkdocstrings-0.25.0-py3-none-any.whl", hash = "sha256:df1b63f26675fcde8c1b77e7ea996cd2f93220b148e06455428f676f5dc838f1"}, + {file = "mkdocstrings-0.25.0.tar.gz", hash = "sha256:066986b3fb5b9ef2d37c4417255a808f7e63b40ff8f67f6cab8054d903fbc91d"}, ] [package.dependencies] @@ -1687,13 +1760,13 @@ jsonasobj = ">=1.2.1" [[package]] name = "pymdown-extensions" -version = "10.8" +version = "10.8.1" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.8-py3-none-any.whl", hash = "sha256:3539003ff0d5e219ba979d2dc961d18fcad5ac259e66c764482e8347b4c0503c"}, - {file = "pymdown_extensions-10.8.tar.gz", hash = "sha256:91ca336caf414e1e5e0626feca86e145de9f85a3921a7bcbd32890b51738c428"}, + {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, + {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, ] [package.dependencies] @@ -1760,13 +1833,13 @@ shexjsg = ">=0.8.1" [[package]] name = "pytest" -version = "8.1.1" +version = "8.2.0" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, - {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, + {file = "pytest-8.2.0-py3-none-any.whl", hash = "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233"}, + {file = "pytest-8.2.0.tar.gz", hash = "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"}, ] [package.dependencies] @@ -1774,11 +1847,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.4,<2.0" +pluggy = ">=1.5,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-logging" @@ -1814,6 +1887,7 @@ description = "A pure Python implementation of the trie data structure." optional = false python-versions = "*" files = [ + {file = "PyTrie-0.4.0-py3-none-any.whl", hash = "sha256:f687c224ee8c66cda8e8628a903011b692635ffbb08d4b39c5f92b18eb78c950"}, {file = "PyTrie-0.4.0.tar.gz", hash = "sha256:8f4488f402d3465993fb6b6efa09866849ed8cda7903b50647b7d0342b805379"}, ] @@ -1856,6 +1930,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1971,104 +2046,90 @@ rpds-py = ">=0.7.0" [[package]] name = "regex" -version = "2024.4.16" +version = "2024.4.28" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "regex-2024.4.16-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb83cc090eac63c006871fd24db5e30a1f282faa46328572661c0a24a2323a08"}, - {file = "regex-2024.4.16-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c91e1763696c0eb66340c4df98623c2d4e77d0746b8f8f2bee2c6883fd1fe18"}, - {file = "regex-2024.4.16-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10188fe732dec829c7acca7422cdd1bf57d853c7199d5a9e96bb4d40db239c73"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:956b58d692f235cfbf5b4f3abd6d99bf102f161ccfe20d2fd0904f51c72c4c66"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a70b51f55fd954d1f194271695821dd62054d949efd6368d8be64edd37f55c86"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c02fcd2bf45162280613d2e4a1ca3ac558ff921ae4e308ecb307650d3a6ee51"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4ed75ea6892a56896d78f11006161eea52c45a14994794bcfa1654430984b22"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd727ad276bb91928879f3aa6396c9a1d34e5e180dce40578421a691eeb77f47"}, - {file = "regex-2024.4.16-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7cbc5d9e8a1781e7be17da67b92580d6ce4dcef5819c1b1b89f49d9678cc278c"}, - {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:78fddb22b9ef810b63ef341c9fcf6455232d97cfe03938cbc29e2672c436670e"}, - {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:445ca8d3c5a01309633a0c9db57150312a181146315693273e35d936472df912"}, - {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:95399831a206211d6bc40224af1c635cb8790ddd5c7493e0bd03b85711076a53"}, - {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7731728b6568fc286d86745f27f07266de49603a6fdc4d19c87e8c247be452af"}, - {file = "regex-2024.4.16-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4facc913e10bdba42ec0aee76d029aedda628161a7ce4116b16680a0413f658a"}, - {file = "regex-2024.4.16-cp310-cp310-win32.whl", hash = "sha256:911742856ce98d879acbea33fcc03c1d8dc1106234c5e7d068932c945db209c0"}, - {file = "regex-2024.4.16-cp310-cp310-win_amd64.whl", hash = "sha256:e0a2df336d1135a0b3a67f3bbf78a75f69562c1199ed9935372b82215cddd6e2"}, - {file = "regex-2024.4.16-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1210365faba7c2150451eb78ec5687871c796b0f1fa701bfd2a4a25420482d26"}, - {file = "regex-2024.4.16-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ab40412f8cd6f615bfedea40c8bf0407d41bf83b96f6fc9ff34976d6b7037fd"}, - {file = "regex-2024.4.16-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd80d1280d473500d8086d104962a82d77bfbf2b118053824b7be28cd5a79ea5"}, - {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bb966fdd9217e53abf824f437a5a2d643a38d4fd5fd0ca711b9da683d452969"}, - {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20b7a68444f536365af42a75ccecb7ab41a896a04acf58432db9e206f4e525d6"}, - {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b74586dd0b039c62416034f811d7ee62810174bb70dffcca6439f5236249eb09"}, - {file = "regex-2024.4.16-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8290b44d8b0af4e77048646c10c6e3aa583c1ca67f3b5ffb6e06cf0c6f0f89"}, - {file = "regex-2024.4.16-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2d80a6749724b37853ece57988b39c4e79d2b5fe2869a86e8aeae3bbeef9eb0"}, - {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3a1018e97aeb24e4f939afcd88211ace472ba566efc5bdf53fd8fd7f41fa7170"}, - {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8d015604ee6204e76569d2f44e5a210728fa917115bef0d102f4107e622b08d5"}, - {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:3d5ac5234fb5053850d79dd8eb1015cb0d7d9ed951fa37aa9e6249a19aa4f336"}, - {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0a38d151e2cdd66d16dab550c22f9521ba79761423b87c01dae0a6e9add79c0d"}, - {file = "regex-2024.4.16-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:159dc4e59a159cb8e4e8f8961eb1fa5d58f93cb1acd1701d8aff38d45e1a84a6"}, - {file = "regex-2024.4.16-cp311-cp311-win32.whl", hash = "sha256:ba2336d6548dee3117520545cfe44dc28a250aa091f8281d28804aa8d707d93d"}, - {file = "regex-2024.4.16-cp311-cp311-win_amd64.whl", hash = "sha256:8f83b6fd3dc3ba94d2b22717f9c8b8512354fd95221ac661784df2769ea9bba9"}, - {file = "regex-2024.4.16-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:80b696e8972b81edf0af2a259e1b2a4a661f818fae22e5fa4fa1a995fb4a40fd"}, - {file = "regex-2024.4.16-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d61ae114d2a2311f61d90c2ef1358518e8f05eafda76eaf9c772a077e0b465ec"}, - {file = "regex-2024.4.16-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ba6745440b9a27336443b0c285d705ce73adb9ec90e2f2004c64d95ab5a7598"}, - {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295004b2dd37b0835ea5c14a33e00e8cfa3c4add4d587b77287825f3418d310"}, - {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4aba818dcc7263852aabb172ec27b71d2abca02a593b95fa79351b2774eb1d2b"}, - {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0800631e565c47520aaa04ae38b96abc5196fe8b4aa9bd864445bd2b5848a7a"}, - {file = "regex-2024.4.16-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08dea89f859c3df48a440dbdcd7b7155bc675f2fa2ec8c521d02dc69e877db70"}, - {file = "regex-2024.4.16-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eeaa0b5328b785abc344acc6241cffde50dc394a0644a968add75fcefe15b9d4"}, - {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4e819a806420bc010489f4e741b3036071aba209f2e0989d4750b08b12a9343f"}, - {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c2d0e7cbb6341e830adcbfa2479fdeebbfbb328f11edd6b5675674e7a1e37730"}, - {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:91797b98f5e34b6a49f54be33f72e2fb658018ae532be2f79f7c63b4ae225145"}, - {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:d2da13568eff02b30fd54fccd1e042a70fe920d816616fda4bf54ec705668d81"}, - {file = "regex-2024.4.16-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:370c68dc5570b394cbaadff50e64d705f64debed30573e5c313c360689b6aadc"}, - {file = "regex-2024.4.16-cp312-cp312-win32.whl", hash = "sha256:904c883cf10a975b02ab3478bce652f0f5346a2c28d0a8521d97bb23c323cc8b"}, - {file = "regex-2024.4.16-cp312-cp312-win_amd64.whl", hash = "sha256:785c071c982dce54d44ea0b79cd6dfafddeccdd98cfa5f7b86ef69b381b457d9"}, - {file = "regex-2024.4.16-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e2f142b45c6fed48166faeb4303b4b58c9fcd827da63f4cf0a123c3480ae11fb"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87ab229332ceb127a165612d839ab87795972102cb9830e5f12b8c9a5c1b508"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81500ed5af2090b4a9157a59dbc89873a25c33db1bb9a8cf123837dcc9765047"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b340cccad138ecb363324aa26893963dcabb02bb25e440ebdf42e30963f1a4e0"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c72608e70f053643437bd2be0608f7f1c46d4022e4104d76826f0839199347a"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a01fe2305e6232ef3e8f40bfc0f0f3a04def9aab514910fa4203bafbc0bb4682"}, - {file = "regex-2024.4.16-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:03576e3a423d19dda13e55598f0fd507b5d660d42c51b02df4e0d97824fdcae3"}, - {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:549c3584993772e25f02d0656ac48abdda73169fe347263948cf2b1cead622f3"}, - {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:34422d5a69a60b7e9a07a690094e824b66f5ddc662a5fc600d65b7c174a05f04"}, - {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5f580c651a72b75c39e311343fe6875d6f58cf51c471a97f15a938d9fe4e0d37"}, - {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3399dd8a7495bbb2bacd59b84840eef9057826c664472e86c91d675d007137f5"}, - {file = "regex-2024.4.16-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8d1f86f3f4e2388aa3310b50694ac44daefbd1681def26b4519bd050a398dc5a"}, - {file = "regex-2024.4.16-cp37-cp37m-win32.whl", hash = "sha256:dd5acc0a7d38fdc7a3a6fd3ad14c880819008ecb3379626e56b163165162cc46"}, - {file = "regex-2024.4.16-cp37-cp37m-win_amd64.whl", hash = "sha256:ba8122e3bb94ecda29a8de4cf889f600171424ea586847aa92c334772d200331"}, - {file = "regex-2024.4.16-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:743deffdf3b3481da32e8a96887e2aa945ec6685af1cfe2bcc292638c9ba2f48"}, - {file = "regex-2024.4.16-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7571f19f4a3fd00af9341c7801d1ad1967fc9c3f5e62402683047e7166b9f2b4"}, - {file = "regex-2024.4.16-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:df79012ebf6f4efb8d307b1328226aef24ca446b3ff8d0e30202d7ebcb977a8c"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e757d475953269fbf4b441207bb7dbdd1c43180711b6208e129b637792ac0b93"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4313ab9bf6a81206c8ac28fdfcddc0435299dc88cad12cc6305fd0e78b81f9e4"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d83c2bc678453646f1a18f8db1e927a2d3f4935031b9ad8a76e56760461105dd"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9df1bfef97db938469ef0a7354b2d591a2d438bc497b2c489471bec0e6baf7c4"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62120ed0de69b3649cc68e2965376048793f466c5a6c4370fb27c16c1beac22d"}, - {file = "regex-2024.4.16-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c2ef6f7990b6e8758fe48ad08f7e2f66c8f11dc66e24093304b87cae9037bb4a"}, - {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8fc6976a3395fe4d1fbeb984adaa8ec652a1e12f36b56ec8c236e5117b585427"}, - {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:03e68f44340528111067cecf12721c3df4811c67268b897fbe695c95f860ac42"}, - {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ec7e0043b91115f427998febaa2beb82c82df708168b35ece3accb610b91fac1"}, - {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c21fc21a4c7480479d12fd8e679b699f744f76bb05f53a1d14182b31f55aac76"}, - {file = "regex-2024.4.16-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:12f6a3f2f58bb7344751919a1876ee1b976fe08b9ffccb4bbea66f26af6017b9"}, - {file = "regex-2024.4.16-cp38-cp38-win32.whl", hash = "sha256:479595a4fbe9ed8f8f72c59717e8cf222da2e4c07b6ae5b65411e6302af9708e"}, - {file = "regex-2024.4.16-cp38-cp38-win_amd64.whl", hash = "sha256:0534b034fba6101611968fae8e856c1698da97ce2efb5c2b895fc8b9e23a5834"}, - {file = "regex-2024.4.16-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7ccdd1c4a3472a7533b0a7aa9ee34c9a2bef859ba86deec07aff2ad7e0c3b94"}, - {file = "regex-2024.4.16-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f2f017c5be19984fbbf55f8af6caba25e62c71293213f044da3ada7091a4455"}, - {file = "regex-2024.4.16-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:803b8905b52de78b173d3c1e83df0efb929621e7b7c5766c0843704d5332682f"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:684008ec44ad275832a5a152f6e764bbe1914bea10968017b6feaecdad5736e0"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65436dce9fdc0aeeb0a0effe0839cb3d6a05f45aa45a4d9f9c60989beca78b9c"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea355eb43b11764cf799dda62c658c4d2fdb16af41f59bb1ccfec517b60bcb07"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c1165f3809ce7774f05cb74e5408cd3aa93ee8573ae959a97a53db3ca3180d"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cccc79a9be9b64c881f18305a7c715ba199e471a3973faeb7ba84172abb3f317"}, - {file = "regex-2024.4.16-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00169caa125f35d1bca6045d65a662af0202704489fada95346cfa092ec23f39"}, - {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6cc38067209354e16c5609b66285af17a2863a47585bcf75285cab33d4c3b8df"}, - {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:23cff1b267038501b179ccbbd74a821ac4a7192a1852d1d558e562b507d46013"}, - {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:b9d320b3bf82a39f248769fc7f188e00f93526cc0fe739cfa197868633d44701"}, - {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:89ec7f2c08937421bbbb8b48c54096fa4f88347946d4747021ad85f1b3021b3c"}, - {file = "regex-2024.4.16-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4918fd5f8b43aa7ec031e0fef1ee02deb80b6afd49c85f0790be1dc4ce34cb50"}, - {file = "regex-2024.4.16-cp39-cp39-win32.whl", hash = "sha256:684e52023aec43bdf0250e843e1fdd6febbe831bd9d52da72333fa201aaa2335"}, - {file = "regex-2024.4.16-cp39-cp39-win_amd64.whl", hash = "sha256:e697e1c0238133589e00c244a8b676bc2cfc3ab4961318d902040d099fec7483"}, - {file = "regex-2024.4.16.tar.gz", hash = "sha256:fa454d26f2e87ad661c4f0c5a5fe4cf6aab1e307d1b94f16ffdfcb089ba685c0"}, + {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61"}, + {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f"}, + {file = "regex-2024.4.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c"}, + {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8"}, + {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea"}, + {file = "regex-2024.4.28-cp310-cp310-win32.whl", hash = "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d"}, + {file = "regex-2024.4.28-cp310-cp310-win_amd64.whl", hash = "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb"}, + {file = "regex-2024.4.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb"}, + {file = "regex-2024.4.28-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf"}, + {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f"}, + {file = "regex-2024.4.28-cp311-cp311-win32.whl", hash = "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630"}, + {file = "regex-2024.4.28-cp311-cp311-win_amd64.whl", hash = "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae"}, + {file = "regex-2024.4.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c"}, + {file = "regex-2024.4.28-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d"}, + {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6"}, + {file = "regex-2024.4.28-cp312-cp312-win32.whl", hash = "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17"}, + {file = "regex-2024.4.28-cp312-cp312-win_amd64.whl", hash = "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666"}, + {file = "regex-2024.4.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94"}, + {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e"}, + {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150"}, + {file = "regex-2024.4.28-cp38-cp38-win32.whl", hash = "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58"}, + {file = "regex-2024.4.28-cp38-cp38-win_amd64.whl", hash = "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae"}, + {file = "regex-2024.4.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2"}, + {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a"}, + {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1"}, + {file = "regex-2024.4.28-cp39-cp39-win32.whl", hash = "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc"}, + {file = "regex-2024.4.28-cp39-cp39-win_amd64.whl", hash = "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962"}, + {file = "regex-2024.4.28.tar.gz", hash = "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4"}, ] [[package]] @@ -2322,28 +2383,28 @@ files = [ [[package]] name = "ruff" -version = "0.4.1" +version = "0.4.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2d9ef6231e3fbdc0b8c72404a1a0c46fd0dcea84efca83beb4681c318ea6a953"}, - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9485f54a7189e6f7433e0058cf8581bee45c31a25cd69009d2a040d1bd4bfaef"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2921ac03ce1383e360e8a95442ffb0d757a6a7ddd9a5be68561a671e0e5807e"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eec8d185fe193ad053eda3a6be23069e0c8ba8c5d20bc5ace6e3b9e37d246d3f"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa27d9d72a94574d250f42b7640b3bd2edc4c58ac8ac2778a8c82374bb27984"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f1ee41580bff1a651339eb3337c20c12f4037f6110a36ae4a2d864c52e5ef954"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0926cefb57fc5fced629603fbd1a23d458b25418681d96823992ba975f050c2b"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6e37f2e3cd74496a74af9a4fa67b547ab3ca137688c484749189bf3a686ceb"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd703a5975ac1998c2cc5e9494e13b28f31e66c616b0a76e206de2562e0843c"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b92f03b4aa9fa23e1799b40f15f8b95cdc418782a567d6c43def65e1bbb7f1cf"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c859f294f8633889e7d77de228b203eb0e9a03071b72b5989d89a0cf98ee262"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b34510141e393519a47f2d7b8216fec747ea1f2c81e85f076e9f2910588d4b64"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e68d248ed688b9d69fd4d18737edcbb79c98b251bba5a2b031ce2470224bdf9"}, - {file = "ruff-0.4.1-py3-none-win32.whl", hash = "sha256:b90506f3d6d1f41f43f9b7b5ff845aeefabed6d2494307bc7b178360a8805252"}, - {file = "ruff-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c7d391e5936af5c9e252743d767c564670dc3889aff460d35c518ee76e4b26d7"}, - {file = "ruff-0.4.1-py3-none-win_arm64.whl", hash = "sha256:a1eaf03d87e6a7cd5e661d36d8c6e874693cb9bc3049d110bc9a97b350680c43"}, - {file = "ruff-0.4.1.tar.gz", hash = "sha256:d592116cdbb65f8b1b7e2a2b48297eb865f6bdc20641879aa9d7b9c11d86db79"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, + {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, + {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, + {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, + {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, ] [[package]] @@ -2571,13 +2632,13 @@ sqlcipher = ["sqlcipher3_binary"] [[package]] name = "sssom" -version = "0.4.7" +version = "0.4.8" description = "Operations on SSSOM mapping tables" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "sssom-0.4.7-py3-none-any.whl", hash = "sha256:93118cafec7f35948f3bdb17f21612cf94162a500c8f569c8a8564de36e3c040"}, - {file = "sssom-0.4.7.tar.gz", hash = "sha256:c2f8bf418f159f778e4564cdec2a859f2bfae5891a33e0b67b2d8bb56c6221b3"}, + {file = "sssom-0.4.8-py3-none-any.whl", hash = "sha256:1b41f5aedb61e8fc4c4cef581da3fd64a3b8bbfaec46062a00a0105ab253d93b"}, + {file = "sssom-0.4.8.tar.gz", hash = "sha256:8a316d836e655f86c8907bbb5916129d59cbf3d189e9dd9c872d0732f80ad89d"}, ] [package.dependencies] @@ -2919,4 +2980,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "20c9bbc4596f5cf803b6a53ad3184e4ebadc8ab97eaa6da867af6c7f29b3b653" +content-hash = "a8a91f6d7aab2f777546f59e2ec5fe1e45587f62ef759708951432c12d4962d9" diff --git a/pyproject.toml b/pyproject.toml index b3d88ed..82843c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,14 +16,15 @@ packages = [ [tool.poetry.dependencies] python = "^3.9" -linkml = ">=1.6.3" +duckdb = "*" +linkml = ">=1.7.8" +loguru = "*" +ordered-set = ">=4.1.0" pydantic = "^2.4" pyyaml = ">=5.0.0" requests = "^2.24.0" -ordered-set = ">=4.1.0" -typer = ">=0.12.3" -loguru = "*" sssom = ">=0.4" +typer = ">=0.12.3" [tool.poetry.dev-dependencies] black = "^24.4" @@ -39,7 +40,7 @@ mkdocstrings = {extras = ["python"], version = ">=0.22.0"} koza = "koza.main:typer_app" [build-system] -requires = ["poetry-core", "poetry-dynamic-version"] +requires = ["poetry-core", "poetry-dynamic-versioning"] build-backend = "poetry_dynamic_versioning.backend" [tool.black] diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 93e87bb..ce602ed 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -6,6 +6,8 @@ from typing import Dict, Optional, Union import yaml +import duckdb + from koza.app import KozaApp from koza.io.reader.csv_reader import CSVReader from koza.io.reader.json_reader import JSONReader @@ -89,6 +91,11 @@ def transform_source( ) koza_app.process_maps() koza_app.process_sources() + # Confirm min number of rows in output + + + + # Write report to output directory def validate_file( diff --git a/src/koza/main.py b/src/koza/main.py index b349a56..5b6aefb 100755 --- a/src/koza/main.py +++ b/src/koza/main.py @@ -34,14 +34,11 @@ def transform( log: bool = typer.Option(False, help="Optional log mode - set true to save output to ./logs"), ) -> None: """Transform a source file""" - output_path = Path(output_dir) - if output_path.exists() and not output_path.is_dir(): raise NotADirectoryError(f"{output_dir} is not a directory") elif not output_path.exists(): output_path.mkdir(parents=True) - transform_source(source, output_dir, output_format, global_table, local_table, schema, row_limit, verbose, log) diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index fa4484a..ca99bff 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -290,11 +290,26 @@ def __post_init__(self): @dataclass(config=PYDANTIC_CONFIG) class PrimaryFileConfig(SourceConfig): """ - node_properties and edge_properties are used for configuring the KGX writer + Primary configuration for transforming a source file + + Parameters + ---------- + node_properties: List[str] (optional) - list of node properties/columns to include + edge_properties: List[str] (optional) - list of edge properties/columns to include + min_node_count: int (optional) - minimum number of nodes required in output + min_edge_count: int (optional) - minimum number of edges required in output + node_report_columns: List[str] (optional) - list of node properties to include in the report + edge_report_columns: List[str] (optional) - list of edge properties to include in the report + depends_on: List[str] (optional) - Optional lookup dictionary for basic mapping + on_map_failure: MapErrorEnum (optional) - How to handle key errors in map files """ node_properties: Optional[List[str]] = None edge_properties: Optional[List[str]] = None + min_node_count: Optional[int] = None + min_edge_count: Optional[int] = None + node_report_columns: Optional[List[str]] = None + edge_report_columns: Optional[List[str]] = None depends_on: List[str] = field(default_factory=list) on_map_failure: MapErrorEnum = MapErrorEnum.warning From 71ef3a3ee1b1a6c7d4ab1b278546946d367decb0 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Tue, 30 Apr 2024 10:59:50 -0600 Subject: [PATCH 20/30] print outfiles --- src/koza/cli_utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index ce602ed..3430e08 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -91,9 +91,14 @@ def transform_source( ) koza_app.process_maps() koza_app.process_sources() - # Confirm min number of rows in output - + ### QC checks + + outfiles = koza_app.outfiles + for outfile in outfiles: + print(f"output files: {outfile}") + + # Confirm min number of rows in output # Write report to output directory From d72cd819061222a50f0c02ecccc71b3fab22023e Mon Sep 17 00:00:00 2001 From: glass-ships Date: Tue, 30 Apr 2024 11:08:59 -0600 Subject: [PATCH 21/30] add outfiles --- src/koza/app.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/koza/app.py b/src/koza/app.py index f814192..35eb0bd 100644 --- a/src/koza/app.py +++ b/src/koza/app.py @@ -43,6 +43,11 @@ def __init__( self.curie_cleaner: CurieCleaner = CurieCleaner() self.writer: KozaWriter = self._get_writer() self.logger = logger + self.outfiles = [] + if hasattr(self.writer, 'nodes_file_name'): + self.outfiles.append(self.writer.nodes_file_name) + if hasattr(self.writer, 'edges_file_name'): + self.outfiles.append(self.writer.edges_file_name) if schema: # self.validate = True From 48e6a53005c4108902c3fabbd286beca618a33ec Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 13:44:57 -0600 Subject: [PATCH 22/30] try checking min number of rows --- .github/workflows/publish.yaml | 48 +++++++++++++++++----------------- src/koza/app.py | 4 +-- src/koza/cli_utils.py | 15 ++++++++--- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index abc4a56..6e7b693 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,33 +1,33 @@ name: publish on pypi on: - release: - types: [published] + release: + types: [published] jobs: - publish: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.10" + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" - - name: Install dependencies - run: | - pip install poetry && poetry install + - name: Install dependencies + run: | + pip install poetry && poetry install - - name: Build - run: | - poetry version $(git describe --tags --abbrev=0) - poetry build + - name: Build + run: | + poetry version $(git describe --tags --abbrev=0) + poetry build - - name: Publish to PyPi - env: - PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - run: | - poetry config http-basic.pypi "__token__" "${PYPI_API_TOKEN}" - poetry publish + - name: Publish to PyPi + env: + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + run: | + poetry config http-basic.pypi "__token__" "${PYPI_API_TOKEN}" + poetry publish diff --git a/src/koza/app.py b/src/koza/app.py index 35eb0bd..b5236a4 100644 --- a/src/koza/app.py +++ b/src/koza/app.py @@ -45,9 +45,9 @@ def __init__( self.logger = logger self.outfiles = [] if hasattr(self.writer, 'nodes_file_name'): - self.outfiles.append(self.writer.nodes_file_name) + self.node_file = self.writer.nodes_file_name if hasattr(self.writer, 'edges_file_name'): - self.outfiles.append(self.writer.edges_file_name) + self.edge_file = self.writer.edges_file_name if schema: # self.validate = True diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 3430e08..6a3c921 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -94,11 +94,18 @@ def transform_source( ### QC checks - outfiles = koza_app.outfiles - for outfile in outfiles: - print(f"output files: {outfile}") - # Confirm min number of rows in output + if hasattr(koza_app, "node_file") and hasattr(source_config, "min_node_count"): + nodes_file = koza_app.node_file + count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] + if count < source_config.min_node_count: + raise ValueError(f"Node count {count} is less than expected {source_config.min_node_count}") + + if hasattr(koza_app, "edge_file") and hasattr(source_config, "min_edge_count"): + edges_file = koza_app.edge_file + count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] + if count < source_config.min_edge_count: + raise ValueError(f"Edge count {count} is less than expected {source_config.min_edge_count}") # Write report to output directory From f805ba994a74264efc0fc1513614348d71617abf Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 14:11:12 -0600 Subject: [PATCH 23/30] add warning for 70% less, error for below that --- src/koza/cli_utils.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 6a3c921..729fa82 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -98,16 +98,20 @@ def transform_source( if hasattr(koza_app, "node_file") and hasattr(source_config, "min_node_count"): nodes_file = koza_app.node_file count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] - if count < source_config.min_node_count: + # Warn if 70% less than expected, error if less than 70% + if count < source_config.min_node_count * 0.7: raise ValueError(f"Node count {count} is less than expected {source_config.min_node_count}") + if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: + logger.warning(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") if hasattr(koza_app, "edge_file") and hasattr(source_config, "min_edge_count"): edges_file = koza_app.edge_file count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] - if count < source_config.min_edge_count: + # Warn if 70% less than expected, error if less than 70% + if count < source_config.min_edge_count * 0.7: raise ValueError(f"Edge count {count} is less than expected {source_config.min_edge_count}") - - # Write report to output directory + if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: + logger.warning(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") def validate_file( From 12d9473171650f2468044b70d79a7aaba4664d13 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 14:20:36 -0600 Subject: [PATCH 24/30] add warning for 70% less, error for below that --- src/koza/cli_utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 729fa82..92c8f63 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -100,18 +100,18 @@ def transform_source( count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% if count < source_config.min_node_count * 0.7: - raise ValueError(f"Node count {count} is less than expected {source_config.min_node_count}") + raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: - logger.warning(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") + logger.warning(f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected") if hasattr(koza_app, "edge_file") and hasattr(source_config, "min_edge_count"): edges_file = koza_app.edge_file count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% if count < source_config.min_edge_count * 0.7: - raise ValueError(f"Edge count {count} is less than expected {source_config.min_edge_count}") + raise ValueError(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: - logger.warning(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") + logger.warning(f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected") def validate_file( From 7dcfa802a1c07f3a9a37f975d0c564f1c7faaa79 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 14:22:31 -0600 Subject: [PATCH 25/30] try log with empty valueerror --- src/koza/cli_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 92c8f63..0b2d17c 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -100,7 +100,9 @@ def transform_source( count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% if count < source_config.min_node_count * 0.7: - raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") + # raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") + logger.error(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") + raise ValueError if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: logger.warning(f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected") From 4f7d6523d530cac103366bbceed320df380c45c5 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 14:28:56 -0600 Subject: [PATCH 26/30] ok that looks horrible --- src/koza/cli_utils.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 0b2d17c..c7486d6 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -100,11 +100,11 @@ def transform_source( count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% if count < source_config.min_node_count * 0.7: - # raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") - logger.error(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") - raise ValueError + raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: - logger.warning(f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected") + logger.warning( + f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected" + ) if hasattr(koza_app, "edge_file") and hasattr(source_config, "min_edge_count"): edges_file = koza_app.edge_file @@ -113,7 +113,9 @@ def transform_source( if count < source_config.min_edge_count * 0.7: raise ValueError(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: - logger.warning(f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected") + logger.warning( + f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected" + ) def validate_file( From 2d2e93174862f09374cd48eb79b4777ac681de77 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 14:45:01 -0600 Subject: [PATCH 27/30] comment out node/edge report columns for now --- src/koza/model/config/source_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/koza/model/config/source_config.py b/src/koza/model/config/source_config.py index ca99bff..8ef42fe 100644 --- a/src/koza/model/config/source_config.py +++ b/src/koza/model/config/source_config.py @@ -308,8 +308,8 @@ class PrimaryFileConfig(SourceConfig): edge_properties: Optional[List[str]] = None min_node_count: Optional[int] = None min_edge_count: Optional[int] = None - node_report_columns: Optional[List[str]] = None - edge_report_columns: Optional[List[str]] = None + # node_report_columns: Optional[List[str]] = None + # edge_report_columns: Optional[List[str]] = None depends_on: List[str] = field(default_factory=list) on_map_failure: MapErrorEnum = MapErrorEnum.warning From 9b6246ac9a2c73e033925b1021fb3b6290ec558b Mon Sep 17 00:00:00 2001 From: glass-ships Date: Fri, 3 May 2024 15:09:43 -0600 Subject: [PATCH 28/30] fix test --- poetry.lock | 18 +++++++++--------- src/koza/cli_utils.py | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/poetry.lock b/poetry.lock index b5c7e9c..71dc2c8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -855,13 +855,13 @@ files = [ [[package]] name = "jsonschema" -version = "4.21.1" +version = "4.22.0" description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, - {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, ] [package.dependencies] @@ -1210,13 +1210,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.20" +version = "9.5.21" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.20-py3-none-any.whl", hash = "sha256:ad0094a7597bcb5d0cc3e8e543a10927c2581f7f647b9bb4861600f583180f9b"}, - {file = "mkdocs_material-9.5.20.tar.gz", hash = "sha256:986eef0250d22f70fb06ce0f4eac64cc92bd797a589ec3892ce31fad976fe3da"}, + {file = "mkdocs_material-9.5.21-py3-none-any.whl", hash = "sha256:210e1f179682cd4be17d5c641b2f4559574b9dea2f589c3f0e7c17c5bd1959bc"}, + {file = "mkdocs_material-9.5.21.tar.gz", hash = "sha256:049f82770f40559d3c2aa2259c562ea7257dbb4aaa9624323b5ef27b2d95a450"}, ] [package.dependencies] @@ -2031,13 +2031,13 @@ rdflib-jsonld = "0.6.1" [[package]] name = "referencing" -version = "0.35.0" +version = "0.35.1" description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.35.0-py3-none-any.whl", hash = "sha256:8080727b30e364e5783152903672df9b6b091c926a146a759080b62ca3126cd6"}, - {file = "referencing-0.35.0.tar.gz", hash = "sha256:191e936b0c696d0af17ad7430a3dc68e88bc11be6514f4757dc890f04ab05889"}, + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, ] [package.dependencies] diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index c7486d6..ec269e3 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -95,7 +95,7 @@ def transform_source( ### QC checks # Confirm min number of rows in output - if hasattr(koza_app, "node_file") and hasattr(source_config, "min_node_count"): + if hasattr(koza_app, "node_file") and source_config.min_node_count is not None: nodes_file = koza_app.node_file count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% @@ -106,7 +106,7 @@ def transform_source( f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected" ) - if hasattr(koza_app, "edge_file") and hasattr(source_config, "min_edge_count"): + if hasattr(koza_app, "edge_file") and source_config.min_edge_count is not None: edges_file = koza_app.edge_file count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] # Warn if 70% less than expected, error if less than 70% From 1e412806a2467ddf7516be13da3b0cb097775695 Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 6 May 2024 18:50:47 -0600 Subject: [PATCH 29/30] try adding node/edge type to cli args --- src/koza/cli_utils.py | 45 ++++++++++++++++++++++++++----------------- src/koza/main.py | 14 +++++++++++++- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index ec269e3..366bb86 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -95,27 +95,36 @@ def transform_source( ### QC checks # Confirm min number of rows in output + if hasattr(koza_app, "node_file") and source_config.min_node_count is not None: - nodes_file = koza_app.node_file - count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] - # Warn if 70% less than expected, error if less than 70% - if count < source_config.min_node_count * 0.7: - raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") - if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: - logger.warning( - f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected" - ) + if row_limit and row_limit < source_config.min_node_count: + # do something here? + pass + else: + nodes_file = koza_app.node_file + count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] + # Warn if 70% less than expected, error if less than 70% + if count < source_config.min_node_count * 0.7: + raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") + if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: + logger.warning( + f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected" + ) if hasattr(koza_app, "edge_file") and source_config.min_edge_count is not None: - edges_file = koza_app.edge_file - count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] - # Warn if 70% less than expected, error if less than 70% - if count < source_config.min_edge_count * 0.7: - raise ValueError(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") - if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: - logger.warning( - f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected" - ) + if row_limit and row_limit < source_config.min_edge_count: + # do something here? + pass + else: + edges_file = koza_app.edge_file + count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] + # Warn if 70% less than expected, error if less than 70% + if count < source_config.min_edge_count * 0.7: + raise ValueError(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") + if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: + logger.warning( + f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected" + ) def validate_file( diff --git a/src/koza/main.py b/src/koza/main.py index 5b6aefb..fe4008b 100755 --- a/src/koza/main.py +++ b/src/koza/main.py @@ -39,7 +39,19 @@ def transform( raise NotADirectoryError(f"{output_dir} is not a directory") elif not output_path.exists(): output_path.mkdir(parents=True) - transform_source(source, output_dir, output_format, global_table, local_table, schema, row_limit, verbose, log) + transform_source( + source, + output_dir, + output_format, + global_table, + local_table, + schema, + node_type=None, + edge_type=None, + row_limit=row_limit, + verbose=verbose, + log=log, + ) @typer_app.command() From 2b6c014fcfc10da54f684ea2b7c8d870505af27e Mon Sep 17 00:00:00 2001 From: glass-ships Date: Mon, 13 May 2024 13:50:40 -0600 Subject: [PATCH 30/30] try fixing row count check --- src/koza/cli_utils.py | 53 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/koza/cli_utils.py b/src/koza/cli_utils.py index 366bb86..edc1393 100644 --- a/src/koza/cli_utils.py +++ b/src/koza/cli_utils.py @@ -3,7 +3,7 @@ """ from pathlib import Path -from typing import Dict, Optional, Union +from typing import Dict, Literal, Optional, Union import yaml import duckdb @@ -66,7 +66,7 @@ def transform_source( with open(source, "r") as source_fh: source_config = PrimaryFileConfig(**yaml.load(source_fh, Loader=UniqueIncludeLoader)) - # TODO: Try moving this to source_config class + # Set name and transform code if not provided if not source_config.name: source_config.name = Path(source).stem @@ -94,37 +94,36 @@ def transform_source( ### QC checks - # Confirm min number of rows in output + def _check_row_count(type: Literal["node", "edge"]): + """Check row count for nodes or edges.""" - if hasattr(koza_app, "node_file") and source_config.min_node_count is not None: - if row_limit and row_limit < source_config.min_node_count: - # do something here? - pass + if type == "node": + outfile = koza_app.node_file + min_count = source_config.min_node_count + elif type == "edge": + outfile = koza_app.edge_file + min_count = source_config.min_edge_count + + count = duckdb.sql(f"SELECT count(*) from '{outfile}' as count").fetchone()[0] + + if row_limit and row_limit < min_count: + logger.warning(f"Row limit '{row_limit}' is less than expected count of {min_count} {type}s") + elif row_limit and row_limit < count: + logger.error(f"Actual {type} count {count} exceeds row limit {row_limit}") else: - nodes_file = koza_app.node_file - count = duckdb.sql(f"SELECT count(*) from '{nodes_file}' as count").fetchone()[0] - # Warn if 70% less than expected, error if less than 70% - if count < source_config.min_node_count * 0.7: - raise ValueError(f"Node count {count} is less than 70% of expected {source_config.min_node_count}") - if source_config.min_node_count * 0.7 <= count < source_config.min_node_count: + if count < min_count * 0.7: + raise ValueError(f"Actual {type} count {count} is less than 70% of expected {min_count} {type}s") + if min_count * 0.7 <= count < min_count: logger.warning( - f"Node count {count} is less than expected {source_config.min_node_count}, but more than 70% of expected" + f"Actual {type} count {count} is less than expected {min_count}, but more than 70% of expected" ) + # Confirm min number of rows in output + if hasattr(koza_app, "node_file") and source_config.min_node_count is not None: + _check_row_count("node") + if hasattr(koza_app, "edge_file") and source_config.min_edge_count is not None: - if row_limit and row_limit < source_config.min_edge_count: - # do something here? - pass - else: - edges_file = koza_app.edge_file - count = duckdb.sql(f"SELECT count(*) from '{edges_file}' as count").fetchone()[0] - # Warn if 70% less than expected, error if less than 70% - if count < source_config.min_edge_count * 0.7: - raise ValueError(f"Edge count {count} is less than 70% of expected {source_config.min_edge_count}") - if source_config.min_edge_count * 0.7 <= count < source_config.min_edge_count: - logger.warning( - f"Edge count {count} is less than expected {source_config.min_edge_count}, but more than 70% of expected" - ) + _check_row_count("edge") def validate_file(