diff --git a/.coveragerc b/.coveragerc index 8f90b5612..92fef198a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -17,4 +17,4 @@ exclude_lines = pragma: no cover raise NotImplementedError except ImportError - if __name__ == .__main__.: \ No newline at end of file + if __name__ == .__main__.: diff --git a/.gitattributes b/.gitattributes index 3dd30005d..31888bdd6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ # Vendor files (not to be indexed) -isa-cookbook/_static/**/* linguist-vendored \ No newline at end of file +isa-cookbook/_static/**/* linguist-vendored diff --git a/.github/workflows/buildandtestpython.yml b/.github/workflows/buildandtestpython.yml index 5b7d72dfc..2961a6cf9 100644 --- a/.github/workflows/buildandtestpython.yml +++ b/.github/workflows/buildandtestpython.yml @@ -21,8 +21,8 @@ jobs: cache-dependency-glob: uv.lock - name: Sync dependencies run: | - uv python pin ${{ matrix.python-version }} - uv sync --group dev + uv python pin ${{ matrix.python-version }} + uv sync --extra database --extra dev - uses: astral-sh/ruff-action@v3 - run: ruff check - run: ruff format diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index 6ac015a18..2693230a8 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -2,7 +2,7 @@ name: Upload Python Package on: release: - types: [published] + types: [ published ] jobs: deploy: @@ -20,7 +20,7 @@ jobs: cache-dependency-glob: uv.lock - name: Sync dependencies run: | - uv sync --no-dev + uv sync --extra database - name: Build run: | echo "Running uv build..." diff --git a/.gitignore b/.gitignore index 5662ca94f..1837fe096 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ _build/ old-tests/ +ISAdatasets/ # Byte-compiled / optimized / DLL files __pycache__/ @@ -123,7 +124,7 @@ features/test_outputs # jenv local file (for Java Versions) .java-version -# never commit test data directory, as it comes from ISA-tools/ISAdatasets! +# never commit test data directory, as it comes from ISA-tools/data! tests/data # ignore virtual environment in subdirectory @@ -144,4 +145,4 @@ isa-reports/* isaRDF/ venv*/ instance/* -instance/ \ No newline at end of file +instance/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a72dd714..146f70ba1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,43 +7,43 @@ repos: - id: validate-pyproject name: ๐Ÿ” Validate pyproject.toml - repo: https://github.com/gitleaks/gitleaks - rev: v8.28.0 + rev: v8.30.0 hooks: - id: gitleaks name: "๐Ÿ”’ Security ยท Detect hardcoded secrets" -- repo: https://github.com/hukkin/mdformat - rev: 0.7.22 - hooks: - - id: mdformat - name: "๐ŸŸข Markdown ยท Format markdown" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: check-added-large-files name: ๐ŸŸข Check large files + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ args: [ "--maxkb=2000" ] - id: check-toml name: ๐ŸŸข Check toml files + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ - id: check-json name: ๐ŸŸข Check json files + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ - id: pretty-format-json name: ๐ŸŸข Format json files + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ args: - "--autofix" - "--indent=4" - "--no-sort-keys" - id: check-yaml name: ๐ŸŸข Check yaml files + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ args: - --unsafe - id: end-of-file-fixer name: ๐ŸŸข Check end of file character - exclude: resources/.+\.(js|css)$ + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ - id: trailing-whitespace name: ๐ŸŸข Check trailing whitespaces - exclude: (tests/data/.+|resources/.+\.(js|css))$ + exclude: features/.+|isa-cookbook/.+|docs/.+|isatools/net/.+|isatools/resources/.+|tests/data/.+ - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.9.1 + rev: 0.9.15 hooks: - id: uv-lock name: โœ… Check uv.lock file @@ -54,7 +54,7 @@ repos: name: ๐Ÿ” Detect missing __init__.py files args: [ "--create", "--track", "--python-folders", "isatools" ] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.0 + rev: v0.14.7 hooks: - id: ruff-check name: ๐Ÿ” Check Format with Ruff @@ -64,7 +64,7 @@ repos: - id: ruff-format name: ๐Ÿ python ยท Format with Ruff - repo: https://github.com/seddonym/import-linter.git - rev: "v2.5.2" + rev: "v2.7" hooks: - id: import-linter name: ๐Ÿชต architecture and package structure check (lint-imports) diff --git a/LICENSE.txt b/LICENSE.txt index edc4bc2d4..58ceccec8 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -100,4 +100,4 @@ EXHIBIT B. Attribution Information Attribution Copyright Notice: Copyright (c) 2015-Present ISA Team Attribution Phrase: Developed by the ISA Team Attribution URL: http://www.isa-tools.org -Display of Attribution Information is required in Larger Works which are defined in the CPAL as a work which combines Covered Code or portions thereof with code not governed by the terms of the CPAL. \ No newline at end of file +Display of Attribution Information is required in Larger Works which are defined in the CPAL as a work which combines Covered Code or portions thereof with code not governed by the terms of the CPAL. diff --git a/get_test_data.sh b/get_test_data.sh index 8054d77e4..6d98d1499 100755 --- a/get_test_data.sh +++ b/get_test_data.sh @@ -1,9 +1,9 @@ #!/bin/bash - +rm -rf tests/data if [ "$TRAVIS_BRANCH" = "develop" ]; then git clone -b tests --single-branch http://github.com/ISA-tools/ISAdatasets tests/data else git clone -b tests --single-branch http://github.com/ISA-tools/ISAdatasets tests/data fi -ls -la tests/data/mtbls \ No newline at end of file +ls -la tests/data/mtbls diff --git a/isa-cookbook/content/notebooks/ISA-json to ISA-Tab and back to ISA-json - roundtrip.ipynb b/isa-cookbook/content/notebooks/ISA-json to ISA-Tab and back to ISA-json - roundtrip.ipynb index 2ec234fa2..6972027f2 100644 --- a/isa-cookbook/content/notebooks/ISA-json to ISA-Tab and back to ISA-json - roundtrip.ipynb +++ b/isa-cookbook/content/notebooks/ISA-json to ISA-Tab and back to ISA-json - roundtrip.ipynb @@ -98,7 +98,7 @@ "outputs": [], "source": [ "from isatools.convert import json2isatab\n", - "with open(os.path.join(\"./../../../tests/data/json/BII-I-1\", \"BII-I-1.json\")) as json_fp:\n", + "with open(os.path.join(\"../../../tests/data/json/BII-I-1\", \"BII-I-1.json\")) as json_fp:\n", " json2isatab.convert(\n", " json_fp, data_path, write_factor_values_in_assay_table=False\n", " )" diff --git a/isatools/constants.py b/isatools/constants.py index 15d061f0f..596714f7b 100644 --- a/isatools/constants.py +++ b/isatools/constants.py @@ -23,7 +23,7 @@ "Acquisition Parameter Data File", "Metabolite Assignment File", "Metabolite Identification File", - "Normalization Name" + "Normalization Name", ] _LABELS_DATA_NODES = [ diff --git a/isatools/convert/isatab2cedar.py b/isatools/convert/isatab2cedar.py index 9c0d07e20..c6454af0e 100644 --- a/isatools/convert/isatab2cedar.py +++ b/isatools/convert/isatab2cedar.py @@ -142,7 +142,6 @@ def createCEDARjson(self, work_dir, json_dir, inv_identifier): error_file_name = os.path.join(json_dir, "error.log") with open(error_file_name, "w") as errorfile: errorfile.write(e.message) -# errorfile.write(e.cause) errorfile.close() if inv_identifier: diff --git a/isatools/convert/magetab2json.py b/isatools/convert/magetab2json.py index 4710f151d..fac615598 100644 --- a/isatools/convert/magetab2json.py +++ b/isatools/convert/magetab2json.py @@ -22,5 +22,5 @@ def convert(idf_file_path): ISA = isatab.load(isa_inv_fp) finally: shutil.rmtree(tmp) - if ISA is not None: - return json.loads(json.dumps(ISA, cls=ISAJSONEncoder)) + if ISA is not None: + return json.loads(json.dumps(ISA, cls=ISAJSONEncoder)) diff --git a/isatools/create/model.py b/isatools/create/model.py index b0f34983a..69cf777f2 100644 --- a/isatools/create/model.py +++ b/isatools/create/model.py @@ -254,7 +254,7 @@ def __repr__(self): def __str__(self): return """"{0} - (type={1}, + (type={1}, factor_values={2}) """.format(self.__class__.__name__, self.type, sorted(self.factor_values, key=lambda x: repr(x))) @@ -327,8 +327,8 @@ def __repr__(self): def __str__(self): return """{0}( - name={name}, - elements={elements_count} items, + name={name}, + elements={elements_count} items, )""".format(self.__class__.__name__, name=self.name, elements_count=len(self.elements)) def __hash__(self): @@ -799,12 +799,12 @@ def __repr__(self): def __str__(self): return """{0}( - id={1.id}, - name={1.name}, - protocol_type={1.protocol_type}, - uri={1.uri}, - description={1.description}, - version={1.version}, + id={1.id}, + name={1.name}, + protocol_type={1.protocol_type}, + uri={1.uri}, + description={1.description}, + version={1.version}, parameter_values={1.parameter_values}) """.format(self.__class__.__name__, self) @@ -1011,7 +1011,7 @@ def __repr__(self): def __str__(self): return """{0}( pre_run_sample_type={1} - post_run_sample_type={2} + post_run_sample_type={2} interspersed_sample_types={3} )""".format( self.__class__.__name__, @@ -1410,9 +1410,9 @@ def __str__(self): links = [(start_node.id, end_node.id) for start_node, end_node in self.links] return """"{0}( id={1.id} - measurement_type={1.measurement_type} + measurement_type={1.measurement_type} technology_type={1.technology_type} - nodes={1.nodes} + nodes={1.nodes} links={2} )""".format(self.__class__.__name__, self, sorted(links, key=lambda link: (link[0], link[1]))) @@ -1604,7 +1604,7 @@ def __repr__(self): def __str__(self): return """{0}( name={1.name}, - sample_plan={1.sample_plan}, + sample_plan={1.sample_plan}, assay_plan={1.assay_plan} )""".format(self.__class__.__name__, self) @@ -1848,7 +1848,7 @@ def __str__(self): return """{0}( name={name}, source_type={source_type}, - group_size={group_size}, + group_size={group_size}, no. cells={cells}, no. sample_assay_plans={sample_assay_plans} )""".format( @@ -2773,7 +2773,7 @@ def __repr__(self): def __str__(self): return """{0}( - identifier={identifier}, + identifier={identifier}, name={name}, description={description}, study_arms={study_arms} diff --git a/isatools/database/models/constraints.py b/isatools/database/models/constraints.py index c727b3874..264242557 100644 --- a/isatools/database/models/constraints.py +++ b/isatools/database/models/constraints.py @@ -63,6 +63,6 @@ def build_material_constraints() -> CheckConstraint: :return: A CheckConstraint object used to validate the Material table. """ - statement = """NOT (material_type IS NOT NULL + statement = """NOT (material_type IS NOT NULL AND material_type != 'Extract Name' AND material_type != 'Labeled Extract Name')""" return CheckConstraint(statement, name="material_type_must_be_extract_name_or_labeled_extract_name") diff --git a/isatools/graphQL/README.md b/isatools/graphQL/README.md index 390317541..8f11f41f4 100644 --- a/isatools/graphQL/README.md +++ b/isatools/graphQL/README.md @@ -1,8 +1,8 @@ # ISA-QL: -ISA-QL is a syntax querying language built for the ISA model and based on [GraphQL](https://graphql.org/) and +ISA-QL is a syntax querying language built for the ISA model and based on [GraphQL](https://graphql.org/) and [Graphene](https://github.com/graphql-python/graphene). -It provides a fast and easy programmatic access to the very complex and nested fields within an ISA Investigation as +It provides a fast and easy programmatic access to the very complex and nested fields within an ISA Investigation as well as the ability to filter attributes based on user inputs. It is bundled with the ISA-api python library and directly integrated as a method of ISA Investigation objects. @@ -23,7 +23,7 @@ with open(investigation_filepath, "r") as investigation_file: investigation_file.close() ``` -One of the powerful features of GraphQL is its ability to self-document through so-called *introspection +One of the powerful features of GraphQL is its ability to self-document through so-called *introspection queries*. This allows interrogating an endpoint information about the queryable fields and their valid inputs. One such *introspection query* has already been written for ease of use and wrapped in the ``investigation.instropect()`` method (see usage below.) @@ -39,7 +39,7 @@ The *introspection query* is available from the ``/graphQL/queries/`` directory. --- ## Queryable Objects: -There are 3 mains queryable objects at the root of the ISA-QL syntax: +There are 3 mains queryable objects at the root of the ISA-QL syntax: - the [investigation](#investigation) @@ -58,7 +58,7 @@ There are 3 mains queryable objects at the root of the ISA-QL syntax: | submissionDate | Submission date of the investigation | DateTime | | publicReleaseDate | Public release date of the investigation | DateTime | | ontologySourceReferences | Ontology source references used by the investigation | [OntologySourceReference](#OntologySourceReference) | -| publications | Publications associated with the investigation | [Publication](#Publication) | +| publications | Publications associated with the investigation | [Publication](#Publication) | | people | People to contact for the investigation | [Person](#Person) | | studies | Studies associated with the investigation | [Study](#Study) | @@ -74,9 +74,9 @@ elif response.errors: ``` As shown in the example above, the `query` is divided into two segments: the first one indicates which object we want to -query (in this case an `investigation`). The second one, located between the second set of curly brackets indicates the -fields we want to retrieve. -Queryable fields can be simple, as shown in the example, or represent complex objects, which +query (in this case an `investigation`). The second one, located between the second set of curly brackets indicates the +fields we want to retrieve. +Queryable fields can be simple, as shown in the example, or represent complex objects, which also have their own queryable fields. ### The Studies query: @@ -101,7 +101,7 @@ also have their own queryable fields. | characteristicCategories | Categories of characteristics associated with this study | [OntologyAnnotation](#OntologyAnnotation) | | unitCategories | Categories of units associated with the study | [OntologyAnnotation](#OntologyAnnotation) | -We can reuse the previous query to request the same fields but this time for any of the studies present in the ISA document. +We can reuse the previous query to request the same fields but this time for any of the studies present in the ISA document. ```python query = '{ studies { title description identifier }}' @@ -138,7 +138,7 @@ elif response.errors: | unitCategories | Categories of units associated with this assay | [OntologyAnnotation](#OntologyAnnotation) | | processSequence | Processes associated with this assay | [Process](#Process) | -The assay query is usable on its own (in which cases, all assays from different studies will be concatenated in the same output) or as a field of a `studies` query. +The assay query is usable on its own (in which cases, all assays from different studies will be concatenated in the same output) or as a field of a `studies` query. The request below will retrieve the filename associated with the investigation, with each study in that investigation, and with each assay in each study. @@ -155,25 +155,25 @@ elif response.errors: ###### Introduction to filters: The assay query is different from investigations and studies because it accepts parameters that will allow to -filter them based on specific inputs. For instance, a user may want to retrieve only the assays performed using +filter them based on specific inputs. For instance, a user may want to retrieve only the assays performed using `nucleotide sequencing`. The `assays` query takes two inputs: - an operator: 'AND' or 'OR', it indicates how filters should be assembled. Its default value is always 'AND'. -- a list of filters to assemble. Each filter contains a key that indicates to which field the filter should be applied - and an expression in the form of an object. This expression contains a key that indicates the operation to run and a +- a list of filters to assemble. Each filter contains a key that indicates to which field the filter should be applied + and an expression in the form of an object. This expression contains a key that indicates the operation to run and a value to compare with. Typically, this is how a filter would look like: - + ``` filters: { technologyType: { eq: "nucleotide sequencing" } } ``` -The first key (`technologyType`) indicated which field to target. The second key (`eq`) indicates which comparison operation should be executed. +The first key (`technologyType`) indicated which field to target. The second key (`eq`) indicates which comparison operation should be executed. -- For strings, it can take the `eq` (equal) or `in` (includes) values. +- For strings, it can take the `eq` (equal) or `in` (includes) values. -- For integers, it can be `lt` (lower than), `lte` (lower than or equal), `gt` (greater than) or `gte` (greater than or equal). +- For integers, it can be `lt` (lower than), `lte` (lower than or equal), `gt` (greater than) or `gte` (greater than or equal). Finally, the string indicates the filter value is "nucleotide sequencing". @@ -196,15 +196,15 @@ This query retrieves filename of assays for which the technology type includes t |------------------|--------------------------------------------------------------------------------------------------|-------------------------------------------|---------------------------|-------------------------------------------| | measurementType | Type of measurement realised in the assay | String | measurementType | X | | executesProtocol | Protocol executed by a process | String | process.executesProtocol | X | -| technologyType | Type of technology used in the assay | String | technologyType | X | +| technologyType | Type of technology used in the assay | String | technologyType | X | | treatmentGroup | Conditions the group was exposed to | [ExposureParameters](#ExposureParameters) | process.inputs | X | | characteristics | Characteristics the material should comply with | [ExposureParameters](#ExposureParameters) | process.inputs | X | | parameterValues | Parameters values a process should comply with | [ParameterValues](#ParameterValues) | process.parameterValues | X | | on | Control to which input/output type the treatmentGroup and characteristics filters should apply | String | see controlled values | "Sample", "Source, "DataFile", "Material" | -Using the `operator` key, we can assemble multiple filters in a single query. -However, at this point the code becomes hard to maintain, and we suggest creating dedicated query files in the `.gql` format. +Using the `operator` key, we can assemble multiple filters in a single query. +However, at this point the code becomes hard to maintain, and we suggest creating dedicated query files in the `.gql` format. We now want to retrieve ISA assay filenames given the following constraints: - the technology used is `nucleotide sequencing` (**exact match**) @@ -391,7 +391,7 @@ elif response.errors: | submissionDate | Submission date of the investigation | DateTime | | publicReleaseDate | Public release date of the investigation | DateTime | | ontologySourceReferences | Ontology source references used by the investigation | [OntologySourceReference](#OntologySourceReference) | -| publications | Publications associated with the investigation | [Publication](#Publication) | +| publications | Publications associated with the investigation | [Publication](#Publication) | | people | People to contact for the investigation | [Person](#Person) | | studies | Studies associated with the investigation | [Study](#Studies) | @@ -435,7 +435,7 @@ elif response.errors: | Field name | Description | Type | |------------------|--------------------------------------------------------|--------------------------------------------------------------------------------------| | name | Name of the process | String | -| executesProtocol | Protocol executed by the process | [Protocol](#Protocol) | +| executesProtocol | Protocol executed by the process | [Protocol](#Protocol) | | parameterValues | Parameters used by the protocol of this process | [ProtocolParameterValue](#ProtocolParameterValue) | | performer | Name of the person who executed the protocol | String | | date | ? | DateTime | @@ -533,7 +533,7 @@ the main key represents the comparator. For example: `measurementType: {eq: "tra |------------------|--------------------------------------------------------------------------------------------------|-------------------------------------------|---------------------------|-------------------------------------------| | measurementType | Type of measurement realised in the assay | String | measurementType | X | | executesProtocol | Protocol executed by a process | String | process.executesProtocol | X | -| technologyType | Type of technology used in the assay | String | technologyType | X | +| technologyType | Type of technology used in the assay | String | technologyType | X | | treatmentGroup | Conditions the group was exposed to | [ExposureParameters](#ExposureParameters) | process.inputs | X | | characteristics | Characteristics the material should comply with | [ExposureParameters](#ExposureParameters) | process.inputs | X | | parameterValues | Parameters values a process should comply with | [ParameterValues](#ParameterValues) | process.parameterValues | X | @@ -575,4 +575,4 @@ the main key represents the comparator. For example: `measurementType: {eq: "tra |------------------|---------------------------------------------------|-------------------------------------------|---------------------------|-------------------------------------------| | treatmentGroup | Conditions the group was exposed to | [ExposureParameters](#ExposureParameters) | process.inputs | X | | type | Name of the output to filter on | [ExposureParameters](#ExposureParameters) | process.inputs | X | -| on | Control the output to apply the filter to | String | see controlled values | "Sample", "DataFile" or "Material" | \ No newline at end of file +| on | Control the output to apply the filter to | String | see controlled values | "Sample", "DataFile" or "Material" | diff --git a/isatools/graphQL/queries/introspection.gql b/isatools/graphQL/queries/introspection.gql index 4221ad0f1..3758b5c13 100644 --- a/isatools/graphQL/queries/introspection.gql +++ b/isatools/graphQL/queries/introspection.gql @@ -84,4 +84,4 @@ fragment TypeRef on __Type { } } } -} \ No newline at end of file +} diff --git a/isatools/isajson/validate.py b/isatools/isajson/validate.py index e4e3ebfb8..048c742ef 100644 --- a/isatools/isajson/validate.py +++ b/isatools/isajson/validate.py @@ -20,6 +20,8 @@ from referencing.jsonschema import DRAFT202012 from isatools.isajson.load import load +from isatools.model.assay import Assay +from isatools.model.study import Study __author__ = "djcomlab@gmail.com (David Johnson)" @@ -887,7 +889,11 @@ def check_measurement_technology_types(assay_json, configs): technology_type = assay_json["technologyType"]["annotationValue"] config = configs[(measurement_type, technology_type)] if config is None: - raise KeyError + raise KeyError( + "Could not find configuration for measurement type '{}' and technology type '{}'".format( + measurement_type, technology_type + ) + ) except KeyError: errors.append( { @@ -982,17 +988,22 @@ def check_assay_graph(process_sequence_json, config): def check_study_groups(study_or_assay): samples = study_or_assay.samples + identifier = "" + if isinstance(study_or_assay, Study): + identifier = study_or_assay.identifier + elif isinstance(study_or_assay, Assay): + identifier = study_or_assay.id study_groups = set() for sample in samples: if len(sample.factor_values) > 0: factors = tuple(sample.factor_values) study_groups.add(factors) num_study_groups = len(study_groups) - log.info("Found {} study groups in {}".format(num_study_groups, study_or_assay.identifier)) + log.info("Found {} study groups in {}".format(num_study_groups, identifier)) info.append( { - "message": "Found {} study groups in {}".format(num_study_groups, study_or_assay.identifier), - "supplemental": "Found {} study groups in {}".format(num_study_groups, study_or_assay.identifier), + "message": "Found {} study groups in {}".format(num_study_groups, identifier), + "supplemental": "Found {} study groups in {}".format(num_study_groups, identifier), "code": 5001, } ) @@ -1002,10 +1013,10 @@ def check_study_groups(study_or_assay): warnings.append( { "message": "Reported study group size {} does not match table {}".format( - num_study_groups, study_or_assay.identifier + num_study_groups, identifier ), "supplemental": "Study group size reported as {} but found {} in {}".format( - study_group_size_in_comment, num_study_groups, study_or_assay.identifier + study_group_size_in_comment, num_study_groups, identifier ), "code": 5002, } @@ -1144,7 +1155,7 @@ def validate( log.fatal("(F) Something went very very wrong! :(") finally: handler.flush() - return {"errors": errors, "warnings": warnings, "validation_finished": True} + return {"errors": errors, "warnings": warnings, "validation_finished": True} def batch_validate(json_file_list): diff --git a/isatools/isatab/load/core.py b/isatools/isatab/load/core.py index 741421ab8..a31e3220f 100644 --- a/isatools/isatab/load/core.py +++ b/isatools/isatab/load/core.py @@ -185,7 +185,11 @@ def get_contacts(self, contact_dataframe: DataFrame) -> list[Person]: elif "Study Person Last Name" in contact_dataframe.columns: prefix = "Study " else: - raise KeyError + raise KeyError( + "Could not find Investigation Person Last Name " + "or Study Person Last Name in the contact " + "sections of the investigation file" + ) for current_row in contact_dataframe.to_dict(orient="records"): person: Person = Person( @@ -280,7 +284,11 @@ def get_publications(self, section_df) -> list[Publication]: elif "Study PubMed ID" in section_df.columns: prefix = "Study " else: - raise KeyError + raise KeyError( + "Could not find Investigation PubMed ID " + "or Study PubMed ID in the publication " + "sections of the investigation file" + ) for _, current_row in section_df.iterrows(): publication: Publication = Publication( diff --git a/isatools/model/assay.py b/isatools/model/assay.py index 116c78361..c321f28b4 100644 --- a/isatools/model/assay.py +++ b/isatools/model/assay.py @@ -75,6 +75,7 @@ def __init__( self.data_files = data_files or [] self.id = id_ + @property def measurement_type(self): """:obj:`OntologyAnnotation: an ontology annotation representing the diff --git a/isatools/model/mixins.py b/isatools/model/mixins.py index 2b4232e42..9a5d4b6b9 100644 --- a/isatools/model/mixins.py +++ b/isatools/model/mixins.py @@ -18,7 +18,7 @@ class MetadataMixin(metaclass=ABCMeta): - """ Abstract mixin class to contain metadata fields found in Investigation + """Abstract mixin class to contain metadata fields found in Investigation and Study sections of ISA Attributes: @@ -161,7 +161,7 @@ def contacts(self, val): class StudyAssayMixin(metaclass=ABCMeta): - """ Abstract mixin class to contain common fields found in Study + """Abstract mixin class to contain common fields found in Study and Assay sections of ISA Attributes: @@ -251,7 +251,7 @@ def sources(self, val): raise AttributeError("{}.sources must be iterable containing Sources".format(type(self).__name__)) def add_source(self, name="", characteristics=None, comments=None): - """ Adds a new source to the source materials list. + """Adds a new source to the source materials list. :param string name: Source name :param list[Characteristics] characteristics: Characteristics about the Source :param list comments: Comments about the Source @@ -260,7 +260,7 @@ def add_source(self, name="", characteristics=None, comments=None): self.sources.append(s) def yield_sources(self, name=None): - """ Gets an iterator of matching sources for a given name. + """Gets an iterator of matching sources for a given name. Args: name: Source name @@ -272,7 +272,7 @@ def yield_sources(self, name=None): return filter(lambda x: x, self.sources) if name is None else filter(lambda x: x.name == name, self.sources) def get_source(self, name): - """ Gets the first matching source material for a given name. + """Gets the first matching source material for a given name. Args: name: Source name @@ -287,7 +287,7 @@ def get_source(self, name): return None def yield_sources_by_characteristic(self, characteristic=None): - """ Gets an iterator of matching sources for a given characteristic. + """Gets an iterator of matching sources for a given characteristic. Args: characteristic: Source characteristic @@ -301,7 +301,7 @@ def yield_sources_by_characteristic(self, characteristic=None): return filter(lambda x: characteristic in x.characteristics, self.sources) def get_source_by_characteristic(self, characteristic): - """ Gets the first matching source material for a given characteristic. + """Gets the first matching source material for a given characteristic. Args: characteristic: Source characteristic @@ -317,7 +317,7 @@ def get_source_by_characteristic(self, characteristic): return None def get_source_names(self): - """ Gets all the source names. + """Gets all the source names. Returns: :obj:`list` of str. @@ -339,7 +339,7 @@ def samples(self, val): raise AttributeError("{}.samples must be iterable containing Samples".format(type(self).__name__)) def add_sample(self, name="", characteristics=None, factor_values=None, derives_from=None, comments=None): - """ Adds a new sample to the sample materials list. + """Adds a new sample to the sample materials list. :param string name: Sample name :param list[Characteristics] characteristics: Characteristics about the sample :param list comments: Comments about the sample @@ -357,14 +357,14 @@ def add_sample(self, name="", characteristics=None, factor_values=None, derives_ self.samples.append(sample) def yield_samples(self, name=None): - """ Gets an iterator of matching samples for a given name. + """Gets an iterator of matching samples for a given name. :param string name: Sample name :return: object:`filter` of object:`Source` that can be iterated on. If name is None, yields all samples. """ return filter(lambda x: x, self.samples) if name is None else filter(lambda x: x.name == name, self.samples) def get_sample(self, name): - """ Gets the first matching sample material for a given name. + """Gets the first matching sample material for a given name. Args: name: Sample name @@ -379,7 +379,7 @@ def get_sample(self, name): return None def yield_samples_by_characteristic(self, characteristic=None): - """ Gets an iterator of matching samples for a given characteristic. + """Gets an iterator of matching samples for a given characteristic. Args: characteristic: Sample characteristic @@ -394,7 +394,7 @@ def yield_samples_by_characteristic(self, characteristic=None): return filter(lambda x: characteristic in x.characteristics, self.samples) def get_sample_by_characteristic(self, characteristic): - """ Gets the first matching sample material for a given characteristic. + """Gets the first matching sample material for a given characteristic. Args: characteristic: Sample characteristic @@ -411,7 +411,7 @@ def get_sample_by_characteristic(self, characteristic): return None def yield_samples_by_factor_value(self, factor_value=None): - """ Gets an iterator of matching samples for a given factor_value. + """Gets an iterator of matching samples for a given factor_value. Args: factor_value: Sample factor value @@ -426,7 +426,7 @@ def yield_samples_by_factor_value(self, factor_value=None): return filter(lambda x: factor_value in x.factor_values, self.samples) def get_sample_by_factor_value(self, factor_value): - """ Gets the first matching sample material for a given factor_value. + """Gets the first matching sample material for a given factor_value. Args: factor_value: Sample factor value @@ -443,7 +443,7 @@ def get_sample_by_factor_value(self, factor_value): return None def get_sample_names(self): - """ Gets all the sample names. + """Gets all the sample names. Returns: :obj:`list` of str. @@ -465,7 +465,7 @@ def other_material(self, val): raise AttributeError("{}.other_material must be iterable containing Materials".format(type(self).__name__)) def yield_materials_by_characteristic(self, characteristic=None): - """ Gets an iterator of matching materials for a given characteristic. + """Gets an iterator of matching materials for a given characteristic. Args: characteristic: Material characteristic @@ -480,7 +480,7 @@ def yield_materials_by_characteristic(self, characteristic=None): return filter(lambda x: characteristic in x.characteristics, self.other_material) def get_material_by_characteristic(self, characteristic): - """ Gets the first matching material for a given + """Gets the first matching material for a given characteristic. Args: diff --git a/isatools/model/ontology_source.py b/isatools/model/ontology_source.py index c0a1eb393..fe5e717c4 100644 --- a/isatools/model/ontology_source.py +++ b/isatools/model/ontology_source.py @@ -19,7 +19,13 @@ class OntologySource(Commentable, Identifiable): """ def __init__( - self, id_="", name: str = "", file: str = "", version: str = "", description: str = "", comments: List[Comment] = None + self, + id_="", + name: str = "", + file: str = "", + version: str = "", + description: str = "", + comments: List[Comment] = None, ): super().__init__(comments) self.id = id_ @@ -130,7 +136,7 @@ def to_dict(self, ld=False): return self.update_isa_object(ontology_source_ref, ld=ld) def from_dict(self, ontology_source): - self.id = ontology_source.get("@id","") + self.id = ontology_source.get("@id", "") self.name = ontology_source["name"] if "name" in ontology_source else "" self.file = ontology_source["file"] if "file" in ontology_source else "" self.version = ontology_source["version"] if "version" in ontology_source else "" diff --git a/isatools/model/patchnote.txt b/isatools/model/patchnote.txt index 52a647553..ba5a5ba79 100644 --- a/isatools/model/patchnote.txt +++ b/isatools/model/patchnote.txt @@ -1,3 +1,3 @@ Full refactor: 1. Dropped the Commentable get_comments() method. -2. Fixed OntologyAnnotation __str__() method. \ No newline at end of file +2. Fixed OntologyAnnotation __str__() method. diff --git a/isatools/net/ols.py b/isatools/net/ols.py index 12cd5c49e..972022336 100644 --- a/isatools/net/ols.py +++ b/isatools/net/ols.py @@ -54,8 +54,12 @@ def get_ols_ontology(ontology_name, page: int): ontology_sources.append( OntologySource( name=ontology_source_json["ontologyId"], - version=ontology_source_json["config"]["version"] if ontology_source_json["config"]["version"] else "", - description=ontology_source_json["config"]["title"] if ontology_source_json["config"]["title"] else "", + version=ontology_source_json["config"]["version"] + if ontology_source_json["config"]["version"] + else "", + description=ontology_source_json["config"]["title"] + if ontology_source_json["config"]["title"] + else "", file=ontology_source_json["_links"]["self"]["href"], ) ) @@ -77,7 +81,6 @@ def search_ols(term, ontology_source): query = "{0}&queryFields=label&ontology={1}&exact=True".format(term, os_search) url += "?q={}".format(query) - #print("OLS_URL", url) log.debug(url) import requests diff --git a/isatools/tests/utils.py b/isatools/tests/utils.py index 9a5e90227..0399bd426 100644 --- a/isatools/tests/utils.py +++ b/isatools/tests/utils.py @@ -19,7 +19,7 @@ log = logging.getLogger("isatools") -DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "tests", "data") +DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "tests", "data") JSON_DATA_DIR = os.path.join(DATA_DIR, "json") diff --git a/isatools/utils.py b/isatools/utils.py index a4e0c28aa..9714f972b 100644 --- a/isatools/utils.py +++ b/isatools/utils.py @@ -335,14 +335,14 @@ def compute_study_factors_on_mtbls(tab_dir_root): :return: None, output writes to stdout Usage: - >>> compute_study_factors_on_mtbls('tests/data') + >>> compute_study_factors_on_mtbls('../tests/data') # if tests/data contains tests/data/MTBLS1, tests/data/MTBLS2 etc. To write to an output file: >>> import sys >>> stdout_console = sys.stdout # save normal stdout >>> sys.stdout = open('out.txt') # set to file - >>> compute_study_factors_on_mtbls('tests/data') + >>> compute_study_factors_on_mtbls('../tests/data') >>> sys.stdout = stdout_console # reset stdout """ for mtbls_dir in [x for x in os.listdir(tab_dir_root) if x.startswith("MTBLS")]: diff --git a/pyproject.toml b/pyproject.toml index fb390db90..2c4f33c89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,39 +33,55 @@ classifiers = [ dependencies = [ "setuptools>=77.0.3,<81", 'numpy~=2.0.2 ; python_version < "3.10"', - 'numpy~=2.2.4 ; python_version >= "3.10"', + 'numpy~=2.2.4,<3.0.0 ; python_version >= "3.10"', 'networkx>=3.2,<3.3 ; python_version < "3.10"', - 'networkx~=3.4.2 ; python_version >= "3.10"', + 'networkx>=3.4.2 ; python_version >= "3.10"', "jsonschema>=4.23.0,<5", "pandas>=2.2.3,<3", "openpyxl>=3.1.5", - "lxml~=6.0.2", - "requests~=2.32.4", - "iso8601~=2.1.0", - "chardet~=5.2.0", - "jinja2~=3.1.4", + "lxml>=6.1.0", + 'requests>=2.34.0 ; python_version >= "3.10"', + 'requests>=2.32.0 ; python_version < "3.10"', + "iso8601>=2.1.0", + "chardet>=5.2.0", + "jinja2>=3.1.4", + "beautifulsoup4>=4.14.2", "ddt~=1.7.2", "deepdiff~=8.6.1", - "beautifulsoup4~=4.14.2", "mzml2isa==1.1.1", "biopython>=1.85,<1.86", - "progressbar2~=4.5.0", - "PyYAML~=6.0.2", - "rdflib~=7.2.1", - "python-dateutil~=2.9.0.post0", - "Flask>=3.1.1", - "flask_sqlalchemy>=3.0.2", - "SQLAlchemy~=2.0.31", #1.4.54 - "graphene~=3.4.3", - "graphql-core~=3.2.6", - "ruff>=0.14.1", - "pytest-timeout>=2.4.0", - "urllib3==2.6.0", - "tornado==6.5.5" + "progressbar2>=4.5.0", + "PyYAML>=6.0.3", + "rdflib>=7.2.1", + "python-dateutil>=2.9.0.post0", + "graphene>=3.4.3,<4.0.0", +# "graphql-core~=3.2.6", +# "urllib3==2.6.0", +# "tornado==6.5.5" ] [project.optional-dependencies] notebook = ["bokeh~=3.4.2"] +dev = [ + "ruff>=0.15.1", + "pytest-timeout>=2.4.0", + "pytest>=8.3.5,<9.0.0", + "coveralls>=4.0.1", + "sure>=2.0.1", + "ddt>=1.7.2", + "deepdiff>=8.6.1", + "behave>=1.2.6", + "httpretty>=1.1.4", + "import-linter>=2.5.2", + "pre-commit>=4.3.0", +] +database = [ + "Flask>=3.1.1", + "flask_sqlalchemy>=3.0.2", + "SQLAlchemy~=2.0.31" +] +all = ["isatools[database,notebook]"] + [project.urls] Code = "https://github.com/ISA-tools/isa-api" @@ -76,7 +92,7 @@ Coverage = "https://coveralls.io/github/ISA-tools/isa-api?branch=master" CI = "https://github.com/ISA-tools/isa-api/actions" [build-system] -requires = ["uv_build>=0.9.3"] +requires = ["uv_build>=0.9.3,<0.10.0"] build-backend = "uv_build" [tool.uv.build-backend] @@ -84,20 +100,6 @@ module-name = "isatools" module-root = "" # data = ["resources/**/*", "net/**/*"] -[dependency-groups] -dev = [ - "pytest>=8.3.5,<9.0.0", - "coveralls>=4.0.1", - "sure>=2.0.1", - "ddt>=1.7.2", - "deepdiff>=8.6.2", - "behave>=1.2.6", - "httpretty>=1.1.4", - "import-linter>=2.5.2", - "ruff>=0.14.1", - "pre-commit>=4.0.1,<5", -] - [tool.setuptools-git-versioning] enabled = true diff --git a/tests/README.md b/tests/README.md index ec25c60eb..fbdb4fb68 100644 --- a/tests/README.md +++ b/tests/README.md @@ -2,4 +2,4 @@ To run the tests, you will need to clone the ISAdatasets repository's tests bran ``` git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets tests/data -``` \ No newline at end of file +``` diff --git a/tests/convert/test_isatab2cedar.py b/tests/convert/test_isatab2cedar.py index de77a01c7..013d3ab15 100644 --- a/tests/convert/test_isatab2cedar.py +++ b/tests/convert/test_isatab2cedar.py @@ -11,9 +11,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not find test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_isatab2json.py b/tests/convert/test_isatab2json.py index 29fa44457..e91a2a397 100644 --- a/tests/convert/test_isatab2json.py +++ b/tests/convert/test_isatab2json.py @@ -13,8 +13,8 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( "Could not fine test data directory in {0}. Ensure you have cloned the " - "ISAdatasets repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "data repository using " + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_isatab2magetab.py b/tests/convert/test_isatab2magetab.py index 7a53720fc..b96c61ad0 100644 --- a/tests/convert/test_isatab2magetab.py +++ b/tests/convert/test_isatab2magetab.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_isatab2sampletab.py b/tests/convert/test_isatab2sampletab.py index a312baad9..509da5c87 100644 --- a/tests/convert/test_isatab2sampletab.py +++ b/tests/convert/test_isatab2sampletab.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_isatab2sra.py b/tests/convert/test_isatab2sra.py index 0546fcba3..0f3727a0c 100644 --- a/tests/convert/test_isatab2sra.py +++ b/tests/convert/test_isatab2sra.py @@ -13,10 +13,12 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): + print("DATA_DIR:", utils.DATA_DIR) + raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_isatab2w4m.py b/tests/convert/test_isatab2w4m.py index 45fdd032e..1e6821de5 100644 --- a/tests/convert/test_isatab2w4m.py +++ b/tests/convert/test_isatab2w4m.py @@ -28,8 +28,8 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( "Could not fine test data directory in {0}. Ensure you have cloned " - "the ISAdatasets repository using git clone -b tests " - "--single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "the data repository using git clone -b tests " + "--single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_json2isatab.py b/tests/convert/test_json2isatab.py index 221dba4a8..81da25717 100644 --- a/tests/convert/test_json2isatab.py +++ b/tests/convert/test_json2isatab.py @@ -11,9 +11,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_json2magetab.py b/tests/convert/test_json2magetab.py index 20876119a..434477a46 100644 --- a/tests/convert/test_json2magetab.py +++ b/tests/convert/test_json2magetab.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_json2sampletab.py b/tests/convert/test_json2sampletab.py index 736bc9db0..1ab38112d 100644 --- a/tests/convert/test_json2sampletab.py +++ b/tests/convert/test_json2sampletab.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_json2sra.py b/tests/convert/test_json2sra.py index 8bf6317c0..402db6dbb 100644 --- a/tests/convert/test_json2sra.py +++ b/tests/convert/test_json2sra.py @@ -14,9 +14,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_magetab2isatab.py b/tests/convert/test_magetab2isatab.py index 7c2c43e5e..accb21416 100644 --- a/tests/convert/test_magetab2isatab.py +++ b/tests/convert/test_magetab2isatab.py @@ -15,9 +15,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_magetab2json.py b/tests/convert/test_magetab2json.py index ecc8ad125..966c4e091 100644 --- a/tests/convert/test_magetab2json.py +++ b/tests/convert/test_magetab2json.py @@ -12,9 +12,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_sampletab2isatab.py b/tests/convert/test_sampletab2isatab.py index daf5aeba0..b28e00a70 100644 --- a/tests/convert/test_sampletab2isatab.py +++ b/tests/convert/test_sampletab2isatab.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_sampletab2json.py b/tests/convert/test_sampletab2json.py index 075e89c73..5121160ba 100644 --- a/tests/convert/test_sampletab2json.py +++ b/tests/convert/test_sampletab2json.py @@ -10,9 +10,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/convert/test_sra2isatab.py b/tests/convert/test_sra2isatab.py index 2db28d4d8..022278a78 100644 --- a/tests/convert/test_sra2isatab.py +++ b/tests/convert/test_sra2isatab.py @@ -20,9 +20,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( "Could not fine test data directory in {0}. Ensure you have cloned " - "the ISAdatasets repository using " + "the data repository using " "git clone -b tests --single-branch " - "git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/create/test_create_models_study_design.py b/tests/create/test_create_models_study_design.py index 2ec8eee78..b60a837b7 100644 --- a/tests/create/test_create_models_study_design.py +++ b/tests/create/test_create_models_study_design.py @@ -1043,8 +1043,8 @@ def test_string_(self): self.assertEqual( str(self.cell), """StudyCell( - name=test epoch 0, - elements=0 items, + name=test epoch 0, + elements=0 items, )""", ) @@ -1706,7 +1706,7 @@ def test_study_sample_plan_str(self): str(self.plan), """SampleAndAssayPlan( name=test plan, - sample_plan=set(), + sample_plan=set(), assay_plan=set() )""", ) @@ -2154,7 +2154,7 @@ def test_study_arm_str(self): unit= comments=0 Comment objects ), - group_size=10, + group_size=10, no. cells=0, no. sample_assay_plans=0 )""", @@ -2814,7 +2814,7 @@ def test_study_design(self): self.assertEqual( str(self.study_design), """StudyDesign( - identifier=None, + identifier=None, name=Study Design, description=None, study_arms=[] @@ -3502,7 +3502,6 @@ def test_compute_parallel_design_group_sizes_non_treatment_map_error(self): self.assertEqual(ex_cm.exception.args[0], "Map for NonTreatment screen is not correctly set.") def test_1(self): - treatments_map = [ (self.first_treatment, self.sample_assay_plan), (self.second_treatment, self.sample_assay_plan), @@ -3755,7 +3754,7 @@ def test_compute_crossover_design_multi_element_cell_three_treatments(self): def test_compute_crossover_design_multi_element_cell_group_sizes_error(self): treatments = [self.first_treatment, self.third_treatment, self.fourth_treatment] with self.assertRaises(TypeError, msg="The group_sizes list has the wrong length") as ex_cm: - StudyDesignFactory.compute_crossover_design_multi_element_cell( + StudyDesignFactory.compute_crossover_design_multi_element_cell( treatments, self.sample_assay_plan, group_sizes=(10, 15, 12, 15, 12), @@ -3810,7 +3809,7 @@ def test_compute_single_arm_design_multi_element_cell_three_treatments(self): def test_compute_single_arm_design_multi_element_cell_group_sizes_error(self): treatments = [self.first_treatment, self.third_treatment, self.fourth_treatment] with self.assertRaises(TypeError, msg="The group_sizes list has the wrong length") as ex_cm: - StudyDesignFactory.compute_single_arm_design_multi_element_cell( + StudyDesignFactory.compute_single_arm_design_multi_element_cell( treatments, self.sample_assay_plan, group_size=(10, 15, 12), diff --git a/tests/database/test_model.py b/tests/database/test_model.py index 9aacace7d..dbf4dd97a 100644 --- a/tests/database/test_model.py +++ b/tests/database/test_model.py @@ -1,169 +1,172 @@ import os +import warnings from json import loads as json_loads from unittest import TestCase -from isatools.database import * - -here = os.path.dirname(os.path.abspath(__file__)) - - -def get_investigation(filename): - with open(os.path.join(here, "..", "data", "json", filename, "%s.json" % filename)) as f: - data = json_loads(f.read()) - investigation = Investigation() - investigation.from_dict(data) - return investigation - - -def create_db(): - investigation = get_investigation("BII-I-1") - app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" - db.init_app(app) - - with app.app_context(): - db.drop_all() - db.create_all() - db.session.add(investigation.to_sql(session=db.session)) - _investigation = db.session.query(Investigation.get_table()).first().to_json() - another_investigation = Investigation() - another_investigation.from_dict(_investigation) - db.session.commit() - - return another_investigation, investigation - - -investigation_from_db, initial_investigation = create_db() -study_from_db = investigation_from_db.studies[0] -study_expected = initial_investigation.studies[0] - - -class TestAssertions(TestCase): - def test_investigation_base_assertions(self): - self.assertEqual( - sorted(investigation_from_db.ontology_source_references, key=lambda d: d.name), - sorted(initial_investigation.ontology_source_references, key=lambda d: d.name), - ) - - def test_study_base_assertions(self): - self.assertEqual(study_from_db.comments, study_expected.comments) - self.assertEqual( - sorted(study_from_db.publications, key=lambda d: d.title), - sorted(study_expected.publications, key=lambda d: d.title), - ) - self.assertEqual( - sorted(study_from_db.factors, key=lambda d: d.name), sorted(study_expected.factors, key=lambda d: d.name) - ) - self.assertEqual( - sorted(study_from_db.units, key=lambda d: d.term), sorted(study_expected.units, key=lambda d: d.term) - ) - self.assertEqual( - sorted(study_from_db.design_descriptors, key=lambda d: d.term), - sorted(study_expected.design_descriptors, key=lambda d: d.term), - ) - self.assertEqual( - sorted(study_from_db.other_material, key=lambda x: x.name), - sorted(study_expected.other_material, key=lambda x: x.name), - ) - - def test_study_sources_assertions(self): - sources_1 = sorted(study_from_db.sources, key=lambda x: x.name) - sources_2 = sorted(study_expected.sources, key=lambda x: x.name) - self.assertEqual(len(sources_1), len(sources_2)) - for index in range(len(sources_1)): - source_1 = sources_1[index] - source_2 = sources_2[index] - self.assertEqual(source_1.name, source_2.name) - self.assertEqual(len(source_1.characteristics), len(source_2.characteristics)) - for _index in range(len(source_1.characteristics)): - characteristic_1 = source_1.characteristics[_index] - self.assertIn(characteristic_1, source_2.characteristics) - - def test_study_samples_assertions(self): - samples_1 = sorted(study_from_db.samples, key=lambda x: x.name) - samples_2 = sorted(study_expected.samples, key=lambda x: x.name) - for index in range(len(samples_1)): - sample_1 = samples_1[index] - sample_2 = samples_2[index] - self.assertEqual(len(sample_1.characteristics), len(sample_2.characteristics)) - for _index in range(len(sample_1.characteristics)): - characteristic_1 = sample_1.characteristics[_index] - self.assertIn(characteristic_1, sample_2.characteristics) - self.assertEqual(len(sample_1.factor_values), len(sample_2.factor_values)) - for _index in range(len(sample_1.factor_values)): - factor_value_1 = sample_1.factor_values[_index] - self.assertIn(factor_value_1, sample_2.factor_values) - - def test_study_contacts_assertions(self): - contacts_1 = study_from_db.contacts - contacts_2 = study_expected.contacts - for contact in contacts_1: - contact.roles = sorted(contact.roles, key=lambda d: d.term) - for contact in contacts_2: - contact.roles = sorted(contact.roles, key=lambda d: d.term) - self.assertEqual(contacts_1, contacts_2) - - def test_study_protocols_assertions(self): - protocols_1 = sorted(study_from_db.protocols, key=lambda x: x.name) - protocols_2 = sorted(study_expected.protocols, key=lambda x: x.name) - for i in range(len(protocols_1)): - protocol_1 = protocols_1[i] - protocol_2 = protocols_2[i] - for param in protocol_1.parameters: - self.assertIn(param, protocol_2.parameters) - - def test_study_characteristic_categories_assertions(self): - characteristic_categories_1 = sorted(study_from_db.characteristic_categories, key=lambda x: x.term) - characteristic_categories_2 = sorted(study_expected.characteristic_categories, key=lambda x: x.term) - self.assertEqual(characteristic_categories_1, characteristic_categories_2) - - def test_study_process_sequence_assertion(self): - process_sequence_1 = study_from_db.process_sequence - process_sequence_2 = study_expected.process_sequence - for sequence_1 in process_sequence_1: - sequence_2 = [s for s in process_sequence_2 if s.id == sequence_1.id][0] - self.assertEqual(sequence_1, sequence_2) - - def test_assay_base_assertions(self): - assays_from_db = study_from_db.assays - assays_expected = study_expected.assays - - for assay_1 in assays_from_db: - assay_2 = [a for a in assays_expected if a.filename == assay_1.filename][0] - self.assertEqual(assay_1.measurement_type, assay_2.measurement_type) - self.assertEqual(assay_1.technology_type, assay_2.technology_type) - self.assertEqual(assay_1.technology_platform, assay_2.technology_platform) - self.assertEqual(sorted(assay_1.units, key=lambda d: d.term), sorted(assay_2.units, key=lambda d: d.term)) +try: + from isatools.database import * + + here = os.path.dirname(os.path.abspath(__file__)) + + def get_investigation(filename): + with open(os.path.join(here, "..", "data", "json", filename, "%s.json" % filename)) as f: + data = json_loads(f.read()) + investigation = Investigation() + investigation.from_dict(data) + return investigation + + def create_db(): + investigation = get_investigation("BII-I-1") + app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" + db.init_app(app) + + with app.app_context(): + db.drop_all() + db.create_all() + db.session.add(investigation.to_sql(session=db.session)) + _investigation = db.session.query(Investigation.get_table()).first().to_json() + another_investigation = Investigation() + another_investigation.from_dict(_investigation) + db.session.commit() + + return another_investigation, investigation + + investigation_from_db, initial_investigation = create_db() + study_from_db = investigation_from_db.studies[0] + study_expected = initial_investigation.studies[0] + + class TestAssertions(TestCase): + def test_investigation_base_assertions(self): + self.assertEqual( + sorted(investigation_from_db.ontology_source_references, key=lambda d: d.name), + sorted(initial_investigation.ontology_source_references, key=lambda d: d.name), + ) + + def test_study_base_assertions(self): + self.assertEqual(study_from_db.comments, study_expected.comments) + self.assertEqual( + sorted(study_from_db.publications, key=lambda d: d.title), + sorted(study_expected.publications, key=lambda d: d.title), + ) + self.assertEqual( + sorted(study_from_db.factors, key=lambda d: d.name), + sorted(study_expected.factors, key=lambda d: d.name), + ) + self.assertEqual( + sorted(study_from_db.units, key=lambda d: d.term), sorted(study_expected.units, key=lambda d: d.term) + ) self.assertEqual( - sorted(assay_1.characteristic_categories, key=lambda d: d.term), - sorted(assay_2.characteristic_categories, key=lambda d: d.term), + sorted(study_from_db.design_descriptors, key=lambda d: d.term), + sorted(study_expected.design_descriptors, key=lambda d: d.term), ) - process_sequence_1 = assay_1.process_sequence - process_sequence_2 = assay_2.process_sequence + self.assertEqual( + sorted(study_from_db.other_material, key=lambda x: x.name), + sorted(study_expected.other_material, key=lambda x: x.name), + ) + + def test_study_sources_assertions(self): + sources_1 = sorted(study_from_db.sources, key=lambda x: x.name) + sources_2 = sorted(study_expected.sources, key=lambda x: x.name) + self.assertEqual(len(sources_1), len(sources_2)) + for index in range(len(sources_1)): + source_1 = sources_1[index] + source_2 = sources_2[index] + self.assertEqual(source_1.name, source_2.name) + self.assertEqual(len(source_1.characteristics), len(source_2.characteristics)) + for _index in range(len(source_1.characteristics)): + characteristic_1 = source_1.characteristics[_index] + self.assertIn(characteristic_1, source_2.characteristics) + + def test_study_samples_assertions(self): + samples_1 = sorted(study_from_db.samples, key=lambda x: x.name) + samples_2 = sorted(study_expected.samples, key=lambda x: x.name) + for index in range(len(samples_1)): + sample_1 = samples_1[index] + sample_2 = samples_2[index] + self.assertEqual(len(sample_1.characteristics), len(sample_2.characteristics)) + for _index in range(len(sample_1.characteristics)): + characteristic_1 = sample_1.characteristics[_index] + self.assertIn(characteristic_1, sample_2.characteristics) + self.assertEqual(len(sample_1.factor_values), len(sample_2.factor_values)) + for _index in range(len(sample_1.factor_values)): + factor_value_1 = sample_1.factor_values[_index] + self.assertIn(factor_value_1, sample_2.factor_values) + + def test_study_contacts_assertions(self): + contacts_1 = study_from_db.contacts + contacts_2 = study_expected.contacts + for contact in contacts_1: + contact.roles = sorted(contact.roles, key=lambda d: d.term) + for contact in contacts_2: + contact.roles = sorted(contact.roles, key=lambda d: d.term) + self.assertEqual(contacts_1, contacts_2) + + def test_study_protocols_assertions(self): + protocols_1 = sorted(study_from_db.protocols, key=lambda x: x.name) + protocols_2 = sorted(study_expected.protocols, key=lambda x: x.name) + for i in range(len(protocols_1)): + protocol_1 = protocols_1[i] + protocol_2 = protocols_2[i] + for param in protocol_1.parameters: + self.assertIn(param, protocol_2.parameters) + + def test_study_characteristic_categories_assertions(self): + characteristic_categories_1 = sorted(study_from_db.characteristic_categories, key=lambda x: x.term) + characteristic_categories_2 = sorted(study_expected.characteristic_categories, key=lambda x: x.term) + self.assertEqual(characteristic_categories_1, characteristic_categories_2) + + def test_study_process_sequence_assertion(self): + process_sequence_1 = study_from_db.process_sequence + process_sequence_2 = study_expected.process_sequence for sequence_1 in process_sequence_1: sequence_2 = [s for s in process_sequence_2 if s.id == sequence_1.id][0] self.assertEqual(sequence_1, sequence_2) - def test_load_more(self): - with app.app_context(): - session = db.session - investigation = get_investigation("BII-I-1") - session.add(investigation.to_sql(session=session)) - session.commit() - i = initial_investigation - self.assertEqual(investigation, i) - - _investigation = session.query(Investigation.get_table()).all() - self.assertEqual(len(_investigation), 2) - - investigation = get_investigation("BII-S-7") - session.add(investigation.to_sql(session=session)) - session.commit() - _investigation = session.query(Investigation.get_table()).all() - self.assertEqual(len(_investigation), 3) - - investigation = get_investigation("BII-S-3") - print(type(investigation)) - session.add(investigation.to_sql(session=session)) - session.commit() - _investigation = session.query(Investigation.get_table()).all() - self.assertEqual(len(_investigation), 4) + def test_assay_base_assertions(self): + assays_from_db = study_from_db.assays + assays_expected = study_expected.assays + + for assay_1 in assays_from_db: + assay_2 = [a for a in assays_expected if a.filename == assay_1.filename][0] + self.assertEqual(assay_1.measurement_type, assay_2.measurement_type) + self.assertEqual(assay_1.technology_type, assay_2.technology_type) + self.assertEqual(assay_1.technology_platform, assay_2.technology_platform) + self.assertEqual( + sorted(assay_1.units, key=lambda d: d.term), sorted(assay_2.units, key=lambda d: d.term) + ) + self.assertEqual( + sorted(assay_1.characteristic_categories, key=lambda d: d.term), + sorted(assay_2.characteristic_categories, key=lambda d: d.term), + ) + process_sequence_1 = assay_1.process_sequence + process_sequence_2 = assay_2.process_sequence + for sequence_1 in process_sequence_1: + sequence_2 = [s for s in process_sequence_2 if s.id == sequence_1.id][0] + self.assertEqual(sequence_1, sequence_2) + + def test_load_more(self): + with app.app_context(): + session = db.session + investigation = get_investigation("BII-I-1") + session.add(investigation.to_sql(session=session)) + session.commit() + i = initial_investigation + self.assertEqual(investigation, i) + + _investigation = session.query(Investigation.get_table()).all() + self.assertEqual(len(_investigation), 2) + + investigation = get_investigation("BII-S-7") + session.add(investigation.to_sql(session=session)) + session.commit() + _investigation = session.query(Investigation.get_table()).all() + self.assertEqual(len(_investigation), 3) + + investigation = get_investigation("BII-S-3") + print(type(investigation)) + session.add(investigation.to_sql(session=session)) + session.commit() + _investigation = session.query(Investigation.get_table()).all() + self.assertEqual(len(_investigation), 4) +except ImportError: + warnings.warn("database packages are not installed. Skipping database test...") diff --git a/tests/isajson/test_isajson.py b/tests/isajson/test_isajson.py index 91b36019e..5cdfcdf2d 100644 --- a/tests/isajson/test_isajson.py +++ b/tests/isajson/test_isajson.py @@ -31,9 +31,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) @@ -460,7 +460,6 @@ def test_json_load_and_dump_bii_s_test(self): assays = [a for a in studies["assays"] if a["filename"] == "a_assay.txt"][0] self.assertEqual(assays["materials"]["otherMaterials"][1]["type"], "Extract Name") - def test_json_load_and_dump_imagefile_test(self): # Load into ISA objects with open(os.path.join(utils.JSON_DATA_DIR, "ISA-Image", "isa-image.json")) as isajson_fp: diff --git a/tests/isatab/test_isatab.py b/tests/isatab/test_isatab.py index 195240756..ec9b54c16 100644 --- a/tests/isatab/test_isatab.py +++ b/tests/isatab/test_isatab.py @@ -47,9 +47,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not find test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not find test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/model/test_datafile.py b/tests/model/test_datafile.py index 3ce831293..5f3b37d8c 100644 --- a/tests/model/test_datafile.py +++ b/tests/model/test_datafile.py @@ -93,7 +93,7 @@ def setUp(self): "PostTranslationalModificationAssignmentFile": PostTranslationalModificationAssignmentFile, "AcquisitionParameterDataFile": AcquisitionParameterDataFile, "FreeInductionDecayDataFile": FreeInductionDecayDataFile, - "MetaboliteAssignmentFile": MetaboliteAssignmentFile + "MetaboliteAssignmentFile": MetaboliteAssignmentFile, } self.classes = {} for filetype in self.types: diff --git a/tests/model/test_investigation.py b/tests/model/test_investigation.py index 3185ee8be..b7439a5cf 100644 --- a/tests/model/test_investigation.py +++ b/tests/model/test_investigation.py @@ -23,7 +23,7 @@ def test_init(self, mock_uuid4): submission_date=mocked_date, public_release_date=mocked_date, ontology_source_references=[ontology_source], - studies=[study] + studies=[study], ) self.assertEqual("id", investigation.identifier) self.assertEqual("file", investigation.filename) @@ -91,11 +91,10 @@ def test_execute_query(self): def test_introspection(self): introspection = self.investigation.introspect() - + self.assertIsNotNone(introspection) + self.assertIsNotNone(introspection.data) self.assertTrue(len(introspection.data["schemas"]["types"]) == 46) self.assertEqual(introspection.data["schemas"]["types"][0]["name"], "IsaQuery") - #print("\nTOTO", introspection.data["schemas"]["types"][0]["name"]) - def test_repr(self): self.assertEqual( @@ -142,7 +141,6 @@ def test_ne(self): @patch("isatools.model.identifiable.uuid4", return_value="mocked_UUID") def test_dict(self, mock_uuid4): - investigation = Investigation() self.assertEqual(investigation.id, "#investigation/" + mock_uuid4.return_value) @@ -201,7 +199,7 @@ def test_dict(self, mock_uuid4): ], "publications": [ { - "@id": "#publication/" + mock_uuid4.return_value, + "@id": "#publication/" + mock_uuid4.return_value, "authorList": "a, b, c", "doi": "doi", "pubMedID": "pubmed_id", diff --git a/tests/model/test_ontology_source.py b/tests/model/test_ontology_source.py index c9c84ed3e..bfd94b8e2 100644 --- a/tests/model/test_ontology_source.py +++ b/tests/model/test_ontology_source.py @@ -86,7 +86,7 @@ def test_validate_field(self): self.assertIsNone(self.ontology_source.validate_field("test_name", "name")) @patch("isatools.model.identifiable.uuid4", return_value="mocked_UUID") - def test_dict(self, mock_uuid4): + def test_dict(self, mock_uuid4): ontology_source = OntologySource( name="name1", version="version1", diff --git a/tests/model/test_publication.py b/tests/model/test_publication.py index 3fb6abc56..380a61fed 100644 --- a/tests/model/test_publication.py +++ b/tests/model/test_publication.py @@ -78,12 +78,9 @@ def test_equalities(self): self.assertTrue(second_publication != self.publication) @patch("isatools.model.identifiable.uuid4", return_value="mocked_UUID") - def test_dict(self, mock_uuid4): + def test_dict(self, mock_uuid4): publication = Publication( - pubmed_id="pubmed_id", - doi="doi", - author_list="a, b, c", - status=OntologyAnnotation(term="OA", id_="123") + pubmed_id="pubmed_id", doi="doi", author_list="a, b, c", status=OntologyAnnotation(term="OA", id_="123") ) self.assertEqual(publication.id, "#publication/" + mock_uuid4.return_value) diff --git a/tests/test_clients/fixtures/ST00010.json b/tests/test_clients/fixtures/ST00010.json index c332f5615..5a9670348 100644 --- a/tests/test_clients/fixtures/ST00010.json +++ b/tests/test_clients/fixtures/ST00010.json @@ -1 +1,254 @@ -{"1":{"study_id":"ST000100","analysis_id":"AN000165","analysis_summary":"HESI positive ion mode","analysis_type":"MS","chromatography system":"Thermo Dionex Ultimate 3000 RS","column_name":"Waters Acquity HSS T3 (100 x 2.1mm,1.8um)","chromatography_type":"Reversed phase","ms_instrument_name":"Thermo Q Exactive Orbitrap","ms_instrument_type":"Orbitrap","ms_type":"ESI","ion_mode":"POSITIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":""},"2":{"study_id":"ST000100","analysis_id":"AN000166","analysis_summary":"HESI negative ion mode","analysis_type":"MS","chromatography system":"Thermo Dionex Ultimate 3000 RS","column_name":"Waters Acquity HSS T3 (100 x 2.1mm,1.8um)","chromatography_type":"Reversed phase","ms_instrument_name":"Thermo Q Exactive Orbitrap","ms_instrument_type":"Orbitrap","ms_type":"ESI","ion_mode":"NEGATIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":""},"3":{"study_id":"ST000101","analysis_id":"AN000167","analysis_summary":"NMR:13C 1D","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"1D 13C","spectrometer_frequency":"600 MHz","nmr_solvent":"D2O","units":""},"4":{"study_id":"ST000101","analysis_id":"AN000168","analysis_summary":"NMR: 1D 1H","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"1D 1H","spectrometer_frequency":"600 MHz","nmr_solvent":"D2O","units":""},"5":{"study_id":"ST000102","analysis_id":"AN000169","analysis_summary":"NMR: 1D presaturation 1H","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"1D 1H","spectrometer_frequency":"700 MHz","nmr_solvent":"D2O","units":""},"6":{"study_id":"ST000102","analysis_id":"AN000170","analysis_summary":"NMR: 2D 1H-13C HSQC","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"2D 1H-13C HSQC","spectrometer_frequency":"700 MHz","nmr_solvent":"D2O","units":""},"7":{"study_id":"ST000103","analysis_id":"AN000171","analysis_summary":"NMR:2D 1H-13C HSQC","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"2D-INADEQUATE","spectrometer_frequency":"600 MHz","nmr_solvent":"D2O and MeOD","units":""},"8":{"study_id":"ST000104","analysis_id":"AN000172","analysis_summary":"NMR:INADEQUATE","analysis_type":"NMR","chromatography system":"","column_name":"","chromatography_type":"","ms_instrument_name":"","ms_instrument_type":"","ms_type":"","ion_mode":"","nmr_instrument_type":"FT-NMR","nmr_experiment_type":"1D 1H","spectrometer_frequency":"700 MHz","nmr_solvent":"D20","units":""},"9":{"study_id":"ST000105","analysis_id":"AN000173","analysis_summary":"MS Q-TOF 6530 positive ion mode","analysis_type":"MS","chromatography system":"Agilent 1200","column_name":"Waters Acquity HSS T3","chromatography_type":"Reversed phase","ms_instrument_name":"Agilent 6530 QTOF","ms_instrument_type":"QTOF","ms_type":"ESI","ion_mode":"POSITIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"Counts"},"10":{"study_id":"ST000105","analysis_id":"AN000174","analysis_summary":"ESI negative ion mode","analysis_type":"MS","chromatography system":"Agilent 1200","column_name":"Waters Acquity HSS T3","chromatography_type":"Reversed phase","ms_instrument_name":"Agilent 6530 QTOF","ms_instrument_type":"QTOF","ms_type":"ESI","ion_mode":"NEGATIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"Counts"},"11":{"study_id":"ST000106","analysis_id":"AN000175","analysis_summary":"ESI positive ion mode","analysis_type":"MS","chromatography system":"Agilent 1200","column_name":"Waters Acquity HSS T3","chromatography_type":"Reversed phase","ms_instrument_name":"Agilent 6530 QTOF","ms_instrument_type":"QTOF","ms_type":"ESI","ion_mode":"POSITIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"Counts"},"12":{"study_id":"ST000106","analysis_id":"AN000176","analysis_summary":"ESI negative ion mode","analysis_type":"MS","chromatography system":"Agilent 1200","column_name":"Waters Acquity HSS T3","chromatography_type":"Reversed phase","ms_instrument_name":"Agilent 6530 QTOF","ms_instrument_type":"QTOF","ms_type":"ESI","ion_mode":"NEGATIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"Counts"},"13":{"study_id":"ST000107","analysis_id":"AN000177","analysis_summary":"LCMS Positive ion mode","analysis_type":"MS","chromatography system":"","column_name":"","chromatography_type":"GC","ms_instrument_name":"ABI Sciex API 4000 QTrap","ms_instrument_type":"Triple quadrupole","ms_type":"ESI","ion_mode":"POSITIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"nM"},"14":{"study_id":"ST000107","analysis_id":"AN000178","analysis_summary":"GCMS Positive ion mode","analysis_type":"MS","chromatography system":"","column_name":"","chromatography_type":"GC","ms_instrument_name":"Agilent 5973N","ms_instrument_type":"Single quadrupole","ms_type":"EI","ion_mode":"POSITIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"nM"}} \ No newline at end of file +{ + "1": { + "study_id": "ST000100", + "analysis_id": "AN000165", + "analysis_summary": "HESI positive ion mode", + "analysis_type": "MS", + "chromatography system": "Thermo Dionex Ultimate 3000 RS", + "column_name": "Waters Acquity HSS T3 (100 x 2.1mm,1.8um)", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Thermo Q Exactive Orbitrap", + "ms_instrument_type": "Orbitrap", + "ms_type": "ESI", + "ion_mode": "POSITIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "" + }, + "2": { + "study_id": "ST000100", + "analysis_id": "AN000166", + "analysis_summary": "HESI negative ion mode", + "analysis_type": "MS", + "chromatography system": "Thermo Dionex Ultimate 3000 RS", + "column_name": "Waters Acquity HSS T3 (100 x 2.1mm,1.8um)", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Thermo Q Exactive Orbitrap", + "ms_instrument_type": "Orbitrap", + "ms_type": "ESI", + "ion_mode": "NEGATIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "" + }, + "3": { + "study_id": "ST000101", + "analysis_id": "AN000167", + "analysis_summary": "NMR:13C 1D", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "1D 13C", + "spectrometer_frequency": "600 MHz", + "nmr_solvent": "D2O", + "units": "" + }, + "4": { + "study_id": "ST000101", + "analysis_id": "AN000168", + "analysis_summary": "NMR: 1D 1H", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "1D 1H", + "spectrometer_frequency": "600 MHz", + "nmr_solvent": "D2O", + "units": "" + }, + "5": { + "study_id": "ST000102", + "analysis_id": "AN000169", + "analysis_summary": "NMR: 1D presaturation 1H", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "1D 1H", + "spectrometer_frequency": "700 MHz", + "nmr_solvent": "D2O", + "units": "" + }, + "6": { + "study_id": "ST000102", + "analysis_id": "AN000170", + "analysis_summary": "NMR: 2D 1H-13C HSQC", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "2D 1H-13C HSQC", + "spectrometer_frequency": "700 MHz", + "nmr_solvent": "D2O", + "units": "" + }, + "7": { + "study_id": "ST000103", + "analysis_id": "AN000171", + "analysis_summary": "NMR:2D 1H-13C HSQC", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "2D-INADEQUATE", + "spectrometer_frequency": "600 MHz", + "nmr_solvent": "D2O and MeOD", + "units": "" + }, + "8": { + "study_id": "ST000104", + "analysis_id": "AN000172", + "analysis_summary": "NMR:INADEQUATE", + "analysis_type": "NMR", + "chromatography system": "", + "column_name": "", + "chromatography_type": "", + "ms_instrument_name": "", + "ms_instrument_type": "", + "ms_type": "", + "ion_mode": "", + "nmr_instrument_type": "FT-NMR", + "nmr_experiment_type": "1D 1H", + "spectrometer_frequency": "700 MHz", + "nmr_solvent": "D20", + "units": "" + }, + "9": { + "study_id": "ST000105", + "analysis_id": "AN000173", + "analysis_summary": "MS Q-TOF 6530 positive ion mode", + "analysis_type": "MS", + "chromatography system": "Agilent 1200", + "column_name": "Waters Acquity HSS T3", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Agilent 6530 QTOF", + "ms_instrument_type": "QTOF", + "ms_type": "ESI", + "ion_mode": "POSITIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "Counts" + }, + "10": { + "study_id": "ST000105", + "analysis_id": "AN000174", + "analysis_summary": "ESI negative ion mode", + "analysis_type": "MS", + "chromatography system": "Agilent 1200", + "column_name": "Waters Acquity HSS T3", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Agilent 6530 QTOF", + "ms_instrument_type": "QTOF", + "ms_type": "ESI", + "ion_mode": "NEGATIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "Counts" + }, + "11": { + "study_id": "ST000106", + "analysis_id": "AN000175", + "analysis_summary": "ESI positive ion mode", + "analysis_type": "MS", + "chromatography system": "Agilent 1200", + "column_name": "Waters Acquity HSS T3", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Agilent 6530 QTOF", + "ms_instrument_type": "QTOF", + "ms_type": "ESI", + "ion_mode": "POSITIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "Counts" + }, + "12": { + "study_id": "ST000106", + "analysis_id": "AN000176", + "analysis_summary": "ESI negative ion mode", + "analysis_type": "MS", + "chromatography system": "Agilent 1200", + "column_name": "Waters Acquity HSS T3", + "chromatography_type": "Reversed phase", + "ms_instrument_name": "Agilent 6530 QTOF", + "ms_instrument_type": "QTOF", + "ms_type": "ESI", + "ion_mode": "NEGATIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "Counts" + }, + "13": { + "study_id": "ST000107", + "analysis_id": "AN000177", + "analysis_summary": "LCMS Positive ion mode", + "analysis_type": "MS", + "chromatography system": "", + "column_name": "", + "chromatography_type": "GC", + "ms_instrument_name": "ABI Sciex API 4000 QTrap", + "ms_instrument_type": "Triple quadrupole", + "ms_type": "ESI", + "ion_mode": "POSITIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "nM" + }, + "14": { + "study_id": "ST000107", + "analysis_id": "AN000178", + "analysis_summary": "GCMS Positive ion mode", + "analysis_type": "MS", + "chromatography system": "", + "column_name": "", + "chromatography_type": "GC", + "ms_instrument_name": "Agilent 5973N", + "ms_instrument_type": "Single quadrupole", + "ms_type": "EI", + "ion_mode": "POSITIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "nM" + } +} diff --git a/tests/test_clients/fixtures/ST000367.json b/tests/test_clients/fixtures/ST000367.json index a38d8b594..4f358bb77 100644 --- a/tests/test_clients/fixtures/ST000367.json +++ b/tests/test_clients/fixtures/ST000367.json @@ -1 +1,38 @@ -{"1":{"study_id":"ST000367","analysis_id":"AN000600","analysis_summary":"Precellys homogenization (IC-FTMS1)","analysis_type":"MS","chromatography system":"Thermo Dionex ICS-5000+","column_name":"Unspecified","chromatography_type":"Ion Chromatography","ms_instrument_name":"Thermo Fusion Tribrid Orbitrap","ms_instrument_type":"FT-ICR-MS","ms_type":"ESI","ion_mode":"NEGATIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"normalized corrected peak area"},"2":{"study_id":"ST000367","analysis_id":"AN000601","analysis_summary":"Retsch homogenization (IC-FTMS2)","analysis_type":"MS","chromatography system":"Thermo Dionex ICS-5000+","column_name":"Unspecified","chromatography_type":"Ion Chromatography","ms_instrument_name":"Thermo Fusion Tribrid Orbitrap","ms_instrument_type":"FT-ICR-MS","ms_type":"ESI","ion_mode":"NEGATIVE","nmr_instrument_type":"","nmr_experiment_type":"","spectrometer_frequency":"","nmr_solvent":"","units":"normalized corrected peak area"}} \ No newline at end of file +{ + "1": { + "study_id": "ST000367", + "analysis_id": "AN000600", + "analysis_summary": "Precellys homogenization (IC-FTMS1)", + "analysis_type": "MS", + "chromatography system": "Thermo Dionex ICS-5000+", + "column_name": "Unspecified", + "chromatography_type": "Ion Chromatography", + "ms_instrument_name": "Thermo Fusion Tribrid Orbitrap", + "ms_instrument_type": "FT-ICR-MS", + "ms_type": "ESI", + "ion_mode": "NEGATIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "normalized corrected peak area" + }, + "2": { + "study_id": "ST000367", + "analysis_id": "AN000601", + "analysis_summary": "Retsch homogenization (IC-FTMS2)", + "analysis_type": "MS", + "chromatography system": "Thermo Dionex ICS-5000+", + "column_name": "Unspecified", + "chromatography_type": "Ion Chromatography", + "ms_instrument_name": "Thermo Fusion Tribrid Orbitrap", + "ms_instrument_type": "FT-ICR-MS", + "ms_type": "ESI", + "ion_mode": "NEGATIVE", + "nmr_instrument_type": "", + "nmr_experiment_type": "", + "spectrometer_frequency": "", + "nmr_solvent": "", + "units": "normalized corrected peak area" + } +} diff --git a/tests/test_clients/fixtures/TOTO.json b/tests/test_clients/fixtures/TOTO.json index 0637a088a..fe51488c7 100644 --- a/tests/test_clients/fixtures/TOTO.json +++ b/tests/test_clients/fixtures/TOTO.json @@ -1 +1 @@ -[] \ No newline at end of file +[] diff --git a/tests/test_sampletab.py b/tests/test_sampletab.py index b5adcd536..f142cd3e8 100644 --- a/tests/test_sampletab.py +++ b/tests/test_sampletab.py @@ -22,12 +22,13 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) +@unittest.skip("Skipping these tests following SAMPLETAB deprecation by EBI") class UnitSampleTabLoad(unittest.TestCase): def setUp(self): self._sampletab_data_dir = utils.SAMPLETAB_DATA_DIR @@ -110,6 +111,7 @@ def test_sampletab_load_GSB_718(self): self.assertEqual(len(ISA.studies[0].process_sequence), 109) +@unittest.skip("Skipping these tests following SAMPLETAB deprecation by EBI") class UnitSampleTabDump(unittest.TestCase): def setUp(self): self._sampletab_data_dir = utils.SAMPLETAB_DATA_DIR diff --git a/tests/test_sra.py b/tests/test_sra.py index b492f2cc9..afc059e56 100644 --- a/tests/test_sra.py +++ b/tests/test_sra.py @@ -15,9 +15,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( "Could not fine test data directory in {0}. Ensure you have cloned " - "the ISAdatasets repository using " + "the data repository using " "git clone -b tests --single-branch " - "git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/test_tests_utils.py b/tests/test_tests_utils.py index 74223410b..80eea729c 100644 --- a/tests/test_tests_utils.py +++ b/tests/test_tests_utils.py @@ -9,9 +9,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/utils/test_graphQL.py b/tests/utils/test_graphQL.py index 5c518d80a..16b0d0a41 100644 --- a/tests/utils/test_graphQL.py +++ b/tests/utils/test_graphQL.py @@ -57,6 +57,7 @@ def test_full_query(self): response = investigation.execute_query(self.query, variables) self.assertTrue(not response.errors) + # @unittest.skip("Not working after fixing lint. Test data and/or expected value must be updated.") def test_introspection(self): response = investigation.introspect() print("\nTHERE: ", response) diff --git a/tests/utils/test_isatab_configurator.py b/tests/utils/test_isatab_configurator.py index 434e5550f..63e6569de 100644 --- a/tests/utils/test_isatab_configurator.py +++ b/tests/utils/test_isatab_configurator.py @@ -7,9 +7,9 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " + "Could not fine test data directory in {0}. Ensure you have cloned the data " "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/utils/test_isatools_utils.py b/tests/utils/test_isatools_utils.py index f3bae2cd7..c4f31d3ed 100644 --- a/tests/utils/test_isatools_utils.py +++ b/tests/utils/test_isatools_utils.py @@ -26,10 +26,10 @@ def setUpModule(): if not os.path.exists(test_utils.DATA_DIR): raise FileNotFoundError( "Could not fine test data directory in {0}. " - "Ensure you have cloned the ISAdatasets " + "Ensure you have cloned the data " "repository using git clone -b tests " "--single-branch git@github.com:ISA-tools/" - "ISAdatasets {0}".format(test_utils.DATA_DIR) + "data {0}".format(test_utils.DATA_DIR) ) diff --git a/tests/validators/test_validate_test_data.py b/tests/validators/test_validate_test_data.py index aa1690f9a..a0fac5f96 100644 --- a/tests/validators/test_validate_test_data.py +++ b/tests/validators/test_validate_test_data.py @@ -17,9 +17,8 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " - "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "Could not fine test data directory in {0}. Ensure you have cloned the data repository using " + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/tests/validators/test_validators.py b/tests/validators/test_validators.py index 7a3f1bbf8..d1df9a287 100644 --- a/tests/validators/test_validators.py +++ b/tests/validators/test_validators.py @@ -14,9 +14,8 @@ def setUpModule(): if not os.path.exists(utils.DATA_DIR): raise FileNotFoundError( - "Could not fine test data directory in {0}. Ensure you have cloned the ISAdatasets " - "repository using " - "git clone -b tests --single-branch git@github.com:ISA-tools/ISAdatasets {0}".format(utils.DATA_DIR) + "Could not fine test data directory in {0}. Ensure you have cloned the data repository using " + "git clone -b tests --single-branch git@github.com:ISA-tools/data {0}".format(utils.DATA_DIR) ) diff --git a/uv.lock b/uv.lock index 8bbd80366..44c61739a 100644 --- a/uv.lock +++ b/uv.lock @@ -778,7 +778,8 @@ dependencies = [ { name = "coverage", version = "7.10.7", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.10'" }, { name = "coverage", version = "7.11.0", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.10'" }, { name = "docopt" }, - { name = "requests" }, + { name = "requests", version = "2.32.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "requests", version = "2.34.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/75/a454fb443eb6a053833f61603a432ffbd7dd6ae53a11159bacfadb9d6219/coveralls-4.0.1.tar.gz", hash = "sha256:7b2a0a2bcef94f295e3cf28dcc55ca40b71c77d1c2446b538e85f0f7bc21aa69", size = 12419, upload-time = "2024-05-15T12:56:14.297Z" } wheels = [ @@ -1030,7 +1031,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7d/ed/6bfa4109fcb23a58819600392564fea69cdc6551ffd5e69ccf1d52a40cbc/greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c", size = 271061, upload-time = "2025-08-07T13:17:15.373Z" }, { url = "https://files.pythonhosted.org/packages/2a/fc/102ec1a2fc015b3a7652abab7acf3541d58c04d3d17a8d3d6a44adae1eb1/greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590", size = 629475, upload-time = "2025-08-07T13:42:54.009Z" }, { url = "https://files.pythonhosted.org/packages/c5/26/80383131d55a4ac0fb08d71660fd77e7660b9db6bdb4e8884f46d9f2cc04/greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c", size = 640802, upload-time = "2025-08-07T13:45:25.52Z" }, - { url = "https://files.pythonhosted.org/packages/9f/7c/e7833dbcd8f376f3326bd728c845d31dcde4c84268d3921afcae77d90d08/greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b", size = 636703, upload-time = "2025-08-07T13:53:12.622Z" }, { url = "https://files.pythonhosted.org/packages/e9/49/547b93b7c0428ede7b3f309bc965986874759f7d89e4e04aeddbc9699acb/greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31", size = 635417, upload-time = "2025-08-07T13:18:25.189Z" }, { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, @@ -1041,7 +1041,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, { url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", size = 640519, upload-time = "2025-08-07T13:53:13.928Z" }, { url = "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", size = 639707, upload-time = "2025-08-07T13:18:27.146Z" }, { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, @@ -1052,7 +1051,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, - { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, @@ -1063,7 +1061,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, - { url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" }, { url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" }, { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, @@ -1074,7 +1071,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, { url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, @@ -1083,7 +1079,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/c0/93885c4106d2626bf51fdec377d6aef740dfa5c4877461889a7cf8e565cc/greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c", size = 269859, upload-time = "2025-08-07T13:16:16.003Z" }, { url = "https://files.pythonhosted.org/packages/4d/f5/33f05dc3ba10a02dedb1485870cf81c109227d3d3aa280f0e48486cac248/greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d", size = 627610, upload-time = "2025-08-07T13:43:01.345Z" }, { url = "https://files.pythonhosted.org/packages/b2/a7/9476decef51a0844195f99ed5dc611d212e9b3515512ecdf7321543a7225/greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58", size = 639417, upload-time = "2025-08-07T13:45:32.094Z" }, - { url = "https://files.pythonhosted.org/packages/bd/e0/849b9159cbb176f8c0af5caaff1faffdece7a8417fcc6fe1869770e33e21/greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4", size = 634751, upload-time = "2025-08-07T13:53:18.848Z" }, { url = "https://files.pythonhosted.org/packages/5f/d3/844e714a9bbd39034144dca8b658dcd01839b72bb0ec7d8014e33e3705f0/greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433", size = 634020, upload-time = "2025-08-07T13:18:36.841Z" }, { url = "https://files.pythonhosted.org/packages/6b/4c/f3de2a8de0e840ecb0253ad0dc7e2bb3747348e798ec7e397d783a3cb380/greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df", size = 582817, upload-time = "2025-08-07T13:18:35.48Z" }, { url = "https://files.pythonhosted.org/packages/89/80/7332915adc766035c8980b161c2e5d50b2f941f453af232c164cff5e0aeb/greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594", size = 1111985, upload-time = "2025-08-07T13:42:42.425Z" }, @@ -1232,11 +1227,11 @@ wheels = [ [[package]] name = "idna" -version = "3.11" +version = "3.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, + { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, ] [[package]] @@ -1286,10 +1281,7 @@ dependencies = [ { name = "chardet" }, { name = "ddt" }, { name = "deepdiff" }, - { name = "flask" }, - { name = "flask-sqlalchemy" }, { name = "graphene" }, - { name = "graphql-core" }, { name = "iso8601" }, { name = "jinja2" }, { name = "jsonschema" }, @@ -1302,24 +1294,26 @@ dependencies = [ { name = "openpyxl" }, { name = "pandas" }, { name = "progressbar2" }, - { name = "pytest-timeout" }, { name = "python-dateutil" }, { name = "pyyaml" }, { name = "rdflib" }, - { name = "requests" }, - { name = "ruff" }, + { name = "requests", version = "2.32.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "requests", version = "2.34.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "setuptools" }, - { name = "sqlalchemy" }, - { name = "tornado" }, - { name = "urllib3" }, ] [package.optional-dependencies] -notebook = [ +all = [ { name = "bokeh" }, + { name = "flask" }, + { name = "flask-sqlalchemy" }, + { name = "sqlalchemy" }, +] +database = [ + { name = "flask" }, + { name = "flask-sqlalchemy" }, + { name = "sqlalchemy" }, ] - -[package.dev-dependencies] dev = [ { name = "behave" }, { name = "coveralls" }, @@ -1329,60 +1323,58 @@ dev = [ { name = "import-linter" }, { name = "pre-commit" }, { name = "pytest" }, + { name = "pytest-timeout" }, { name = "ruff" }, { name = "sure" }, ] +notebook = [ + { name = "bokeh" }, +] [package.metadata] requires-dist = [ - { name = "beautifulsoup4", specifier = "~=4.14.2" }, + { name = "beautifulsoup4", specifier = ">=4.14.2" }, + { name = "behave", marker = "extra == 'dev'", specifier = ">=1.2.6" }, { name = "biopython", specifier = ">=1.85,<1.86" }, { name = "bokeh", marker = "extra == 'notebook'", specifier = "~=3.4.2" }, - { name = "chardet", specifier = "~=5.2.0" }, + { name = "chardet", specifier = ">=5.2.0" }, + { name = "coveralls", marker = "extra == 'dev'", specifier = ">=4.0.1" }, { name = "ddt", specifier = "~=1.7.2" }, + { name = "ddt", marker = "extra == 'dev'", specifier = ">=1.7.2" }, { name = "deepdiff", specifier = "~=8.6.1" }, - { name = "flask", specifier = ">=3.1.1" }, - { name = "flask-sqlalchemy", specifier = ">=3.0.2" }, - { name = "graphene", specifier = "~=3.4.3" }, - { name = "graphql-core", specifier = "~=3.2.6" }, - { name = "iso8601", specifier = "~=2.1.0" }, - { name = "jinja2", specifier = "~=3.1.4" }, + { name = "deepdiff", marker = "extra == 'dev'", specifier = ">=8.6.1" }, + { name = "flask", marker = "extra == 'database'", specifier = ">=3.1.1" }, + { name = "flask-sqlalchemy", marker = "extra == 'database'", specifier = ">=3.0.2" }, + { name = "graphene", specifier = ">=3.4.3,<4.0.0" }, + { name = "httpretty", marker = "extra == 'dev'", specifier = ">=1.1.4" }, + { name = "import-linter", marker = "extra == 'dev'", specifier = ">=2.5.2" }, + { name = "isatools", extras = ["database", "notebook"], marker = "extra == 'all'" }, + { name = "iso8601", specifier = ">=2.1.0" }, + { name = "jinja2", specifier = ">=3.1.4" }, { name = "jsonschema", specifier = ">=4.23.0,<5" }, - { name = "lxml", specifier = "~=6.0.2" }, + { name = "lxml", specifier = ">=6.1.0" }, { name = "mzml2isa", specifier = "==1.1.1" }, { name = "networkx", marker = "python_full_version < '3.10'", specifier = ">=3.2,<3.3" }, - { name = "networkx", marker = "python_full_version >= '3.10'", specifier = "~=3.4.2" }, + { name = "networkx", marker = "python_full_version >= '3.10'", specifier = ">=3.4.2" }, { name = "numpy", marker = "python_full_version < '3.10'", specifier = "~=2.0.2" }, - { name = "numpy", marker = "python_full_version >= '3.10'", specifier = "~=2.2.4" }, + { name = "numpy", marker = "python_full_version >= '3.10'", specifier = "~=2.2.4,<3.0.0" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=2.2.3,<3" }, - { name = "progressbar2", specifier = "~=4.5.0" }, - { name = "pytest-timeout", specifier = ">=2.4.0" }, - { name = "python-dateutil", specifier = "~=2.9.0.post0" }, - { name = "pyyaml", specifier = "~=6.0.2" }, - { name = "rdflib", specifier = "~=7.2.1" }, - { name = "requests", specifier = "~=2.32.4" }, - { name = "ruff", specifier = ">=0.14.1" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.3.0" }, + { name = "progressbar2", specifier = ">=4.5.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.5,<9.0.0" }, + { name = "pytest-timeout", marker = "extra == 'dev'", specifier = ">=2.4.0" }, + { name = "python-dateutil", specifier = ">=2.9.0.post0" }, + { name = "pyyaml", specifier = ">=6.0.3" }, + { name = "rdflib", specifier = ">=7.2.1" }, + { name = "requests", marker = "python_full_version < '3.10'", specifier = ">=2.32.0" }, + { name = "requests", marker = "python_full_version >= '3.10'", specifier = ">=2.34.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.1" }, { name = "setuptools", specifier = ">=77.0.3,<81" }, - { name = "sqlalchemy", specifier = "~=2.0.31" }, - { name = "tornado", specifier = "==6.5.5" }, - { name = "urllib3", specifier = "==2.6.0" }, -] -provides-extras = ["notebook"] - -[package.metadata.requires-dev] -dev = [ - { name = "behave", specifier = ">=1.2.6" }, - { name = "coveralls", specifier = ">=4.0.1" }, - { name = "ddt", specifier = ">=1.7.2" }, - { name = "deepdiff", specifier = ">=8.6.2" }, - { name = "httpretty", specifier = ">=1.1.4" }, - { name = "import-linter", specifier = ">=2.5.2" }, - { name = "pre-commit", specifier = ">=4.0.1,<5" }, - { name = "pytest", specifier = ">=8.3.5,<9.0.0" }, - { name = "ruff", specifier = ">=0.14.1" }, - { name = "sure", specifier = ">=2.0.1" }, + { name = "sqlalchemy", marker = "extra == 'database'", specifier = "~=2.0.31" }, + { name = "sure", marker = "extra == 'dev'", specifier = ">=2.0.1" }, ] +provides-extras = ["notebook", "dev", "database", "all"] [[package]] name = "iso8601" @@ -1454,142 +1446,136 @@ wheels = [ [[package]] name = "lxml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/88/262177de60548e5a2bfc46ad28232c9e9cbde697bd94132aeb80364675cb/lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62", size = 4073426, upload-time = "2025-09-22T04:04:59.287Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/8a/f8192a08237ef2fb1b19733f709db88a4c43bc8ab8357f01cb41a27e7f6a/lxml-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e77dd455b9a16bbd2a5036a63ddbd479c19572af81b624e79ef422f929eef388", size = 8590589, upload-time = "2025-09-22T04:00:10.51Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/27bcd07ae17ff5e5536e8d88f4c7d581b48963817a13de11f3ac3329bfa2/lxml-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d444858b9f07cefff6455b983aea9a67f7462ba1f6cbe4a21e8bf6791bf2153", size = 4629671, upload-time = "2025-09-22T04:00:15.411Z" }, - { url = "https://files.pythonhosted.org/packages/02/5a/a7d53b3291c324e0b6e48f3c797be63836cc52156ddf8f33cd72aac78866/lxml-6.0.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f952dacaa552f3bb8834908dddd500ba7d508e6ea6eb8c52eb2d28f48ca06a31", size = 4999961, upload-time = "2025-09-22T04:00:17.619Z" }, - { url = "https://files.pythonhosted.org/packages/f5/55/d465e9b89df1761674d8672bb3e4ae2c47033b01ec243964b6e334c6743f/lxml-6.0.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:71695772df6acea9f3c0e59e44ba8ac50c4f125217e84aab21074a1a55e7e5c9", size = 5157087, upload-time = "2025-09-22T04:00:19.868Z" }, - { url = "https://files.pythonhosted.org/packages/62/38/3073cd7e3e8dfc3ba3c3a139e33bee3a82de2bfb0925714351ad3d255c13/lxml-6.0.2-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:17f68764f35fd78d7c4cc4ef209a184c38b65440378013d24b8aecd327c3e0c8", size = 5067620, upload-time = "2025-09-22T04:00:21.877Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d3/1e001588c5e2205637b08985597827d3827dbaaece16348c8822bfe61c29/lxml-6.0.2-cp310-cp310-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:058027e261afed589eddcfe530fcc6f3402d7fd7e89bfd0532df82ebc1563dba", size = 5406664, upload-time = "2025-09-22T04:00:23.714Z" }, - { url = "https://files.pythonhosted.org/packages/20/cf/cab09478699b003857ed6ebfe95e9fb9fa3d3c25f1353b905c9b73cfb624/lxml-6.0.2-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8ffaeec5dfea5881d4c9d8913a32d10cfe3923495386106e4a24d45300ef79c", size = 5289397, upload-time = "2025-09-22T04:00:25.544Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/02a2d0c38ac9a8b9f9e5e1bbd3f24b3f426044ad618b552e9549ee91bd63/lxml-6.0.2-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:f2e3b1a6bb38de0bc713edd4d612969dd250ca8b724be8d460001a387507021c", size = 4772178, upload-time = "2025-09-22T04:00:27.602Z" }, - { url = "https://files.pythonhosted.org/packages/56/87/e1ceadcc031ec4aa605fe95476892d0b0ba3b7f8c7dcdf88fdeff59a9c86/lxml-6.0.2-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d6690ec5ec1cce0385cb20896b16be35247ac8c2046e493d03232f1c2414d321", size = 5358148, upload-time = "2025-09-22T04:00:29.323Z" }, - { url = "https://files.pythonhosted.org/packages/fe/13/5bb6cf42bb228353fd4ac5f162c6a84fd68a4d6f67c1031c8cf97e131fc6/lxml-6.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2a50c3c1d11cad0ebebbac357a97b26aa79d2bcaf46f256551152aa85d3a4d1", size = 5112035, upload-time = "2025-09-22T04:00:31.061Z" }, - { url = "https://files.pythonhosted.org/packages/e4/e2/ea0498552102e59834e297c5c6dff8d8ded3db72ed5e8aad77871476f073/lxml-6.0.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:3efe1b21c7801ffa29a1112fab3b0f643628c30472d507f39544fd48e9549e34", size = 4799111, upload-time = "2025-09-22T04:00:33.11Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9e/8de42b52a73abb8af86c66c969b3b4c2a96567b6ac74637c037d2e3baa60/lxml-6.0.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:59c45e125140b2c4b33920d21d83681940ca29f0b83f8629ea1a2196dc8cfe6a", size = 5351662, upload-time = "2025-09-22T04:00:35.237Z" }, - { url = "https://files.pythonhosted.org/packages/28/a2/de776a573dfb15114509a37351937c367530865edb10a90189d0b4b9b70a/lxml-6.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:452b899faa64f1805943ec1c0c9ebeaece01a1af83e130b69cdefeda180bb42c", size = 5314973, upload-time = "2025-09-22T04:00:37.086Z" }, - { url = "https://files.pythonhosted.org/packages/50/a0/3ae1b1f8964c271b5eec91db2043cf8c6c0bce101ebb2a633b51b044db6c/lxml-6.0.2-cp310-cp310-win32.whl", hash = "sha256:1e786a464c191ca43b133906c6903a7e4d56bef376b75d97ccbb8ec5cf1f0a4b", size = 3611953, upload-time = "2025-09-22T04:00:39.224Z" }, - { url = "https://files.pythonhosted.org/packages/d1/70/bd42491f0634aad41bdfc1e46f5cff98825fb6185688dc82baa35d509f1a/lxml-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:dacf3c64ef3f7440e3167aa4b49aa9e0fb99e0aa4f9ff03795640bf94531bcb0", size = 4032695, upload-time = "2025-09-22T04:00:41.402Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d0/05c6a72299f54c2c561a6c6cbb2f512e047fca20ea97a05e57931f194ac4/lxml-6.0.2-cp310-cp310-win_arm64.whl", hash = "sha256:45f93e6f75123f88d7f0cfd90f2d05f441b808562bf0bc01070a00f53f5028b5", size = 3680051, upload-time = "2025-09-22T04:00:43.525Z" }, - { url = "https://files.pythonhosted.org/packages/77/d5/becbe1e2569b474a23f0c672ead8a29ac50b2dc1d5b9de184831bda8d14c/lxml-6.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:13e35cbc684aadf05d8711a5d1b5857c92e5e580efa9a0d2be197199c8def607", size = 8634365, upload-time = "2025-09-22T04:00:45.672Z" }, - { url = "https://files.pythonhosted.org/packages/28/66/1ced58f12e804644426b85d0bb8a4478ca77bc1761455da310505f1a3526/lxml-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b1675e096e17c6fe9c0e8c81434f5736c0739ff9ac6123c87c2d452f48fc938", size = 4650793, upload-time = "2025-09-22T04:00:47.783Z" }, - { url = "https://files.pythonhosted.org/packages/11/84/549098ffea39dfd167e3f174b4ce983d0eed61f9d8d25b7bf2a57c3247fc/lxml-6.0.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8ac6e5811ae2870953390452e3476694196f98d447573234592d30488147404d", size = 4944362, upload-time = "2025-09-22T04:00:49.845Z" }, - { url = "https://files.pythonhosted.org/packages/ac/bd/f207f16abf9749d2037453d56b643a7471d8fde855a231a12d1e095c4f01/lxml-6.0.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5aa0fc67ae19d7a64c3fe725dc9a1bb11f80e01f78289d05c6f62545affec438", size = 5083152, upload-time = "2025-09-22T04:00:51.709Z" }, - { url = "https://files.pythonhosted.org/packages/15/ae/bd813e87d8941d52ad5b65071b1affb48da01c4ed3c9c99e40abb266fbff/lxml-6.0.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de496365750cc472b4e7902a485d3f152ecf57bd3ba03ddd5578ed8ceb4c5964", size = 5023539, upload-time = "2025-09-22T04:00:53.593Z" }, - { url = "https://files.pythonhosted.org/packages/02/cd/9bfef16bd1d874fbe0cb51afb00329540f30a3283beb9f0780adbb7eec03/lxml-6.0.2-cp311-cp311-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:200069a593c5e40b8f6fc0d84d86d970ba43138c3e68619ffa234bc9bb806a4d", size = 5344853, upload-time = "2025-09-22T04:00:55.524Z" }, - { url = "https://files.pythonhosted.org/packages/b8/89/ea8f91594bc5dbb879734d35a6f2b0ad50605d7fb419de2b63d4211765cc/lxml-6.0.2-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d2de809c2ee3b888b59f995625385f74629707c9355e0ff856445cdcae682b7", size = 5225133, upload-time = "2025-09-22T04:00:57.269Z" }, - { url = "https://files.pythonhosted.org/packages/b9/37/9c735274f5dbec726b2db99b98a43950395ba3d4a1043083dba2ad814170/lxml-6.0.2-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:b2c3da8d93cf5db60e8858c17684c47d01fee6405e554fb55018dd85fc23b178", size = 4677944, upload-time = "2025-09-22T04:00:59.052Z" }, - { url = "https://files.pythonhosted.org/packages/20/28/7dfe1ba3475d8bfca3878365075abe002e05d40dfaaeb7ec01b4c587d533/lxml-6.0.2-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:442de7530296ef5e188373a1ea5789a46ce90c4847e597856570439621d9c553", size = 5284535, upload-time = "2025-09-22T04:01:01.335Z" }, - { url = "https://files.pythonhosted.org/packages/e7/cf/5f14bc0de763498fc29510e3532bf2b4b3a1c1d5d0dff2e900c16ba021ef/lxml-6.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2593c77efde7bfea7f6389f1ab249b15ed4aa5bc5cb5131faa3b843c429fbedb", size = 5067343, upload-time = "2025-09-22T04:01:03.13Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b0/bb8275ab5472f32b28cfbbcc6db7c9d092482d3439ca279d8d6fa02f7025/lxml-6.0.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3e3cb08855967a20f553ff32d147e14329b3ae70ced6edc2f282b94afbc74b2a", size = 4725419, upload-time = "2025-09-22T04:01:05.013Z" }, - { url = "https://files.pythonhosted.org/packages/25/4c/7c222753bc72edca3b99dbadba1b064209bc8ed4ad448af990e60dcce462/lxml-6.0.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ed6c667fcbb8c19c6791bbf40b7268ef8ddf5a96940ba9404b9f9a304832f6c", size = 5275008, upload-time = "2025-09-22T04:01:07.327Z" }, - { url = "https://files.pythonhosted.org/packages/6c/8c/478a0dc6b6ed661451379447cdbec77c05741a75736d97e5b2b729687828/lxml-6.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b8f18914faec94132e5b91e69d76a5c1d7b0c73e2489ea8929c4aaa10b76bbf7", size = 5248906, upload-time = "2025-09-22T04:01:09.452Z" }, - { url = "https://files.pythonhosted.org/packages/2d/d9/5be3a6ab2784cdf9accb0703b65e1b64fcdd9311c9f007630c7db0cfcce1/lxml-6.0.2-cp311-cp311-win32.whl", hash = "sha256:6605c604e6daa9e0d7f0a2137bdc47a2e93b59c60a65466353e37f8272f47c46", size = 3610357, upload-time = "2025-09-22T04:01:11.102Z" }, - { url = "https://files.pythonhosted.org/packages/e2/7d/ca6fb13349b473d5732fb0ee3eec8f6c80fc0688e76b7d79c1008481bf1f/lxml-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e5867f2651016a3afd8dd2c8238baa66f1e2802f44bc17e236f547ace6647078", size = 4036583, upload-time = "2025-09-22T04:01:12.766Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a2/51363b5ecd3eab46563645f3a2c3836a2fc67d01a1b87c5017040f39f567/lxml-6.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:4197fb2534ee05fd3e7afaab5d8bfd6c2e186f65ea7f9cd6a82809c887bd1285", size = 3680591, upload-time = "2025-09-22T04:01:14.874Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c8/8ff2bc6b920c84355146cd1ab7d181bc543b89241cfb1ebee824a7c81457/lxml-6.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a59f5448ba2ceccd06995c95ea59a7674a10de0810f2ce90c9006f3cbc044456", size = 8661887, upload-time = "2025-09-22T04:01:17.265Z" }, - { url = "https://files.pythonhosted.org/packages/37/6f/9aae1008083bb501ef63284220ce81638332f9ccbfa53765b2b7502203cf/lxml-6.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e8113639f3296706fbac34a30813929e29247718e88173ad849f57ca59754924", size = 4667818, upload-time = "2025-09-22T04:01:19.688Z" }, - { url = "https://files.pythonhosted.org/packages/f1/ca/31fb37f99f37f1536c133476674c10b577e409c0a624384147653e38baf2/lxml-6.0.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a8bef9b9825fa8bc816a6e641bb67219489229ebc648be422af695f6e7a4fa7f", size = 4950807, upload-time = "2025-09-22T04:01:21.487Z" }, - { url = "https://files.pythonhosted.org/packages/da/87/f6cb9442e4bada8aab5ae7e1046264f62fdbeaa6e3f6211b93f4c0dd97f1/lxml-6.0.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:65ea18d710fd14e0186c2f973dc60bb52039a275f82d3c44a0e42b43440ea534", size = 5109179, upload-time = "2025-09-22T04:01:23.32Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/a7760713e65888db79bbae4f6146a6ae5c04e4a204a3c48896c408cd6ed2/lxml-6.0.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c371aa98126a0d4c739ca93ceffa0fd7a5d732e3ac66a46e74339acd4d334564", size = 5023044, upload-time = "2025-09-22T04:01:25.118Z" }, - { url = "https://files.pythonhosted.org/packages/a2/b0/7e64e0460fcb36471899f75831509098f3fd7cd02a3833ac517433cb4f8f/lxml-6.0.2-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:700efd30c0fa1a3581d80a748157397559396090a51d306ea59a70020223d16f", size = 5359685, upload-time = "2025-09-22T04:01:27.398Z" }, - { url = "https://files.pythonhosted.org/packages/b9/e1/e5df362e9ca4e2f48ed6411bd4b3a0ae737cc842e96877f5bf9428055ab4/lxml-6.0.2-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c33e66d44fe60e72397b487ee92e01da0d09ba2d66df8eae42d77b6d06e5eba0", size = 5654127, upload-time = "2025-09-22T04:01:29.629Z" }, - { url = "https://files.pythonhosted.org/packages/c6/d1/232b3309a02d60f11e71857778bfcd4acbdb86c07db8260caf7d008b08f8/lxml-6.0.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90a345bbeaf9d0587a3aaffb7006aa39ccb6ff0e96a57286c0cb2fd1520ea192", size = 5253958, upload-time = "2025-09-22T04:01:31.535Z" }, - { url = "https://files.pythonhosted.org/packages/35/35/d955a070994725c4f7d80583a96cab9c107c57a125b20bb5f708fe941011/lxml-6.0.2-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:064fdadaf7a21af3ed1dcaa106b854077fbeada827c18f72aec9346847cd65d0", size = 4711541, upload-time = "2025-09-22T04:01:33.801Z" }, - { url = "https://files.pythonhosted.org/packages/1e/be/667d17363b38a78c4bd63cfd4b4632029fd68d2c2dc81f25ce9eb5224dd5/lxml-6.0.2-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fbc74f42c3525ac4ffa4b89cbdd00057b6196bcefe8bce794abd42d33a018092", size = 5267426, upload-time = "2025-09-22T04:01:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/ea/47/62c70aa4a1c26569bc958c9ca86af2bb4e1f614e8c04fb2989833874f7ae/lxml-6.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ddff43f702905a4e32bc24f3f2e2edfe0f8fde3277d481bffb709a4cced7a1f", size = 5064917, upload-time = "2025-09-22T04:01:37.448Z" }, - { url = "https://files.pythonhosted.org/packages/bd/55/6ceddaca353ebd0f1908ef712c597f8570cc9c58130dbb89903198e441fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6da5185951d72e6f5352166e3da7b0dc27aa70bd1090b0eb3f7f7212b53f1bb8", size = 4788795, upload-time = "2025-09-22T04:01:39.165Z" }, - { url = "https://files.pythonhosted.org/packages/cf/e8/fd63e15da5e3fd4c2146f8bbb3c14e94ab850589beab88e547b2dbce22e1/lxml-6.0.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:57a86e1ebb4020a38d295c04fc79603c7899e0df71588043eb218722dabc087f", size = 5676759, upload-time = "2025-09-22T04:01:41.506Z" }, - { url = "https://files.pythonhosted.org/packages/76/47/b3ec58dc5c374697f5ba37412cd2728f427d056315d124dd4b61da381877/lxml-6.0.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2047d8234fe735ab77802ce5f2297e410ff40f5238aec569ad7c8e163d7b19a6", size = 5255666, upload-time = "2025-09-22T04:01:43.363Z" }, - { url = "https://files.pythonhosted.org/packages/19/93/03ba725df4c3d72afd9596eef4a37a837ce8e4806010569bedfcd2cb68fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f91fd2b2ea15a6800c8e24418c0775a1694eefc011392da73bc6cef2623b322", size = 5277989, upload-time = "2025-09-22T04:01:45.215Z" }, - { url = "https://files.pythonhosted.org/packages/c6/80/c06de80bfce881d0ad738576f243911fccf992687ae09fd80b734712b39c/lxml-6.0.2-cp312-cp312-win32.whl", hash = "sha256:3ae2ce7d6fedfb3414a2b6c5e20b249c4c607f72cb8d2bb7cc9c6ec7c6f4e849", size = 3611456, upload-time = "2025-09-22T04:01:48.243Z" }, - { url = "https://files.pythonhosted.org/packages/f7/d7/0cdfb6c3e30893463fb3d1e52bc5f5f99684a03c29a0b6b605cfae879cd5/lxml-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:72c87e5ee4e58a8354fb9c7c84cbf95a1c8236c127a5d1b7683f04bed8361e1f", size = 4011793, upload-time = "2025-09-22T04:01:50.042Z" }, - { url = "https://files.pythonhosted.org/packages/ea/7b/93c73c67db235931527301ed3785f849c78991e2e34f3fd9a6663ffda4c5/lxml-6.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:61cb10eeb95570153e0c0e554f58df92ecf5109f75eacad4a95baa709e26c3d6", size = 3672836, upload-time = "2025-09-22T04:01:52.145Z" }, - { url = "https://files.pythonhosted.org/packages/53/fd/4e8f0540608977aea078bf6d79f128e0e2c2bba8af1acf775c30baa70460/lxml-6.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9b33d21594afab46f37ae58dfadd06636f154923c4e8a4d754b0127554eb2e77", size = 8648494, upload-time = "2025-09-22T04:01:54.242Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f4/2a94a3d3dfd6c6b433501b8d470a1960a20ecce93245cf2db1706adf6c19/lxml-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c8963287d7a4c5c9a432ff487c52e9c5618667179c18a204bdedb27310f022f", size = 4661146, upload-time = "2025-09-22T04:01:56.282Z" }, - { url = "https://files.pythonhosted.org/packages/25/2e/4efa677fa6b322013035d38016f6ae859d06cac67437ca7dc708a6af7028/lxml-6.0.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1941354d92699fb5ffe6ed7b32f9649e43c2feb4b97205f75866f7d21aa91452", size = 4946932, upload-time = "2025-09-22T04:01:58.989Z" }, - { url = "https://files.pythonhosted.org/packages/ce/0f/526e78a6d38d109fdbaa5049c62e1d32fdd70c75fb61c4eadf3045d3d124/lxml-6.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb2f6ca0ae2d983ded09357b84af659c954722bbf04dea98030064996d156048", size = 5100060, upload-time = "2025-09-22T04:02:00.812Z" }, - { url = "https://files.pythonhosted.org/packages/81/76/99de58d81fa702cc0ea7edae4f4640416c2062813a00ff24bd70ac1d9c9b/lxml-6.0.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb2a12d704f180a902d7fa778c6d71f36ceb7b0d317f34cdc76a5d05aa1dd1df", size = 5019000, upload-time = "2025-09-22T04:02:02.671Z" }, - { url = "https://files.pythonhosted.org/packages/b5/35/9e57d25482bc9a9882cb0037fdb9cc18f4b79d85df94fa9d2a89562f1d25/lxml-6.0.2-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:6ec0e3f745021bfed19c456647f0298d60a24c9ff86d9d051f52b509663feeb1", size = 5348496, upload-time = "2025-09-22T04:02:04.904Z" }, - { url = "https://files.pythonhosted.org/packages/a6/8e/cb99bd0b83ccc3e8f0f528e9aa1f7a9965dfec08c617070c5db8d63a87ce/lxml-6.0.2-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:846ae9a12d54e368933b9759052d6206a9e8b250291109c48e350c1f1f49d916", size = 5643779, upload-time = "2025-09-22T04:02:06.689Z" }, - { url = "https://files.pythonhosted.org/packages/d0/34/9e591954939276bb679b73773836c6684c22e56d05980e31d52a9a8deb18/lxml-6.0.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef9266d2aa545d7374938fb5c484531ef5a2ec7f2d573e62f8ce722c735685fd", size = 5244072, upload-time = "2025-09-22T04:02:08.587Z" }, - { url = "https://files.pythonhosted.org/packages/8d/27/b29ff065f9aaca443ee377aff699714fcbffb371b4fce5ac4ca759e436d5/lxml-6.0.2-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:4077b7c79f31755df33b795dc12119cb557a0106bfdab0d2c2d97bd3cf3dffa6", size = 4718675, upload-time = "2025-09-22T04:02:10.783Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f756f9c2cd27caa1a6ef8c32ae47aadea697f5c2c6d07b0dae133c244fbe/lxml-6.0.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a7c5d5e5f1081955358533be077166ee97ed2571d6a66bdba6ec2f609a715d1a", size = 5255171, upload-time = "2025-09-22T04:02:12.631Z" }, - { url = "https://files.pythonhosted.org/packages/61/46/bb85ea42d2cb1bd8395484fd72f38e3389611aa496ac7772da9205bbda0e/lxml-6.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8f8d0cbd0674ee89863a523e6994ac25fd5be9c8486acfc3e5ccea679bad2679", size = 5057175, upload-time = "2025-09-22T04:02:14.718Z" }, - { url = "https://files.pythonhosted.org/packages/95/0c/443fc476dcc8e41577f0af70458c50fe299a97bb6b7505bb1ae09aa7f9ac/lxml-6.0.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2cbcbf6d6e924c28f04a43f3b6f6e272312a090f269eff68a2982e13e5d57659", size = 4785688, upload-time = "2025-09-22T04:02:16.957Z" }, - { url = "https://files.pythonhosted.org/packages/48/78/6ef0b359d45bb9697bc5a626e1992fa5d27aa3f8004b137b2314793b50a0/lxml-6.0.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dfb874cfa53340009af6bdd7e54ebc0d21012a60a4e65d927c2e477112e63484", size = 5660655, upload-time = "2025-09-22T04:02:18.815Z" }, - { url = "https://files.pythonhosted.org/packages/ff/ea/e1d33808f386bc1339d08c0dcada6e4712d4ed8e93fcad5f057070b7988a/lxml-6.0.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb8dae0b6b8b7f9e96c26fdd8121522ce5de9bb5538010870bd538683d30e9a2", size = 5247695, upload-time = "2025-09-22T04:02:20.593Z" }, - { url = "https://files.pythonhosted.org/packages/4f/47/eba75dfd8183673725255247a603b4ad606f4ae657b60c6c145b381697da/lxml-6.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:358d9adae670b63e95bc59747c72f4dc97c9ec58881d4627fe0120da0f90d314", size = 5269841, upload-time = "2025-09-22T04:02:22.489Z" }, - { url = "https://files.pythonhosted.org/packages/76/04/5c5e2b8577bc936e219becb2e98cdb1aca14a4921a12995b9d0c523502ae/lxml-6.0.2-cp313-cp313-win32.whl", hash = "sha256:e8cd2415f372e7e5a789d743d133ae474290a90b9023197fd78f32e2dc6873e2", size = 3610700, upload-time = "2025-09-22T04:02:24.465Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0a/4643ccc6bb8b143e9f9640aa54e38255f9d3b45feb2cbe7ae2ca47e8782e/lxml-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:b30d46379644fbfc3ab81f8f82ae4de55179414651f110a1514f0b1f8f6cb2d7", size = 4010347, upload-time = "2025-09-22T04:02:26.286Z" }, - { url = "https://files.pythonhosted.org/packages/31/ef/dcf1d29c3f530577f61e5fe2f1bd72929acf779953668a8a47a479ae6f26/lxml-6.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:13dcecc9946dca97b11b7c40d29fba63b55ab4170d3c0cf8c0c164343b9bfdcf", size = 3671248, upload-time = "2025-09-22T04:02:27.918Z" }, - { url = "https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe", size = 8659801, upload-time = "2025-09-22T04:02:30.113Z" }, - { url = "https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d", size = 4659403, upload-time = "2025-09-22T04:02:32.119Z" }, - { url = "https://files.pythonhosted.org/packages/00/ce/74903904339decdf7da7847bb5741fc98a5451b42fc419a86c0c13d26fe2/lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d", size = 4966974, upload-time = "2025-09-22T04:02:34.155Z" }, - { url = "https://files.pythonhosted.org/packages/1f/d3/131dec79ce61c5567fecf82515bd9bc36395df42501b50f7f7f3bd065df0/lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5", size = 5102953, upload-time = "2025-09-22T04:02:36.054Z" }, - { url = "https://files.pythonhosted.org/packages/3a/ea/a43ba9bb750d4ffdd885f2cd333572f5bb900cd2408b67fdda07e85978a0/lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0", size = 5055054, upload-time = "2025-09-22T04:02:38.154Z" }, - { url = "https://files.pythonhosted.org/packages/60/23/6885b451636ae286c34628f70a7ed1fcc759f8d9ad382d132e1c8d3d9bfd/lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba", size = 5352421, upload-time = "2025-09-22T04:02:40.413Z" }, - { url = "https://files.pythonhosted.org/packages/48/5b/fc2ddfc94ddbe3eebb8e9af6e3fd65e2feba4967f6a4e9683875c394c2d8/lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0", size = 5673684, upload-time = "2025-09-22T04:02:42.288Z" }, - { url = "https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d", size = 5252463, upload-time = "2025-09-22T04:02:44.165Z" }, - { url = "https://files.pythonhosted.org/packages/9b/da/ba6eceb830c762b48e711ded880d7e3e89fc6c7323e587c36540b6b23c6b/lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37", size = 4698437, upload-time = "2025-09-22T04:02:46.524Z" }, - { url = "https://files.pythonhosted.org/packages/a5/24/7be3f82cb7990b89118d944b619e53c656c97dc89c28cfb143fdb7cd6f4d/lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9", size = 5269890, upload-time = "2025-09-22T04:02:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/1b/bd/dcfb9ea1e16c665efd7538fc5d5c34071276ce9220e234217682e7d2c4a5/lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917", size = 5097185, upload-time = "2025-09-22T04:02:50.746Z" }, - { url = "https://files.pythonhosted.org/packages/21/04/a60b0ff9314736316f28316b694bccbbabe100f8483ad83852d77fc7468e/lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f", size = 4745895, upload-time = "2025-09-22T04:02:52.968Z" }, - { url = "https://files.pythonhosted.org/packages/d6/bd/7d54bd1846e5a310d9c715921c5faa71cf5c0853372adf78aee70c8d7aa2/lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8", size = 5695246, upload-time = "2025-09-22T04:02:54.798Z" }, - { url = "https://files.pythonhosted.org/packages/fd/32/5643d6ab947bc371da21323acb2a6e603cedbe71cb4c99c8254289ab6f4e/lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a", size = 5260797, upload-time = "2025-09-22T04:02:57.058Z" }, - { url = "https://files.pythonhosted.org/packages/33/da/34c1ec4cff1eea7d0b4cd44af8411806ed943141804ac9c5d565302afb78/lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c", size = 5277404, upload-time = "2025-09-22T04:02:58.966Z" }, - { url = "https://files.pythonhosted.org/packages/82/57/4eca3e31e54dc89e2c3507e1cd411074a17565fa5ffc437c4ae0a00d439e/lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b", size = 3670072, upload-time = "2025-09-22T04:03:38.05Z" }, - { url = "https://files.pythonhosted.org/packages/e3/e0/c96cf13eccd20c9421ba910304dae0f619724dcf1702864fd59dd386404d/lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed", size = 4080617, upload-time = "2025-09-22T04:03:39.835Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5d/b3f03e22b3d38d6f188ef044900a9b29b2fe0aebb94625ce9fe244011d34/lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8", size = 3754930, upload-time = "2025-09-22T04:03:41.565Z" }, - { url = "https://files.pythonhosted.org/packages/5e/5c/42c2c4c03554580708fc738d13414801f340c04c3eff90d8d2d227145275/lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d", size = 8910380, upload-time = "2025-09-22T04:03:01.645Z" }, - { url = "https://files.pythonhosted.org/packages/bf/4f/12df843e3e10d18d468a7557058f8d3733e8b6e12401f30b1ef29360740f/lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba", size = 4775632, upload-time = "2025-09-22T04:03:03.814Z" }, - { url = "https://files.pythonhosted.org/packages/e4/0c/9dc31e6c2d0d418483cbcb469d1f5a582a1cd00a1f4081953d44051f3c50/lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601", size = 4975171, upload-time = "2025-09-22T04:03:05.651Z" }, - { url = "https://files.pythonhosted.org/packages/e7/2b/9b870c6ca24c841bdd887504808f0417aa9d8d564114689266f19ddf29c8/lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed", size = 5110109, upload-time = "2025-09-22T04:03:07.452Z" }, - { url = "https://files.pythonhosted.org/packages/bf/0c/4f5f2a4dd319a178912751564471355d9019e220c20d7db3fb8307ed8582/lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37", size = 5041061, upload-time = "2025-09-22T04:03:09.297Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/554eed290365267671fe001a20d72d14f468ae4e6acef1e179b039436967/lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338", size = 5306233, upload-time = "2025-09-22T04:03:11.651Z" }, - { url = "https://files.pythonhosted.org/packages/7a/31/1d748aa275e71802ad9722df32a7a35034246b42c0ecdd8235412c3396ef/lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9", size = 5604739, upload-time = "2025-09-22T04:03:13.592Z" }, - { url = "https://files.pythonhosted.org/packages/8f/41/2c11916bcac09ed561adccacceaedd2bf0e0b25b297ea92aab99fd03d0fa/lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd", size = 5225119, upload-time = "2025-09-22T04:03:15.408Z" }, - { url = "https://files.pythonhosted.org/packages/99/05/4e5c2873d8f17aa018e6afde417c80cc5d0c33be4854cce3ef5670c49367/lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d", size = 4633665, upload-time = "2025-09-22T04:03:17.262Z" }, - { url = "https://files.pythonhosted.org/packages/0f/c9/dcc2da1bebd6275cdc723b515f93edf548b82f36a5458cca3578bc899332/lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9", size = 5234997, upload-time = "2025-09-22T04:03:19.14Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e2/5172e4e7468afca64a37b81dba152fc5d90e30f9c83c7c3213d6a02a5ce4/lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e", size = 5090957, upload-time = "2025-09-22T04:03:21.436Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b3/15461fd3e5cd4ddcb7938b87fc20b14ab113b92312fc97afe65cd7c85de1/lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d", size = 4764372, upload-time = "2025-09-22T04:03:23.27Z" }, - { url = "https://files.pythonhosted.org/packages/05/33/f310b987c8bf9e61c4dd8e8035c416bd3230098f5e3cfa69fc4232de7059/lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec", size = 5634653, upload-time = "2025-09-22T04:03:25.767Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/51c80e75e0bc9382158133bdcf4e339b5886c6ee2418b5199b3f1a61ed6d/lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272", size = 5233795, upload-time = "2025-09-22T04:03:27.62Z" }, - { url = "https://files.pythonhosted.org/packages/56/4d/4856e897df0d588789dd844dbed9d91782c4ef0b327f96ce53c807e13128/lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f", size = 5257023, upload-time = "2025-09-22T04:03:30.056Z" }, - { url = "https://files.pythonhosted.org/packages/0f/85/86766dfebfa87bea0ab78e9ff7a4b4b45225df4b4d3b8cc3c03c5cd68464/lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312", size = 3911420, upload-time = "2025-09-22T04:03:32.198Z" }, - { url = "https://files.pythonhosted.org/packages/fe/1a/b248b355834c8e32614650b8008c69ffeb0ceb149c793961dd8c0b991bb3/lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca", size = 4406837, upload-time = "2025-09-22T04:03:34.027Z" }, - { url = "https://files.pythonhosted.org/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c", size = 3822205, upload-time = "2025-09-22T04:03:36.249Z" }, - { url = "https://files.pythonhosted.org/packages/38/66/dd13c74fad495957374c8a81c932f4874d3dca5aa0db9e4369f06a399718/lxml-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2c8458c2cdd29589a8367c09c8f030f1d202be673f0ca224ec18590b3b9fb694", size = 8602363, upload-time = "2025-09-22T04:03:58.698Z" }, - { url = "https://files.pythonhosted.org/packages/5e/f4/edb9d47dce464b5dd044d35775ee794364935b93ab6226c95e199118890d/lxml-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3fee0851639d06276e6b387f1c190eb9d7f06f7f53514e966b26bae46481ec90", size = 4634995, upload-time = "2025-09-22T04:04:01.122Z" }, - { url = "https://files.pythonhosted.org/packages/66/f2/d80c97b6ed83a99bc24b2b29919d5e618af5322df6d3aa61064093712309/lxml-6.0.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2142a376b40b6736dfc214fd2902409e9e3857eff554fed2d3c60f097e62a62", size = 5003737, upload-time = "2025-09-22T04:04:02.98Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f1/18b750f79f8889b9109b24749f23ac137870b4f685edc4be54be0ff2c730/lxml-6.0.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6b5b39cc7e2998f968f05309e666103b53e2edd01df8dc51b90d734c0825444", size = 5160821, upload-time = "2025-09-22T04:04:04.854Z" }, - { url = "https://files.pythonhosted.org/packages/cf/88/2b6a415dbad411c3e9c092128eb7db06054d2d9460aa56676d17ee4f4fd5/lxml-6.0.2-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4aec24d6b72ee457ec665344a29acb2d35937d5192faebe429ea02633151aad", size = 5070959, upload-time = "2025-09-22T04:04:07.042Z" }, - { url = "https://files.pythonhosted.org/packages/7c/d0/5354afaa0f2e53625e5f96f6bd049a4875c3ab79d96d6c4871dd1f4a98c4/lxml-6.0.2-cp39-cp39-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:b42f4d86b451c2f9d06ffb4f8bbc776e04df3ba070b9fe2657804b1b40277c48", size = 5410267, upload-time = "2025-09-22T04:04:10.458Z" }, - { url = "https://files.pythonhosted.org/packages/51/63/10dea35a01291dc529fa9d6ba204ea627a1c77b7fbb180d404f6cc4dd2fd/lxml-6.0.2-cp39-cp39-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cdaefac66e8b8f30e37a9b4768a391e1f8a16a7526d5bc77a7928408ef68e93", size = 5292990, upload-time = "2025-09-22T04:04:12.405Z" }, - { url = "https://files.pythonhosted.org/packages/37/58/51ef422d8bec58db600b3552e5f2d870ec01ffacf11d98689c42ffdcbf7f/lxml-6.0.2-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:b738f7e648735714bbb82bdfd030203360cfeab7f6e8a34772b3c8c8b820568c", size = 4776318, upload-time = "2025-09-22T04:04:14.22Z" }, - { url = "https://files.pythonhosted.org/packages/77/97/3f797820e82e3a58a19bc51068b40f3b9ab7d0934ba6e5ba6b147b618319/lxml-6.0.2-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:daf42de090d59db025af61ce6bdb2521f0f102ea0e6ea310f13c17610a97da4c", size = 5360191, upload-time = "2025-09-22T04:04:16.236Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/a9306a8ab122e2f5dfbf4f71fb09beeadca26b0c275708432bbc33f40edc/lxml-6.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:66328dabea70b5ba7e53d94aa774b733cf66686535f3bc9250a7aab53a91caaf", size = 5116114, upload-time = "2025-09-22T04:04:18.594Z" }, - { url = "https://files.pythonhosted.org/packages/ea/23/2118a1685277b9fa8726ec7ee903db55aa300dcea3d406a220cbe3710953/lxml-6.0.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:e237b807d68a61fc3b1e845407e27e5eb8ef69bc93fe8505337c1acb4ee300b6", size = 4801704, upload-time = "2025-09-22T04:04:20.466Z" }, - { url = "https://files.pythonhosted.org/packages/4e/e8/d5be34da2059dc9a4ff8643fd6ad3f8234a27b2a44831b7fff58c4dbb3e3/lxml-6.0.2-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:ac02dc29fd397608f8eb15ac1610ae2f2f0154b03f631e6d724d9e2ad4ee2c84", size = 5355451, upload-time = "2025-09-22T04:04:22.417Z" }, - { url = "https://files.pythonhosted.org/packages/61/84/5aebc8e150d5bf488815ea2d8798c7ff509cc37b5725caa3c1f11bdd3245/lxml-6.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:817ef43a0c0b4a77bd166dc9a09a555394105ff3374777ad41f453526e37f9cb", size = 5318630, upload-time = "2025-09-22T04:04:24.301Z" }, - { url = "https://files.pythonhosted.org/packages/35/04/629ae603c1c17fb7adc9df2bc21aa5ac96afb84001700b13c1f038f3118c/lxml-6.0.2-cp39-cp39-win32.whl", hash = "sha256:bc532422ff26b304cfb62b328826bd995c96154ffd2bac4544f37dbb95ecaa8f", size = 3614032, upload-time = "2025-09-22T04:04:26.158Z" }, - { url = "https://files.pythonhosted.org/packages/71/de/07b7b1249acbecbf48f7e42c3ce87a657af6ff38e30f12a1ad81f16010f2/lxml-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:995e783eb0374c120f528f807443ad5a83a656a8624c467ea73781fc5f8a8304", size = 4035311, upload-time = "2025-09-22T04:04:28.413Z" }, - { url = "https://files.pythonhosted.org/packages/60/e3/02c4c55b281606f3c8e118300e16a9fcf5f3462cc46ce740ed0b82fc3f1b/lxml-6.0.2-cp39-cp39-win_arm64.whl", hash = "sha256:08b9d5e803c2e4725ae9e8559ee880e5328ed61aa0935244e0515d7d9dbec0aa", size = 3683462, upload-time = "2025-09-22T04:04:30.399Z" }, - { url = "https://files.pythonhosted.org/packages/e7/9c/780c9a8fce3f04690b374f72f41306866b0400b9d0fdf3e17aaa37887eed/lxml-6.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e748d4cf8fef2526bb2a589a417eba0c8674e29ffcb570ce2ceca44f1e567bf6", size = 3939264, upload-time = "2025-09-22T04:04:32.892Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5a/1ab260c00adf645d8bf7dec7f920f744b032f69130c681302821d5debea6/lxml-6.0.2-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4ddb1049fa0579d0cbd00503ad8c58b9ab34d1254c77bc6a5576d96ec7853dba", size = 4216435, upload-time = "2025-09-22T04:04:34.907Z" }, - { url = "https://files.pythonhosted.org/packages/f2/37/565f3b3d7ffede22874b6d86be1a1763d00f4ea9fc5b9b6ccb11e4ec8612/lxml-6.0.2-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cb233f9c95f83707dae461b12b720c1af9c28c2d19208e1be03387222151daf5", size = 4325913, upload-time = "2025-09-22T04:04:37.205Z" }, - { url = "https://files.pythonhosted.org/packages/22/ec/f3a1b169b2fb9d03467e2e3c0c752ea30e993be440a068b125fc7dd248b0/lxml-6.0.2-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc456d04db0515ce3320d714a1eac7a97774ff0849e7718b492d957da4631dd4", size = 4269357, upload-time = "2025-09-22T04:04:39.322Z" }, - { url = "https://files.pythonhosted.org/packages/77/a2/585a28fe3e67daa1cf2f06f34490d556d121c25d500b10082a7db96e3bcd/lxml-6.0.2-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2613e67de13d619fd283d58bda40bff0ee07739f624ffee8b13b631abf33083d", size = 4412295, upload-time = "2025-09-22T04:04:41.647Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d9/a57dd8bcebd7c69386c20263830d4fa72d27e6b72a229ef7a48e88952d9a/lxml-6.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:24a8e756c982c001ca8d59e87c80c4d9dcd4d9b44a4cbeb8d9be4482c514d41d", size = 3516913, upload-time = "2025-09-22T04:04:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/0b/11/29d08bc103a62c0eba8016e7ed5aeebbf1e4312e83b0b1648dd203b0e87d/lxml-6.0.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1c06035eafa8404b5cf475bb37a9f6088b0aca288d4ccc9d69389750d5543700", size = 3949829, upload-time = "2025-09-22T04:04:45.608Z" }, - { url = "https://files.pythonhosted.org/packages/12/b3/52ab9a3b31e5ab8238da241baa19eec44d2ab426532441ee607165aebb52/lxml-6.0.2-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c7d13103045de1bdd6fe5d61802565f1a3537d70cd3abf596aa0af62761921ee", size = 4226277, upload-time = "2025-09-22T04:04:47.754Z" }, - { url = "https://files.pythonhosted.org/packages/a0/33/1eaf780c1baad88224611df13b1c2a9dfa460b526cacfe769103ff50d845/lxml-6.0.2-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a3c150a95fbe5ac91de323aa756219ef9cf7fde5a3f00e2281e30f33fa5fa4f", size = 4330433, upload-time = "2025-09-22T04:04:49.907Z" }, - { url = "https://files.pythonhosted.org/packages/7a/c1/27428a2ff348e994ab4f8777d3a0ad510b6b92d37718e5887d2da99952a2/lxml-6.0.2-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60fa43be34f78bebb27812ed90f1925ec99560b0fa1decdb7d12b84d857d31e9", size = 4272119, upload-time = "2025-09-22T04:04:51.801Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d0/3020fa12bcec4ab62f97aab026d57c2f0cfd480a558758d9ca233bb6a79d/lxml-6.0.2-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21c73b476d3cfe836be731225ec3421fa2f048d84f6df6a8e70433dff1376d5a", size = 4417314, upload-time = "2025-09-22T04:04:55.024Z" }, - { url = "https://files.pythonhosted.org/packages/6c/77/d7f491cbc05303ac6801651aabeb262d43f319288c1ea96c66b1d2692ff3/lxml-6.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:27220da5be049e936c3aca06f174e8827ca6445a4353a1995584311487fc4e3e", size = 3518768, upload-time = "2025-09-22T04:04:57.097Z" }, +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/3b/aab6728cae887456f409b4d75e8a01856e4f04bd510de38052a47768b680/lxml-6.1.1.tar.gz", hash = "sha256:ba96ae44888e0185281e937633a743ea90d5a196c6000f82565ebb0580012d40", size = 4197430, upload-time = "2026-05-18T19:19:06.424Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/da/dbe4dfc01ac226fb0504fad035f4d69f3202f3502e20e68537631daddd96/lxml-6.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:09dd5b7075dc2f7709654a46543ba1ea3c2e217b2ed8fbd413a8a945a0f40f60", size = 8541124, upload-time = "2026-05-18T19:17:11.589Z" }, + { url = "https://files.pythonhosted.org/packages/78/20/f7095ed9fc2c025f9cfe71cc6ec9f1feb05624edc1812423b5f1aecf3d4b/lxml-6.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f6ac4ef4d82dff54670227a69c67782ae0b811b5cf6b17954f1e8f7502fc0d1d", size = 4602783, upload-time = "2026-05-18T19:17:20.888Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a4/65c63ca98bd129f6cff7b8c2fa48953ab058cc6005b541354e7dd54d8000/lxml-6.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:556e94a63c9b04716f8e4de2abb65775061f846e89331b6c5be79183a24f98ea", size = 5002687, upload-time = "2026-05-18T19:17:01.738Z" }, + { url = "https://files.pythonhosted.org/packages/96/1d/ab7a5c4b5a394d98a94e2d0fc67bab8297597426770dd4978370fbdaf531/lxml-6.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c6bf403fbb3b3e348a561a5f4f0b9961835657981c802a1df03653eef8a9074", size = 5155099, upload-time = "2026-05-18T19:17:05.159Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b1/07603bfeeb891a2596d5c2a68f7d2f70f7d11c841ebe391412c69c2857b0/lxml-6.1.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1dde6131244bba38a17c745836ba190bc753fd73c9291666287fd0a3fa3dcf30", size = 5057225, upload-time = "2026-05-18T19:17:08.117Z" }, + { url = "https://files.pythonhosted.org/packages/7a/16/cb391ee4b90186fa16d9ebcbe3ea96c71b8da3b0686386c8dcbcc3c67d44/lxml-6.1.1-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98fc784c2c1440667aeedf8465bdfe10208acf0ead656a2c68627299f546b315", size = 5287643, upload-time = "2026-05-18T19:17:11.507Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d6/b619717f918fd76747448fdbaee0e769edbc70e659b5b5d0112b7020b7a3/lxml-6.1.1-cp310-cp310-manylinux_2_28_i686.whl", hash = "sha256:add8cf6ddf9a65116119a28ece0f7886e30af27ba724a7594305f1d1b58a92a1", size = 5412445, upload-time = "2026-05-18T19:17:22.182Z" }, + { url = "https://files.pythonhosted.org/packages/c6/80/12bc5390ac0a3edeb579d9535e5049a5dda663438728e179d52fb319c33a/lxml-6.1.1-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:cf9d57306d848218f3601fee7601fab1a327c942d56e2e97610583cb4dd74206", size = 4770864, upload-time = "2026-05-18T19:17:26.851Z" }, + { url = "https://files.pythonhosted.org/packages/0b/59/6500c09da3137f54f020e908d81cfc5ee3e8888e908fd380207afad7c2e6/lxml-6.1.1-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88136950da4d13c318bde414ce10219931937851327f44328f2df4d2c4614067", size = 5359594, upload-time = "2026-05-18T19:17:32.527Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9b/f64b4cc6b7ebcf75d95af3cde934d254b5f2f10d4163928d838d86b6eb48/lxml-6.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cecdd5dfdc87b1fd87dbf81d4b037a544f47f4c744200a67013771682d67686a", size = 5107713, upload-time = "2026-05-18T19:17:04.402Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/c7388ad5d3a72315d2832dc1458cbf4f2af7f2b990b606ff4876efd04511/lxml-6.1.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd312b9692e831d2ffcad61eab31d91d4b4655a962e61de8fb410472cbcd37aa", size = 4803973, upload-time = "2026-05-18T19:17:06.545Z" }, + { url = "https://files.pythonhosted.org/packages/3f/22/76197f0bbf165f0b9e75be59be4997e5259cde973f12f098c1b54c7f5d60/lxml-6.1.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:5b7328b46d49fc9477d91ae8f6d55340347d827b7734ba3ea33faae0efef1383", size = 5349925, upload-time = "2026-05-18T19:17:09.743Z" }, + { url = "https://files.pythonhosted.org/packages/24/52/d2a0cfeccb9bcdc47c7ee05cdae5d69b48c9acf20997790a6338bb0d0b3b/lxml-6.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37a58976370f36d9329d118ad0b953c5aeb9119ac9c6a4e258942a225d0573a1", size = 5309825, upload-time = "2026-05-18T19:17:13.831Z" }, + { url = "https://files.pythonhosted.org/packages/19/4a/b30944266776c2f49749ef2445aa7e78898194134b80ad776386f61b56ae/lxml-6.1.1-cp310-cp310-win32.whl", hash = "sha256:cea3f4c1af79af13cdb2da0c028111d8f8522d4f22a000c82385535f24e5cf3a", size = 3598402, upload-time = "2026-05-18T19:17:08.21Z" }, + { url = "https://files.pythonhosted.org/packages/9e/97/33691c66a4d7ec1a5a98e7c909a5b83ee45c7f7ba4cf92b1c4cf26e98079/lxml-6.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:3abf332af33a74288675d936fe861fd4344da0dd6622193fbc4f2bfbb35536b5", size = 4021295, upload-time = "2026-05-18T19:17:28.638Z" }, + { url = "https://files.pythonhosted.org/packages/d0/5f/26a4dd0e12b9456ff7b12a21af5b491eb6629680d1edd73f4140fd386bcf/lxml-6.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:8dadbe5b217ff35b6a8d16610dd710219b59b76d13f0e3f0d9f36786206e4485", size = 3667717, upload-time = "2026-05-19T19:22:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/62/b0/83f481780d1548750b8ce2ec824073deef2f452d9cd1a6faff8507e3d16d/lxml-6.1.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:53b7d2b7a10b1c35c0a5e21e9224accf60c1bbfba523990732e521b2b73adef2", size = 8526461, upload-time = "2026-05-18T19:17:25.862Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d5/30fa0f808002c7329397bfbb24e306789c0b29f04aa5842c07b174b4216f/lxml-6.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ff3f333630ab480244a1bff72043e511a91eb22e7595dead8653ee5612dd8f3d", size = 4595375, upload-time = "2026-05-18T19:17:34.555Z" }, + { url = "https://files.pythonhosted.org/packages/4f/d2/edb71cf0e561581a7c5eb2626244320eb04e9f8ce6d563184fd668b45073/lxml-6.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a4bbea04c97f6d78a48e3fbc1cb9116d2780b1b39e03a23f6eb9b603fd61f510", size = 4923654, upload-time = "2026-05-18T19:17:42.917Z" }, + { url = "https://files.pythonhosted.org/packages/4c/77/1bc7eeb0de4577d783fb625aa092cc9357883bba35845a3666bf1259f3dc/lxml-6.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:db1d75f6617a49c1c01bc7023713e0ff59ab32c9579ae62a7674c0e34f3b0b0a", size = 5067921, upload-time = "2026-05-18T19:17:49.175Z" }, + { url = "https://files.pythonhosted.org/packages/1b/3c/c0690d74bd2bc17bc03b5b0d093569ead597dd0bfa088bf99eef8c24e19c/lxml-6.1.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a12689be69a28ddaa0ab99a5a1137da2afd5f8f16df7b5680b66f616d3eda1d", size = 5002456, upload-time = "2026-05-18T19:17:59.715Z" }, + { url = "https://files.pythonhosted.org/packages/66/8d/d1b3271af0c0f1e27e8472a849e4d2c65bc7766884b9ad2da9e76e145c88/lxml-6.1.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b73c339ae29b90fd2d06e58ebd555a751bde9cd6bbd36cc0281b9a2c94e9d8", size = 5202776, upload-time = "2026-05-18T19:18:08.924Z" }, + { url = "https://files.pythonhosted.org/packages/7a/45/689824ffb237fd10125ad273f32b28ff04dc6203c2822c85ff65a93df65e/lxml-6.1.1-cp311-cp311-manylinux_2_28_i686.whl", hash = "sha256:752d3bbfe874715ccd0aec7f88d7fc623c0f1fd7aa7b3238a084e017bad2a009", size = 5329945, upload-time = "2026-05-18T19:18:13.673Z" }, + { url = "https://files.pythonhosted.org/packages/5d/c0/ef73af53767e958fd87d437c170f272e2f6e6c0f854939f133a895f1e711/lxml-6.1.1-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:6b1761fbf9ec984e2e9d9c589ef5f5fd684b7c19f92aadd567a26c5224958db6", size = 4659237, upload-time = "2026-05-18T19:18:18.657Z" }, + { url = "https://files.pythonhosted.org/packages/a0/5e/e1158e40397585e91cb0472374a1f63d0926a1ddeaa92f13d1a1ffe306d5/lxml-6.1.1-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d680fbcb768404c601ecb43519ecd8461f6954cb11c06a78962f666832ccfca8", size = 5265904, upload-time = "2026-05-18T19:18:24.883Z" }, + { url = "https://files.pythonhosted.org/packages/a0/16/8687e5d1400ed1c0bc41dace232ebb7553952b618ea1f2e5fb6e2cfbbe23/lxml-6.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:162af1091cd785f2f27e62d3547ae9bc58ec5c86dd314d67021fd02463708d83", size = 5045225, upload-time = "2026-05-18T19:17:20.073Z" }, + { url = "https://files.pythonhosted.org/packages/ca/18/d877bd1ae2e5ffdfd4836565aba350db31feb2f2656d6ce70316ed66a05e/lxml-6.1.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e9308ff8241c532df3f3e570f9a5aeed6c853f888512ba4b75638d7c11c95ef6", size = 4712721, upload-time = "2026-05-18T19:17:40.512Z" }, + { url = "https://files.pythonhosted.org/packages/44/4d/1f44fd1d770b10dacbf6b5c6e520f4d6e0708744930f719dc04e67cab981/lxml-6.1.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5f6994074ebae6ffb04447268e37dc16edc304f9859cf91acb86e0af6c1b395c", size = 5252549, upload-time = "2026-05-18T19:17:51.236Z" }, + { url = "https://files.pythonhosted.org/packages/64/5d/1d66b84f850089254c230ef6ea6b267a5a54e2e179a5d960036a05d501d7/lxml-6.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80c2dfadb855da477cf73373ad29a333535dedb9b12bad02c9814c8e2b43bf08", size = 5226877, upload-time = "2026-05-18T19:18:00.875Z" }, + { url = "https://files.pythonhosted.org/packages/ad/00/84c4b5302d42a2d0184f38d538c8a197f33b52a50bd4f7bcfe990bce3036/lxml-6.1.1-cp311-cp311-win32.whl", hash = "sha256:30a89d3ac8faec007453fb541f3f46807eeec88edd5826f6e3fe001752a2c621", size = 3594072, upload-time = "2026-05-18T19:17:12.714Z" }, + { url = "https://files.pythonhosted.org/packages/61/9d/2e2f7d876349f45e0f3e29f72da311668853d59b58d473a2dea4f0160135/lxml-6.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:abbefa31eee84842140f67acef1c828e28bba8bbf0c3bc6e5492a9af88152c28", size = 4025469, upload-time = "2026-05-18T19:17:50.566Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d5/570e6390e4110331e6208b2ba83d1482cc9146808ee118b22824a34c1070/lxml-6.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:dcb292aa7fe485ceff7af4f92e46c5af397daec5dff64871a528f0fc47a3cc5b", size = 3667640, upload-time = "2026-05-19T19:22:48.293Z" }, + { url = "https://files.pythonhosted.org/packages/6a/6e/c4add832b6fc1e887125b96f880d7b9b70aae5248718e046b1704bcac4b9/lxml-6.1.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:104c09bda8d2a562824c0e319d0768ce26a779b7601e0931d33b09b53c392ef7", size = 8570821, upload-time = "2026-05-18T19:17:42.068Z" }, + { url = "https://files.pythonhosted.org/packages/22/00/ff3009c88e65de8011630acf8ab5a09cb2becd2aaf47fba2f3449f6224e9/lxml-6.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:25c6997a9a534e016695a0ba06b2f07945de682731ff01065b6d5a4474179da1", size = 4624252, upload-time = "2026-05-18T19:17:47.897Z" }, + { url = "https://files.pythonhosted.org/packages/42/95/bb63f0fd62e554fe078e1fb3c8fe9083c14ddc7ad7fa178d10e57e071ac7/lxml-6.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c921ba5c51e4e9f63b8b00267d06566e1f63407408a0496da2d1d0bfc819c7fc", size = 4930746, upload-time = "2026-05-18T19:18:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/eb/99/0013e8d9b5960f4f041cf0b73e2f80c23eb5205b1f7bfb20203243651359/lxml-6.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:54a7f95e4de5fb94e2f9f4b9055c6ba33bf3d628fd77a1d647c5923caa2cdcdc", size = 5093723, upload-time = "2026-05-18T19:18:34.168Z" }, + { url = "https://files.pythonhosted.org/packages/29/91/317b332636bfc7bddcff828d41b3307f50043f4b237e40849c333d80fa1a/lxml-6.1.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f2ec43df44b1f76249ee0a615334f9b5b060e1c8bd90e706dad2d14d02f383", size = 5005557, upload-time = "2026-05-18T19:18:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/42/2f/cc9bf06afe70f9c9093ae60855d9759da9db601ec4080f7473319666ffd7/lxml-6.1.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:70ef8a7e102a1508f8121aae5b0867abd663f72c14f0a9c937e6554cb4587b7b", size = 5631036, upload-time = "2026-05-18T19:18:44.858Z" }, + { url = "https://files.pythonhosted.org/packages/08/f6/af32e23e563971ffb0fb86be52bc5be5c2c118858ffc119bf6a9039b173d/lxml-6.1.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ebe6af670449830d6d9b752c256a983291c766a1365ba5d5460048f9e33a7818", size = 5240367, upload-time = "2026-05-18T19:18:49.217Z" }, + { url = "https://files.pythonhosted.org/packages/78/83/8555d40948b09ce86f1bd0c68a7ac31d07b1929f92cc1b074006c97ef2d2/lxml-6.1.1-cp312-cp312-manylinux_2_28_i686.whl", hash = "sha256:27acc820660aaffa4f7c087f29120e12980f7779d56d8492d263170111284740", size = 5350171, upload-time = "2026-05-18T19:18:52.779Z" }, + { url = "https://files.pythonhosted.org/packages/63/75/5d92da93729b7bad783689e6496049fa40927b45bec7bf183c981de3ca70/lxml-6.1.1-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:1db753c9115ec7100d073b744d17e25e88a8f90f5c39b2f5dd878149af59671f", size = 4694874, upload-time = "2026-05-18T19:18:55.139Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b5/3aad415a9a25b822e783f15deeb4dffccf5113030f1afa2222dd929313d9/lxml-6.1.1-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4f469aebd783bb741c2ecb2a681008fd26bfe5c16a9a72ed5467f834e810df2", size = 5244492, upload-time = "2026-05-18T19:19:01.28Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a1/5fcf7eb9904b80086aa47dcf0027de07b1bb990afad2e6823144c368ae04/lxml-6.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:766b010012d59470072c1816b5b6c69f1d243e5db36ea5968e94accf430a4635", size = 5048232, upload-time = "2026-05-18T19:18:12.67Z" }, + { url = "https://files.pythonhosted.org/packages/77/74/1f601b63c7a69fcdf10fa9b148c81da8442204194f6c55509cc485c786b9/lxml-6.1.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b8d812c6011c08b8111a15e54dd990b8923692d80adf35488bee34026c35accf", size = 4777023, upload-time = "2026-05-18T19:18:15.928Z" }, + { url = "https://files.pythonhosted.org/packages/a2/b9/7a78f51aec95b1bf780d78e12705a9f6533284f8693dc5c0e6724fa53d3f/lxml-6.1.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fe0306bd29505a9177aac19f1877174b0e7422c222a59f70b2cd41633448c3dc", size = 5645773, upload-time = "2026-05-18T19:18:23.223Z" }, + { url = "https://files.pythonhosted.org/packages/a5/6e/98a7b7ad54e4e74fa1f20fff776913980619d0ebe5558232d7da6580bdd8/lxml-6.1.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5ba186ad207446c65d3bb3d3e0412b032b1d9f595e59861e2354798c5703d955", size = 5233088, upload-time = "2026-05-18T19:18:31.433Z" }, + { url = "https://files.pythonhosted.org/packages/65/d1/bc0ed2427bf609f2ee10da303a6a226f9c8bce94f945dc29a32ce55de6e4/lxml-6.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa366a1e55b8ebfe8ca8ddc3cfe75c8ebade181aeb0f661d0cb05986b647f72a", size = 5260995, upload-time = "2026-05-18T19:18:37.091Z" }, + { url = "https://files.pythonhosted.org/packages/69/8b/6772e1a4b513fc50a8d931f19edde0e13ae6918510a1e13ff67864f3e5ed/lxml-6.1.1-cp312-cp312-win32.whl", hash = "sha256:126c93f7f56f0eda92f6d8c619edc463a4f23d9252f1c9d0405a76f25fa9f11a", size = 3596382, upload-time = "2026-05-18T19:17:18.37Z" }, + { url = "https://files.pythonhosted.org/packages/1b/89/45198e9624762af2dfd2cb8782598477ceb29f6e59caab560388ae1f4ec1/lxml-6.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:26e6eda8d38c1fcab1090dd196ee87cbd13788e531937610e2589085de074e77", size = 3997255, upload-time = "2026-05-18T19:17:56.781Z" }, + { url = "https://files.pythonhosted.org/packages/90/a9/7a54b6834088d9ae528a7b780584ba6a39a9457b0ac330479f20ffbc9449/lxml-6.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:6540377fbd53fe1b629172288c464fb18db11ce1fa7dc15891da10aa9dcc3e7f", size = 3659610, upload-time = "2026-05-19T19:22:50.843Z" }, + { url = "https://files.pythonhosted.org/packages/a5/eb/7e6f37c5584ccbb2ff267f56fd0339016938c1c8684cfefab9b33ffc2f36/lxml-6.1.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:68a9198d0fc122d14bb76837de9aa80cf84caed990b5b237f532ed87d3706736", size = 8559780, upload-time = "2026-05-18T19:17:57.661Z" }, + { url = "https://files.pythonhosted.org/packages/a1/36/587c2521cf23a2cd6c9c22108aa7528f683a1f195ed7ccd23a4b1786ad36/lxml-6.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7d47866cb32fb503450b6edc9df355d10dc49836af2e89901bd6ac6b0896d9d9", size = 4618006, upload-time = "2026-05-18T19:18:04.452Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ca/ab7bfe2bf4c972af5e7878262845ead3a24a929a9b04bc11c7c1ece6c82a/lxml-6.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb7c9811bfaa8b1ed5ed319f5d370dfbcaa59d52ea64be2a5a85e18195930354", size = 4924139, upload-time = "2026-05-18T19:19:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/6b/55/a0c72851dfee5ecc689f949723a73dea457758912542cb955b108eaf0d8f/lxml-6.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:762ff394d5bd56da0cf034a23dcce4e13923f15321a2adfa2ac00201dc6d3fca", size = 5082329, upload-time = "2026-05-18T19:19:09.728Z" }, + { url = "https://files.pythonhosted.org/packages/f0/b6/0608f7d61a3b96cc67e5648a3d906e31a5082093e10e7be65b3886289938/lxml-6.1.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a088f287f7d8275a33c07f2cac6c50b9319309a0200a39e7e75d80c707723099", size = 4993564, upload-time = "2026-05-18T19:19:13.608Z" }, + { url = "https://files.pythonhosted.org/packages/4c/66/ae227524b066d29d55bf0b453d93d2d793c40218657d643dcbbca13b8faf/lxml-6.1.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e902da4b04e6b52e5893900d4b8ab46068f75f3561f01bf1080957f9fd932ed6", size = 5613467, upload-time = "2026-05-18T19:19:16.228Z" }, + { url = "https://files.pythonhosted.org/packages/a6/76/dbe4a00b50385e40194231dcfe5a12c059de7cf90e89c83407d2b085b719/lxml-6.1.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d4962d4c66bf830a7e59ed6cfc17d148149898a3aefa8ec6e59763e6e3ed085", size = 5228304, upload-time = "2026-05-18T19:19:19.354Z" }, + { url = "https://files.pythonhosted.org/packages/1c/01/00b1b8442ed2041793336868ba0b9ea4b13d7da7c085c6404c207a63bf79/lxml-6.1.1-cp313-cp313-manylinux_2_28_i686.whl", hash = "sha256:581d4c8ae690a6609e64862dd6b7c2489635c2d13907fc2b20f2bc200ff1d21e", size = 5341607, upload-time = "2026-05-18T19:19:22.297Z" }, + { url = "https://files.pythonhosted.org/packages/63/36/1ad29931e9a4638bb707869f01d423a6c815f82152138d1a40dfcfde2b95/lxml-6.1.1-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:876e1ff5930ed8bf295ec5ef9a8155e9b6b1876bbf1deed8b3a8069311875a8f", size = 4700168, upload-time = "2026-05-18T19:19:25.133Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d1/a9536cecf9be18a0dc72d32bead283a2332d1ffebd2dd3ac70ce444686e5/lxml-6.1.1-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9eb9b5a968f6e0f6d640092a567e14529ff8cea2e29d00da6f78a79fa49f013c", size = 5232487, upload-time = "2026-05-18T19:19:28.603Z" }, + { url = "https://files.pythonhosted.org/packages/0e/77/b4fb1e03bf5d130e879214d3100092e386418807fb74dd0adc4b0a48f351/lxml-6.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:aa49e06d94aba782c6a02eecb7e507969e7e7a41b267f1b359bb35585f295d5b", size = 5044231, upload-time = "2026-05-18T19:18:42.246Z" }, + { url = "https://files.pythonhosted.org/packages/26/4c/d00daeeb0a5530c4028a9232aa1b93db3ef4ed2158c116ea73c79a9765b3/lxml-6.1.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:70cdfd80589d59e43e18005dd7244e8895e93db8ab6a620b7e23df5445a4e3d2", size = 4769450, upload-time = "2026-05-18T19:18:48.013Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6a/715a3a8d156ce42f29cf014706f5410c2ff3b02267774110fc23266409fe/lxml-6.1.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:aad9aa39483ed8ec44d6d2e59e5b98a0d80676ef0d92f44bfc374836111f62f5", size = 5635874, upload-time = "2026-05-18T19:18:51.914Z" }, + { url = "https://files.pythonhosted.org/packages/45/37/0544bc21dde2a88f3a17b504e6fc79c0e01d25a33c2f6079724e9e72b9c7/lxml-6.1.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d49514be2f28d895c38cf9d2b72d7b9a07d00314519f456c0b50b53cfcf4c785", size = 5223987, upload-time = "2026-05-18T19:18:59.715Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f8/f6a5e8185bcb28c2befae3d31f8e3df3b811cb0f47746517a81279fcafe1/lxml-6.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:47402e62c52ff5988c1e8c6c63177f5708bccf48e366dea4e3dcf1e645e04947", size = 5250276, upload-time = "2026-05-18T19:19:03.834Z" }, + { url = "https://files.pythonhosted.org/packages/c7/f2/1a2b9f1b7a49d45495369be7ef9ad05b262930f2eab3e3145706fca8083f/lxml-6.1.1-cp313-cp313-win32.whl", hash = "sha256:3483644525531e1d5762b0c44a8e18b6efba321b6dcf8a8952de10b037618bca", size = 3596903, upload-time = "2026-05-18T19:17:29.863Z" }, + { url = "https://files.pythonhosted.org/packages/e6/99/f4ffb024f238eec2131aaa09f3278fb6129cf892741bf68e1fc1afb8c100/lxml-6.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:a10bd2fd62e8ce916ececb342f348f190724a098c1faa056fdfb2a22ad5e8660", size = 3995869, upload-time = "2026-05-18T19:18:02.596Z" }, + { url = "https://files.pythonhosted.org/packages/d1/53/70eb8c5c6037f27448f1e3c54ebede9545a801ae63f0a7254afca4fe8e45/lxml-6.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:424aa57aca0897eb922aef34395bd1289b3b6f04e6bae20ea123c0c7e333cffc", size = 3658490, upload-time = "2026-05-19T19:22:53.846Z" }, + { url = "https://files.pythonhosted.org/packages/13/e2/2e325795566de01d0d7c3bb57d3c370616b2d07b01214e84eec5d3b10963/lxml-6.1.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:19b7ab10b210b0b3ad7985d9ac4eb66ab09a90b20fe6e2f7ba55d01a234345d0", size = 8577146, upload-time = "2026-05-18T19:18:17.765Z" }, + { url = "https://files.pythonhosted.org/packages/93/cf/5630b5e4be7d2e6bee8efe83865c925221103cf0221303b104ce134b01e2/lxml-6.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c08e5c694306507275f2290073350c4f32e383db15213b2c69e7ff39c1193840", size = 4623866, upload-time = "2026-05-18T19:18:30.669Z" }, + { url = "https://files.pythonhosted.org/packages/d2/51/3904907c063451cf8d4a5c9fe0cad95fa1f4ec57f4e3884fa0731bd7a305/lxml-6.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:74a9717fd0d82effef5c2854f0d917231d5324b5a3eb7275c43ac9fa32f97a14", size = 4950022, upload-time = "2026-05-18T19:19:31.958Z" }, + { url = "https://files.pythonhosted.org/packages/94/cd/9c7611a51c37a2830928405817cc5d56a97f64fab83cc3f628748b135749/lxml-6.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efe0374196335f93b53269acd811b944f2e6bdc88e8894f214bd636455484909", size = 5086695, upload-time = "2026-05-18T19:19:34.764Z" }, + { url = "https://files.pythonhosted.org/packages/da/d6/24e3b5906abb0b674ff2ae195bc3ce59708df2bcd17cf17703b2d7dd643a/lxml-6.1.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac931cdc9442c1763b8a8f6cd62c0c938737eafc5be75eff88df55fc73bc0d00", size = 5031642, upload-time = "2026-05-18T19:19:37.771Z" }, + { url = "https://files.pythonhosted.org/packages/2d/db/6ec54f99019838bff54785c51da07f189eb4676861c5f2730962b0d8d665/lxml-6.1.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:aee395f5d0927f947758b4ec119fd5fc8ec71f07a1c5c52077b30b04c0fa6955", size = 5647338, upload-time = "2026-05-18T19:19:40.553Z" }, + { url = "https://files.pythonhosted.org/packages/42/3d/ef4dcfffd22d27a61805d8ed9f7fb888495bc6aa88648fa07c1eaa5586b6/lxml-6.1.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9395002973c827b3ed67db77e6ec09f092919a587022174554096a269378fb13", size = 5239528, upload-time = "2026-05-18T19:19:43.657Z" }, + { url = "https://files.pythonhosted.org/packages/62/bb/37fb3f0dff146bdcfa78eec47879273820b2a0bf350ec236ce14bd0b1c26/lxml-6.1.1-cp314-cp314-manylinux_2_28_i686.whl", hash = "sha256:73bc2086f141224ebddb7fc5c6a36ca58b31b94b561e1dfe8e073e3270fad1e7", size = 5350730, upload-time = "2026-05-18T19:19:46.307Z" }, + { url = "https://files.pythonhosted.org/packages/90/42/43253f168388df4fae1f38c01df36ddb9bee39e2048167b54cdcbae85ea3/lxml-6.1.1-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:3779def59032b81e44a5f70096ef6bf2082f8d901937dca354474ba09782e245", size = 4697530, upload-time = "2026-05-18T19:19:49.889Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a8/c5a8504f81bbdfc8e7094c2c850cdb4ed6777fc4d5ddd9e5ab819f3b0d54/lxml-6.1.1-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:86c89b9d55ebf820ad7c90bc533410f0d098054f293351f10603c0c46ff598f5", size = 5250670, upload-time = "2026-05-18T19:19:53.199Z" }, + { url = "https://files.pythonhosted.org/packages/77/b7/c7e76ab18744d75e21f320ebf9ff9d1ceae2b54dd431ea5a64caf26c9672/lxml-6.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19607c6bbff2a44cf3fe8250abccd20942d3462473e0a721d01d379ed017e462", size = 5084485, upload-time = "2026-05-18T19:19:08.422Z" }, + { url = "https://files.pythonhosted.org/packages/31/31/b35c53f8ef7b7c31cacd23d3638652fff7bcd1deb6eedb709ab43b685908/lxml-6.1.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:c6ed5141a5c7507cf3ee76bd363b0d6f801e3321adc35b5d825a23115faa5465", size = 4737635, upload-time = "2026-05-18T19:19:12.321Z" }, + { url = "https://files.pythonhosted.org/packages/d9/06/31f23c813a7fe8e0cb1b175e915b08c9bf4e86d225b210feadbdbe519667/lxml-6.1.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:62aeb7e85b5d60320b9d77eef2e773994e2c0ce10121b277e0a19804e1654a5a", size = 5670681, upload-time = "2026-05-18T19:19:15.001Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bc/ce619bccc89b1fd9ad8a8e1330ee3f3beff9f2ff95b712d7bbcdd6e22fc3/lxml-6.1.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b1b963fd8f5caa68e99dfae060d54de1fe9cba899b8718b44a00cdca53c3e590", size = 5238229, upload-time = "2026-05-18T19:19:18.131Z" }, + { url = "https://files.pythonhosted.org/packages/2f/5d/b329acbbedc0b619ebc2be6cf7ee9ed07e80892c88d4dfd612c33805789a/lxml-6.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63876be28efefa04a1df615b46770e82042cce445cfdce55160522f57b231ccb", size = 5264191, upload-time = "2026-05-18T19:19:21.118Z" }, + { url = "https://files.pythonhosted.org/packages/d6/85/be36fb1425b30db3c3f9df75fe86343ebffb79e6320bd7f588e25bfeac39/lxml-6.1.1-cp314-cp314-win32.whl", hash = "sha256:7f7a92e8583f06b1fd49d01158143b8461cfcd135dcb10ec807270a3051bd603", size = 3657202, upload-time = "2026-05-18T19:17:39.509Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ce/3cf9a827342269f54d405a6202397de63f07c69cbd6ce7d183a3f0cba1e9/lxml-6.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:b2d444f2e66624d68e9c6b211e28a76e22fff5fcabcfff4deac18b529b7d4137", size = 4064497, upload-time = "2026-05-18T19:18:14.662Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3e/1a957bde8f0760039e627f94699f82caa782c9d838d86c3d28245ee67212/lxml-6.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:3fd9728a2735fda14f4e8235830c86b539e9661e849665bf926d3f867943b4bf", size = 3741991, upload-time = "2026-05-19T19:22:59.111Z" }, + { url = "https://files.pythonhosted.org/packages/78/b2/00ed55b3a2efa4658fb795c38d1090ec9b3e8a6c3683d4441fa517f09c3b/lxml-6.1.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:787b2496d0dbe8cd180984e8d29e3a6f76e7ea34db781cb3bd55e4ba1ef8b4ee", size = 8827545, upload-time = "2026-05-18T19:18:41.193Z" }, + { url = "https://files.pythonhosted.org/packages/c0/73/74573db19baa618d5f266f2407898b087ff6927115b00b71e5fc1b700847/lxml-6.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2c8daa471358dc2d6fcf02165e80ec68f77871a286df95bc5cc3816153b0fd2c", size = 4735736, upload-time = "2026-05-18T19:18:46.761Z" }, + { url = "https://files.pythonhosted.org/packages/16/02/6f7061f4f95f51e545d48e87647c54791d204a4e881be4156e7a26ba5338/lxml-6.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:acd7d70b64c0aae0c7922cca83d288a16f5f6da523637697872253415269baef", size = 4970291, upload-time = "2026-05-18T19:19:56.215Z" }, + { url = "https://files.pythonhosted.org/packages/b0/02/55fc057d8283427dea7d6edb102e7a840239c77a64a983d92f62a304c0e9/lxml-6.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4f0dd2f01f9f8a89f565d000e03abcf0a13d692a346c8d22f628d49af098777a", size = 5102822, upload-time = "2026-05-18T19:19:59.223Z" }, + { url = "https://files.pythonhosted.org/packages/e4/48/8e1cf78d89d66850121d9255a2a24414c98f775da93b90cf976956c24b14/lxml-6.1.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b7e8a14c8634bf6f7a568634cb395305a6d964aeb5b7ee32248094bed3a7e2c", size = 5027923, upload-time = "2026-05-18T19:20:01.549Z" }, + { url = "https://files.pythonhosted.org/packages/ed/00/0632a0647612c8af24d26997b3b961397daa9d5b2581444805933629a4cb/lxml-6.1.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:86281fbdd6a8162756f8d603f37e3435bfa38043adb79c6dc6a2dfee065e7525", size = 5595843, upload-time = "2026-05-18T19:20:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/bc/86/ab008a7dc360711b66858d61c80a5979a70a09f2aa2b05d9698df80b803d/lxml-6.1.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5d7152ec39ca7c402d8fb9bad86140a15b9503bd0c54484e3f1bbe3dd37ceca", size = 5224515, upload-time = "2026-05-18T19:20:06.381Z" }, + { url = "https://files.pythonhosted.org/packages/75/c6/2702ff375e728e34f56d9a45339a9cf7e4427e917f542225242d63a05afa/lxml-6.1.1-cp314-cp314t-manylinux_2_28_i686.whl", hash = "sha256:88d8cb75b9d82858497a5393e3c63cfbf03035225e4b35a49ed7ccb151e4dc0e", size = 5312511, upload-time = "2026-05-18T19:20:09.308Z" }, + { url = "https://files.pythonhosted.org/packages/b7/57/a5807c98f87a86f10ef9ffab35516df7c0f0c4b6d5d33e9f608ab9c04a31/lxml-6.1.1-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f64ec5397ea6a41fc1b4af0380d79b44a755b5531dcaccd9940fb260dca93038", size = 4639206, upload-time = "2026-05-18T19:20:11.704Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e1/8a0a2c35734812395f4da4eaf33748a7e5705bfb2a58b128da764339d5ec/lxml-6.1.1-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d34bbf07dbc7ca5970671b1512e928991fb5e9d95365636c9b2d8b4f53af405e", size = 5232404, upload-time = "2026-05-18T19:20:14.064Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e2/0e6a4dd5ad84d01d99aa7bae7cfefd4a760a0e0f8176818241de17d9b6c0/lxml-6.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:17e0e18d4ad8adbd0399291bc44845b69d9dd68439a3cdebdf35ff902ec05072", size = 5083769, upload-time = "2026-05-18T19:19:23.758Z" }, + { url = "https://files.pythonhosted.org/packages/a0/7e/161f33d463f6ffc1c7679104b65086dea120080d49dde4d238f015aaee2f/lxml-6.1.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:3ab541146f1f6968c462d6c2ac495148e8cdba2f8347700b2141b6ec5a75bf52", size = 4758936, upload-time = "2026-05-18T19:19:27.256Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fb/2369825e3f6ca99305bf9f7b7085fda91c8b0922a89e54d900974aa3ef85/lxml-6.1.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2a0217714657e023ef4293500f65aa20fce6164c8fd6b08fa5bd4a859fb14b9b", size = 5620296, upload-time = "2026-05-18T19:19:29.993Z" }, + { url = "https://files.pythonhosted.org/packages/30/90/d61e383146f74c5ab683947ea14dc7b82778838ab9b95ea73a23b60d0191/lxml-6.1.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:05a82eb6e1530a64f26225b55cbd178113bd0b5af1c2b625f25e5296742c26d2", size = 5228598, upload-time = "2026-05-18T19:19:33.523Z" }, + { url = "https://files.pythonhosted.org/packages/76/2d/2dafd8149e94b05bb070690efd5bb2680720681e03ff03fc57d2b70a1105/lxml-6.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9e36f163528fc50cbef305f02a5fd66d404edf7049cdaff211dbc2cba5a7013e", size = 5247845, upload-time = "2026-05-18T19:19:36.649Z" }, + { url = "https://files.pythonhosted.org/packages/ce/68/b30e913340c380ddac9580c6e6230991fc37240ec4f64704833e4f3e2769/lxml-6.1.1-cp314-cp314t-win32.whl", hash = "sha256:649dda677cf3bd6ac9ae14007ba0c824ded8ce5808b53fc7431d9140399118c1", size = 3897345, upload-time = "2026-05-18T19:17:33.562Z" }, + { url = "https://files.pythonhosted.org/packages/3c/4e/9eb2af5335545f9fbcd7af57bcf87c6025d31eaa31b14ec184a6c8675328/lxml-6.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:793033d6c5cdf33a573f910d9bea14ef8f5771820411d118da8e1182edb53d5e", size = 4393350, upload-time = "2026-05-18T19:18:10.076Z" }, + { url = "https://files.pythonhosted.org/packages/7f/2c/0f1e93c636720e8a3eb59af2bfda99d98b55891e1c53bc30c2e0e865f01b/lxml-6.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:58bb955caba94e467d2a96da17660d2d704e0675894cba21ab8a775b8621fd1c", size = 3817223, upload-time = "2026-05-19T19:22:56.823Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b5/0a0f61cc8c6aa61f439d276e62e70cbf4f32205f57b1fbd483b8d0cf514b/lxml-6.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9f79d5325907f13e1be0b3e4dacc1049d1dffc4aeee3c995284bea5fe0fab7d", size = 8553821, upload-time = "2026-05-18T19:18:54.406Z" }, + { url = "https://files.pythonhosted.org/packages/f6/dc/66603d8f755d26f39c41cf29ed30e4a3bc93973d72a825cd12be91c5bd7b/lxml-6.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:83b6b30eb131da7a75b601f28c5d6971e6ed3e887919bf6b6a1ad3c2df289080", size = 4607623, upload-time = "2026-05-18T19:18:58.556Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ad/5ea70128e6b0d34a52d16e2386666f8f9529c17cfac46d5980fd22c35daa/lxml-6.1.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:441dd227fa0690eb9fc81edabc63cdcefc212bba99b906dcf6e32cc1a9d3e533", size = 5005993, upload-time = "2026-05-18T19:20:24.125Z" }, + { url = "https://files.pythonhosted.org/packages/85/c2/13a33e8659f95d59f28a293f31c31d61d858a1bd4294b82a662cfbae126b/lxml-6.1.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e07c65f443c887bbcf31cc1771d932ecc192a5273943589b3c7572b749f1ffb2", size = 5160240, upload-time = "2026-05-18T19:20:26.549Z" }, + { url = "https://files.pythonhosted.org/packages/65/06/e850042d7b33cf47d2f1bc4accb31ab34478f56f46c376b7a67c6b1a84c5/lxml-6.1.1-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5bec7d03d78d853597d6107854c2310ce3f761fd218fe9fe91d5101fcf6c2efe", size = 5062940, upload-time = "2026-05-18T19:20:29.027Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5a/8d7a0b3e42b21a553f01e288e70283f4de37c015c9c2477a0c31dafa0408/lxml-6.1.1-cp39-cp39-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f76acfb5f68ba982635a53fd985a8044be98a35b43232c2a1ee235ffab3e1dd", size = 5292921, upload-time = "2026-05-18T19:20:31.463Z" }, + { url = "https://files.pythonhosted.org/packages/03/7c/9238d52bc426c8737b427ce57ea48c8a5a91974c5dcc55a34260dd851763/lxml-6.1.1-cp39-cp39-manylinux_2_28_i686.whl", hash = "sha256:8d43ca737b20e106e4aebc42b2f3ae19f00ba63d7eb731698ee083d72d15646f", size = 5416716, upload-time = "2026-05-18T19:20:34.059Z" }, + { url = "https://files.pythonhosted.org/packages/6e/06/be127e1f36410d8ec84964adf76694b72f7705593c16c838dc8b1061b0b8/lxml-6.1.1-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:32ab449a5486f6c758e849bb86710d0e45edc24a04e250c01555f8f5653958f8", size = 4773279, upload-time = "2026-05-18T19:20:36.555Z" }, + { url = "https://files.pythonhosted.org/packages/77/42/5e3ca677b4d56ae189a454764d28d922d343750419548409974d913a9b65/lxml-6.1.1-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53c909b62a0532183542fed00c5a7218258c56292d409bc789886fe1cb04c438", size = 5361618, upload-time = "2026-05-18T19:20:39.044Z" }, + { url = "https://files.pythonhosted.org/packages/cd/20/816979635625f8b8f88b69b5f7d9a4ebdc3c0bab1bf70c824e4ffe239879/lxml-6.1.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:640f97d43d867bcb9c75b3af013b64850756b746cb6bce8ace83b70da3abba9d", size = 5111217, upload-time = "2026-05-18T19:19:42.123Z" }, + { url = "https://files.pythonhosted.org/packages/25/86/a6ec97064d25959d4932f2e91b547ce6b8380daa27de08b103c7b50be323/lxml-6.1.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:469e3618338bd7ab5beb412d2439825479fcf0dab99e394ca563dbc4eaf6c834", size = 4808149, upload-time = "2026-05-18T19:19:45.317Z" }, + { url = "https://files.pythonhosted.org/packages/ac/85/dc6087d1ba06589202ee25cda29abb175443da2da70c9e6bcf92091ad272/lxml-6.1.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:aae97dfdb60715c164419ac2532a76d013c3918a665eb6cb7288098b5f349aaf", size = 5352761, upload-time = "2026-05-18T19:19:48.608Z" }, + { url = "https://files.pythonhosted.org/packages/69/93/e89fcb55d12b8e1473ce9a62b8f6ee215c89532f7a75a7ce55830834373b/lxml-6.1.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c9a4b821dc7055bf9e05ff5719e18ec501f75c0f0bbfabd573b277559780833d", size = 5315355, upload-time = "2026-05-18T19:19:51.077Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c1/4f07e22d26e2e1ad741666f768df2d3b18ff1ddab3a99e2cb35d5b5df3a3/lxml-6.1.1-cp39-cp39-win32.whl", hash = "sha256:639f6c857d91d9be29bd7502348d6736dab168b54b5158cd899abf11684dc186", size = 3601121, upload-time = "2026-05-18T19:17:58.57Z" }, + { url = "https://files.pythonhosted.org/packages/1e/49/4bcb779b303876f1750eb37f534230ef4e7221341826cbd5e42388087393/lxml-6.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:34c2d737beabfe35baada43941ed519251e9a12e779031496bcd5d539fcfd730", size = 4024637, upload-time = "2026-05-18T19:18:32.806Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e6/0d1b437d0783874ff15fb94be03045bce6dcefbce1ea22e44a2dbd59a902/lxml-6.1.1-cp39-cp39-win_arm64.whl", hash = "sha256:07a4a68e286ee7a1ed7dfb8af83e615757c0ccfe9f18c6b4ea6771388d9ba8c9", size = 3670865, upload-time = "2026-05-19T19:23:01.555Z" }, + { url = "https://files.pythonhosted.org/packages/b5/32/86a3f0f724a3a402d4627937a7fc27b160e45e7012b4adf47f6e1e844511/lxml-6.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:31033dc34636ea6b7d5cc11b1ddbda78a14de858ba9d3e1ed4b69a3085bc521e", size = 3930127, upload-time = "2026-05-18T19:19:02.27Z" }, + { url = "https://files.pythonhosted.org/packages/40/44/d832e82af08723761556d004b1d04d281c09f9a8cecd7d3148548c9941a3/lxml-6.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3893c14c4b6ac5b2d54ba8cf03e99fe5104e592de491f19bd6b82756c09f8004", size = 4210769, upload-time = "2026-05-18T19:20:41.427Z" }, + { url = "https://files.pythonhosted.org/packages/6d/39/0dc5949f759ed7d951e0bb8c2f2d9d7aca1908d22352fa84a8afd2ea54af/lxml-6.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c07da4cebf6889f03ebac8d238f62318e29f495de0aa18a51ea14e61ae907e2e", size = 4318163, upload-time = "2026-05-18T19:20:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/e6/fb/8ab3845fe046ba4cbf74536bcf6801a774b7caf4350de1c5d37f1f0a9e90/lxml-6.1.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f6f0ce10945fab9c4c06ce14e22af9059d1a87493a9af4501a5b0b9187e21cf2", size = 4250945, upload-time = "2026-05-18T19:20:47.385Z" }, + { url = "https://files.pythonhosted.org/packages/68/1b/7553ab136894374ffae8851ec06f98f511cd8e66246e41b6be059d0a7289/lxml-6.1.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f8844cd288697c6425c9beba919302241e3278871dc6519515e72b04e987abcf", size = 4401664, upload-time = "2026-05-18T19:20:50.489Z" }, + { url = "https://files.pythonhosted.org/packages/db/a4/441aee36c6f6b249823d20fd91f9be9ab89d7c5a8ae542a4a4ca6d342d56/lxml-6.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:ed21202aec73cda4d55d1ce57b389aadb90ffb044e6cd1080b8347efe1b1ec84", size = 3508989, upload-time = "2026-05-18T19:18:38.158Z" }, ] [[package]] @@ -2494,17 +2480,40 @@ wheels = [ name = "requests" version = "2.32.5" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, + { name = "certifi", marker = "python_full_version < '3.10'" }, + { name = "charset-normalizer", marker = "python_full_version < '3.10'" }, + { name = "idna", marker = "python_full_version < '3.10'" }, + { name = "urllib3", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] +[[package]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version == '3.10.*'", +] +dependencies = [ + { name = "certifi", marker = "python_full_version >= '3.10'" }, + { name = "charset-normalizer", marker = "python_full_version >= '3.10'" }, + { name = "idna", marker = "python_full_version >= '3.10'" }, + { name = "urllib3", marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + [[package]] name = "rpds-py" version = "0.27.1" @@ -2669,28 +2678,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" }, - { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" }, - { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" }, - { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" }, - { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" }, - { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" }, - { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" }, - { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" }, - { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" }, - { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" }, - { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" }, - { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" }, +version = "0.15.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, + { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, + { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, + { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, + { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, ] [[package]] @@ -2713,11 +2721,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8" +version = "2.8.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/2c/0a5f6f8ee0d5589e48c7640213ed5175d52cf540a06725b628cc1a45d6ce/soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e", size = 121110, upload-time = "2026-05-24T13:55:57.154Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, + { url = "https://files.pythonhosted.org/packages/5e/f5/0c41cb68dcae6b7de4fac4188a3a9589e21fb31df21ea3a2e888db95e6c9/soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65", size = 37304, upload-time = "2026-05-24T13:55:55.406Z" }, ] [[package]] @@ -2834,19 +2842,19 @@ wheels = [ [[package]] name = "tornado" -version = "6.5.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, - { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, - { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, - { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, - { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, - { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, - { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, - { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, - { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, +version = "6.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/dc/c7043cab6fed8ae159fc1923ce829ada35c4dbd797d408a43858ffaf9639/tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163", size = 448543, upload-time = "2026-06-08T17:34:38.052Z" }, + { url = "https://files.pythonhosted.org/packages/92/4f/090b1431e5a43df696feceffc268c5383cc079ecb5f08ce58f917109aafe/tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100", size = 446707, upload-time = "2026-06-08T17:34:39.594Z" }, + { url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" }, + { url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" }, + { url = "https://files.pythonhosted.org/packages/5c/42/5f0e56c01e8d9d36f4e23f367b85ae6cae0c1ecddd5e6977d8388ad27488/tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4", size = 451047, upload-time = "2026-06-08T17:34:46.784Z" }, + { url = "https://files.pythonhosted.org/packages/c9/a4/b393076ffb21b469eec5b328a0534cf03a3b90bfc6b1f09507cdd075d938/tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4", size = 451485, upload-time = "2026-06-08T17:34:48.248Z" }, + { url = "https://files.pythonhosted.org/packages/71/2e/7b1c769803121b809112cf9a00681c472eae1d80e32d7ec0e0bd61d0d0e1/tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796", size = 450506, upload-time = "2026-06-08T17:34:49.702Z" }, ] [[package]]