From d15afd4e11649183acc50d714cb7e756261c509d Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Fri, 22 Mar 2024 13:02:14 -0700 Subject: [PATCH 1/7] WIP: duckdb transforms --- notebooks/Tutorial-SQLCompiler.ipynb | 856 ++++++++++++++++++ poetry.lock | 80 +- pyproject.toml | 4 + src/linkml_transformer/compiler/compiler.py | 4 +- .../compiler/sql_compiler.py | 126 ++- .../datamodel/transformer_model.yaml | 3 + src/linkml_transformer/session.py | 56 +- .../transformer/duckdb_transformer.py | 37 + tests/test_compiler/test_duckdb_compiler.py | 42 + .../test_compliance/test_compliance_suite.py | 51 +- 10 files changed, 1224 insertions(+), 35 deletions(-) create mode 100644 notebooks/Tutorial-SQLCompiler.ipynb create mode 100644 src/linkml_transformer/transformer/duckdb_transformer.py create mode 100644 tests/test_compiler/test_duckdb_compiler.py diff --git a/notebooks/Tutorial-SQLCompiler.ipynb b/notebooks/Tutorial-SQLCompiler.ipynb new file mode 100644 index 0000000..dba5c4e --- /dev/null +++ b/notebooks/Tutorial-SQLCompiler.ipynb @@ -0,0 +1,856 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# LinkML-Transformer tutorial: Compiling to SQL\n", + "\n", + "This tutorial walks through use of the SQL compiler" + ], + "metadata": { + "collapsed": false + }, + "id": "df75d53a3e91e573" + }, + { + "cell_type": "code", + "execution_count": 3, + "outputs": [], + "source": [ + "import yaml" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:31:47.717372Z", + "start_time": "2024-03-22T15:31:47.713457Z" + } + }, + "id": "63a064b31f623bdd" + }, + { + "cell_type": "markdown", + "source": [ + "## Creating an example schema\n", + "\n", + "We will use a LinkML SchemaBuilder object to progressively build up a schema, adding\n", + "additional features as we go.\n", + "\n", + "We'll start with a simple `Person` schema, with a few single valued scalar slots:" + ], + "metadata": { + "collapsed": false + }, + "id": "e2cbd6b8994905f6" + }, + { + "cell_type": "code", + "execution_count": 4, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema\n", + "id: http://example.org/test-schema\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml: https://w3id.org/linkml/\n", + " test_schema: http://example.org/test-schema/\n", + "default_prefix: test_schema\n", + "default_range: string\n", + "slots:\n", + " family_name:\n", + " range: string\n", + " given_name:\n", + " range: string\n", + " age_in_years:\n", + " range: integer\n", + " height_in_cm:\n", + " range: float\n", + "classes:\n", + " Person:\n", + " slots:\n", + " - family_name\n", + " - given_name\n", + " - age_in_years\n", + " - height_in_cm\n" + ] + } + ], + "source": [ + "from linkml.utils.schema_builder import SchemaBuilder\n", + "from linkml_runtime.linkml_model import SlotDefinition\n", + "\n", + "sb = SchemaBuilder()\n", + "sb.add_class(\"Person\", slots=[SlotDefinition(\"family_name\", range=\"string\"), \n", + " SlotDefinition(\"given_name\", range=\"string\"),\n", + " SlotDefinition(\"age_in_years\", range=\"integer\"),\n", + " SlotDefinition(\"height_in_cm\", range=\"float\"),\n", + " ])\n", + "sb.add_defaults()\n", + "print(yaml.dump(sb.as_dict(), sort_keys=False))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:31:48.568091Z", + "start_time": "2024-03-22T15:31:48.546064Z" + } + }, + "id": "ef2c60ef7fbcbe20" + }, + { + "cell_type": "markdown", + "source": [ + "## Creating a Transformer Session object\n", + "\n", + "We will use a `Session` object which conveniently wraps a number of different capabilities;\n", + "the first of these capabilities is to map (transform) data objects from one schema to another\n", + "(implicit) schema using a *transformer specification*).\n", + "\n", + "Our initial transformer specification will be a trivial isomorphic one that:\n", + "\n", + "- maps the `Person` class to an `Individual` class\n", + "- passes through `name` fields as-is\n", + "- renames measurement fields (`age_in_years` and `height_in_cm` to `age` and `height`)" + ], + "metadata": { + "collapsed": false + }, + "id": "d4228629dd7e2ef2" + }, + { + "cell_type": "code", + "execution_count": 5, + "outputs": [], + "source": [ + "from linkml_transformer.session import Session\n", + "\n", + "session = Session()\n", + "session.set_source_schema(sb.as_dict())" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:31:49.071324Z", + "start_time": "2024-03-22T15:31:49.057115Z" + } + }, + "id": "a6257aa9e6ab021e" + }, + { + "cell_type": "code", + "execution_count": 6, + "outputs": [], + "source": [ + "# Transformer specification (in YAML)\n", + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " family_name:\n", + " populated_from: family_name\n", + " given_name:\n", + " populated_from: given_name\n", + " age:\n", + " populated_from: age_in_years\n", + " height:\n", + " populated_from: height_in_cm\n", + "\"\"\")" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:31:49.541418Z", + "start_time": "2024-03-22T15:31:49.294760Z" + } + }, + "id": "47b95e209790b423" + }, + { + "cell_type": "code", + "execution_count": 7, + "outputs": [], + "source": [ + "from linkml_transformer.compiler.sql_compiler import SQLCompiler\n", + "\n", + "compiler = SQLCompiler()" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:31:49.951730Z", + "start_time": "2024-03-22T15:31:49.949246Z" + } + }, + "id": "f1538dfa61775402" + }, + { + "cell_type": "code", + "execution_count": 9, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CREATE TABLE IF NOT EXISTS Individual (\n", + "family_name AS family_name\n", + "given_name AS given_name\n", + "age AS age_in_years\n", + "height AS height_in_cm\n", + ");\n" + ] + } + ], + "source": [ + "compiled = compiler.compile(session.transformer_specification)\n", + "print(compiled.serialization)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:32:08.957082Z", + "start_time": "2024-03-22T15:32:08.947948Z" + } + }, + "id": "95b6adb322799f1f" + }, + { + "cell_type": "markdown", + "source": [], + "metadata": { + "collapsed": false + }, + "id": "8313d6acb588178e" + }, + { + "cell_type": "code", + "execution_count": 11, + "outputs": [], + "source": [ + "import duckdb" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T17:13:13.511531Z", + "start_time": "2024-03-22T17:13:10.763461Z" + } + }, + "id": "1c623cdc3c1cfbca" + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "con = duckdb.connect(database=':memory:')\n" + ], + "metadata": { + "collapsed": false + }, + "id": "564d2bd8387d7c77" + }, + { + "cell_type": "markdown", + "source": [ + "## Using Expressions\n", + "\n", + "In addition to renaming fields, we can derive field values via evaluation of function *expressions*.\n", + "\n", + "You are encouraged to follow the subset of Python defined by the LinkML expression language. This provides\n", + "both safety, and declarativity. However, if you need\n", + "to, you can include arbitrary Python code, provided you configure the session to allow this.\n", + "\n", + "We'll keep the original schema, and will provide a new Transformer specification, \n", + "giving an example of both string manipulation functions and arithmetic functions; the latter\n", + "perform unit conversions (later on we will see more flexible and declarative ways to perform unit conversions).\n", + "\n" + ], + "metadata": { + "collapsed": false + }, + "id": "4562b534b6f23910" + }, + { + "cell_type": "code", + "execution_count": 10, + "outputs": [], + "source": [ + "\n", + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " name:\n", + " expr: \"{given_name} + ' ' + {family_name}\"\n", + " description: Concatenating given and family names\n", + " note this is a bad assumption for names in general,\n", + " this is just for demonstration\n", + " age_in_months:\n", + " expr: age_in_years * 12\n", + " height_in_meters:\n", + " expr: height_in_cm / 100\n", + "\"\"\")\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-22T15:40:45.674315Z", + "start_time": "2024-03-22T15:40:45.634241Z" + } + }, + "id": "789a7b6535ab410f" + }, + { + "cell_type": "markdown", + "source": [ + "Note that when we visualize this specification, dotted lines are shown indicating a relationship\n", + "between source and target that is different from direct copy:" + ], + "metadata": { + "collapsed": false + }, + "id": "e02eaa2cde3172c8" + }, + { + "cell_type": "code", + "execution_count": 9, + "outputs": [ + { + "data": { + "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nname : string\n\nage_in_months : string\n\nheight_in_meters : string\n\n\n\nsourcePerson:given_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:family_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age_in_months\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height_in_meters\n\n\n\n\n\n", + "text/plain": "" + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.graphviz()" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.283023Z", + "start_time": "2024-01-17T22:30:02.345894Z" + } + }, + "id": "2a18ccb5d7dc469b" + }, + { + "cell_type": "markdown", + "source": [ + "Now we'll transform the same object as before, and see the results:" + ], + "metadata": { + "collapsed": false + }, + "id": "f7019db8d391ab97" + }, + { + "cell_type": "code", + "execution_count": 10, + "outputs": [ + { + "data": { + "text/plain": "{'name': 'Jane Doe', 'age_in_months': 504, 'height_in_meters': 1.8}" + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.transform(obj)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.283868Z", + "start_time": "2024-01-17T22:30:03.278695Z" + } + }, + "id": "5e20e98e2b23751f" + }, + { + "cell_type": "markdown", + "source": [ + "As expected, we concatenated the name fields, and converted the age and height fields to different units.\n", + "\n", + "Let's take a look at the derived schema for this new transformation:" + ], + "metadata": { + "collapsed": false + }, + "id": "ad9fd0f70178fd26" + }, + { + "cell_type": "code", + "execution_count": 11, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema-derived\n", + "id: http://example.org/test-schema-derived\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml:\n", + " prefix_prefix: linkml\n", + " prefix_reference: https://w3id.org/linkml/\n", + " test_schema:\n", + " prefix_prefix: test_schema\n", + " prefix_reference: http://example.org/test-schema/\n", + "default_prefix: http://example.org/test-schema-derived/\n", + "default_range: string\n", + "classes:\n", + " Individual:\n", + " name: Individual\n", + " attributes:\n", + " name:\n", + " name: name\n", + " age_in_months:\n", + " name: age_in_months\n", + " height_in_meters:\n", + " name: height_in_meters\n" + ] + } + ], + "source": [ + "print(yaml_dumper.dumps(session.target_schema()))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.290589Z", + "start_time": "2024-01-17T22:30:03.286701Z" + } + }, + "id": "7c1f7efef1836364" + }, + { + "cell_type": "markdown", + "source": [ + "Note that at this time, deriving ranges using expressions is not supported, so the two measurement fields\n", + "are erroneously typed as having the `default_range` of `string`. However, in principle, if you use the\n", + "linkml subset of Python it should be possible to infer the range of the derived field, and this may be added\n", + "in future versions. Currently the tool chain is at an early stage of development." + ], + "metadata": { + "collapsed": false + }, + "id": "e87b7f45dc137a68" + }, + { + "cell_type": "markdown", + "source": [ + "## Unit conversions\n", + "\n", + "Next we will look at a different way of doing unit conversions. The LinkML specification allows\n", + "schemas to explicitly declare the units of slots, so let's modify our schema to do this, adding\n", + "a UCUM code for our `height_in_cm` slot:" + ], + "metadata": { + "collapsed": false + }, + "id": "ff3d20924263ec15" + }, + { + "cell_type": "code", + "execution_count": 12, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema\n", + "id: http://example.org/test-schema\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml: https://w3id.org/linkml/\n", + " test_schema: http://example.org/test-schema/\n", + "default_prefix: test_schema\n", + "default_range: string\n", + "slots:\n", + " family_name:\n", + " range: string\n", + " given_name:\n", + " range: string\n", + " age_in_years:\n", + " range: integer\n", + " height_in_cm:\n", + " range: float\n", + " unit:\n", + " ucum_code: cm\n", + "classes:\n", + " Person:\n", + " slots:\n", + " - family_name\n", + " - given_name\n", + " - age_in_years\n", + " - height_in_cm\n" + ] + } + ], + "source": [ + "from linkml_runtime.linkml_model.units import UnitOfMeasure\n", + "sb.schema.slots['height_in_cm'].unit = UnitOfMeasure(ucum_code='cm')\n", + "session.set_source_schema(sb.as_dict())\n", + "print(yaml.dump(sb.as_dict(), sort_keys=False))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.323328Z", + "start_time": "2024-01-17T22:30:03.300567Z" + } + }, + "id": "65a5ce5d97e27f76" + }, + { + "cell_type": "markdown", + "source": [ + "## Adding target_unit to transformer specification\n", + "\n", + "We will create a new transformer specification, focusing on the `height_in_cm` field. We will\n", + "transform this into a `height_in_meters` field, and will use the `target_unit` field to specify\n", + "the target unit." + ], + "metadata": { + "collapsed": false + }, + "id": "c5cf59ec9ac3148e" + }, + { + "cell_type": "code", + "execution_count": 13, + "outputs": [], + "source": [ + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " name:\n", + " expr: \"{given_name} + ' ' + {family_name}\"\n", + " height_in_meters:\n", + " populated_from: height_in_cm\n", + " unit_conversion:\n", + " target_unit: m\n", + "\"\"\")" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.365363Z", + "start_time": "2024-01-17T22:30:03.321298Z" + } + }, + "id": "bc99bad97970b1b7" + }, + { + "cell_type": "code", + "execution_count": 14, + "outputs": [ + { + "data": { + "text/plain": "{'name': 'Jane Doe', 'height_in_meters': 1.8}" + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.transform(obj)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.622621Z", + "start_time": "2024-01-17T22:30:03.370531Z" + } + }, + "id": "831b444d9c47e0ea" + }, + { + "cell_type": "markdown", + "source": [ + "## Units in derived schema\n", + "\n", + "Next we'll look at the derived target schema, and as expected we see that it has inferred\n", + "the target unit for the `height_in_meters` field:" + ], + "metadata": { + "collapsed": false + }, + "id": "6f37087c6dfc30ef" + }, + { + "cell_type": "code", + "execution_count": 15, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema-derived\n", + "id: http://example.org/test-schema-derived\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml:\n", + " prefix_prefix: linkml\n", + " prefix_reference: https://w3id.org/linkml/\n", + " test_schema:\n", + " prefix_prefix: test_schema\n", + " prefix_reference: http://example.org/test-schema/\n", + "default_prefix: http://example.org/test-schema-derived/\n", + "default_range: string\n", + "classes:\n", + " Individual:\n", + " name: Individual\n", + " attributes:\n", + " name:\n", + " name: name\n", + " height_in_meters:\n", + " name: height_in_meters\n", + " range: float\n", + " unit:\n", + " ucum_code: m\n" + ] + } + ], + "source": [ + "print(yaml_dumper.dumps(session.target_schema()))\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.629604Z", + "start_time": "2024-01-17T22:30:03.624546Z" + } + }, + "id": "b589e0e95550962d" + }, + { + "cell_type": "markdown", + "source": [ + "## Tabular serialization" + ], + "metadata": { + "collapsed": false + }, + "id": "8f4c4cb125aade0b" + }, + { + "cell_type": "code", + "execution_count": 16, + "outputs": [], + "source": [ + "slot = sb.add_slot(\"aliases\", multivalued=True, range=\"string\", replace_if_present=True)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.630816Z", + "start_time": "2024-01-17T22:30:03.629262Z" + } + }, + "id": "f492b27c0f0fbf88" + }, + { + "cell_type": "code", + "execution_count": 17, + "outputs": [], + "source": [ + "sb.schema.classes['Person'].slots.append(slot.name)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.661717Z", + "start_time": "2024-01-17T22:30:03.635358Z" + } + }, + "id": "3ac3f93ab8561300" + }, + { + "cell_type": "code", + "execution_count": 18, + "outputs": [], + "source": [ + "session.set_source_schema(sb.as_dict())" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.662631Z", + "start_time": "2024-01-17T22:30:03.646582Z" + } + }, + "id": "84262d357323f76e" + }, + { + "cell_type": "code", + "execution_count": 19, + "outputs": [], + "source": [ + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " family_name:\n", + " populated_from: family_name\n", + " given_name:\n", + " populated_from: given_name\n", + " age:\n", + " populated_from: age_in_years\n", + " height:\n", + " populated_from: height_in_cm\n", + " aliases:\n", + " populated_from: aliases\n", + " stringification:\n", + " delimiter: '|'\n", + "\"\"\") " + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.709283Z", + "start_time": "2024-01-17T22:30:03.667849Z" + } + }, + "id": "2f282430f48e13c0" + }, + { + "cell_type": "code", + "execution_count": 20, + "outputs": [ + { + "data": { + "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age': 42,\n 'height': 180.0,\n 'aliases': 'Jane|Janie|Janey'}" + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj = {\n", + " \"given_name\": \"Jane\",\n", + " \"family_name\": \"Doe\",\n", + " \"age_in_years\": 42,\n", + " \"height_in_cm\": 180.0,\n", + " \"aliases\": [\"Jane\", \"Janie\", \"Janey\"]\n", + " }\n", + "flattened = session.transform(obj)\n", + "flattened" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.739195Z", + "start_time": "2024-01-17T22:30:03.711288Z" + } + }, + "id": "fdd23ae82909770e" + }, + { + "cell_type": "markdown", + "source": [ + "this can easily be serialized to a CSV/TSV" + ], + "metadata": { + "collapsed": false + }, + "id": "c5174dcbf7dd0c43" + }, + { + "cell_type": "markdown", + "source": [ + "## Reverse transform\n", + "\n", + "If a transform does not contain one-way functions,\n", + "it can be *reversed*.\n", + "\n", + "In this case, reversing the transform allows us to map\n", + "from the tabular form back to the richer original representation." + ], + "metadata": { + "collapsed": false + }, + "id": "fae8392b02526408" + }, + { + "cell_type": "code", + "execution_count": 21, + "outputs": [ + { + "data": { + "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age_in_years': 42,\n 'height_in_cm': 180.0,\n 'aliases': ['Jane', 'Janie', 'Janey']}" + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.reverse_transform(flattened)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.781498Z", + "start_time": "2024-01-17T22:30:03.754420Z" + } + }, + "id": "e8c1c3f98081d38" + }, + { + "cell_type": "code", + "execution_count": 21, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-01-17T22:30:03.785065Z", + "start_time": "2024-01-17T22:30:03.782845Z" + } + }, + "id": "ee14ace4b1c7d256" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/poetry.lock b/poetry.lock index 16c3dca..65a1047 100644 --- a/poetry.lock +++ b/poetry.lock @@ -716,6 +716,63 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] +[[package]] +name = "duckdb" +version = "0.10.1" +description = "DuckDB in-process database" +category = "dev" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "duckdb-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0ac172788e3d8e410e009e3699016a4d7f17b4c7cde20f98856fca1fea79d247"}, + {file = "duckdb-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f754c20d3b963574da58b0d22029681b79c63f2e32060f10b687f41b7bba54d7"}, + {file = "duckdb-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c68b1ef88b8cce185381ec69f437d20059c30623375bab41ac07a1104acdb57"}, + {file = "duckdb-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f566f615278844ea240c9a3497c0ef201331628f78e0f9f4d64f72f82210e750"}, + {file = "duckdb-0.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67d2996c3372a0f7d8f41f1c49e00ecdb26f83cdd9132b76730224ad68b1f1e3"}, + {file = "duckdb-0.10.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c3b3a18a58eebabb426beafc2f7da01d59805d660fc909e5e143b6db04d881a"}, + {file = "duckdb-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:343795d13ec3d8cd06c250225a05fd3c348c3ed49cccdde01addd46cb50f3559"}, + {file = "duckdb-0.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:33f99c2e9e4060464673912312b4ec91060d66638756592c9484c62824ff4e85"}, + {file = "duckdb-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdbe4173729043b2fd949be83135b035820bb2faf64648500563b16f3f6f02ee"}, + {file = "duckdb-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f90738310a76bd1618acbc7345175582d36b6907cb0ed07841a3d800dea189d6"}, + {file = "duckdb-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d14d00560832592cbac2817847b649bd1d573f125d064518afb6eec5b02e15a"}, + {file = "duckdb-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11c0bf253c96079c6139e8a0880300d80f4dc9f21a8c5c239d2ebc060b227d46"}, + {file = "duckdb-0.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcc60833bb1a1fb2c33b052cf793fef48f681c565d982acff6ac7a86369794da"}, + {file = "duckdb-0.10.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88cdc0c2501dd7a65b1df2a76d7624b93d9b6d27febd2ee80b7e5643a0b40bcb"}, + {file = "duckdb-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:698a8d1d48b150d344d8aa6dbc30a22ea30fb14ff2b15c90004fc9fcb0b3a3e9"}, + {file = "duckdb-0.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:b450aa2b3e0eb1fc0f7ad276bd1e4a5a03b1a4def6c45366af17557de2cafbdf"}, + {file = "duckdb-0.10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:40dd55ea9c31abc69e5a8299f16c877e0b1950fd9a311c117efb4dd3c0dc8458"}, + {file = "duckdb-0.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7c1b3538bb9c2b49f48b26f092444525b22186efa4e77ba070603ed4a348a66"}, + {file = "duckdb-0.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bce024b69bae426b0739c470803f7b44261bdc0c0700ea7c41dff5f2d70ca4f3"}, + {file = "duckdb-0.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52af2a078340b2e1b57958477ebc1be07786d3ad5796777e87d4f453e0477b4c"}, + {file = "duckdb-0.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3c52b08c773e52484542300339ebf295e3c9b12d5d7d49b2567e252c16205a7"}, + {file = "duckdb-0.10.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:097aa9b6d5c9f5d3ed8c35b16020a67731d04befc35f6b89ccb5db9d5f1489c4"}, + {file = "duckdb-0.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b5a14a80ad09d65c270d16761b04ea6b074811cdfde6b5e4db1a8b0184125d1b"}, + {file = "duckdb-0.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fb98dbbdbf8048b07223dc6e7401333bb4e83681dde4cded2d239051ea102b5"}, + {file = "duckdb-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28857b0d595c229827cc3631ae9b74ff52d11614435aa715e09d8629d2e1b609"}, + {file = "duckdb-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d85645136fc25026978b5db81869e8a120cfb60e1645a29a0f6dd155be9e59e"}, + {file = "duckdb-0.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2e10582db74b99051e718279c1be204c98a63a5b6aa4e09226b7249e414146"}, + {file = "duckdb-0.10.1-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6a88358d86a8ce689fdd4136514aebedf958e910361156a0bb0e53dc3c55f7d"}, + {file = "duckdb-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b025afa30fcdcede094386e7c519e6964d26de5ad95f4e04a2a0a713676d4465"}, + {file = "duckdb-0.10.1-cp37-cp37m-win_amd64.whl", hash = "sha256:910be5005de7427c5231a7200027e0adb951e048c612b895340effcd3e660d5a"}, + {file = "duckdb-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:13d81752763f14203a53981f32bd09731900eb6fda4048fbc532eae5e7bf30e5"}, + {file = "duckdb-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21858225b8a5c5dead128f62e4e88facdcbfdce098e18cbcd86a6cd8f48fb2b3"}, + {file = "duckdb-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8bf46d55685906729998eca70ee751934e0425d86863148e658277526c54282e"}, + {file = "duckdb-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f786b4402b9c31461ea0520d919e2166df4f9e6e21fd3c7bb0035fa985b5dfe"}, + {file = "duckdb-0.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32e52c6e939a4bada220803e6bde6fc0ce870da5662a33cabdd3be14824183a6"}, + {file = "duckdb-0.10.1-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c563b565ea68cfebe9c4078646503b3d38930218f9c3c278277d58952873771"}, + {file = "duckdb-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:af8382280f24273a535e08b80e9383ad739c66e22855ce68716dfbaeaf8910b9"}, + {file = "duckdb-0.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:2e6e01e2499e07873b09316bf4d6808f712c57034fa24c255565c4f92386e8e3"}, + {file = "duckdb-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7791a0aa2cea972a612d31d4a289c81c5d00181328ed4f7642907f68f8b1fb9f"}, + {file = "duckdb-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1ace20383fb0ba06229e060a6bb0bcfd48a4582a02e43f05991720504508eb59"}, + {file = "duckdb-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5aad3e085c33253c689205b5ea3c5d9d54117c1249276c90d495cb85d9adce76"}, + {file = "duckdb-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa08173f68e678793dfe6aab6490ac753204ca7935beb8dbde778dbe593552d8"}, + {file = "duckdb-0.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:525efad4e6caff80d0f6a51d466470839146e3880da36d4544fee7ff842e7e20"}, + {file = "duckdb-0.10.1-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48d84577216010ee407913bad9dc47af4cbc65e479c91e130f7bd909a32caefe"}, + {file = "duckdb-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6e65f00294c3b8576ae651e91e732ea1cefc4aada89c307fb02f49231fd11e1f"}, + {file = "duckdb-0.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:30aa9dbbfc1f9607249fc148af9e6d6fd253fdc2f4c9924d4957d6a535558b4f"}, + {file = "duckdb-0.10.1.tar.gz", hash = "sha256:0d5b6daa9bb54a635e371798994caa08f26d2f145ebcbc989e16b0a0104e84fb"}, +] + [[package]] name = "editorconfig" version = "0.12.3" @@ -2810,6 +2867,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -3381,30 +3439,50 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, @@ -4077,4 +4155,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "aa8778026cd61fdf9b198224af216dafc02982e92682b2ecb63e3a85d1d0dcc4" +content-hash = "89c14a0b6cd18d6be5afa890486d44d9ecf73bf7c68e04049f72ae377c453076" diff --git a/pyproject.toml b/pyproject.toml index 05e85f5..1ce97ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,10 @@ pint = "^0.23" [tool.poetry.group.graphviz.dependencies] graphviz = "^0.20.1" + +[tool.poetry.group.duckdb.dependencies] +duckdb = "^0.10.1" + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/src/linkml_transformer/compiler/compiler.py b/src/linkml_transformer/compiler/compiler.py index 52b533a..c923f1b 100644 --- a/src/linkml_transformer/compiler/compiler.py +++ b/src/linkml_transformer/compiler/compiler.py @@ -13,7 +13,7 @@ - LinkML-Transformer Specifications to Hamilton """ from abc import ABC -from dataclasses import dataclass +from dataclasses import dataclass, field from types import ModuleType from typing import Iterator, Optional @@ -27,7 +27,7 @@ @dataclass class CompiledSpecification: - serialization: str + serialization: str = field(default="") _module: Optional[ModuleType] = None diff --git a/src/linkml_transformer/compiler/sql_compiler.py b/src/linkml_transformer/compiler/sql_compiler.py index 2fab732..4c772c4 100644 --- a/src/linkml_transformer/compiler/sql_compiler.py +++ b/src/linkml_transformer/compiler/sql_compiler.py @@ -1,12 +1,134 @@ +from linkml_runtime import SchemaView +from linkml_runtime.linkml_model import SlotDefinition + from linkml_transformer.compiler.compiler import CompiledSpecification, Compiler -from linkml_transformer.datamodel.transformer_model import TransformationSpecification +from linkml_transformer.datamodel.transformer_model import TransformationSpecification, ClassDerivation, \ + SerializationSyntaxType + + +LINKML_TO_SQL_TYPE_MAP = { + "string": "TEXT", + "integer": "INTEGER", + "boolean": "BOOLEAN", + "float": "REAL", + "decimal": "REAL", + "datetime": "TIMESTAMP", + "date": "DATE", + "time": "TIME", + "uri": "TEXT", + "any": "TEXT" +} + class SQLCompiler(Compiler): """ Compiles a Transformation Specification to SQL CREATE TABLE or VIEW statements. + Note: this is currently highly geared towards DuckDB. """ + add_if_not_exists: bool = True + new_table_when_transforming: bool = False def compile(self, specification: TransformationSpecification) -> CompiledSpecification: - raise NotImplementedError + compiled = CompiledSpecification() + for cd in specification.class_derivations.values(): + self.compile_class(compiled, cd, specification) + return compiled + + def compile_class(self, compiled: CompiledSpecification, cd: ClassDerivation, specification: TransformationSpecification) -> None: + """ + Compile a class derivation to SQL. + + :param compiled: (modified in place) + :param cd: + :param specification: + :return: + """ + stmt = "" + if self.new_table_when_transforming: + stmt += f"CREATE TABLE " + if self.add_if_not_exists: + stmt += "IF NOT EXISTS " + stmt += f"{cd.name} \n" + else: + stmt += f"INSERT INTO {cd.name} SELECT \n" + col_trs = [] + for sd in cd.slot_derivations.values(): + col_trs.append(self.compile_slot_derivation(sd)) + if not col_trs: + return + stmt += ", \n".join(col_trs) + if self.new_table_when_transforming: + stmt += ");" + stmt += f" FROM {cd.name}" + compiled.serialization += f"{stmt};\n" + + def compile_slot_derivation(self, sd) -> str: + expr = sd.populated_from + if expr is None: + expr = sd.name + if sd.stringification: + syntax = sd.stringification.syntax + delimiter = sd.stringification.delimiter + if sd.stringification.reversed: + pass + else: + # duckdb specific? + if syntax == SerializationSyntaxType.JSON: + expr = f"CAST({expr} AS TEXT)" + elif delimiter: + expr = f"STRING_AGG({expr}, '{delimiter}')" + return f" {sd.name} AS {expr}" + + + def create_ddl(self, schemaview: SchemaView) -> str: + """ + Create DDL for the entire schema. + + Note core LinkML has a SQL DDL generator, but this is primarily for pure relational models. + + DuckDB allows complex datatypes. + + TODO: move to LinkML core + :param schemaview: + :return: + """ + ddl = [] + for c in schemaview.all_classes().values(): + if c.mixin or c.abstract: + continue + col_strs = [] + for s in schemaview.class_induced_slots(c.name): + col_strs.append(f" {s.name} {self.sql_type(s, schemaview)}") + if not col_strs: + continue + ddl.append(f"CREATE TABLE IF NOT EXISTS {c.name} (") + ddl.append(",\n".join(col_strs)) + ddl.append(");") + return "\n".join(ddl) + + def sql_type(self, slot: SlotDefinition, schemaview: SchemaView) -> str: + """ + Map LinkML types to DuckDB SQL types. + + :param slot: + :param schemaview: + :return: + """ + typ = "TEXT" + if slot.range: + if slot.range in LINKML_TO_SQL_TYPE_MAP: + typ = LINKML_TO_SQL_TYPE_MAP.get(slot.range, typ) + elif slot.range in schemaview.all_classes(): + if slot.inlined: + typ = "TEXT" + else: + # TODO: consider structs + typ = "JSON" + + if slot.multivalued: + typ = f"{typ}[]" + return typ + + diff --git a/src/linkml_transformer/datamodel/transformer_model.yaml b/src/linkml_transformer/datamodel/transformer_model.yaml index e269e96..280a39a 100644 --- a/src/linkml_transformer/datamodel/transformer_model.yaml +++ b/src/linkml_transformer/datamodel/transformer_model.yaml @@ -312,6 +312,9 @@ classes: - value: ';' reversed: range: boolean + over_slots: + range: string + multivalued: true syntax: range: SerializationSyntaxType examples: diff --git a/src/linkml_transformer/session.py b/src/linkml_transformer/session.py index 1d6e3f4..d62a914 100644 --- a/src/linkml_transformer/session.py +++ b/src/linkml_transformer/session.py @@ -7,6 +7,8 @@ from linkml_runtime import SchemaView from linkml_runtime.dumpers import yaml_dumper from linkml_runtime.linkml_model import SchemaDefinition +from linkml_runtime.processing.referencevalidator import ReferenceValidator +from linkml_runtime.utils.introspection import package_schemaview from linkml_transformer import ObjectTransformer from linkml_transformer.datamodel.transformer_model import TransformationSpecification @@ -22,16 +24,33 @@ class Session: A wrapper object for a transformer session. """ + transformer_specification: Optional[TransformationSpecification] = None source_schemaview: Optional[SchemaView] = None object_transformer: Optional[ObjectTransformer] = None schema_mapper: Optional[SchemaMapper] = None _target_schema: Optional[SchemaDefinition] = None + _target_schemaview: Optional[SchemaView] = None + + def set_transformer_specification( + self, specification: Optional[Union[TransformationSpecification, dict, str, Path]] = None + ): + if isinstance(specification, TransformationSpecification): + self.transformer_specification = specification + elif isinstance(specification, dict): + # TODO: centralize this code + normalizer = ReferenceValidator( + package_schemaview("linkml_transformer.datamodel.transformer_model") + ) + normalizer.expand_all = True + specification = normalizer.normalize(specification) + self.transformer_specification = TransformationSpecification(**specification) + elif isinstance(specification, str): + if "\n" in specification: + obj = yaml.safe_load(specification) + else: + obj = yaml.safe_load(open(specification)) + self.set_transformer_specification(obj) - @property - def transformer_specification(self) -> TransformationSpecification: - if self.object_transformer is None: - raise ValueError("No transformer specified") - return self.object_transformer.specification def set_source_schema(self, schema: Union[str, Path, dict, SchemaView, SchemaDefinition]): """ @@ -53,7 +72,7 @@ def set_source_schema(self, schema: Union[str, Path, dict, SchemaView, SchemaDef self._target_schema = None def set_object_transformer( - self, transformer: Optional[Union[ObjectTransformer, dict, str, Path]] = None + self, transformer: Optional[Union[ObjectTransformer, TransformationSpecification, dict, str, Path]] = None ): if transformer is None: if self.object_transformer is not None: @@ -62,25 +81,32 @@ def set_object_transformer( else: logger.warning("No transformer specified") return - if isinstance(transformer, ObjectTransformer): - self.object_transformer = transformer - elif isinstance(transformer, dict): - self.object_transformer = ObjectTransformer() - self.object_transformer.create_transformer_specification(transformer) - elif isinstance(transformer, str): - self.object_transformer = ObjectTransformer() - self.object_transformer.create_transformer_specification(yaml.safe_load(transformer)) + if transformer is not None: + if isinstance(transformer, ObjectTransformer): + self.object_transformer = transformer + else: + self.set_transformer_specification(transformer) + self.object_transformer = ObjectTransformer() + self.object_transformer.specification = self.transformer_specification self._target_schema = None + @property def target_schema(self) -> SchemaDefinition: if self._target_schema is None: if not self.schema_mapper: self.schema_mapper = SchemaMapper(source_schemaview=self.source_schemaview) self._target_schema = self.schema_mapper.derive_schema( - self.object_transformer.specification + self.transformer_specification ) return self._target_schema + @property + def target_schemaview(self) -> SchemaView: + if self._target_schemaview is None: + # TODO: simplify + self._target_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema)) + return self._target_schemaview + def transform(self, obj: dict, **kwargs) -> dict: if self.object_transformer is None: raise ValueError("No transformer specified") diff --git a/src/linkml_transformer/transformer/duckdb_transformer.py b/src/linkml_transformer/transformer/duckdb_transformer.py new file mode 100644 index 0000000..1c9bd3c --- /dev/null +++ b/src/linkml_transformer/transformer/duckdb_transformer.py @@ -0,0 +1,37 @@ +import json +import logging +from dataclasses import dataclass +from typing import Any, Dict, List, Optional, Type, Union + + +from linkml_transformer.transformer.transformer import OBJECT_TYPE, Transformer + +DICT_OBJ = Dict[str, Any] + + +logger = logging.getLogger(__name__) + + +@dataclass +class DuckDBTransformer(Transformer): + """ + A Transformer that works on DuckDB data. + """ + + def transform( + self, + source_obj: OBJECT_TYPE, + source_type: str = None, + target_type: str = None, + ) -> Union[DICT_OBJ, Any]: + """ + Transform a source object into a target object. + + :param source_obj: source data structure + :param source_type: source_obj instantiates this (may be class, type, or enum) + :param target_type: target_obj instantiates this (may be class, type, or enum) + :return: transformed data, either as type target_type or a dictionary + """ + import duckdb + sv = self.source_schemaview + raise NotImplementedError("DuckDBTransformer.transform") diff --git a/tests/test_compiler/test_duckdb_compiler.py b/tests/test_compiler/test_duckdb_compiler.py new file mode 100644 index 0000000..804463c --- /dev/null +++ b/tests/test_compiler/test_duckdb_compiler.py @@ -0,0 +1,42 @@ +""" +Tests compilation of a specification to python +""" +import pytest +from linkml_runtime import SchemaView +from linkml_runtime.dumpers import yaml_dumper +from linkml_runtime.utils.compile_python import compile_python + +import tests.input.examples.personinfo_basic.model.personinfo_model as src +from linkml_transformer.compiler.sql_compiler import SQLCompiler +from linkml_transformer.session import Session +from linkml_transformer.utils.loaders import load_specification +from tests import SCHEMA1, SPECIFICATION + + +@pytest.fixture +def session(): + session = Session() + session.set_source_schema(SCHEMA1) + session.set_transformer_specification(SPECIFICATION) + return session + + +def test_compile(session): + compiler = SQLCompiler() + assert session.transformer_specification is not None + compiled = compiler.compile(session.transformer_specification) + # TODO: include imports so that code compiles + print(compiled.serialization) + source_sv = SchemaView(SCHEMA1) + source_ddl = compiler.create_ddl(source_sv) + print(source_ddl) + target_sv = session.target_schemaview + print(yaml_dumper.dumps(target_sv.schema)) + target_ddl = compiler.create_ddl(target_sv) + print(target_ddl) + + + import duckdb + conn = duckdb.connect(':memory:') + conn.execute(target_ddl) + conn.execute(compiled.serialization) diff --git a/tests/test_compliance/test_compliance_suite.py b/tests/test_compliance/test_compliance_suite.py index 3160d56..a595094 100644 --- a/tests/test_compliance/test_compliance_suite.py +++ b/tests/test_compliance/test_compliance_suite.py @@ -19,6 +19,7 @@ import logging import re from dataclasses import dataclass +from types import ModuleType from typing import Any, Dict, Optional import pytest @@ -29,6 +30,7 @@ from linkml_runtime.linkml_model import Prefix, SchemaDefinition from linkml_transformer.compiler.python_compiler import PythonCompiler +from linkml_transformer.compiler.sql_compiler import SQLCompiler from linkml_transformer.datamodel.transformer_model import ( CollectionType, SerializationSyntaxType, @@ -91,6 +93,25 @@ def build_transformer(**kwargs) -> TransformationSpecification: return mapper.specification +def create_compilers(spec: TransformationSpecification, expected_map: [Dict[ModuleType, str]]): + """ + Test compilation of transformation specifications to other languages. + + This test is a placeholder for future development, where the + transformation specification will be compiled to other languages + (e.g. SQL, R2RML, etc.) + + :param spec: transformation specification + :return: + """ + for compiler_type, expected in expected_map.items(): + compiler = compiler_type() + compiled_spec = compiler.compile(spec) + print(f"**Compiled Specification ({compiler_type.__name__})**:\n\n") + print(compiled_spec.serialization) + assert expected in compiled_spec.serialization + + @dataclass class State: schema_mapper: SchemaMapper = None @@ -697,18 +718,18 @@ def test_complex_unit_conversion( @pytest.mark.parametrize( - "delimiter,source_value,target_value", + "syntax,delimiter,source_value,target_value", [ - (",", ["a", "b"], "a,b"), - ("|", ["a", "b"], "a|b"), - ("|", ["a"], "a"), - ("|", [], ""), - (SerializationSyntaxType.JSON, ["a", "b"], '["a", "b"]'), - (SerializationSyntaxType.JSON, [], "[]"), - (SerializationSyntaxType.YAML, ["a", "b"], "[a, b]"), + (None, ",", ["a", "b"], "a,b"), + (None, "|", ["a", "b"], "a|b"), + (None, "|", ["a"], "a"), + (None, "|", [], ""), + (SerializationSyntaxType.JSON, None, ["a", "b"], '["a", "b"]'), + (SerializationSyntaxType.JSON, None, [], "[]"), + (SerializationSyntaxType.YAML, None, ["a", "b"], "[a, b]"), ], ) -def test_stringify(invocation_tracker, delimiter, source_value, target_value): +def test_stringify(invocation_tracker, syntax, delimiter, source_value, target_value): """ Test compaction of multivalued slots into a string. @@ -719,6 +740,7 @@ def test_stringify(invocation_tracker, delimiter, source_value, target_value): - flattening lists or more complex objects using JSON or YAML :param invocation_tracker: pytest fixture to emit metadata + :param syntax: SerializationSyntaxType :param delimiter: delimiter to use in stringification :param source_value: source value (a list) :param target_value: expected value of slot in target object (a string) @@ -733,18 +755,16 @@ def test_stringify(invocation_tracker, delimiter, source_value, target_value): } schema = build_schema("types", classes=classes) source_sv = SchemaView(schema) - stringification = {} - if isinstance(delimiter, SerializationSyntaxType): - stringification["syntax"] = delimiter.value - else: - stringification["delimiter"] = delimiter cds = { "D": { "populated_from": "C", "slot_derivations": { "s1_verbatim": { "populated_from": "s1", - "stringification": stringification, + "stringification": { + "syntax": syntax, + "delimiter": delimiter, + }, } }, } @@ -758,6 +778,7 @@ def test_stringify(invocation_tracker, delimiter, source_value, target_value): source_sv=source_sv, invertible=True, ) + create_compilers(spec, {SQLCompiler: ""}) @pytest.mark.parametrize( From 75c179a5234343d18c8aea53bfddd8419e025763 Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Fri, 22 Mar 2024 19:12:54 -0700 Subject: [PATCH 2/7] Initial duckdb transformer --- notebooks/Tutorial.ipynb | 98 +++++++++++++++---------------- src/linkml_transformer/session.py | 4 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/notebooks/Tutorial.ipynb b/notebooks/Tutorial.ipynb index 73a00a9..456f5a1 100644 --- a/notebooks/Tutorial.ipynb +++ b/notebooks/Tutorial.ipynb @@ -24,8 +24,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:29:59.302402Z", - "start_time": "2024-01-17T22:29:58.965289Z" + "end_time": "2024-03-23T02:12:23.927439Z", + "start_time": "2024-03-23T02:12:23.819885Z" } }, "id": "63a064b31f623bdd" @@ -97,8 +97,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:29:59.378265Z", - "start_time": "2024-01-17T22:29:58.988218Z" + "end_time": "2024-03-23T02:12:24.139985Z", + "start_time": "2024-03-23T02:12:23.842320Z" } }, "id": "ef2c60ef7fbcbe20" @@ -136,8 +136,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:01.239725Z", - "start_time": "2024-01-17T22:29:59.312872Z" + "end_time": "2024-03-23T02:12:24.847826Z", + "start_time": "2024-03-23T02:12:24.138432Z" } }, "id": "a6257aa9e6ab021e" @@ -166,8 +166,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:01.484509Z", - "start_time": "2024-01-17T22:30:01.238874Z" + "end_time": "2024-03-23T02:12:25.094008Z", + "start_time": "2024-03-23T02:12:24.897951Z" } }, "id": "47b95e209790b423" @@ -191,7 +191,7 @@ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nfamily_name : string\n\ngiven_name : string\n\nage : integer\n\nheight : float\n\n\n\nsourcePerson:family_name->targetIndividual:family_name\n\n\n\n\n\nsourcePerson:given_name->targetIndividual:given_name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height\n\n\n\n\n\n", - "text/plain": "" + "text/plain": "" }, "execution_count": 5, "metadata": {}, @@ -204,8 +204,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:02.244818Z", - "start_time": "2024-01-17T22:30:01.486984Z" + "end_time": "2024-03-23T02:12:25.426050Z", + "start_time": "2024-03-23T02:12:25.096688Z" } }, "id": "1c623cdc3c1cfbca" @@ -249,8 +249,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:02.251017Z", - "start_time": "2024-01-17T22:30:02.241183Z" + "end_time": "2024-03-23T02:12:25.435969Z", + "start_time": "2024-03-23T02:12:25.431387Z" } }, "id": "9f4d1fc4ca97f80c" @@ -331,13 +331,13 @@ "source": [ "from linkml_runtime.dumpers import yaml_dumper\n", "\n", - "print(yaml_dumper.dumps(session.target_schema()))" + "print(yaml_dumper.dumps(session.target_schema))" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:02.260147Z", - "start_time": "2024-01-17T22:30:02.253561Z" + "end_time": "2024-03-23T02:12:25.442750Z", + "start_time": "2024-03-23T02:12:25.434388Z" } }, "id": "687912c18bf6752" @@ -398,8 +398,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:02.326085Z", - "start_time": "2024-01-17T22:30:02.258015Z" + "end_time": "2024-03-23T02:12:25.502675Z", + "start_time": "2024-03-23T02:12:25.460193Z" } }, "id": "789a7b6535ab410f" @@ -422,7 +422,7 @@ { "data": { "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nname : string\n\nage_in_months : string\n\nheight_in_meters : string\n\n\n\nsourcePerson:given_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:family_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age_in_months\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height_in_meters\n\n\n\n\n\n", - "text/plain": "" + "text/plain": "" }, "execution_count": 9, "metadata": {}, @@ -435,8 +435,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.283023Z", - "start_time": "2024-01-17T22:30:02.345894Z" + "end_time": "2024-03-23T02:12:25.810836Z", + "start_time": "2024-03-23T02:12:25.509345Z" } }, "id": "2a18ccb5d7dc469b" @@ -470,8 +470,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.283868Z", - "start_time": "2024-01-17T22:30:03.278695Z" + "end_time": "2024-03-23T02:12:25.816826Z", + "start_time": "2024-03-23T02:12:25.812549Z" } }, "id": "5e20e98e2b23751f" @@ -523,13 +523,13 @@ } ], "source": [ - "print(yaml_dumper.dumps(session.target_schema()))" + "print(yaml_dumper.dumps(session.target_schema))" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.290589Z", - "start_time": "2024-01-17T22:30:03.286701Z" + "end_time": "2024-03-23T02:12:25.825306Z", + "start_time": "2024-03-23T02:12:25.820116Z" } }, "id": "7c1f7efef1836364" @@ -608,8 +608,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.323328Z", - "start_time": "2024-01-17T22:30:03.300567Z" + "end_time": "2024-03-23T02:12:25.850932Z", + "start_time": "2024-03-23T02:12:25.833403Z" } }, "id": "65a5ce5d97e27f76" @@ -649,8 +649,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.365363Z", - "start_time": "2024-01-17T22:30:03.321298Z" + "end_time": "2024-03-23T02:12:25.901551Z", + "start_time": "2024-03-23T02:12:25.853769Z" } }, "id": "bc99bad97970b1b7" @@ -674,8 +674,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.622621Z", - "start_time": "2024-01-17T22:30:03.370531Z" + "end_time": "2024-03-23T02:12:26.176193Z", + "start_time": "2024-03-23T02:12:25.901292Z" } }, "id": "831b444d9c47e0ea" @@ -729,13 +729,13 @@ } ], "source": [ - "print(yaml_dumper.dumps(session.target_schema()))\n" + "print(yaml_dumper.dumps(session.target_schema))\n" ], "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.629604Z", - "start_time": "2024-01-17T22:30:03.624546Z" + "end_time": "2024-03-23T02:12:26.176598Z", + "start_time": "2024-03-23T02:12:26.152743Z" } }, "id": "b589e0e95550962d" @@ -760,8 +760,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.630816Z", - "start_time": "2024-01-17T22:30:03.629262Z" + "end_time": "2024-03-23T02:12:26.176672Z", + "start_time": "2024-03-23T02:12:26.156764Z" } }, "id": "f492b27c0f0fbf88" @@ -776,8 +776,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.661717Z", - "start_time": "2024-01-17T22:30:03.635358Z" + "end_time": "2024-03-23T02:12:26.176741Z", + "start_time": "2024-03-23T02:12:26.159739Z" } }, "id": "3ac3f93ab8561300" @@ -792,8 +792,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.662631Z", - "start_time": "2024-01-17T22:30:03.646582Z" + "end_time": "2024-03-23T02:12:26.177256Z", + "start_time": "2024-03-23T02:12:26.168743Z" } }, "id": "84262d357323f76e" @@ -825,8 +825,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.709283Z", - "start_time": "2024-01-17T22:30:03.667849Z" + "end_time": "2024-03-23T02:12:26.249455Z", + "start_time": "2024-03-23T02:12:26.222590Z" } }, "id": "2f282430f48e13c0" @@ -858,8 +858,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.739195Z", - "start_time": "2024-01-17T22:30:03.711288Z" + "end_time": "2024-03-23T02:12:26.279106Z", + "start_time": "2024-03-23T02:12:26.242965Z" } }, "id": "fdd23ae82909770e" @@ -909,8 +909,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.781498Z", - "start_time": "2024-01-17T22:30:03.754420Z" + "end_time": "2024-03-23T02:12:26.339410Z", + "start_time": "2024-03-23T02:12:26.280636Z" } }, "id": "e8c1c3f98081d38" @@ -923,8 +923,8 @@ "metadata": { "collapsed": false, "ExecuteTime": { - "end_time": "2024-01-17T22:30:03.785065Z", - "start_time": "2024-01-17T22:30:03.782845Z" + "end_time": "2024-03-23T02:12:26.339637Z", + "start_time": "2024-03-23T02:12:26.317148Z" } }, "id": "ee14ace4b1c7d256" diff --git a/src/linkml_transformer/session.py b/src/linkml_transformer/session.py index d62a914..8f8ab62 100644 --- a/src/linkml_transformer/session.py +++ b/src/linkml_transformer/session.py @@ -118,7 +118,7 @@ def reverse_transform(self, obj: dict, **kwargs) -> dict: inv_spec = self.invert() reverse_transformer = ObjectTransformer() reverse_transformer.specification = inv_spec - reverse_transformer.source_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema())) + reverse_transformer.source_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema)) return reverse_transformer.transform(obj, **kwargs) def invert(self, in_place=False) -> TransformationSpecification: @@ -127,7 +127,7 @@ def invert(self, in_place=False) -> TransformationSpecification: """ inverter = TransformationSpecificationInverter( source_schemaview=self.source_schemaview, - target_schemaview=SchemaView(yaml_dumper.dumps(self.target_schema())), + target_schemaview=SchemaView(yaml_dumper.dumps(self.target_schema)), ) inv_spec = inverter.invert(self.transformer_specification) if in_place: From de7f8c0d0eed0b7db178a698faab71fc5a1d094e Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Fri, 22 Mar 2024 19:28:27 -0700 Subject: [PATCH 3/7] format --- .../compiler/sql_compiler.py | 22 +++++++++++-------- src/linkml_transformer/session.py | 10 ++++----- .../transformer/duckdb_transformer.py | 2 +- tests/test_compiler/test_duckdb_compiler.py | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/linkml_transformer/compiler/sql_compiler.py b/src/linkml_transformer/compiler/sql_compiler.py index 4c772c4..95faae9 100644 --- a/src/linkml_transformer/compiler/sql_compiler.py +++ b/src/linkml_transformer/compiler/sql_compiler.py @@ -2,9 +2,11 @@ from linkml_runtime.linkml_model import SlotDefinition from linkml_transformer.compiler.compiler import CompiledSpecification, Compiler -from linkml_transformer.datamodel.transformer_model import TransformationSpecification, ClassDerivation, \ - SerializationSyntaxType - +from linkml_transformer.datamodel.transformer_model import ( + ClassDerivation, + SerializationSyntaxType, + TransformationSpecification, +) LINKML_TO_SQL_TYPE_MAP = { "string": "TEXT", @@ -16,17 +18,17 @@ "date": "DATE", "time": "TIME", "uri": "TEXT", - "any": "TEXT" + "any": "TEXT", } - class SQLCompiler(Compiler): """ Compiles a Transformation Specification to SQL CREATE TABLE or VIEW statements. Note: this is currently highly geared towards DuckDB. """ + add_if_not_exists: bool = True new_table_when_transforming: bool = False @@ -36,7 +38,12 @@ def compile(self, specification: TransformationSpecification) -> CompiledSpecifi self.compile_class(compiled, cd, specification) return compiled - def compile_class(self, compiled: CompiledSpecification, cd: ClassDerivation, specification: TransformationSpecification) -> None: + def compile_class( + self, + compiled: CompiledSpecification, + cd: ClassDerivation, + specification: TransformationSpecification, + ) -> None: """ Compile a class derivation to SQL. @@ -81,7 +88,6 @@ def compile_slot_derivation(self, sd) -> str: expr = f"STRING_AGG({expr}, '{delimiter}')" return f" {sd.name} AS {expr}" - def create_ddl(self, schemaview: SchemaView) -> str: """ Create DDL for the entire schema. @@ -130,5 +136,3 @@ def sql_type(self, slot: SlotDefinition, schemaview: SchemaView) -> str: if slot.multivalued: typ = f"{typ}[]" return typ - - diff --git a/src/linkml_transformer/session.py b/src/linkml_transformer/session.py index 8f8ab62..a29a53e 100644 --- a/src/linkml_transformer/session.py +++ b/src/linkml_transformer/session.py @@ -51,7 +51,6 @@ def set_transformer_specification( obj = yaml.safe_load(open(specification)) self.set_transformer_specification(obj) - def set_source_schema(self, schema: Union[str, Path, dict, SchemaView, SchemaDefinition]): """ Sets the schema from a path or SchemaView object. @@ -72,7 +71,10 @@ def set_source_schema(self, schema: Union[str, Path, dict, SchemaView, SchemaDef self._target_schema = None def set_object_transformer( - self, transformer: Optional[Union[ObjectTransformer, TransformationSpecification, dict, str, Path]] = None + self, + transformer: Optional[ + Union[ObjectTransformer, TransformationSpecification, dict, str, Path] + ] = None, ): if transformer is None: if self.object_transformer is not None: @@ -95,9 +97,7 @@ def target_schema(self) -> SchemaDefinition: if self._target_schema is None: if not self.schema_mapper: self.schema_mapper = SchemaMapper(source_schemaview=self.source_schemaview) - self._target_schema = self.schema_mapper.derive_schema( - self.transformer_specification - ) + self._target_schema = self.schema_mapper.derive_schema(self.transformer_specification) return self._target_schema @property diff --git a/src/linkml_transformer/transformer/duckdb_transformer.py b/src/linkml_transformer/transformer/duckdb_transformer.py index 1c9bd3c..ccde2c0 100644 --- a/src/linkml_transformer/transformer/duckdb_transformer.py +++ b/src/linkml_transformer/transformer/duckdb_transformer.py @@ -3,7 +3,6 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Type, Union - from linkml_transformer.transformer.transformer import OBJECT_TYPE, Transformer DICT_OBJ = Dict[str, Any] @@ -33,5 +32,6 @@ def transform( :return: transformed data, either as type target_type or a dictionary """ import duckdb + sv = self.source_schemaview raise NotImplementedError("DuckDBTransformer.transform") diff --git a/tests/test_compiler/test_duckdb_compiler.py b/tests/test_compiler/test_duckdb_compiler.py index 804463c..f816f37 100644 --- a/tests/test_compiler/test_duckdb_compiler.py +++ b/tests/test_compiler/test_duckdb_compiler.py @@ -35,8 +35,8 @@ def test_compile(session): target_ddl = compiler.create_ddl(target_sv) print(target_ddl) - import duckdb - conn = duckdb.connect(':memory:') + + conn = duckdb.connect(":memory:") conn.execute(target_ddl) conn.execute(compiled.serialization) From e11ba6a1ef259e712283d7a821b2b9d044a01e40 Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Mon, 25 Mar 2024 07:22:07 -0700 Subject: [PATCH 4/7] refactored docs --- Makefile | 4 +- README.md | 329 +--- mkdocs.yml | 13 +- notebooks/Tutorial.ipynb | 954 ----------- poetry.lock | 1501 +++++++++-------- pyproject.toml | 7 +- src/docs/about.md | 1 - src/docs/faq.md | 38 + src/docs/index.md | 180 ++ src/linkml_transformer/cli/cli.py | 3 +- src/linkml_transformer/compiler/compiler.py | 4 + .../datamodel/specification_view.py | 17 - .../functions/unit_conversion.py | 1 + .../inference/schema_mapper.py | 1 + src/linkml_transformer/session.py | 29 +- .../transformer/duckdb_transformer.py | 41 +- .../transformer/object_transformer.py | 10 +- .../transformer/transformer.py | 30 +- .../utils/multi_file_transformer.py | 3 +- tests/test_compiler/test_duckdb_compiler.py | 1 + tests/test_compiler/test_graphviz_compiler.py | 1 + tests/test_compiler/test_markdown_compiler.py | 1 + tests/test_compiler/test_python_compiler.py | 1 + .../test_compliance/test_compliance_suite.py | 7 +- .../test_duckdb_transformer.py | 41 + .../test_object_transformer.py | 12 +- 26 files changed, 1206 insertions(+), 2024 deletions(-) delete mode 100644 notebooks/Tutorial.ipynb delete mode 100644 src/docs/about.md create mode 100644 src/docs/faq.md create mode 100644 src/docs/index.md delete mode 100644 src/linkml_transformer/datamodel/specification_view.py create mode 100644 tests/test_transformer/test_duckdb_transformer.py diff --git a/Makefile b/Makefile index b21a2c8..c88f588 100644 --- a/Makefile +++ b/Makefile @@ -96,13 +96,13 @@ $(DOCDIR): gendoc: $(DOCDIR) cp -pr $(SRC)/docs/* $(DOCDIR) ; \ - $(RUN) gen-doc -d $(DOCDIR) $(SOURCE_SCHEMA_PATH) + $(RUN) gen-doc -d $(DOCDIR) $(SOURCE_SCHEMA_PATH) --index-name datamodel testdoc: gendoc serve MKDOCS = $(RUN) mkdocs mkd-%: - $(MKDOCS) $* + $(MKDOCS) $* $(MKDOCS_ARGS) PROJECT_FOLDERS = sqlschema shex shacl protobuf prefixmap owl jsonschema jsonld graphql excel git-init-add: git-init git-add git-commit git-status diff --git a/README.md b/README.md index 0017d8d..b1ea7ff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # linkml-transformer +[![Pyversions](https://img.shields.io/pypi/pyversions/linkml-transformer.svg)](https://pypi.python.org/pypi/linkml-transformer) +![](https://github.com/linkml/linkml-transformer/workflows/Build/badge.svg) +[![PyPi](https://img.shields.io/pypi/v/linkml-transformer.svg)](https://pypi.python.org/pypi/linkml-transformer) +[![codecov](https://codecov.io/gh/linkml/linkml-transformer/branch/main/graph/badge.svg?token=WNQNG986UN)](https://codecov.io/gh/linkml/linkml-transformer) + LinkML Transformer is a framework for specifying and executing mappings between data models. Features: @@ -14,6 +19,10 @@ Features: - Visualizations of mappings - Mappings are reversible (provided all expressions used are reversible) +For full documentation see: + +- [linkml.io/linkml-transformer/](https://linkml.io/linkml-transformer/) + Status: The transformation data model is not yet fully stable, and may be subject to change. @@ -21,325 +30,7 @@ Not all parts of the model are implemented in the reference Python framework. ## Quickstart -* [Tutorial Notebook](notebooks/Tutorial.ipynb) +* [Tutorial Notebook](src/docs/examples/Tutorial.ipynb) * [Generated Docs](https://linkml.github.io/linkml-transformer/) * [Compliance Suite](https://linkml.github.io/linkml-transformer/specification/compliance) -## Basic idea - -Given an object that conforms to a LinkML schema,e.g.: - -```yaml -given_name: Jane -family_name: Doe -height_in_cm: 172.0 -age_in_years: 33 -aliases: [Janey, Janie] -``` - -Define a mapping in YAML: - -```yaml -class_derivations: - Individual: - populated_from: Person - slot_derivations: - name: - expr: "{given_name} + ' ' + {family_name}" - description: Concatenating given and family names - note this is a bad assumption for names in general, - this is just for demonstration - height_in_meters: - populated_from: height_in_cm - unit_conversion: - target_unit: m - aliases: - populated_from: aliases - stringification: - delimiter: '|' -``` - -Transform the data: - -```yaml -name: Jane Doe -height_in_meters: 1.72 -aliases: Janey|Janie -``` - -## Installation and usage - -Installation and command line usage: - -```bash -pip[x] install linkml-transformer -cd tests/input/examples/personinfo_basic -linkml-tr map-data \ - -T transform/personinfo-to-agent.transform.yaml \ - -s source/personinfo.yaml \ - data/Container-001.yaml \ - -o output/Translated-001.yaml -``` - -The command line has subcommands for: - -- `map-data` - map data from a source schema to a target schema -- `derive-schema` - derive a target schema from a source schema and a mapping -- `invert` - reverses a mapping -- `compile` - compiles a mapping to another framework - - `markdown` - for generating static sites - - `graphviz` - for generating visualizations - - `python` - (partial) - - forthcoming: `r2rml`, ... - -## Details - -This repo contains both: - -- A data model for a data model *transformation language* -- A reference python implementation - -The transformation language is specified in terms of LinkML schemas. -It is intended to be a *ployglot* transformation language, used for -specifying how to map data models independent of underlying representation -(TSVs, JSON/YAML, RDF, SQL Database, ...). - -Use cases include: - -- ETL and mapping from one data model to another -- Database migrations (one version of a schema to another) -- Creating "profiles" -- Specifying mappings between different serializations of a model (e.g. OO to Relational) -- Mapping between normalized/non-redundant forms and denormalized/query-optimized forms - -## Tutorials - -* [Tutorial Notebook](notebooks/Tutorial.ipynb) - for Python developers - -## Data Model - -The data model for transformations mirrors the data model for schemas: - -- A top level `TransformationSpecification` class contains: - - Zero or more `ClassDerivation` objects, specifying how to map to a class, containing: - - Zero or more `SlotDerivation` objects, specifying how to map to a slot, containing: - - Zero or more `EnumDerivation` objects, specifying how to map permissible values. - -See the [generated docs](https://linkml.github.io/linkml-transformer/) - -## Conformance Suite - -The Transformers conformance suite contains a collection of tests for each feature of the language. - -See: - -* [Compliance Suite](https://linkml.github.io/linkml-transformer/specification/compliance) - - -## Running the code - -```bash -linkml-tr --help -Usage: linkml-tr [OPTIONS] COMMAND [ARGS]... - - CLI for linkml-transformer. - -Options: - -v, --verbose - -q, --quiet TEXT - --help Show this message and exit. - -Commands: - derive-schema Derive a schema from a source schema and a mapping. - map-data Map data in a source schema using a transformation. -``` - -### map-data - -Transforms (maps) data from a source schema to a target schema. This could range from a simple data dictionary mapping -through to a complex mappings. - -``` -cd tests/input/examples/personinfo_basic -linkml-tr map-data -T transform/personinfo-to-agent.transform.yaml -s source/personinfo.yaml data/Container-001.yaml -``` - -### derive-schema - -``` -cd tests/input/examples/personinfo_basic -linkml-tr derive-schema -T transform/personinfo-to-agent.transform.yaml source/personinfo.yaml -``` - - -## Examples - -See the tests folder for most up-to-date examples - -### Mapping between two similar data models - -Given a *source* object - -```yaml -persons: - - id: P:001 - name: fred bloggs - primary_email: fred.bloggs@example.com - age_in_years: 33 - has_familial_relationships: - - type: SIBLING_OF - related_to: P:002 - current_address: - street: 1 oak street - aliases: - - a - - b - has_medical_history: - - diagnosis: - id: C:001 - name: c1 - - diagnosis: - id: C:002 - - id: P:002 - name: Alison Wu - has_familial_relationships: - - type: SIBLING_OF - related_to: P:001 - has_medical_history: - - diagnosis: - id: C:001 - name: c1 (renamed) -organizations: - - id: ROR:1 - name: Acme -``` - -and a corresponding schema, consider the case -of mapping to a largely isomorphic schema, with some minor differences: - -- class names are changes (e.g Person to Agent) -- age is represented as a string, e.g. "33 years" -- some fields are denormalized - -The mapping may look like: - -```yaml -id: my-mappings -title: my mappings -prefixes: - foo: foo -source_schema: s1 -target_schema: s2 -class_derivations: - Container: - populated_from: Container - slot_derivations: - agents: - populated_from: persons - Agent: - populated_from: Person - slot_derivations: - - ## implicitly same name in Agent - id: - - label: - populated_from: name - - age: - expr: "str({age_in_years})+' years'" - - primary_email: - - gender: - - has_familial_relationships: - populated_from: has_familial_relationships - - FamilialRelationship: - populated_from: FamilialRelationship - slot_derivations: - type: - related_to: -``` - -### Deriving Schemas - -Formally a mapping consists of a source schema `S`, a target schema `T`, and a mapping `M`. - -In practice, any of these can be *partially* specified and derived from the others. - -For example: - -- given `S`, and `T`, derive *isomorphic mappings* `M` based on shared URIs -- given `S and `M`, derive `T` by applying M to the schema - -You can use the `derive-schema` command to derive a schema from a source schema and a mapping. -This can also be thought of as "profiling" a schema (in the FHIR sense). - -See [tests/test_mapper/test_schema_mapper.py](tests/test_schema_mapper/test_schema_mapper.py) for examples - -### Measurements and units - -```yaml -- id: P:001 - height: - value: 172.0 - unit: cm -``` - -<==> - -```yaml -- id: P:001 - height_in_cm: 172.0 -``` - -<==> - -```yaml -- id: P:001 - height: "172.0 cm" -``` - -## Not supported - -- Aggregation -- ... - -## Why another framework? - -There are a number of excellent frameworks for performing mapping and data transformations. -The LinkML Transformer framework was born out of a need for a framework that: - -- was not inherently tied to: - - a particular serialization format (e.g. RDF, JSON, ...) - - a particular programming language (e.g. Python, Java, ...) - - a particular database system or database language (e.g. PostgreSQL or SQL or SPARQL) - - not tied to a particular kind of transformation (e.g. ORM or Tables to RDF) -- was a natural fit for the LinkML data modeling framework -- was declarative and easy to perform machine reasoning over -- is simple for simple use cases - -In its current state, this framework is less powerful and expressive than many other frameworks -or methodologies for performing transformations. If you need to perform complex data transformations, -you might be better off using an expressive query language like SPARQL or SQL, or even just coding -transformations directly in a programming language or library like Python or Pandas (but note that -even for the coding use case, the LinkML Transformer framework can be useful as a standard way -of *documenting* transformations). - -Currently the main use case for this framework is *mostly isomorphic* transformations, with lightweight -manipulations. These lend themselves well to a declarative framework. Uses cases that are a particularly good fit -involve mapping between data-dictionary like standards, with large numbers of metadata elements, where these -elements can often be mapped one-to-one, or with simple manipulations (e.g. unit conversions). - -The origins lie partly in the SSSOM standard, which is intended as an ultra-simple way of specifying -precise mappings between *entities* (e.g. schema.org Person is the same as DBPedia person). We observed -that many people wanted to extend the language to perform more complex mappings. To address this, we -help a workshop at the Biocuration conference in Padua, Italy in 2022. - -- [Discussion](https://github.com/orgs/linkml/discussions/1829) -- [SSSOM paper](https://academic.oup.com/database/article/doi/10.1093/database/baac035/6591806) -- [SSSOM Update 2023](https://ceur-ws.org/Vol-3591/om2023_STpaper3.pdf) -- [SSSOM Complex Mappings Workshop 2023](https://www.youtube.com/playlist?list=PLqu_J7ADQtKyX55F7RqZtaSS7TwGd3MoR) -- [Mapping Data Structures: Challenges and Approaches](https://doi.org/10.5281/zenodo.10343505) diff --git a/mkdocs.yml b/mkdocs.yml index 2c610be..9db5a93 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,14 +1,21 @@ site_name: "LinkML-Transformer" theme: - name: material +# name: material + name: windmill features: - content.tabs.link plugins: - search - mermaid2 + - mknotebooks: + execute: true # This will execute the notebooks when building the site nav: - Index: index.md + - Examples: + Tutorial: examples/Tutorial.ipynb - Specification: + Data Model: datamodel.md Compliance Suite: specification/compliance.md -site_url: https://cmungall.github.io/linkml-transformer/ -repo_url: https://github.com/cmungall/linkml-transformer/ + - FAQ: faq.md +site_url: https://linkml.github.io/linkml-transformer/ +repo_url: https://github.com/linkml/linkml-transformer/ diff --git a/notebooks/Tutorial.ipynb b/notebooks/Tutorial.ipynb deleted file mode 100644 index 456f5a1..0000000 --- a/notebooks/Tutorial.ipynb +++ /dev/null @@ -1,954 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# LinkML-Transformer tutorial\n", - "\n", - "This tutorial walks through basic programmatic use of the LinkML-Transformer framework.\n", - "This is intended for Python developers - note that many of the operations here can also be performed\n", - "at the command line." - ], - "metadata": { - "collapsed": false - }, - "id": "df75d53a3e91e573" - }, - { - "cell_type": "code", - "execution_count": 1, - "outputs": [], - "source": [ - "import yaml" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:23.927439Z", - "start_time": "2024-03-23T02:12:23.819885Z" - } - }, - "id": "63a064b31f623bdd" - }, - { - "cell_type": "markdown", - "source": [ - "## Creating an example schema\n", - "\n", - "We will use a LinkML SchemaBuilder object to progressively build up a schema, adding\n", - "additional features as we go.\n", - "\n", - "We'll start with a simple `Person` schema, with a few single valued scalar slots:" - ], - "metadata": { - "collapsed": false - }, - "id": "e2cbd6b8994905f6" - }, - { - "cell_type": "code", - "execution_count": 2, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "name: test-schema\n", - "id: http://example.org/test-schema\n", - "imports:\n", - "- linkml:types\n", - "prefixes:\n", - " linkml: https://w3id.org/linkml/\n", - " test_schema: http://example.org/test-schema/\n", - "default_prefix: test_schema\n", - "default_range: string\n", - "slots:\n", - " family_name:\n", - " range: string\n", - " given_name:\n", - " range: string\n", - " age_in_years:\n", - " range: integer\n", - " height_in_cm:\n", - " range: float\n", - "classes:\n", - " Person:\n", - " slots:\n", - " - family_name\n", - " - given_name\n", - " - age_in_years\n", - " - height_in_cm\n" - ] - } - ], - "source": [ - "from linkml.utils.schema_builder import SchemaBuilder\n", - "from linkml_runtime.linkml_model import SlotDefinition\n", - "\n", - "sb = SchemaBuilder()\n", - "sb.add_class(\"Person\", slots=[SlotDefinition(\"family_name\", range=\"string\"), \n", - " SlotDefinition(\"given_name\", range=\"string\"),\n", - " SlotDefinition(\"age_in_years\", range=\"integer\"),\n", - " SlotDefinition(\"height_in_cm\", range=\"float\"),\n", - " ])\n", - "sb.add_defaults()\n", - "print(yaml.dump(sb.as_dict(), sort_keys=False))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:24.139985Z", - "start_time": "2024-03-23T02:12:23.842320Z" - } - }, - "id": "ef2c60ef7fbcbe20" - }, - { - "cell_type": "markdown", - "source": [ - "## Creating a Transformer Session object\n", - "\n", - "We will use a `Session` object which conveniently wraps a number of different capabilities;\n", - "the first of these capabilities is to map (transform) data objects from one schema to another\n", - "(implicit) schema using a *transformer specification*).\n", - "\n", - "Our initial transformer specification will be a trivial isomorphic one that:\n", - "\n", - "- maps the `Person` class to an `Individual` class\n", - "- passes through `name` fields as-is\n", - "- renames measurement fields (`age_in_years` and `height_in_cm` to `age` and `height`)" - ], - "metadata": { - "collapsed": false - }, - "id": "d4228629dd7e2ef2" - }, - { - "cell_type": "code", - "execution_count": 3, - "outputs": [], - "source": [ - "from linkml_transformer.session import Session\n", - "\n", - "session = Session()\n", - "session.set_source_schema(sb.as_dict())" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:24.847826Z", - "start_time": "2024-03-23T02:12:24.138432Z" - } - }, - "id": "a6257aa9e6ab021e" - }, - { - "cell_type": "code", - "execution_count": 4, - "outputs": [], - "source": [ - "# Transformer specification (in YAML)\n", - "session.set_object_transformer(\"\"\"\n", - "class_derivations:\n", - " Individual:\n", - " populated_from: Person\n", - " slot_derivations:\n", - " family_name:\n", - " populated_from: family_name\n", - " given_name:\n", - " populated_from: given_name\n", - " age:\n", - " populated_from: age_in_years\n", - " height:\n", - " populated_from: height_in_cm\n", - "\"\"\")" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.094008Z", - "start_time": "2024-03-23T02:12:24.897951Z" - } - }, - "id": "47b95e209790b423" - }, - { - "cell_type": "markdown", - "source": [ - "## Visualizing transformer specifications\n", - "\n", - "We can visualize the transformer specification using graphviz:" - ], - "metadata": { - "collapsed": false - }, - "id": "8313d6acb588178e" - }, - { - "cell_type": "code", - "execution_count": 5, - "outputs": [ - { - "data": { - "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nfamily_name : string\n\ngiven_name : string\n\nage : integer\n\nheight : float\n\n\n\nsourcePerson:family_name->targetIndividual:family_name\n\n\n\n\n\nsourcePerson:given_name->targetIndividual:given_name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height\n\n\n\n\n\n", - "text/plain": "" - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.graphviz()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.426050Z", - "start_time": "2024-03-23T02:12:25.096688Z" - } - }, - "id": "1c623cdc3c1cfbca" - }, - { - "cell_type": "markdown", - "source": [ - "## Transforming objects\n", - "\n", - "We'll next make a simple `Person` object. Note that for simplicity we are specifying this\n", - "using a Python dictionary. The framework also works with objects instantiating either\n", - "Pydantic or Dataclasses classes (use the `transform_object` method instead of `transform`)." - ], - "metadata": { - "collapsed": false - }, - "id": "a15707b9cd2d3db5" - }, - { - "cell_type": "code", - "execution_count": 6, - "outputs": [ - { - "data": { - "text/plain": "{'family_name': 'Doe', 'given_name': 'Jane', 'age': 42, 'height': 180.0}" - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "obj = {\n", - " \"given_name\": \"Jane\",\n", - " \"family_name\": \"Doe\",\n", - " \"age_in_years\": 42,\n", - " \"height_in_cm\": 180.0,\n", - " }\n", - "session.transform(obj)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.435969Z", - "start_time": "2024-03-23T02:12:25.431387Z" - } - }, - "id": "9f4d1fc4ca97f80c" - }, - { - "cell_type": "markdown", - "source": [ - "This does what we expect - it renames the two fields, but leaves all values intact.\n", - "\n", - "Note that because we use using dictionaries here, the renaming of the class has no effect,\n", - "as this is implicit with JSON/dictionaries.\n", - "\n", - "TODO: docs on type designator fields\n", - "\n", - "For command line users, the same thing can be achieved with the `map-data` command." - ], - "metadata": { - "collapsed": false - }, - "id": "b3826284a497d04e" - }, - { - "cell_type": "markdown", - "source": [ - "## Deriving target schemas\n", - "\n", - "LinkML-Transformer is intended as a *declarative* framework, in contrast to writing Python\n", - "transformation code. This allows tools to introspect mappings and perform other kinds of inference.\n", - "An example of this is *deriving the (implicit) target schema*\n", - "\n", - "Here we use the `target_schema` method on the session object to derive the target schema:" - ], - "metadata": { - "collapsed": false - }, - "id": "d6aa71d062e96aa1" - }, - { - "cell_type": "code", - "execution_count": 7, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "name: test-schema-derived\n", - "id: http://example.org/test-schema-derived\n", - "imports:\n", - "- linkml:types\n", - "prefixes:\n", - " linkml:\n", - " prefix_prefix: linkml\n", - " prefix_reference: https://w3id.org/linkml/\n", - " test_schema:\n", - " prefix_prefix: test_schema\n", - " prefix_reference: http://example.org/test-schema/\n", - "default_prefix: http://example.org/test-schema-derived/\n", - "default_range: string\n", - "classes:\n", - " Individual:\n", - " name: Individual\n", - " attributes:\n", - " family_name:\n", - " name: family_name\n", - " range: string\n", - " given_name:\n", - " name: given_name\n", - " range: string\n", - " age:\n", - " name: age\n", - " range: integer\n", - " height:\n", - " name: height\n", - " range: float\n" - ] - } - ], - "source": [ - "from linkml_runtime.dumpers import yaml_dumper\n", - "\n", - "print(yaml_dumper.dumps(session.target_schema))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.442750Z", - "start_time": "2024-03-23T02:12:25.434388Z" - } - }, - "id": "687912c18bf6752" - }, - { - "cell_type": "markdown", - "source": [ - "As expected, this is isomorphic to the original (source) schema, with fields and classes renamed." - ], - "metadata": { - "collapsed": false - }, - "id": "2c89abbd8e298981" - }, - { - "cell_type": "markdown", - "source": [ - "## Using Expressions\n", - "\n", - "In addition to renaming fields, we can derive field values via evaluation of function *expressions*.\n", - "\n", - "You are encouraged to follow the subset of Python defined by the LinkML expression language. This provides\n", - "both safety, and declarativity. However, if you need\n", - "to, you can include arbitrary Python code, provided you configure the session to allow this.\n", - "\n", - "We'll keep the original schema, and will provide a new Transformer specification, \n", - "giving an example of both string manipulation functions and arithmetic functions; the latter\n", - "perform unit conversions (later on we will see more flexible and declarative ways to perform unit conversions).\n", - "\n" - ], - "metadata": { - "collapsed": false - }, - "id": "4562b534b6f23910" - }, - { - "cell_type": "code", - "execution_count": 8, - "outputs": [], - "source": [ - "\n", - "session.set_object_transformer(\"\"\"\n", - "class_derivations:\n", - " Individual:\n", - " populated_from: Person\n", - " slot_derivations:\n", - " name:\n", - " expr: \"{given_name} + ' ' + {family_name}\"\n", - " description: Concatenating given and family names\n", - " note this is a bad assumption for names in general,\n", - " this is just for demonstration\n", - " age_in_months:\n", - " expr: age_in_years * 12\n", - " height_in_meters:\n", - " expr: height_in_cm / 100\n", - "\"\"\")\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.502675Z", - "start_time": "2024-03-23T02:12:25.460193Z" - } - }, - "id": "789a7b6535ab410f" - }, - { - "cell_type": "markdown", - "source": [ - "Note that when we visualize this specification, dotted lines are shown indicating a relationship\n", - "between source and target that is different from direct copy:" - ], - "metadata": { - "collapsed": false - }, - "id": "e02eaa2cde3172c8" - }, - { - "cell_type": "code", - "execution_count": 9, - "outputs": [ - { - "data": { - "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nname : string\n\nage_in_months : string\n\nheight_in_meters : string\n\n\n\nsourcePerson:given_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:family_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age_in_months\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height_in_meters\n\n\n\n\n\n", - "text/plain": "" - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.graphviz()" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.810836Z", - "start_time": "2024-03-23T02:12:25.509345Z" - } - }, - "id": "2a18ccb5d7dc469b" - }, - { - "cell_type": "markdown", - "source": [ - "Now we'll transform the same object as before, and see the results:" - ], - "metadata": { - "collapsed": false - }, - "id": "f7019db8d391ab97" - }, - { - "cell_type": "code", - "execution_count": 10, - "outputs": [ - { - "data": { - "text/plain": "{'name': 'Jane Doe', 'age_in_months': 504, 'height_in_meters': 1.8}" - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.transform(obj)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.816826Z", - "start_time": "2024-03-23T02:12:25.812549Z" - } - }, - "id": "5e20e98e2b23751f" - }, - { - "cell_type": "markdown", - "source": [ - "As expected, we concatenated the name fields, and converted the age and height fields to different units.\n", - "\n", - "Let's take a look at the derived schema for this new transformation:" - ], - "metadata": { - "collapsed": false - }, - "id": "ad9fd0f70178fd26" - }, - { - "cell_type": "code", - "execution_count": 11, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "name: test-schema-derived\n", - "id: http://example.org/test-schema-derived\n", - "imports:\n", - "- linkml:types\n", - "prefixes:\n", - " linkml:\n", - " prefix_prefix: linkml\n", - " prefix_reference: https://w3id.org/linkml/\n", - " test_schema:\n", - " prefix_prefix: test_schema\n", - " prefix_reference: http://example.org/test-schema/\n", - "default_prefix: http://example.org/test-schema-derived/\n", - "default_range: string\n", - "classes:\n", - " Individual:\n", - " name: Individual\n", - " attributes:\n", - " name:\n", - " name: name\n", - " age_in_months:\n", - " name: age_in_months\n", - " height_in_meters:\n", - " name: height_in_meters\n" - ] - } - ], - "source": [ - "print(yaml_dumper.dumps(session.target_schema))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.825306Z", - "start_time": "2024-03-23T02:12:25.820116Z" - } - }, - "id": "7c1f7efef1836364" - }, - { - "cell_type": "markdown", - "source": [ - "Note that at this time, deriving ranges using expressions is not supported, so the two measurement fields\n", - "are erroneously typed as having the `default_range` of `string`. However, in principle, if you use the\n", - "linkml subset of Python it should be possible to infer the range of the derived field, and this may be added\n", - "in future versions. Currently the tool chain is at an early stage of development." - ], - "metadata": { - "collapsed": false - }, - "id": "e87b7f45dc137a68" - }, - { - "cell_type": "markdown", - "source": [ - "## Unit conversions\n", - "\n", - "Next we will look at a different way of doing unit conversions. The LinkML specification allows\n", - "schemas to explicitly declare the units of slots, so let's modify our schema to do this, adding\n", - "a UCUM code for our `height_in_cm` slot:" - ], - "metadata": { - "collapsed": false - }, - "id": "ff3d20924263ec15" - }, - { - "cell_type": "code", - "execution_count": 12, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "name: test-schema\n", - "id: http://example.org/test-schema\n", - "imports:\n", - "- linkml:types\n", - "prefixes:\n", - " linkml: https://w3id.org/linkml/\n", - " test_schema: http://example.org/test-schema/\n", - "default_prefix: test_schema\n", - "default_range: string\n", - "slots:\n", - " family_name:\n", - " range: string\n", - " given_name:\n", - " range: string\n", - " age_in_years:\n", - " range: integer\n", - " height_in_cm:\n", - " range: float\n", - " unit:\n", - " ucum_code: cm\n", - "classes:\n", - " Person:\n", - " slots:\n", - " - family_name\n", - " - given_name\n", - " - age_in_years\n", - " - height_in_cm\n" - ] - } - ], - "source": [ - "from linkml_runtime.linkml_model.units import UnitOfMeasure\n", - "sb.schema.slots['height_in_cm'].unit = UnitOfMeasure(ucum_code='cm')\n", - "session.set_source_schema(sb.as_dict())\n", - "print(yaml.dump(sb.as_dict(), sort_keys=False))" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.850932Z", - "start_time": "2024-03-23T02:12:25.833403Z" - } - }, - "id": "65a5ce5d97e27f76" - }, - { - "cell_type": "markdown", - "source": [ - "## Adding target_unit to transformer specification\n", - "\n", - "We will create a new transformer specification, focusing on the `height_in_cm` field. We will\n", - "transform this into a `height_in_meters` field, and will use the `target_unit` field to specify\n", - "the target unit." - ], - "metadata": { - "collapsed": false - }, - "id": "c5cf59ec9ac3148e" - }, - { - "cell_type": "code", - "execution_count": 13, - "outputs": [], - "source": [ - "session.set_object_transformer(\"\"\"\n", - "class_derivations:\n", - " Individual:\n", - " populated_from: Person\n", - " slot_derivations:\n", - " name:\n", - " expr: \"{given_name} + ' ' + {family_name}\"\n", - " height_in_meters:\n", - " populated_from: height_in_cm\n", - " unit_conversion:\n", - " target_unit: m\n", - "\"\"\")" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:25.901551Z", - "start_time": "2024-03-23T02:12:25.853769Z" - } - }, - "id": "bc99bad97970b1b7" - }, - { - "cell_type": "code", - "execution_count": 14, - "outputs": [ - { - "data": { - "text/plain": "{'name': 'Jane Doe', 'height_in_meters': 1.8}" - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.transform(obj)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.176193Z", - "start_time": "2024-03-23T02:12:25.901292Z" - } - }, - "id": "831b444d9c47e0ea" - }, - { - "cell_type": "markdown", - "source": [ - "## Units in derived schema\n", - "\n", - "Next we'll look at the derived target schema, and as expected we see that it has inferred\n", - "the target unit for the `height_in_meters` field:" - ], - "metadata": { - "collapsed": false - }, - "id": "6f37087c6dfc30ef" - }, - { - "cell_type": "code", - "execution_count": 15, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "name: test-schema-derived\n", - "id: http://example.org/test-schema-derived\n", - "imports:\n", - "- linkml:types\n", - "prefixes:\n", - " linkml:\n", - " prefix_prefix: linkml\n", - " prefix_reference: https://w3id.org/linkml/\n", - " test_schema:\n", - " prefix_prefix: test_schema\n", - " prefix_reference: http://example.org/test-schema/\n", - "default_prefix: http://example.org/test-schema-derived/\n", - "default_range: string\n", - "classes:\n", - " Individual:\n", - " name: Individual\n", - " attributes:\n", - " name:\n", - " name: name\n", - " height_in_meters:\n", - " name: height_in_meters\n", - " range: float\n", - " unit:\n", - " ucum_code: m\n" - ] - } - ], - "source": [ - "print(yaml_dumper.dumps(session.target_schema))\n" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.176598Z", - "start_time": "2024-03-23T02:12:26.152743Z" - } - }, - "id": "b589e0e95550962d" - }, - { - "cell_type": "markdown", - "source": [ - "## Tabular serialization" - ], - "metadata": { - "collapsed": false - }, - "id": "8f4c4cb125aade0b" - }, - { - "cell_type": "code", - "execution_count": 16, - "outputs": [], - "source": [ - "slot = sb.add_slot(\"aliases\", multivalued=True, range=\"string\", replace_if_present=True)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.176672Z", - "start_time": "2024-03-23T02:12:26.156764Z" - } - }, - "id": "f492b27c0f0fbf88" - }, - { - "cell_type": "code", - "execution_count": 17, - "outputs": [], - "source": [ - "sb.schema.classes['Person'].slots.append(slot.name)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.176741Z", - "start_time": "2024-03-23T02:12:26.159739Z" - } - }, - "id": "3ac3f93ab8561300" - }, - { - "cell_type": "code", - "execution_count": 18, - "outputs": [], - "source": [ - "session.set_source_schema(sb.as_dict())" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.177256Z", - "start_time": "2024-03-23T02:12:26.168743Z" - } - }, - "id": "84262d357323f76e" - }, - { - "cell_type": "code", - "execution_count": 19, - "outputs": [], - "source": [ - "session.set_object_transformer(\"\"\"\n", - "class_derivations:\n", - " Individual:\n", - " populated_from: Person\n", - " slot_derivations:\n", - " family_name:\n", - " populated_from: family_name\n", - " given_name:\n", - " populated_from: given_name\n", - " age:\n", - " populated_from: age_in_years\n", - " height:\n", - " populated_from: height_in_cm\n", - " aliases:\n", - " populated_from: aliases\n", - " stringification:\n", - " delimiter: '|'\n", - "\"\"\") " - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.249455Z", - "start_time": "2024-03-23T02:12:26.222590Z" - } - }, - "id": "2f282430f48e13c0" - }, - { - "cell_type": "code", - "execution_count": 20, - "outputs": [ - { - "data": { - "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age': 42,\n 'height': 180.0,\n 'aliases': 'Jane|Janie|Janey'}" - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "obj = {\n", - " \"given_name\": \"Jane\",\n", - " \"family_name\": \"Doe\",\n", - " \"age_in_years\": 42,\n", - " \"height_in_cm\": 180.0,\n", - " \"aliases\": [\"Jane\", \"Janie\", \"Janey\"]\n", - " }\n", - "flattened = session.transform(obj)\n", - "flattened" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.279106Z", - "start_time": "2024-03-23T02:12:26.242965Z" - } - }, - "id": "fdd23ae82909770e" - }, - { - "cell_type": "markdown", - "source": [ - "this can easily be serialized to a CSV/TSV" - ], - "metadata": { - "collapsed": false - }, - "id": "c5174dcbf7dd0c43" - }, - { - "cell_type": "markdown", - "source": [ - "## Reverse transform\n", - "\n", - "If a transform does not contain one-way functions,\n", - "it can be *reversed*.\n", - "\n", - "In this case, reversing the transform allows us to map\n", - "from the tabular form back to the richer original representation." - ], - "metadata": { - "collapsed": false - }, - "id": "fae8392b02526408" - }, - { - "cell_type": "code", - "execution_count": 21, - "outputs": [ - { - "data": { - "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age_in_years': 42,\n 'height_in_cm': 180.0,\n 'aliases': ['Jane', 'Janie', 'Janey']}" - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "session.reverse_transform(flattened)" - ], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.339410Z", - "start_time": "2024-03-23T02:12:26.280636Z" - } - }, - "id": "e8c1c3f98081d38" - }, - { - "cell_type": "code", - "execution_count": 21, - "outputs": [], - "source": [], - "metadata": { - "collapsed": false, - "ExecuteTime": { - "end_time": "2024-03-23T02:12:26.339637Z", - "start_time": "2024-03-23T02:12:26.317148Z" - } - }, - "id": "ee14ace4b1c7d256" - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/poetry.lock b/poetry.lock index 65a1047..4d4c034 100644 --- a/poetry.lock +++ b/poetry.lock @@ -25,14 +25,14 @@ files = [ [[package]] name = "anyio" -version = "4.2.0" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] @@ -48,14 +48,14 @@ trio = ["trio (>=0.23)"] [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] [[package]] @@ -139,14 +139,14 @@ test = ["dateparser (>=1.0.0,<2.0.0)", "pre-commit", "pytest", "pytest-cov", "py [[package]] name = "asteval" -version = "0.9.31" +version = "0.9.32" description = "Safe, minimalistic evaluator of python expression using ast module" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "asteval-0.9.31-py3-none-any.whl", hash = "sha256:2761750c184d97707c292b62df3b10e330a809a2201721acc435a2b89a114263"}, - {file = "asteval-0.9.31.tar.gz", hash = "sha256:a2da066b6696dba9835c5f7dec63e0ffb5bd2b4e3bb5f0b9a604aeafb17d833d"}, + {file = "asteval-0.9.32-py3-none-any.whl", hash = "sha256:4d0da45a15f15eeb88bb53cf4c352591ccb00f00f81f74649fd7084519adc3fe"}, + {file = "asteval-0.9.32.tar.gz", hash = "sha256:3bef25a973d378fda21c83a38c6292c4d0d94773f49f42073e69dbb19932bb74"}, ] [package.extras] @@ -226,20 +226,23 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "beautifulsoup4" -version = "4.12.2" +version = "4.12.3" description = "Screen-scraping library" category = "dev" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [package.dependencies] soupsieve = ">1.2" [package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] @@ -264,26 +267,26 @@ css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "cachetools" -version = "5.3.2" +version = "5.3.3" description = "Extensible memoizing collections and decorators" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"}, - {file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"}, + {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, + {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, ] [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] @@ -369,7 +372,7 @@ rdflib = ">=0.4.2" name = "chardet" version = "5.2.0" description = "Universal encoding detector for Python 3" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -506,14 +509,14 @@ files = [ [[package]] name = "comm" -version = "0.2.1" +version = "0.2.2" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, - {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, ] [package.dependencies] @@ -524,64 +527,64 @@ test = ["pytest"] [[package]] name = "coverage" -version = "7.4.0" +version = "7.4.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, - {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, - {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, - {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, - {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, - {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, - {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, - {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, - {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, - {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, - {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, - {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, - {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, - {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, - {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, - {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, - {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, - {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, - {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, - {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, - {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, - {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c"}, + {file = "coverage-7.4.4-cp310-cp310-win32.whl", hash = "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d"}, + {file = "coverage-7.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b"}, + {file = "coverage-7.4.4-cp311-cp311-win32.whl", hash = "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286"}, + {file = "coverage-7.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9"}, + {file = "coverage-7.4.4-cp312-cp312-win32.whl", hash = "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0"}, + {file = "coverage-7.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c"}, + {file = "coverage-7.4.4-cp38-cp38-win32.whl", hash = "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e"}, + {file = "coverage-7.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade"}, + {file = "coverage-7.4.4-cp39-cp39-win32.whl", hash = "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57"}, + {file = "coverage-7.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c"}, + {file = "coverage-7.4.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677"}, + {file = "coverage-7.4.4.tar.gz", hash = "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49"}, ] [package.dependencies] @@ -592,14 +595,14 @@ toml = ["tomli"] [[package]] name = "curies" -version = "0.7.4" +version = "0.7.8" description = "Idiomatic conversion between URIs and compact URIs (CURIEs)." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "curies-0.7.4-py3-none-any.whl", hash = "sha256:478f1818345988933d8bc6060f80a985401331f856ff8cf9bd98fa00d178ad39"}, - {file = "curies-0.7.4.tar.gz", hash = "sha256:d3aaf16644b26ac2605ff83c565ec7df0ba0b5f7425516047666e609ec5fb718"}, + {file = "curies-0.7.8-py3-none-any.whl", hash = "sha256:a60b2559f08557176b0a3df1f7c47ec7cd8ae4e0695f23fc6574825d2ccd17eb"}, + {file = "curies-0.7.8.tar.gz", hash = "sha256:d208ad40b5e40b532285c917f116001f9e887a48dda54e6eedd10e514ea6aa1a"}, ] [package.dependencies] @@ -617,30 +620,34 @@ tests = ["coverage", "pytest"] [[package]] name = "debugpy" -version = "1.8.0" +version = "1.8.1" description = "An implementation of the Debug Adapter Protocol for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb"}, - {file = "debugpy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada"}, - {file = "debugpy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f"}, - {file = "debugpy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637"}, - {file = "debugpy-1.8.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e"}, - {file = "debugpy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6"}, - {file = "debugpy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b"}, - {file = "debugpy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153"}, - {file = "debugpy-1.8.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd"}, - {file = "debugpy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f"}, - {file = "debugpy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa"}, - {file = "debugpy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595"}, - {file = "debugpy-1.8.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8"}, - {file = "debugpy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332"}, - {file = "debugpy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6"}, - {file = "debugpy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926"}, - {file = "debugpy-1.8.0-py2.py3-none-any.whl", hash = "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4"}, - {file = "debugpy-1.8.0.zip", hash = "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0"}, + {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, + {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, + {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, + {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, + {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, + {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, + {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, + {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, + {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, + {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, + {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, + {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, + {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, + {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, + {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, + {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, + {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, + {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, + {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, + {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, + {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, + {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, ] [[package]] @@ -708,7 +715,7 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] name = "distlib" version = "0.3.8" description = "Distribution utilities" -category = "main" +category = "dev" optional = false python-versions = "*" files = [ @@ -775,14 +782,13 @@ files = [ [[package]] name = "editorconfig" -version = "0.12.3" +version = "0.12.4" description = "EditorConfig File Locator and Interpreter for Python" category = "dev" optional = false python-versions = "*" files = [ - {file = "EditorConfig-0.12.3-py3-none-any.whl", hash = "sha256:6b0851425aa875b08b16789ee0eeadbd4ab59666e9ebe728e526314c4a2e52c1"}, - {file = "EditorConfig-0.12.3.tar.gz", hash = "sha256:57f8ce78afcba15c8b18d46b5170848c88d56fd38f05c2ec60dbbfcb8996e89e"}, + {file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"}, ] [[package]] @@ -846,7 +852,7 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "filelock" version = "3.13.1" description = "A platform independent file lock." -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -889,22 +895,55 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["flake8", "markdown", "twine", "wheel"] +[[package]] +name = "gitdb" +version = "4.0.11" +description = "Git Object Database" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.42" +description = "GitPython is a Python library used to interact with Git repositories" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.42-py3-none-any.whl", hash = "sha256:1bf9cd7c9e7255f77778ea54359e54ac22a72a5b51288c457c881057b7bb9ecd"}, + {file = "GitPython-3.1.42.tar.gz", hash = "sha256:2d99869e0fef71a73cbd242528105af1d6c1b108c60dfabd994bf292f76c3ceb"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar"] + [[package]] name = "graphviz" -version = "0.20.1" +version = "0.20.3" description = "Simple Python interface for Graphviz" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, - {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, + {file = "graphviz-0.20.3-py3-none-any.whl", hash = "sha256:81f848f2904515d8cd359cc611faba817598d2feaac4027b266aa3eda7b3dde5"}, + {file = "graphviz-0.20.3.zip", hash = "sha256:09d6bc81e6a9fa392e7ba52135a9d49f1ed62526f96499325930e87ca1b5925d"}, ] [package.extras] dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] -docs = ["sphinx (>=5)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] -test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>=3)"] +docs = ["sphinx (>=5,<7)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] +test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] [[package]] name = "greenlet" @@ -978,6 +1017,18 @@ files = [ docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + [[package]] name = "hbreader" version = "0.9.1" @@ -990,6 +1041,53 @@ files = [ {file = "hbreader-0.9.1.tar.gz", hash = "sha256:d2c132f8ba6276d794c66224c3297cec25c8079d0a4cf019c061611e0a3b94fa"}, ] +[[package]] +name = "httpcore" +version = "1.0.4" +description = "A minimal low-level HTTP client." +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"}, + {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] +trio = ["trio (>=0.22.0,<0.25.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = ">=1.0.0,<2.0.0" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] + [[package]] name = "idna" version = "3.6" @@ -1004,23 +1102,23 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.1" +version = "7.1.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, + {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, + {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" @@ -1036,14 +1134,14 @@ files = [ [[package]] name = "ipykernel" -version = "6.28.0" +version = "6.29.3" description = "IPython Kernel for Jupyter" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "ipykernel-6.28.0-py3-none-any.whl", hash = "sha256:c6e9a9c63a7f4095c0a22a79f765f079f9ec7be4f2430a898ddea889e8665661"}, - {file = "ipykernel-6.28.0.tar.gz", hash = "sha256:69c11403d26de69df02225916f916b37ea4b9af417da0a8c827f84328d88e5f3"}, + {file = "ipykernel-6.29.3-py3-none-any.whl", hash = "sha256:5aa086a4175b0229d4eca211e181fb473ea78ffd9869af36ba7694c947302a21"}, + {file = "ipykernel-6.29.3.tar.gz", hash = "sha256:e14c250d1f9ea3989490225cc1a542781b095a18a19447fcf2b5eaf7d0ac5bd2"}, ] [package.dependencies] @@ -1066,7 +1164,7 @@ cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] pyqt5 = ["pyqt5"] pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] [[package]] name = "ipython" @@ -1108,22 +1206,22 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa [[package]] name = "ipywidgets" -version = "8.1.1" +version = "8.1.2" description = "Jupyter interactive widgets" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "ipywidgets-8.1.1-py3-none-any.whl", hash = "sha256:2b88d728656aea3bbfd05d32c747cfd0078f9d7e159cf982433b58ad717eed7f"}, - {file = "ipywidgets-8.1.1.tar.gz", hash = "sha256:40211efb556adec6fa450ccc2a77d59ca44a060f4f9f136833df59c9f538e6e8"}, + {file = "ipywidgets-8.1.2-py3-none-any.whl", hash = "sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60"}, + {file = "ipywidgets-8.1.2.tar.gz", hash = "sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9"}, ] [package.dependencies] comm = ">=0.1.3" ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.9,<3.1.0" +jupyterlab-widgets = ">=3.0.10,<3.1.0" traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.9,<4.1.0" +widgetsnbextension = ">=4.0.10,<4.1.0" [package.extras] test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] @@ -1180,14 +1278,14 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] @@ -1198,13 +1296,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsbeautifier" -version = "1.14.11" +version = "1.15.1" description = "JavaScript unobfuscator and beautifier." category = "dev" optional = false python-versions = "*" files = [ - {file = "jsbeautifier-1.14.11.tar.gz", hash = "sha256:6b632581ea60dd1c133cd25a48ad187b4b91f526623c4b0fb5443ef805250505"}, + {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"}, ] [package.dependencies] @@ -1229,19 +1327,16 @@ pyyaml = "*" [[package]] name = "json5" -version = "0.9.14" +version = "0.9.24" description = "A Python implementation of the JSON5 data format." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, - {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, + {file = "json5-0.9.24-py3-none-any.whl", hash = "sha256:4ca101fd5c7cb47960c055ef8f4d0e31e15a7c6c48c3b6f1473fc83b6c462a13"}, + {file = "json5-0.9.24.tar.gz", hash = "sha256:0c638399421da959a20952782800e5c1a78c14e08e1dc9738fa10d8ec14d58c8"}, ] -[package.extras] -dev = ["hypothesis"] - [[package]] name = "jsonasobj" version = "1.3.1" @@ -1286,14 +1381,14 @@ jsonpointer = ">=1.9" [[package]] name = "jsonpath-ng" -version = "1.6.0" +version = "1.6.1" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." category = "dev" optional = false python-versions = "*" files = [ - {file = "jsonpath-ng-1.6.0.tar.gz", hash = "sha256:5483f8e9d74c39c9abfab554c070ae783c1c8cbadf5df60d561bc705ac68a07e"}, - {file = "jsonpath_ng-1.6.0-py3-none-any.whl", hash = "sha256:6fd04833412c4b3d9299edf369542f5e67095ca84efa17cbb7f06a34958adc9f"}, + {file = "jsonpath-ng-1.6.1.tar.gz", hash = "sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa"}, + {file = "jsonpath_ng-1.6.1-py3-none-any.whl", hash = "sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be"}, ] [package.dependencies] @@ -1313,14 +1408,14 @@ files = [ [[package]] name = "jsonschema" -version = "4.20.0" +version = "4.21.1" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"}, - {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"}, + {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, + {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, ] [package.dependencies] @@ -1380,14 +1475,14 @@ qtconsole = "*" [[package]] name = "jupyter-client" -version = "8.6.0" +version = "8.6.1" description = "Jupyter protocol implementation and client libraries" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.6.0-py3-none-any.whl", hash = "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99"}, - {file = "jupyter_client-8.6.0.tar.gz", hash = "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7"}, + {file = "jupyter_client-8.6.1-py3-none-any.whl", hash = "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f"}, + {file = "jupyter_client-8.6.1.tar.gz", hash = "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f"}, ] [package.dependencies] @@ -1429,14 +1524,14 @@ test = ["flaky", "pexpect", "pytest"] [[package]] name = "jupyter-core" -version = "5.7.1" +version = "5.7.2" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, - {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, ] [package.dependencies] @@ -1446,18 +1541,18 @@ traitlets = ">=5.3" [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyter-events" -version = "0.9.0" +version = "0.10.0" description = "Jupyter Event System library" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_events-0.9.0-py3-none-any.whl", hash = "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf"}, - {file = "jupyter_events-0.9.0.tar.gz", hash = "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399"}, + {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, + {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, ] [package.dependencies] @@ -1476,14 +1571,14 @@ test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "p [[package]] name = "jupyter-lsp" -version = "2.2.1" +version = "2.2.4" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter-lsp-2.2.1.tar.gz", hash = "sha256:b17fab6d70fe83c8896b0cff59237640038247c196056b43684a0902b6a9e0fb"}, - {file = "jupyter_lsp-2.2.1-py3-none-any.whl", hash = "sha256:17a689910c5e4ae5e7d334b02f31d08ffbe98108f6f658fb05e4304b4345368b"}, + {file = "jupyter-lsp-2.2.4.tar.gz", hash = "sha256:5e50033149344065348e688608f3c6d654ef06d9856b67655bd7b6bac9ee2d59"}, + {file = "jupyter_lsp-2.2.4-py3-none-any.whl", hash = "sha256:da61cb63a16b6dff5eac55c2699cc36eac975645adee02c41bdfc03bf4802e77"}, ] [package.dependencies] @@ -1492,14 +1587,14 @@ jupyter-server = ">=1.1.2" [[package]] name = "jupyter-server" -version = "2.12.2" +version = "2.13.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server-2.12.2-py3-none-any.whl", hash = "sha256:abcfa33f98a959f908c8733aa2d9fa0101d26941cbd49b148f4cef4d3046fc61"}, - {file = "jupyter_server-2.12.2.tar.gz", hash = "sha256:5eae86be15224b5375cdec0c3542ce72ff20f7a25297a2a8166a250bb455a519"}, + {file = "jupyter_server-2.13.0-py3-none-any.whl", hash = "sha256:77b2b49c3831fbbfbdb5048cef4350d12946191f833a24e5f83e5f8f4803e97b"}, + {file = "jupyter_server-2.13.0.tar.gz", hash = "sha256:c80bfb049ea20053c3d9641c2add4848b38073bf79f1729cea1faed32fc1c78e"}, ] [package.dependencies] @@ -1525,18 +1620,18 @@ websocket-client = "*" [package.extras] docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] [[package]] name = "jupyter-server-terminals" -version = "0.5.1" +version = "0.5.3" description = "A Jupyter Server Extension Providing Terminals." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_server_terminals-0.5.1-py3-none-any.whl", hash = "sha256:5e63e947ddd97bb2832db5ef837a258d9ccd4192cd608c1270850ad947ae5dd7"}, - {file = "jupyter_server_terminals-0.5.1.tar.gz", hash = "sha256:16d3be9cf48be6a1f943f3a6c93c033be259cf4779184c66421709cf63dccfea"}, + {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, + {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, ] [package.dependencies] @@ -1549,18 +1644,19 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.0.10" +version = "4.1.5" description = "JupyterLab computational environment" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.0.10-py3-none-any.whl", hash = "sha256:fe010ad9e37017488b468632ef2ead255fc7c671c5b64d9ca13e1f7b7e665c37"}, - {file = "jupyterlab-4.0.10.tar.gz", hash = "sha256:46177eb8ede70dc73be922ac99f8ef943bdc2dfbc6a31b353c4bde848a35dee1"}, + {file = "jupyterlab-4.1.5-py3-none-any.whl", hash = "sha256:3bc843382a25e1ab7bc31d9e39295a9f0463626692b7995597709c0ab236ab2c"}, + {file = "jupyterlab-4.1.5.tar.gz", hash = "sha256:c9ad75290cb10bfaff3624bf3fbb852319b4cce4c456613f8ebbaa98d03524db"}, ] [package.dependencies] async-lru = ">=1.0.0" +httpx = ">=0.25.0" importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} ipykernel = "*" jinja2 = ">=3.0.3" @@ -1575,9 +1671,9 @@ tornado = ">=6.2.0" traitlets = "*" [package.extras] -dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.1.6)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8,<7.2.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.0.1)", "ipython (==8.14.0)", "ipywidgets (==8.0.6)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post0)", "matplotlib (==3.7.1)", "nbconvert (>=7.0.0)", "pandas (==2.0.2)", "scipy (==1.10.1)", "vega-datasets (==0.9.0)"] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.2.0)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] +docs-screenshots = ["altair (==5.2.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.1)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post6)", "matplotlib (==3.8.2)", "nbconvert (>=7.0.0)", "pandas (==2.2.0)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] [[package]] @@ -1594,14 +1690,14 @@ files = [ [[package]] name = "jupyterlab-server" -version = "2.25.2" +version = "2.25.4" description = "A set of server components for JupyterLab and JupyterLab like applications." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab_server-2.25.2-py3-none-any.whl", hash = "sha256:5b1798c9cc6a44f65c757de9f97fc06fc3d42535afbf47d2ace5e964ab447aaf"}, - {file = "jupyterlab_server-2.25.2.tar.gz", hash = "sha256:bd0ec7a99ebcedc8bcff939ef86e52c378e44c2707e053fcd81d046ce979ee63"}, + {file = "jupyterlab_server-2.25.4-py3-none-any.whl", hash = "sha256:eb645ecc8f9b24bac5decc7803b6d5363250e16ec5af814e516bc2c54dd88081"}, + {file = "jupyterlab_server-2.25.4.tar.gz", hash = "sha256:2098198e1e82e0db982440f9b5136175d73bea2cd42a6480aa6fd502cb23c4f9"}, ] [package.dependencies] @@ -1617,18 +1713,18 @@ requests = ">=2.31" [package.extras] docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] [[package]] name = "jupyterlab-widgets" -version = "3.0.9" +version = "3.0.10" description = "Jupyter interactive widgets for JupyterLab" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "jupyterlab_widgets-3.0.9-py3-none-any.whl", hash = "sha256:3cf5bdf5b897bf3bccf1c11873aa4afd776d7430200f765e0686bd352487b58d"}, - {file = "jupyterlab_widgets-3.0.9.tar.gz", hash = "sha256:6005a4e974c7beee84060fdfba341a3218495046de8ae3ec64888e5fe19fdb4c"}, + {file = "jupyterlab_widgets-3.0.10-py3-none-any.whl", hash = "sha256:dd61f3ae7a5a7f80299e14585ce6cf3d6925a96c9103c978eda293197730cb64"}, + {file = "jupyterlab_widgets-3.0.10.tar.gz", hash = "sha256:04f2ac04976727e4f9d0fa91cdc2f1ab860f965e504c29dbd6a65c882c9d04c0"}, ] [[package]] @@ -1651,14 +1747,14 @@ regex = ["regex"] [[package]] name = "linkml" -version = "1.6.7" +version = "1.7.6" description = "Linked Open Data Modeling Language" category = "dev" optional = false -python-versions = ">=3.8.1,<4.0.0" +python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "linkml-1.6.7-py3-none-any.whl", hash = "sha256:e7c936d1025891138e6b2876ed1b388fa8495281fc152f873ddc9ee60a58950d"}, - {file = "linkml-1.6.7.tar.gz", hash = "sha256:fd7d55a3a1d894a4a5de25336bc70eaeb6e40582ff497da03b51589219c73c64"}, + {file = "linkml-1.7.6-py3-none-any.whl", hash = "sha256:034ead225b3aab46f8bd55fd6cafa8afec135d56238312c9e5da30065319553b"}, + {file = "linkml-1.7.6.tar.gz", hash = "sha256:4638166c8c4dcb2a892a14df9d2e8799d66205b570f3888cbb984efc89aaab09"}, ] [package.dependencies] @@ -1671,7 +1767,7 @@ jinja2 = ">=3.1.0" jsonasobj2 = ">=1.0.3,<2.0.0" jsonschema = {version = ">=4.0.0", extras = ["format"]} linkml-dataops = "*" -linkml-runtime = ">=1.6.0" +linkml-runtime = ">=1.7.0" openpyxl = "*" parse = "*" prefixcommons = ">=0.1.7" @@ -1687,6 +1783,10 @@ requests = ">=2.22" sqlalchemy = ">=1.4.31" watchdog = ">=0.9.0" +[package.extras] +shacl = ["pyshacl (>=0.25.0,<0.26.0)"] +tests = ["pyshacl (>=0.25.0,<0.26.0)"] + [[package]] name = "linkml-dataops" version = "0.1.0" @@ -1708,14 +1808,14 @@ linkml-runtime = ">=1.1.6" [[package]] name = "linkml-runtime" -version = "1.6.3" +version = "1.7.4" description = "Runtime environment for LinkML, the Linked open data modeling language" category = "main" optional = false -python-versions = ">=3.7.6,<4.0.0" +python-versions = "<4.0,>=3.8" files = [ - {file = "linkml_runtime-1.6.3-py3-none-any.whl", hash = "sha256:08f616302ce493be775104c87bd5a2ec0eb2c67624e611a3f7e28c978d08a4d1"}, - {file = "linkml_runtime-1.6.3.tar.gz", hash = "sha256:88e3d0b776055723d187128c03527145dc1ffdc2d2a69e89f8aabce203d418a3"}, + {file = "linkml_runtime-1.7.4-py3-none-any.whl", hash = "sha256:6808e752a95b709b0fbc66841df7707bb0011b09286fe71b4169d4b885ee27a7"}, + {file = "linkml_runtime-1.7.4.tar.gz", hash = "sha256:b5578c3b82b08d50d45f4a6b858004839dbb5c81150f9057a54e79ef78f3d04e"}, ] [package.dependencies] @@ -1735,14 +1835,14 @@ requests = "*" [[package]] name = "markdown" -version = "3.5.1" +version = "3.6" description = "Python implementation of John Gruber's Markdown." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, - {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, ] [package.dependencies] @@ -1754,72 +1854,72 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] @@ -1895,14 +1995,14 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.3" +version = "9.5.15" description = "Documentation that simply works" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.3-py3-none-any.whl", hash = "sha256:76c93a8525cceb0b395b9cedab3428bf518cf6439adef2b940f1c1574b775d89"}, - {file = "mkdocs_material-9.5.3.tar.gz", hash = "sha256:5899219f422f0a6de784232d9d40374416302ffae3c160cacc72969fcc1ee372"}, + {file = "mkdocs_material-9.5.15-py3-none-any.whl", hash = "sha256:e5c96dec3d19491de49ca643fc1dbb92b278e43cdb816c775bc47db77d9b62fb"}, + {file = "mkdocs_material-9.5.15.tar.gz", hash = "sha256:39f03cca45e82bf54eb7456b5a18bd252eabfdd67f237a229471484a0a4d4635"}, ] [package.dependencies] @@ -1919,8 +2019,8 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] @@ -1957,16 +2057,49 @@ pyyaml = "*" requests = "*" setuptools = ">=18.5" +[[package]] +name = "mkdocs-windmill" +version = "1.0.5" +description = "MkDocs theme focused on navigation and usability" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "mkdocs-windmill-1.0.5.tar.gz", hash = "sha256:a75f92cfd4aa992a4310d187860ecc50d5e2a690ba9d0899275013778ef5e704"}, + {file = "mkdocs_windmill-1.0.5-py2-none-any.whl", hash = "sha256:15c3f629bb500b941b848782f87ef1803bf5c97cc6702b80b54647ad0a9298d7"}, +] + +[package.dependencies] +mkdocs = "*" + +[[package]] +name = "mknotebooks" +version = "0.8.0" +description = "Plugin for mkdocs to generate markdown documents from jupyter notebooks." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "mknotebooks-0.8.0-py3-none-any.whl", hash = "sha256:4a9b998260c09bcc311455a19a44cc395a30ee82dc1e86e3316dd09f2445ebd3"}, +] + +[package.dependencies] +gitpython = "*" +jupyter-client = "*" +markdown = ">=3.3.3" +mkdocs = ">=1.5.0" +nbconvert = ">=6.0.0" + [[package]] name = "nbclient" -version = "0.9.0" +version = "0.10.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "dev" optional = false python-versions = ">=3.8.0" files = [ - {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, - {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, ] [package.dependencies] @@ -1978,18 +2111,18 @@ traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.14.0" -description = "Converting Jupyter Notebooks" +version = "7.16.3" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "nbconvert-7.14.0-py3-none-any.whl", hash = "sha256:483dde47facdaa4875903d651305ad53cd76e2255ae3c61efe412a95f2d22a24"}, - {file = "nbconvert-7.14.0.tar.gz", hash = "sha256:92b9a44b63e5a7fb4f6fa0ef41261e35c16925046ccd1c04a5c8099bf100476e"}, + {file = "nbconvert-7.16.3-py3-none-any.whl", hash = "sha256:ddeff14beeeedf3dd0bc506623e41e4507e551736de59df69a91f86700292b3b"}, + {file = "nbconvert-7.16.3.tar.gz", hash = "sha256:a6733b78ce3d47c3f85e504998495b07e6ea9cf9bf6ec1c98dda63ec6ad19142"}, ] [package.dependencies] @@ -2016,19 +2149,19 @@ docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sp qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] webpdf = ["playwright"] [[package]] name = "nbformat" -version = "5.9.2" +version = "5.10.3" description = "The Jupyter Notebook format" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, + {file = "nbformat-5.10.3-py3-none-any.whl", hash = "sha256:d9476ca28676799af85385f409b49d95e199951477a159a576ef2a675151e5e8"}, + {file = "nbformat-5.10.3.tar.gz", hash = "sha256:60ed5e910ef7c6264b87d644f276b1b49e24011930deef54605188ddeb211685"}, ] [package.dependencies] @@ -2043,31 +2176,31 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] [[package]] name = "nest-asyncio" -version = "1.5.8" +version = "1.6.0" description = "Patch asyncio to allow nested event loops" category = "dev" optional = false python-versions = ">=3.5" files = [ - {file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"}, - {file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"}, + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, ] [[package]] name = "notebook" -version = "7.0.6" +version = "7.1.2" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "notebook-7.0.6-py3-none-any.whl", hash = "sha256:0fe8f67102fea3744fedf652e4c15339390902ca70c5a31c4f547fa23da697cc"}, - {file = "notebook-7.0.6.tar.gz", hash = "sha256:ec6113b06529019f7f287819af06c97a2baf7a95ac21a8f6e32192898e9f9a58"}, + {file = "notebook-7.1.2-py3-none-any.whl", hash = "sha256:fc6c24b9aef18d0cd57157c9c47e95833b9b0bdc599652639acf0bdb61dc7d5f"}, + {file = "notebook-7.1.2.tar.gz", hash = "sha256:efc2c80043909e0faa17fce9e9b37c059c03af0ec99a4d4db84cb21d9d2e936a"}, ] [package.dependencies] jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.0.2,<5" +jupyterlab = ">=4.1.1,<4.2" jupyterlab-server = ">=2.22.1,<3" notebook-shim = ">=0.2,<0.3" tornado = ">=6.2.0" @@ -2079,14 +2212,14 @@ test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4 [[package]] name = "notebook-shim" -version = "0.2.3" +version = "0.2.4" description = "A shim layer for notebook traits and config" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "notebook_shim-0.2.3-py3-none-any.whl", hash = "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7"}, - {file = "notebook_shim-0.2.3.tar.gz", hash = "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9"}, + {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, + {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, ] [package.dependencies] @@ -2127,26 +2260,26 @@ dev = ["black", "mypy", "pytest"] [[package]] name = "overrides" -version = "7.4.0" +version = "7.7.0" description = "A decorator to automatically detect mismatch when overriding a method." category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "overrides-7.4.0-py3-none-any.whl", hash = "sha256:3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d"}, - {file = "overrides-7.4.0.tar.gz", hash = "sha256:9502a3cca51f4fac40b5feca985b6703a5c1f6ad815588a7ca9e285b9dca6757"}, + {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, + {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, ] [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] @@ -2162,26 +2295,26 @@ files = [ [[package]] name = "pandocfilters" -version = "1.5.0" +version = "1.5.1" description = "Utilities for writing pandoc filters in python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, - {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, ] [[package]] name = "parse" -version = "1.20.0" +version = "1.20.1" description = "parse() is the opposite of format()" category = "dev" optional = false python-versions = "*" files = [ - {file = "parse-1.20.0-py2.py3-none-any.whl", hash = "sha256:5e171b001452fa9f004c5a58a93525175468daf69b493e9fa915347ed7ff6968"}, - {file = "parse-1.20.0.tar.gz", hash = "sha256:bd28bae37714b45d5894d77160a16e2be36b64a3b618c81168b3684676aa498b"}, + {file = "parse-1.20.1-py2.py3-none-any.whl", hash = "sha256:76ddd5214255ae711db4c512be636151fbabaa948c6f30115aecc440422ca82c"}, + {file = "parse-1.20.1.tar.gz", hash = "sha256:09002ca350ad42e76629995f71f7b518670bcf93548bdde3684fd55d2be51975"}, ] [[package]] @@ -2256,30 +2389,30 @@ xarray = ["xarray"] [[package]] name = "platformdirs" -version = "4.1.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, - {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" -version = "1.3.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -2318,37 +2451,30 @@ requests = ">=2.28.1,<3.0.0" [[package]] name = "prefixmaps" -version = "0.2.1" +version = "0.2.2" description = "A python library for retrieving semantic prefix maps" category = "main" optional = false -python-versions = ">=3.9,<4.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "prefixmaps-0.2.1-py3-none-any.whl", hash = "sha256:0d204caeb4c368cb7a981de98117665fd8885ba76f058714f27f5963e620d5a1"}, - {file = "prefixmaps-0.2.1.tar.gz", hash = "sha256:8aed88739f900e6c0df0ada061b90223c79c29ca074f5ae6d3de423aef8fa3cf"}, + {file = "prefixmaps-0.2.2-py3-none-any.whl", hash = "sha256:4ac2bf3ddb9b27c40c978cf937e9bedb160050d24e8c679b94c9c885e1d73c72"}, + {file = "prefixmaps-0.2.2.tar.gz", hash = "sha256:a36b1554154ef465271bde82dc91cd671e2d31dc1f50c2fd08ccb0d7d5791c33"}, ] [package.dependencies] -click = ">=8.1.3" curies = ">=0.5.3" -pydantic = ">=2.5,<3.0" pyyaml = ">=5.3.1" -tox = ">=4.11.3,<5.0.0" - -[package.extras] -docs = ["Sphinx[docs] (>=7.2.6,<8.0.0)", "myst-parser[docs] (>=2.0.0,<3.0.0)", "sphinx-autodoc-typehints[docs] (>=1.23.4,<2.0.0)", "sphinx-click[docs] (>=4.3.0,<5.0.0)", "sphinx-rtd-theme[docs] (>=1.0.0,<2.0.0)"] -refresh = ["bioregistry[refresh] (>=0.10.65,<0.11.0)", "rdflib[refresh] (>=6.2.0,<7.0.0)", "requests[refresh] (>=2.28.1,<3.0.0)"] [[package]] name = "prometheus-client" -version = "0.19.0" +version = "0.20.0" description = "Python client for the Prometheus monitoring system." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "prometheus_client-0.19.0-py3-none-any.whl", hash = "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92"}, - {file = "prometheus_client-0.19.0.tar.gz", hash = "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1"}, + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, ] [package.extras] @@ -2371,28 +2497,28 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.7" +version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "psutil-5.9.7-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0bd41bf2d1463dfa535942b2a8f0e958acf6607ac0be52265ab31f7923bcd5e6"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:5794944462509e49d4d458f4dbfb92c47539e7d8d15c796f141f474010084056"}, - {file = "psutil-5.9.7-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:fe361f743cb3389b8efda21980d93eb55c1f1e3898269bc9a2a1d0bb7b1f6508"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e469990e28f1ad738f65a42dcfc17adaed9d0f325d55047593cb9033a0ab63df"}, - {file = "psutil-5.9.7-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:3c4747a3e2ead1589e647e64aad601981f01b68f9398ddf94d01e3dc0d1e57c7"}, - {file = "psutil-5.9.7-cp27-none-win32.whl", hash = "sha256:1d4bc4a0148fdd7fd8f38e0498639ae128e64538faa507df25a20f8f7fb2341c"}, - {file = "psutil-5.9.7-cp27-none-win_amd64.whl", hash = "sha256:4c03362e280d06bbbfcd52f29acd79c733e0af33d707c54255d21029b8b32ba6"}, - {file = "psutil-5.9.7-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ea36cc62e69a13ec52b2f625c27527f6e4479bca2b340b7a452af55b34fcbe2e"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1132704b876e58d277168cd729d64750633d5ff0183acf5b3c986b8466cd0284"}, - {file = "psutil-5.9.7-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8b7f07948f1304497ce4f4684881250cd859b16d06a1dc4d7941eeb6233bfe"}, - {file = "psutil-5.9.7-cp36-cp36m-win32.whl", hash = "sha256:b27f8fdb190c8c03914f908a4555159327d7481dac2f01008d483137ef3311a9"}, - {file = "psutil-5.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:44969859757f4d8f2a9bd5b76eba8c3099a2c8cf3992ff62144061e39ba8568e"}, - {file = "psutil-5.9.7-cp37-abi3-win32.whl", hash = "sha256:c727ca5a9b2dd5193b8644b9f0c883d54f1248310023b5ad3e92036c5e2ada68"}, - {file = "psutil-5.9.7-cp37-abi3-win_amd64.whl", hash = "sha256:f37f87e4d73b79e6c5e749440c3113b81d1ee7d26f21c19c47371ddea834f414"}, - {file = "psutil-5.9.7-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:032f4f2c909818c86cea4fe2cc407f1c0f0cde8e6c6d702b28b8ce0c0d143340"}, - {file = "psutil-5.9.7.tar.gz", hash = "sha256:3f02134e82cfb5d089fddf20bb2e03fd5cd52395321d1c8458a9e58500ff417c"}, + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, ] [package.extras] @@ -2439,19 +2565,19 @@ files = [ [[package]] name = "pydantic" -version = "2.5.3" +version = "2.6.4" description = "Data validation using Python type hints" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, - {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, + {file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"}, + {file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.14.6" +pydantic-core = "2.16.3" typing-extensions = ">=4.6.1" [package.extras] @@ -2459,117 +2585,91 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.14.6" +version = "2.16.3" description = "" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, - {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, - {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, - {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, - {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, - {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, - {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, - {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, - {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, - {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, - {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, - {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, - {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, - {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, - {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, - {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, + {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, + {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, + {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, + {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, + {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, + {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, + {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, + {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, + {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, + {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, + {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, + {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, + {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, ] [package.dependencies] @@ -2609,14 +2709,14 @@ jsonasobj = ">=1.2.1" [[package]] name = "pymdown-extensions" -version = "10.7" +version = "10.7.1" description = "Extension pack for Python Markdown." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"}, - {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"}, + {file = "pymdown_extensions-10.7.1-py3-none-any.whl", hash = "sha256:f5cc7000d7ff0d1ce9395d216017fa4df3dde800afb1fb72d1c7d3fd35e710f4"}, + {file = "pymdown_extensions-10.7.1.tar.gz", hash = "sha256:c70e146bdd83c744ffc766b4671999796aba18842b268510a329f7f64700d584"}, ] [package.dependencies] @@ -2628,14 +2728,14 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pyparsing" -version = "3.1.1" +version = "3.1.2" description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "main" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, - {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, ] [package.extras] @@ -2645,7 +2745,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyproject-api" version = "1.6.1" description = "API to interact with the python pyproject.toml based projects" -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2762,14 +2862,14 @@ pytest = ">=2.8.1" [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -2827,18 +2927,18 @@ files = [ [[package]] name = "pywinpty" -version = "2.0.12" +version = "2.0.13" description = "Pseudo terminal support for Windows from Python." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pywinpty-2.0.12-cp310-none-win_amd64.whl", hash = "sha256:21319cd1d7c8844fb2c970fb3a55a3db5543f112ff9cfcd623746b9c47501575"}, - {file = "pywinpty-2.0.12-cp311-none-win_amd64.whl", hash = "sha256:853985a8f48f4731a716653170cd735da36ffbdc79dcb4c7b7140bce11d8c722"}, - {file = "pywinpty-2.0.12-cp312-none-win_amd64.whl", hash = "sha256:1617b729999eb6713590e17665052b1a6ae0ad76ee31e60b444147c5b6a35dca"}, - {file = "pywinpty-2.0.12-cp38-none-win_amd64.whl", hash = "sha256:189380469ca143d06e19e19ff3fba0fcefe8b4a8cc942140a6b863aed7eebb2d"}, - {file = "pywinpty-2.0.12-cp39-none-win_amd64.whl", hash = "sha256:7520575b6546db23e693cbd865db2764097bd6d4ef5dc18c92555904cd62c3d4"}, - {file = "pywinpty-2.0.12.tar.gz", hash = "sha256:8197de460ae8ebb7f5d1701dfa1b5df45b157bb832e92acba316305e18ca00dd"}, + {file = "pywinpty-2.0.13-cp310-none-win_amd64.whl", hash = "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56"}, + {file = "pywinpty-2.0.13-cp311-none-win_amd64.whl", hash = "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99"}, + {file = "pywinpty-2.0.13-cp312-none-win_amd64.whl", hash = "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4"}, + {file = "pywinpty-2.0.13-cp38-none-win_amd64.whl", hash = "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d"}, + {file = "pywinpty-2.0.13-cp39-none-win_amd64.whl", hash = "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b"}, + {file = "pywinpty-2.0.13.tar.gz", hash = "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde"}, ] [[package]] @@ -3122,14 +3222,14 @@ rdflib-jsonld = "0.6.1" [[package]] name = "referencing" -version = "0.32.1" +version = "0.34.0" description = "JSON Referencing + Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "referencing-0.32.1-py3-none-any.whl", hash = "sha256:7e4dc12271d8e15612bfe35792f5ea1c40970dadf8624602e33db2758f7ee554"}, - {file = "referencing-0.32.1.tar.gz", hash = "sha256:3c57da0513e9563eb7e203ebe9bb3a1b509b042016433bd1e45a2853466c3dd3"}, + {file = "referencing-0.34.0-py3-none-any.whl", hash = "sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4"}, + {file = "referencing-0.34.0.tar.gz", hash = "sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844"}, ] [package.dependencies] @@ -3302,123 +3402,123 @@ files = [ [[package]] name = "rpds-py" -version = "0.16.2" +version = "0.18.0" description = "Python bindings to Rust's persistent data structures (rpds)" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.16.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:509b617ac787cd1149600e731db9274ebbef094503ca25158e6f23edaba1ca8f"}, - {file = "rpds_py-0.16.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:413b9c17388bbd0d87a329d8e30c1a4c6e44e2bb25457f43725a8e6fe4161e9e"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2946b120718eba9af2b4dd103affc1164a87b9e9ebff8c3e4c05d7b7a7e274e2"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35ae5ece284cf36464eb160880018cf6088a9ac5ddc72292a6092b6ef3f4da53"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc6a7620ba7639a3db6213da61312cb4aa9ac0ca6e00dc1cbbdc21c2aa6eb57"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8cb6fe8ecdfffa0e711a75c931fb39f4ba382b4b3ccedeca43f18693864fe850"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dace7b26a13353e24613417ce2239491b40a6ad44e5776a18eaff7733488b44"}, - {file = "rpds_py-0.16.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1bdbc5fcb04a7309074de6b67fa9bc4b418ab3fc435fec1f2779a0eced688d04"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f42e25c016927e2a6b1ce748112c3ab134261fc2ddc867e92d02006103e1b1b7"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eab36eae3f3e8e24b05748ec9acc66286662f5d25c52ad70cadab544e034536b"}, - {file = "rpds_py-0.16.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0474df4ade9a3b4af96c3d36eb81856cb9462e4c6657d4caecfd840d2a13f3c9"}, - {file = "rpds_py-0.16.2-cp310-none-win32.whl", hash = "sha256:84c5a4d1f9dd7e2d2c44097fb09fffe728629bad31eb56caf97719e55575aa82"}, - {file = "rpds_py-0.16.2-cp310-none-win_amd64.whl", hash = "sha256:2bd82db36cd70b3628c0c57d81d2438e8dd4b7b32a6a9f25f24ab0e657cb6c4e"}, - {file = "rpds_py-0.16.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:adc0c3d6fc6ae35fee3e4917628983f6ce630d513cbaad575b4517d47e81b4bb"}, - {file = "rpds_py-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec23fcad480e77ede06cf4127a25fc440f7489922e17fc058f426b5256ee0edb"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07aab64e2808c3ebac2a44f67e9dc0543812b715126dfd6fe4264df527556cb6"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4ebb8b20bd09c5ce7884c8f0388801100f5e75e7f733b1b6613c713371feefc"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3d7e2ea25d3517c6d7e5a1cc3702cffa6bd18d9ef8d08d9af6717fc1c700eed"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f28ac0e8e7242d140f99402a903a2c596ab71550272ae9247ad78f9a932b5698"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19f00f57fdd38db4bb5ad09f9ead1b535332dbf624200e9029a45f1f35527ebb"}, - {file = "rpds_py-0.16.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3da5a4c56953bdbf6d04447c3410309616c54433146ccdb4a277b9cb499bc10e"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec2e1cf025b2c0f48ec17ff3e642661da7ee332d326f2e6619366ce8e221f018"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e0441fb4fdd39a230477b2ca9be90868af64425bfe7b122b57e61e45737a653b"}, - {file = "rpds_py-0.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9f0350ef2fba5f34eb0c9000ea328e51b9572b403d2f7f3b19f24085f6f598e8"}, - {file = "rpds_py-0.16.2-cp311-none-win32.whl", hash = "sha256:5a80e2f83391ad0808b4646732af2a7b67550b98f0cae056cb3b40622a83dbb3"}, - {file = "rpds_py-0.16.2-cp311-none-win_amd64.whl", hash = "sha256:e04e56b4ca7a770593633556e8e9e46579d66ec2ada846b401252a2bdcf70a6d"}, - {file = "rpds_py-0.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5e6caa3809e50690bd92fa490f5c38caa86082c8c3315aa438bce43786d5e90d"}, - {file = "rpds_py-0.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e53b9b25cac9065328901713a7e9e3b12e4f57ef4280b370fbbf6fef2052eef"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af27423662f32d7501a00c5e7342f7dbd1e4a718aea7a239781357d15d437133"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43d4dd5fb16eb3825742bad8339d454054261ab59fed2fbac84e1d84d5aae7ba"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e061de3b745fe611e23cd7318aec2c8b0e4153939c25c9202a5811ca911fd733"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b811d182ad17ea294f2ec63c0621e7be92a1141e1012383461872cead87468f"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5552f328eaef1a75ff129d4d0c437bf44e43f9436d3996e8eab623ea0f5fcf73"}, - {file = "rpds_py-0.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dcbe1f8dd179e4d69b70b1f1d9bb6fd1e7e1bdc9c9aad345cdeb332e29d40748"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8aad80645a011abae487d356e0ceb359f4938dfb6f7bcc410027ed7ae4f7bb8b"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6f5549d6ed1da9bfe3631ca9483ae906f21410be2445b73443fa9f017601c6f"}, - {file = "rpds_py-0.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d452817e0d9c749c431a1121d56a777bd7099b720b3d1c820f1725cb40928f58"}, - {file = "rpds_py-0.16.2-cp312-none-win32.whl", hash = "sha256:888a97002e986eca10d8546e3c8b97da1d47ad8b69726dcfeb3e56348ebb28a3"}, - {file = "rpds_py-0.16.2-cp312-none-win_amd64.whl", hash = "sha256:d8dda2a806dfa4a9b795950c4f5cc56d6d6159f7d68080aedaff3bdc9b5032f5"}, - {file = "rpds_py-0.16.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:071980663c273bf3d388fe5c794c547e6f35ba3335477072c713a3176bf14a60"}, - {file = "rpds_py-0.16.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:726ac36e8a3bb8daef2fd482534cabc5e17334052447008405daca7ca04a3108"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9e557db6a177470316c82f023e5d571811c9a4422b5ea084c85da9aa3c035fc"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90123853fc8b1747f80b0d354be3d122b4365a93e50fc3aacc9fb4c2488845d6"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a61f659665a39a4d17d699ab3593d7116d66e1e2e3f03ef3fb8f484e91908808"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc97f0640e91d7776530f06e6836c546c1c752a52de158720c4224c9e8053cad"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a54e99a2b9693a37ebf245937fd6e9228b4cbd64b9cc961e1f3391ec6c7391"}, - {file = "rpds_py-0.16.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4b677d929cf1f6bac07ad76e0f2d5de367e6373351c01a9c0a39f6b21b4a8b"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5ef00873303d678aaf8b0627e111fd434925ca01c657dbb2641410f1cdaef261"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:349cb40897fd529ca15317c22c0eab67f5ac5178b5bd2c6adc86172045210acc"}, - {file = "rpds_py-0.16.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2ddef620e70eaffebed5932ce754d539c0930f676aae6212f8e16cd9743dd365"}, - {file = "rpds_py-0.16.2-cp38-none-win32.whl", hash = "sha256:882ce6e25e585949c3d9f9abd29202367175e0aab3aba0c58c9abbb37d4982ff"}, - {file = "rpds_py-0.16.2-cp38-none-win_amd64.whl", hash = "sha256:f4bd4578e44f26997e9e56c96dedc5f1af43cc9d16c4daa29c771a00b2a26851"}, - {file = "rpds_py-0.16.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:69ac7ea9897ec201ce68b48582f3eb34a3f9924488a5432a93f177bf76a82a7e"}, - {file = "rpds_py-0.16.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a9880b4656efe36ccad41edc66789e191e5ee19a1ea8811e0aed6f69851a82f4"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94cb58c0ba2c62ee108c2b7c9131b2c66a29e82746e8fa3aa1a1effbd3dcf1"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24f7a2eb3866a9e91f4599851e0c8d39878a470044875c49bd528d2b9b88361c"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca57468da2d9a660bcf8961637c85f2fbb2aa64d9bc3f9484e30c3f9f67b1dd7"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccd4e400309e1f34a5095bf9249d371f0fd60f8a3a5c4a791cad7b99ce1fd38d"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80443fe2f7b3ea3934c5d75fb0e04a5dbb4a8e943e5ff2de0dec059202b70a8b"}, - {file = "rpds_py-0.16.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d6a9f052e72d493efd92a77f861e45bab2f6be63e37fa8ecf0c6fd1a58fedb0"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:35953f4f2b3216421af86fd236b7c0c65935936a94ea83ddbd4904ba60757773"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:981d135c7cdaf6cd8eadae1c950de43b976de8f09d8e800feed307140d3d6d00"}, - {file = "rpds_py-0.16.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d0dd7ed2f16df2e129496e7fbe59a34bc2d7fc8db443a606644d069eb69cbd45"}, - {file = "rpds_py-0.16.2-cp39-none-win32.whl", hash = "sha256:703d95c75a72e902544fda08e965885525e297578317989fd15a6ce58414b41d"}, - {file = "rpds_py-0.16.2-cp39-none-win_amd64.whl", hash = "sha256:e93ec1b300acf89730cf27975ef574396bc04edecc358e9bd116fb387a123239"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:44627b6ca7308680a70766454db5249105fa6344853af6762eaad4158a2feebe"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3f91df8e6dbb7360e176d1affd5fb0246d2b88d16aa5ebc7db94fd66b68b61da"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d904c5693e08bad240f16d79305edba78276be87061c872a4a15e2c301fa2c0"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:290a81cfbe4673285cdf140ec5cd1658ffbf63ab359f2b352ebe172e7cfa5bf0"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b634c5ec0103c5cbebc24ebac4872b045cccb9456fc59efdcf6fe39775365bd2"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a297a4d08cc67c7466c873c78039d87840fb50d05473db0ec1b7b03d179bf322"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2e75e17bd0bb66ee34a707da677e47c14ee51ccef78ed6a263a4cc965a072a1"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f1b9d9260e06ea017feb7172976ab261e011c1dc2f8883c7c274f6b2aabfe01a"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:162d7cd9cd311c1b0ff1c55a024b8f38bd8aad1876b648821da08adc40e95734"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:9b32f742ce5b57201305f19c2ef7a184b52f6f9ba6871cc042c2a61f0d6b49b8"}, - {file = "rpds_py-0.16.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac08472f41ea77cd6a5dae36ae7d4ed3951d6602833af87532b556c1b4601d63"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:495a14b72bbe217f2695dcd9b5ab14d4f8066a00f5d209ed94f0aca307f85f6e"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d6b6937ae9eac6d6c0ca3c42774d89fa311f55adff3970fb364b34abde6ed3d"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a61226465bda9283686db8f17d02569a98e4b13c637be5a26d44aa1f1e361c2"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5cf6af100ffb5c195beec11ffaa8cf8523057f123afa2944e6571d54da84cdc9"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6df15846ee3fb2e6397fe25d7ca6624af9f89587f3f259d177b556fed6bebe2c"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1be2f033df1b8be8c3167ba3c29d5dca425592ee31e35eac52050623afba5772"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96f957d6ab25a78b9e7fc9749d754b98eac825a112b4e666525ce89afcbd9ed5"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:088396c7c70e59872f67462fcac3ecbded5233385797021976a09ebd55961dfe"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4c46ad6356e1561f2a54f08367d1d2e70a0a1bb2db2282d2c1972c1d38eafc3b"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:47713dc4fce213f5c74ca8a1f6a59b622fc1b90868deb8e8e4d993e421b4b39d"}, - {file = "rpds_py-0.16.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:f811771019f063bbd0aa7bb72c8a934bc13ebacb4672d712fc1639cfd314cccc"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f19afcfc0dd0dca35694df441e9b0f95bc231b512f51bded3c3d8ca32153ec19"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a4b682c5775d6a3d21e314c10124599976809455ee67020e8e72df1769b87bc3"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c647ca87fc0ebe808a41de912e9a1bfef9acb85257e5d63691364ac16b81c1f0"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:302bd4983bbd47063e452c38be66153760112f6d3635c7eeefc094299fa400a9"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf721ede3eb7b829e4a9b8142bd55db0bdc82902720548a703f7e601ee13bdc3"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:358dafc89ce3894c7f486c615ba914609f38277ef67f566abc4c854d23b997fa"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cad0f59ee3dc35526039f4bc23642d52d5f6616b5f687d846bfc6d0d6d486db0"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cffa76b385dfe1e38527662a302b19ffb0e7f5cf7dd5e89186d2c94a22dd9d0c"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:83640a5d7cd3bff694747d50436b8b541b5b9b9782b0c8c1688931d6ee1a1f2d"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:ed99b4f7179d2111702020fd7d156e88acd533f5a7d3971353e568b6051d5c97"}, - {file = "rpds_py-0.16.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4022b9dc620e14f30201a8a73898a873c8e910cb642bcd2f3411123bc527f6ac"}, - {file = "rpds_py-0.16.2.tar.gz", hash = "sha256:781ef8bfc091b19960fc0142a23aedadafa826bc32b433fdfe6fd7f964d7ef44"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88"}, + {file = "rpds_py-0.18.0-cp310-none-win32.whl", hash = "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337"}, + {file = "rpds_py-0.18.0-cp310-none-win_amd64.whl", hash = "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836"}, + {file = "rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1"}, + {file = "rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7"}, + {file = "rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98"}, + {file = "rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594"}, + {file = "rpds_py-0.18.0-cp38-none-win32.whl", hash = "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"}, + {file = "rpds_py-0.18.0-cp38-none-win_amd64.whl", hash = "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20"}, + {file = "rpds_py-0.18.0-cp39-none-win32.whl", hash = "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7"}, + {file = "rpds_py-0.18.0-cp39-none-win_amd64.whl", hash = "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f"}, + {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, ] [[package]] name = "ruamel-yaml" -version = "0.18.5" +version = "0.18.6" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "ruamel.yaml-0.18.5-py3-none-any.whl", hash = "sha256:a013ac02f99a69cdd6277d9664689eb1acba07069f912823177c5eced21a6ada"}, - {file = "ruamel.yaml-0.18.5.tar.gz", hash = "sha256:61917e3a35a569c1133a8f772e1226961bf5a1198bea7e23f06a0841dea1ab0e"}, + {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, + {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, ] [package.dependencies] @@ -3507,20 +3607,20 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "69.0.3" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, - {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shexjsg" @@ -3549,16 +3649,28 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "smmap" +version = "5.0.1" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, +] + [[package]] name = "sniffio" -version = "1.3.0" +version = "1.3.1" description = "Sniff out which async library your code is running under" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] @@ -3625,61 +3737,61 @@ pandas = ["pandas (>=1.3.5)"] [[package]] name = "sqlalchemy" -version = "2.0.25" +version = "2.0.29" description = "Database Abstraction Library" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"}, - {file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"}, - {file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"}, - {file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"}, - {file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"}, - {file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"}, - {file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"}, - {file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"}, - {file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win32.whl", hash = "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win_amd64.whl", hash = "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win32.whl", hash = "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win_amd64.whl", hash = "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win32.whl", hash = "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win_amd64.whl", hash = "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win32.whl", hash = "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win_amd64.whl", hash = "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win32.whl", hash = "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win_amd64.whl", hash = "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win32.whl", hash = "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win_amd64.whl", hash = "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c"}, + {file = "SQLAlchemy-2.0.29-py3-none-any.whl", hash = "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305"}, + {file = "SQLAlchemy-2.0.29.tar.gz", hash = "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0"}, ] [package.dependencies] @@ -3733,14 +3845,14 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "terminado" -version = "0.18.0" +version = "0.18.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "terminado-0.18.0-py3-none-any.whl", hash = "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e"}, - {file = "terminado-0.18.0.tar.gz", hash = "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded"}, + {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, + {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, ] [package.dependencies] @@ -3807,82 +3919,82 @@ files = [ [[package]] name = "tox" -version = "4.11.4" +version = "4.14.2" description = "tox is a generic virtualenv management and test command line tool" -category = "main" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "tox-4.11.4-py3-none-any.whl", hash = "sha256:2adb83d68f27116812b69aa36676a8d6a52249cb0d173649de0e7d0c2e3e7229"}, - {file = "tox-4.11.4.tar.gz", hash = "sha256:73a7240778fabf305aeb05ab8ea26e575e042ab5a18d71d0ed13e343a51d6ce1"}, + {file = "tox-4.14.2-py3-none-any.whl", hash = "sha256:2900c4eb7b716af4a928a7fdc2ed248ad6575294ed7cfae2ea41203937422847"}, + {file = "tox-4.14.2.tar.gz", hash = "sha256:0defb44f6dafd911b61788325741cc6b2e12ea71f987ac025ad4d649f1f1a104"}, ] [package.dependencies] -cachetools = ">=5.3.1" +cachetools = ">=5.3.2" chardet = ">=5.2" colorama = ">=0.4.6" -filelock = ">=3.12.3" -packaging = ">=23.1" -platformdirs = ">=3.10" +filelock = ">=3.13.1" +packaging = ">=23.2" +platformdirs = ">=4.1" pluggy = ">=1.3" pyproject-api = ">=1.6.1" tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} -virtualenv = ">=20.24.3" +virtualenv = ">=20.25" [package.extras] -docs = ["furo (>=2023.8.19)", "sphinx (>=7.2.4)", "sphinx-argparse-cli (>=1.11.1)", "sphinx-autodoc-typehints (>=1.24)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.1.1)", "devpi-process (>=1)", "diff-cover (>=7.7)", "distlib (>=0.3.7)", "flaky (>=3.7)", "hatch-vcs (>=0.3)", "hatchling (>=1.18)", "psutil (>=5.9.5)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-xdist (>=3.3.1)", "re-assert (>=1.1)", "time-machine (>=2.12)", "wheel (>=0.41.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-argparse-cli (>=1.11.1)", "sphinx-autodoc-typehints (>=1.25.2)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.11)"] +testing = ["build[virtualenv] (>=1.0.3)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=8.0.2)", "distlib (>=0.3.8)", "flaky (>=3.7)", "hatch-vcs (>=0.4)", "hatchling (>=1.21)", "psutil (>=5.9.7)", "pytest (>=7.4.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-xdist (>=3.5)", "re-assert (>=1.1)", "time-machine (>=2.13)", "wheel (>=0.42)"] [[package]] name = "traitlets" -version = "5.14.1" +version = "5.14.2" description = "Traitlets Python configuration system" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, - {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, + {file = "traitlets-5.14.2-py3-none-any.whl", hash = "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80"}, + {file = "traitlets-5.14.2.tar.gz", hash = "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.1)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "types-python-dateutil" -version = "2.8.19.20240106" +version = "2.9.0.20240316" description = "Typing stubs for python-dateutil" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, - {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, ] [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] name = "ucumvert" -version = "0.1.1" +version = "0.1.2" description = "Python parser & interface for UCUM (Unified Code for Units of Measure)." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "ucumvert-0.1.1-py3-none-any.whl", hash = "sha256:4aeb75d978e4cc85ed269144edf4b7513640c1fec622ec50dc38189cfd27e0d6"}, - {file = "ucumvert-0.1.1.tar.gz", hash = "sha256:547911befd4afed6c5265fc613ae1d7981619e20f18998b3b8725ef916c78e23"}, + {file = "ucumvert-0.1.2-py3-none-any.whl", hash = "sha256:480f0cd9315ebc5c6da3117de42296a4f8e35deb84a7f0b8719a909129afb72b"}, + {file = "ucumvert-0.1.2.tar.gz", hash = "sha256:a7c0dab878571ed5e03abab988c46e40e40092b253d6da5041d2305e1ddecd02"}, ] [package.dependencies] @@ -3911,31 +4023,32 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.1.0" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.0" +version = "20.25.1" description = "Virtual Python Environment builder" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, - {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, + {file = "virtualenv-20.25.1-py3-none-any.whl", hash = "sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a"}, + {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, ] [package.dependencies] @@ -3949,39 +4062,41 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "watchdog" -version = "3.0.0" +version = "4.0.0" description = "Filesystem events monitoring" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, ] [package.extras] @@ -4046,14 +4161,14 @@ test = ["websockets"] [[package]] name = "widgetsnbextension" -version = "4.0.9" +version = "4.0.10" description = "Jupyter interactive widgets for Jupyter Notebook" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "widgetsnbextension-4.0.9-py3-none-any.whl", hash = "sha256:91452ca8445beb805792f206e560c1769284267a30ceb1cec9f5bcc887d15175"}, - {file = "widgetsnbextension-4.0.9.tar.gz", hash = "sha256:3c1f5e46dc1166dfd40a42d685e6a51396fd34ff878742a3e47c6f0cc4a2a385"}, + {file = "widgetsnbextension-4.0.10-py3-none-any.whl", hash = "sha256:d37c3724ec32d8c48400a435ecfa7d3e259995201fbefa37163124a9fcb393cc"}, + {file = "widgetsnbextension-4.0.10.tar.gz", hash = "sha256:64196c5ff3b9a9183a8e699a4227fb0b7002f252c814098e66c4d1cd0644688f"}, ] [[package]] @@ -4138,21 +4253,21 @@ files = [ [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "89c14a0b6cd18d6be5afa890486d44d9ecf73bf7c68e04049f72ae377c453076" +content-hash = "4175279fa83ef62c842f590e323f31fd3080118d1323971402ba98c2d3439c6f" diff --git a/pyproject.toml b/pyproject.toml index 1ce97ba..4b63f9e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.9" -linkml-runtime = ">=1.5.2" +linkml-runtime = ">=1.7.2" asteval = "^0.9.29" deepdiff = "^6.7.1" pydantic = "^2.5.3" @@ -16,8 +16,11 @@ ucumvert = "^0.1.1" [tool.poetry.dev-dependencies] pytest = "^7.3.1" pytest-cov = "^4.0.0" -linkml = ">=1.5.0" +linkml = ">=1.7.0" mkdocs-mermaid2-plugin = "^0.6.0" +mknotebooks = "^0.8.0" +mkdocs-windmill = "*" +tox = "*" [tool.poetry.scripts] linkml-tr = "linkml_transformer.cli.cli:main" diff --git a/src/docs/about.md b/src/docs/about.md deleted file mode 100644 index 2269d5d..0000000 --- a/src/docs/about.md +++ /dev/null @@ -1 +0,0 @@ -# LinkML-Transformer diff --git a/src/docs/faq.md b/src/docs/faq.md new file mode 100644 index 0000000..cbccbe0 --- /dev/null +++ b/src/docs/faq.md @@ -0,0 +1,38 @@ +# FAQ + +## Why another framework? + +There are a number of excellent frameworks for performing mapping and data transformations. +The LinkML Transformer framework was born out of a need for a framework that: + +- was not inherently tied to: + - a particular serialization format (e.g. RDF, JSON, ...) + - a particular programming language (e.g. Python, Java, ...) + - a particular database system or database language (e.g. PostgreSQL or SQL or SPARQL) + - not tied to a particular kind of transformation (e.g. ORM or Tables to RDF) +- was a natural fit for the LinkML data modeling framework +- was declarative and easy to perform machine reasoning over +- is simple for simple use cases + +In its current state, this framework is less powerful and expressive than many other frameworks +or methodologies for performing transformations. If you need to perform complex data transformations, +you might be better off using an expressive query language like SPARQL or SQL, or even just coding +transformations directly in a programming language or library like Python or Pandas (but note that +even for the coding use case, the LinkML Transformer framework can be useful as a standard way +of *documenting* transformations). + +Currently the main use case for this framework is *mostly isomorphic* transformations, with lightweight +manipulations. These lend themselves well to a declarative framework. Uses cases that are a particularly good fit +involve mapping between data-dictionary like standards, with large numbers of metadata elements, where these +elements can often be mapped one-to-one, or with simple manipulations (e.g. unit conversions). + +The origins lie partly in the SSSOM standard, which is intended as an ultra-simple way of specifying +precise mappings between *entities* (e.g. schema.org Person is the same as DBPedia person). We observed +that many people wanted to extend the language to perform more complex mappings. To address this, we +help a workshop at the Biocuration conference in Padua, Italy in 2022. + +- [Discussion](https://github.com/orgs/linkml/discussions/1829) +- [SSSOM paper](https://academic.oup.com/database/article/doi/10.1093/database/baac035/6591806) +- [SSSOM Update 2023](https://ceur-ws.org/Vol-3591/om2023_STpaper3.pdf) +- [SSSOM Complex Mappings Workshop 2023](https://www.youtube.com/playlist?list=PLqu_J7ADQtKyX55F7RqZtaSS7TwGd3MoR) +- [Mapping Data Structures: Challenges and Approaches](https://doi.org/10.5281/zenodo.10343505) diff --git a/src/docs/index.md b/src/docs/index.md new file mode 100644 index 0000000..a3064e1 --- /dev/null +++ b/src/docs/index.md @@ -0,0 +1,180 @@ +# LinkML-Transformer + +LinkML Transformer is a framework for specifying and executing mappings between data models. + +Features: + +- YAML-based lightweight syntax +- Python library for executing mappings on data files +- Ability to compile to other frameworks (SQL/DuckDB) +- Derivation of target (implicit) schemas, allowing easy customization of data models (*profiling*) +- Simple YAML dictionaries for simple mappings +- Automatic unit conversion +- Use of subset of Python to specify complex mappings +- Visualizations of mappings +- Mappings are reversible (provided all expressions used are reversible) +- Compatibility with SSSOM + +This documentation are available at: + +- [linkml.io/linkml-transformer/](https://linkml.io/linkml-transformer/) + +Status: + +The transformation data model is not yet fully stable, and may be subject to change. +Not all parts of the model are implemented in the reference Python framework. + +## Basic idea + +Given an object that conforms to a LinkML schema,e.g.: + +```yaml +given_name: Jane +family_name: Doe +height_in_cm: 172.0 +age_in_years: 33 +aliases: [Janey, Janie] +``` + +Define a mapping in YAML: + +```yaml +class_derivations: + Individual: + populated_from: Person + slot_derivations: + name: + expr: "{given_name} + ' ' + {family_name}" + description: Concatenating given and family names + note this is a bad assumption for names in general, + this is just for demonstration + height_in_meters: + populated_from: height_in_cm + unit_conversion: + target_unit: m + aliases: + populated_from: aliases + stringification: + delimiter: '|' +``` + +The schema mapping (aka [TransformationSpecification](TransformationSpecification.md)) specifies how to transform the data model. + +The schema mapping is a collection of one or more [ClassDerivation](ClassDerivation.md) objects, +which themselves consist of one or more [SlotDerivation](SlotDerivation.md) objects. + +Transform the data: + +```bash +linkml-tr map-data -T tr.yaml -s schema.yaml my-data.yaml +``` + +Giving: + +```yaml +name: Jane Doe +height_in_meters: 1.72 +aliases: Janey|Janie +``` + +## Installation and usage + +Installation and command line usage: + +```bash +pip[x] install linkml-transformer +cd tests/input/examples/personinfo_basic +linkml-tr map-data \ + -T transform/personinfo-to-agent.transform.yaml \ + -s source/personinfo.yaml \ + data/Container-001.yaml \ + -o output/Translated-001.yaml +``` + +The command line has subcommands for: + +- `map-data` - map data from a source schema to a target schema +- `derive-schema` - derive a target schema from a source schema and a mapping +- `invert` - reverses a mapping +- `compile` - compiles a mapping to another framework + - `markdown` - for generating static sites + - `graphviz` - for generating visualizations + - `python` - (partial) + - forthcoming: `r2rml`, ... + +## Details + +This repo contains both: + +- A [data model](datamodel) for a data model *transformation language* +- A reference python implementation + +The transformation language is specified in terms of [LinkML](https://linkml.io) schemas. +It is intended to be a *ployglot* transformation language, used for +specifying how to map data models independent of underlying representation +(TSVs, JSON/YAML, RDF, SQL Database, ...). + +Use cases include: + +- ETL and mapping from one data model to another +- Database migrations (one version of a schema to another) +- Creating "profiles" +- Specifying mappings between different serializations of a model (e.g. OO to Relational) +- Mapping between normalized/non-redundant forms and denormalized/query-optimized forms + + +## Data Model + +The data model for transformations mirrors the data model for schemas: + +- A top level [TransformationSpecification](TransformationSpecification.md) class contains: + - Zero or more [ClassDerivation](ClassDerivation.md) objects, specifying how to map to a class, containing + - Zero or more [SlotDerivation](SlotDerivation.md) objects, specifying how to map to a slot + - Zero or more [EnumDerivation](EnumDerivation.md) objects, specifying how to map to an enum + +See the [generated docs](datamodel.md) + +## Conformance Suite + +The Transformers conformance suite contains a collection of tests for each feature of the language. + +See: + +* [Compliance Suite](specification/compliance.md) + + +## Running the code + +```bash +linkml-tr --help +Usage: linkml-tr [OPTIONS] COMMAND [ARGS]... + + CLI for linkml-transformer. + +Options: + -v, --verbose + -q, --quiet TEXT + --help Show this message and exit. + +Commands: + derive-schema Derive a schema from a source schema and a mapping. + map-data Map data in a source schema using a transformation. +``` + +### map-data + +Transforms (maps) data from a source schema to a target schema. This could range from a simple data dictionary mapping +through to a complex mappings. + +``` +cd tests/input/examples/personinfo_basic +linkml-tr map-data -T transform/personinfo-to-agent.transform.yaml -s source/personinfo.yaml data/Container-001.yaml +``` + +### derive-schema + +``` +cd tests/input/examples/personinfo_basic +linkml-tr derive-schema -T transform/personinfo-to-agent.transform.yaml source/personinfo.yaml +``` + diff --git a/src/linkml_transformer/cli/cli.py b/src/linkml_transformer/cli/cli.py index c61c888..394d2e0 100644 --- a/src/linkml_transformer/cli/cli.py +++ b/src/linkml_transformer/cli/cli.py @@ -1,4 +1,5 @@ """Command line interface for linkml-transformer.""" + import logging import sys @@ -93,7 +94,7 @@ def map_data( with open(input) as file: input_obj = yaml.safe_load(file) tr.index(input_obj, source_type) - tr_obj = tr.transform(input_obj, source_type) + tr_obj = tr.map_object(input_obj, source_type) if output: outfile = open(output, "w", encoding="utf-8") else: diff --git a/src/linkml_transformer/compiler/compiler.py b/src/linkml_transformer/compiler/compiler.py index c923f1b..2a09c47 100644 --- a/src/linkml_transformer/compiler/compiler.py +++ b/src/linkml_transformer/compiler/compiler.py @@ -12,6 +12,7 @@ - LinkML-Transformer Specifications to Pandas - LinkML-Transformer Specifications to Hamilton """ + from abc import ABC from dataclasses import dataclass, field from types import ModuleType @@ -47,6 +48,9 @@ class Compiler(ABC): an alternative representation. An example compiler would be a R2RML compiler. + + Note: Compilers and Importers will in general be implemented by providing + mapping specifications """ source_schemaview: SchemaView = None diff --git a/src/linkml_transformer/datamodel/specification_view.py b/src/linkml_transformer/datamodel/specification_view.py deleted file mode 100644 index 8f701e5..0000000 --- a/src/linkml_transformer/datamodel/specification_view.py +++ /dev/null @@ -1,17 +0,0 @@ -from dataclasses import dataclass -from typing import List - -from linkml_transformer.datamodel.transformer_model import ( - ElementDerivation, - TransformationSpecification, -) - - -@dataclass -class TransformerSpecificationView: - specification: TransformationSpecification = None - - def derivations(self, derivation: ElementDerivation) -> List[ElementDerivation]: - """Return all derivations of a given derivation""" - closure = [derivation] - return closure diff --git a/src/linkml_transformer/functions/unit_conversion.py b/src/linkml_transformer/functions/unit_conversion.py index 49f771d..1f5d2a6 100644 --- a/src/linkml_transformer/functions/unit_conversion.py +++ b/src/linkml_transformer/functions/unit_conversion.py @@ -6,6 +6,7 @@ For UCUM, the ucumvert library is used to convert UCUM units to pint units, see ``_. """ + from enum import Enum from functools import lru_cache from typing import Any, Optional diff --git a/src/linkml_transformer/inference/schema_mapper.py b/src/linkml_transformer/inference/schema_mapper.py index 044c570..37713d7 100644 --- a/src/linkml_transformer/inference/schema_mapper.py +++ b/src/linkml_transformer/inference/schema_mapper.py @@ -3,6 +3,7 @@ AKA profiling """ + import logging from collections import defaultdict from copy import copy diff --git a/src/linkml_transformer/session.py b/src/linkml_transformer/session.py index a29a53e..74c297c 100644 --- a/src/linkml_transformer/session.py +++ b/src/linkml_transformer/session.py @@ -1,7 +1,8 @@ import logging from dataclasses import dataclass from pathlib import Path -from typing import Any, Optional, Union +from types import ModuleType +from typing import Any, Optional, Type, Union import yaml from linkml_runtime import SchemaView @@ -14,6 +15,7 @@ from linkml_transformer.datamodel.transformer_model import TransformationSpecification from linkml_transformer.inference.inverter import TransformationSpecificationInverter from linkml_transformer.inference.schema_mapper import SchemaMapper +from linkml_transformer.transformer.transformer import Transformer logger = logging.getLogger(__name__) @@ -22,10 +24,19 @@ class Session: """ A wrapper object for a transformer session. + + TODO: + + - rename to Manager? + - consolidate configuration + - include source and target database + + - current spec, src_sv, tgt_sv all live in both this class and transformer """ transformer_specification: Optional[TransformationSpecification] = None source_schemaview: Optional[SchemaView] = None + transformer: Optional[Transformer] = None object_transformer: Optional[ObjectTransformer] = None schema_mapper: Optional[SchemaMapper] = None _target_schema: Optional[SchemaDefinition] = None @@ -34,6 +45,8 @@ class Session: def set_transformer_specification( self, specification: Optional[Union[TransformationSpecification, dict, str, Path]] = None ): + if isinstance(specification, Path): + specification = str(specification) if isinstance(specification, TransformationSpecification): self.transformer_specification = specification elif isinstance(specification, dict): @@ -70,6 +83,16 @@ def set_source_schema(self, schema: Union[str, Path, dict, SchemaView, SchemaDef self.source_schemaview = sv self._target_schema = None + def set_transformer( + self, + transformer: Optional[Union[Transformer, Type[Transformer]]], + **kwargs, + ): + if isinstance(transformer, Type): + transformer = transformer() + transformer.specification = self.transformer_specification + self.transformer = transformer + def set_object_transformer( self, transformer: Optional[ @@ -112,14 +135,14 @@ def transform(self, obj: dict, **kwargs) -> dict: raise ValueError("No transformer specified") if not self.object_transformer.source_schemaview: self.object_transformer.source_schemaview = self.source_schemaview - return self.object_transformer.transform(obj, **kwargs) + return self.object_transformer.map_object(obj, **kwargs) def reverse_transform(self, obj: dict, **kwargs) -> dict: inv_spec = self.invert() reverse_transformer = ObjectTransformer() reverse_transformer.specification = inv_spec reverse_transformer.source_schemaview = SchemaView(yaml_dumper.dumps(self.target_schema)) - return reverse_transformer.transform(obj, **kwargs) + return reverse_transformer.map_object(obj, **kwargs) def invert(self, in_place=False) -> TransformationSpecification: """ diff --git a/src/linkml_transformer/transformer/duckdb_transformer.py b/src/linkml_transformer/transformer/duckdb_transformer.py index ccde2c0..45bb41f 100644 --- a/src/linkml_transformer/transformer/duckdb_transformer.py +++ b/src/linkml_transformer/transformer/duckdb_transformer.py @@ -3,9 +3,13 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Type, Union +from duckdb import DuckDBPyConnection + +from linkml_transformer.compiler.sql_compiler import SQLCompiler from linkml_transformer.transformer.transformer import OBJECT_TYPE, Transformer DICT_OBJ = Dict[str, Any] +DATABASE = Union[str, DuckDBPyConnection] logger = logging.getLogger(__name__) @@ -17,12 +21,13 @@ class DuckDBTransformer(Transformer): A Transformer that works on DuckDB data. """ - def transform( + def map_object( self, source_obj: OBJECT_TYPE, source_type: str = None, target_type: str = None, - ) -> Union[DICT_OBJ, Any]: + **kwargs, + ) -> OBJECT_TYPE: """ Transform a source object into a target object. @@ -31,7 +36,37 @@ def transform( :param target_type: target_obj instantiates this (may be class, type, or enum) :return: transformed data, either as type target_type or a dictionary """ - import duckdb sv = self.source_schemaview raise NotImplementedError("DuckDBTransformer.transform") + + def map_database( + self, source_database: DATABASE, target_database: Optional[DATABASE] = None, **kwargs + ) -> OBJECT_TYPE: + """ + Transform source resource. + + :param source_database: + :param target_database: + :param kwargs: + :return: + """ + import duckdb + + if target_database is None: + target_database = source_database + + def _connect(db: DATABASE) -> DuckDBPyConnection: + if isinstance(db, str): + return duckdb.connect(db) + return db + + source_connection = _connect(source_database) + target_connection = _connect(target_database) + sql_compiler = SQLCompiler() + source_connection.sql(sql_compiler.create_ddl(self.source_schemaview)) + target_connection.sql(sql_compiler.create_ddl(self.target_schemaview)) + if not self.specification: + raise ValueError("No specification provided.") + compiled = sql_compiler.compile(self.specification) + source_connection.execute(compiled.serialization) diff --git a/src/linkml_transformer/transformer/object_transformer.py b/src/linkml_transformer/transformer/object_transformer.py index 74ba290..63068be 100644 --- a/src/linkml_transformer/transformer/object_transformer.py +++ b/src/linkml_transformer/transformer/object_transformer.py @@ -55,7 +55,7 @@ def index(self, source_obj: Any, target: str = None): else: self.object_index = ObjectIndex(source_obj, schemaview=self.source_schemaview) - def transform( + def map_object( self, source_obj: OBJECT_TYPE, source_type: str = None, @@ -174,16 +174,16 @@ def transform( source_class_slot_range = source_class_slot.range if source_class_slot.multivalued: if isinstance(v, list): - v = [self.transform(v1, source_class_slot_range, target_range) for v1 in v] + v = [self.map_object(v1, source_class_slot_range, target_range) for v1 in v] elif isinstance(v, dict): v = { - k1: self.transform(v1, source_class_slot_range, target_range) + k1: self.map_object(v1, source_class_slot_range, target_range) for k1, v1 in v.items() } else: v = [v] else: - v = self.transform(v, source_class_slot_range, target_range) + v = self.map_object(v, source_class_slot_range, target_range) if ( self._is_coerce_to_multivalued(slot_derivation, class_deriv) and v is not None @@ -342,7 +342,7 @@ def transform_object( # source_obj_dict = source_obj.dict() # else: # raise ValueError(f"Do not know how to handle type: {typ}") - tr_obj_dict = self.transform(source_obj, source_type_name) + tr_obj_dict = self.map_object(source_obj, source_type_name) return target_class(**tr_obj_dict) def transform_enum(self, source_value: str, enum_name: str, source_obj: Any) -> Optional[str]: diff --git a/src/linkml_transformer/transformer/transformer.py b/src/linkml_transformer/transformer/transformer.py index d1944d9..d2fb35e 100644 --- a/src/linkml_transformer/transformer/transformer.py +++ b/src/linkml_transformer/transformer/transformer.py @@ -2,12 +2,12 @@ Transformers (aka data mappers) are used to transform objects from one class to another using a transformation specification. """ + import logging from abc import ABC from copy import deepcopy from dataclasses import dataclass, field from pathlib import Path -from types import ModuleType from typing import Any, Dict, Optional, Union import yaml @@ -46,29 +46,24 @@ class Transformer(ABC): subclass this """ - source_schemaview: SchemaView = None - """A view over the schema describing the input/source object.""" - specification: TransformationSpecification = None """A specification of how to generate target objects from source objects.""" + source_schemaview: SchemaView = None + """A view over the schema describing the input/source object.""" + _derived_specification: TransformationSpecification = None """A specification with inferred missing values.""" target_schemaview: Optional[SchemaView] = None """A view over the schema describing the output/target object.""" - target_module: Optional[ModuleType] = None - """The python module which the target object should conform to.""" - - prefix_map: Optional[Dict[str, str]] = None - """Additional prefixes""" - unrestricted_eval: bool = field(default=False) + """Set to True to allow arbitrary evals as part of transformation.""" _curie_converter: Converter = None - def transform(self, obj: OBJECT_TYPE, source_type: str = None) -> OBJECT_TYPE: + def map_object(self, obj: OBJECT_TYPE, source_type: str = None, **kwargs) -> OBJECT_TYPE: """ Transform source object into an instance of the target class. @@ -78,6 +73,19 @@ def transform(self, obj: OBJECT_TYPE, source_type: str = None) -> OBJECT_TYPE: """ raise NotImplementedError + def map_database( + self, source_database: Any, target_database: Optional[Any] = None, **kwargs + ) -> OBJECT_TYPE: + """ + Transform source resource. + + :param source_database: + :param target_database: + :param kwargs: + :return: + """ + raise NotImplementedError + def load_source_schema(self, path: Union[str, Path, dict]): """ Sets source_schemaview from a schema path. diff --git a/src/linkml_transformer/utils/multi_file_transformer.py b/src/linkml_transformer/utils/multi_file_transformer.py index 8752574..2c1dda6 100644 --- a/src/linkml_transformer/utils/multi_file_transformer.py +++ b/src/linkml_transformer/utils/multi_file_transformer.py @@ -1,6 +1,7 @@ """Iterate through all examples in a folder testing them for validity. """ + import glob import logging import os @@ -190,7 +191,7 @@ def process_instructions( for step in tr.steps: input_obj = yaml.safe_load(open(str(root_directory / step.source_data))) transformer.index(input_obj, step.source_class) - target_obj = transformer.transform(input_obj, source_type=step.source_class) + target_obj = transformer.map_object(input_obj, source_type=step.source_class) if step.target_data: out_path = output_directory / step.target_data out_path.parent.mkdir(parents=True, exist_ok=True) diff --git a/tests/test_compiler/test_duckdb_compiler.py b/tests/test_compiler/test_duckdb_compiler.py index f816f37..f3d3837 100644 --- a/tests/test_compiler/test_duckdb_compiler.py +++ b/tests/test_compiler/test_duckdb_compiler.py @@ -1,6 +1,7 @@ """ Tests compilation of a specification to python """ + import pytest from linkml_runtime import SchemaView from linkml_runtime.dumpers import yaml_dumper diff --git a/tests/test_compiler/test_graphviz_compiler.py b/tests/test_compiler/test_graphviz_compiler.py index 2858c1b..14ef715 100644 --- a/tests/test_compiler/test_graphviz_compiler.py +++ b/tests/test_compiler/test_graphviz_compiler.py @@ -1,6 +1,7 @@ """ Tests compilation of a specification to graphviz """ + import pytest from linkml_runtime import SchemaView diff --git a/tests/test_compiler/test_markdown_compiler.py b/tests/test_compiler/test_markdown_compiler.py index bd2c507..7da9263 100644 --- a/tests/test_compiler/test_markdown_compiler.py +++ b/tests/test_compiler/test_markdown_compiler.py @@ -1,6 +1,7 @@ """ Tests compilation of a specification to markdown """ + import pytest from linkml_runtime import SchemaView diff --git a/tests/test_compiler/test_python_compiler.py b/tests/test_compiler/test_python_compiler.py index 52e54b7..2767d45 100644 --- a/tests/test_compiler/test_python_compiler.py +++ b/tests/test_compiler/test_python_compiler.py @@ -1,6 +1,7 @@ """ Tests compilation of a specification to python """ + import pytest from linkml_runtime import SchemaView from linkml_runtime.utils.compile_python import compile_python diff --git a/tests/test_compliance/test_compliance_suite.py b/tests/test_compliance/test_compliance_suite.py index a595094..4a63c31 100644 --- a/tests/test_compliance/test_compliance_suite.py +++ b/tests/test_compliance/test_compliance_suite.py @@ -16,6 +16,7 @@ code can be abstract. You are encouraged to look at the markdown outputs to see what is being generated for each test. """ + import logging import re from dataclasses import dataclass @@ -166,11 +167,11 @@ def map_object( mapper.index(source_object, target=source_root) if raises_error: with pytest.raises(raises_error): - target_object = mapper.transform(source_object) + target_object = mapper.map_object(source_object) logger.debug(f"Unexpected Target Object: {target_object}") target_object = None else: - target_object = mapper.transform(source_object) + target_object = mapper.map_object(source_object) assert ( target_object == expected_target_object ), f"failed to map {source_object} to {expected_target_object}" @@ -197,7 +198,7 @@ def map_object( print("**Inverted Transformation Specification** (Derived):\n\n") print_yaml(inv_spec) inv_mapper = ObjectTransformer(source_schemaview=target_sv, specification=inv_spec) - inv_target_object = inv_mapper.transform(target_object) + inv_target_object = inv_mapper.map_object(target_object) if roundtrip_object is None: roundtrip_object = source_object assert ( diff --git a/tests/test_transformer/test_duckdb_transformer.py b/tests/test_transformer/test_duckdb_transformer.py new file mode 100644 index 0000000..c7953f7 --- /dev/null +++ b/tests/test_transformer/test_duckdb_transformer.py @@ -0,0 +1,41 @@ +""" +Tests compilation of a specification to python +""" + +import pytest +from linkml_runtime import SchemaView +from linkml_runtime.dumpers import yaml_dumper +from linkml_runtime.utils.compile_python import compile_python + +import tests.input.examples.personinfo_basic.model.personinfo_model as src +from linkml_transformer.compiler.sql_compiler import SQLCompiler +from linkml_transformer.session import Session +from linkml_transformer.transformer.duckdb_transformer import DuckDBTransformer +from linkml_transformer.utils.loaders import load_specification +from tests import ( + PERSONINFO_SRC_SCHEMA, + PERSONINFO_TGT_SCHEMA, + PERSONINFO_TR, + SCHEMA1, + SPECIFICATION, +) + + +@pytest.fixture +def session() -> Session: + session = Session() + session.set_source_schema(PERSONINFO_SRC_SCHEMA) + session.set_transformer_specification(PERSONINFO_TR) + if not session.transformer_specification: + raise ValueError("No specification provided.") + tr = DuckDBTransformer() + session.set_transformer(tr) + tr.specification = session.transformer_specification + tr.source_schemaview = SchemaView(str(PERSONINFO_SRC_SCHEMA)) + tr.target_schemaview = SchemaView(str(PERSONINFO_TGT_SCHEMA)) + return session + + +def test_compile(session: Session): + pytest.skip("TODO") + session.transformer.map_database(":memory:") diff --git a/tests/test_transformer/test_object_transformer.py b/tests/test_transformer/test_object_transformer.py index 5630979..942932b 100644 --- a/tests/test_transformer/test_object_transformer.py +++ b/tests/test_transformer/test_object_transformer.py @@ -73,7 +73,7 @@ def test_transform_dict(self) -> None: tr = self.tr person_dict: dict[str, Any] = yaml.safe_load(open(str(PERSONINFO_DATA))) assert person_dict["age_in_years"] == AGE_INT - target_dict: dict[str, Any] = tr.transform(person_dict, source_type="Person") + target_dict: dict[str, Any] = tr.map_object(person_dict, source_type="Person") assert isinstance(target_dict, type(TARGET_DATA)) assert target_dict["age"] == AGE_STRING assert target_dict == TARGET_DATA @@ -86,7 +86,7 @@ def test_transform_dict_in_container(self): tr = self.tr person_dict: dict[str, Any] = yaml.safe_load(open(str(PERSONINFO_DATA))) container_dict = {"persons": [person_dict]} - target_dict = tr.transform(container_dict, source_type="Container") + target_dict = tr.map_object(container_dict, source_type="Container") assert target_dict == {"agents": [TARGET_DATA]} def test_transform_multiple_dicts_in_container(self) -> None: @@ -96,7 +96,7 @@ def test_transform_multiple_dicts_in_container(self) -> None: """ tr = self.tr container_dict: dict[str, Any] = yaml.safe_load(open(str(PERSONINFO_CONTAINER_DATA))) - target_dict: dict[str, Any] = tr.transform(container_dict, source_type="Container") + target_dict: dict[str, Any] = tr.map_object(container_dict, source_type="Container") assert target_dict == CONTAINER_DATA def check_familial_relationships(self, obj, data_model, expected): @@ -294,7 +294,7 @@ def test_denormalized_transform_dict(self): assert mset["mappings"] == [{"subject": "X:1", "object": "Y:1", "predicate": "P:1"}] assert mset["entities"] == {"X:1": {"name": "x1"}, "Y:1": {"name": "y1"}} tr.index(mset, "MappingSet") - target_obj = tr.transform(mset, source_type="MappingSet") + target_obj = tr.map_object(mset, source_type="MappingSet") assert isinstance(target_obj, dict) assert target_obj["mappings"][0] == { "subject_id": "X:1", @@ -391,7 +391,7 @@ def mk(mv: bool, explicit: bool = False): source_schemaview=SchemaView(source_schema), target_schemaview=SchemaView(target_schema), ) - target_instance = tr.transform(source_instance, class_name) + target_instance = tr.map_object(source_instance, class_name) assert [val] if target_multivalued else val == target_instance[att_name] def test_self_transform(self): @@ -404,7 +404,7 @@ def test_self_transform(self): ) normalizer.expand_all = True source_object = normalizer.normalize(source_object) - derived = tr.transform(source_object) + derived = tr.map_object(source_object) print(derived) print(yaml.dump(derived)) From 9b8b0759ac03e3028f5b3a5519d6eba45517d8d1 Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Mon, 25 Mar 2024 07:22:43 -0700 Subject: [PATCH 5/7] refactored docs --- src/docs/examples/Tutorial.ipynb | 954 +++++++++++++++++++++++++++++++ 1 file changed, 954 insertions(+) create mode 100644 src/docs/examples/Tutorial.ipynb diff --git a/src/docs/examples/Tutorial.ipynb b/src/docs/examples/Tutorial.ipynb new file mode 100644 index 0000000..456f5a1 --- /dev/null +++ b/src/docs/examples/Tutorial.ipynb @@ -0,0 +1,954 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# LinkML-Transformer tutorial\n", + "\n", + "This tutorial walks through basic programmatic use of the LinkML-Transformer framework.\n", + "This is intended for Python developers - note that many of the operations here can also be performed\n", + "at the command line." + ], + "metadata": { + "collapsed": false + }, + "id": "df75d53a3e91e573" + }, + { + "cell_type": "code", + "execution_count": 1, + "outputs": [], + "source": [ + "import yaml" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:23.927439Z", + "start_time": "2024-03-23T02:12:23.819885Z" + } + }, + "id": "63a064b31f623bdd" + }, + { + "cell_type": "markdown", + "source": [ + "## Creating an example schema\n", + "\n", + "We will use a LinkML SchemaBuilder object to progressively build up a schema, adding\n", + "additional features as we go.\n", + "\n", + "We'll start with a simple `Person` schema, with a few single valued scalar slots:" + ], + "metadata": { + "collapsed": false + }, + "id": "e2cbd6b8994905f6" + }, + { + "cell_type": "code", + "execution_count": 2, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema\n", + "id: http://example.org/test-schema\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml: https://w3id.org/linkml/\n", + " test_schema: http://example.org/test-schema/\n", + "default_prefix: test_schema\n", + "default_range: string\n", + "slots:\n", + " family_name:\n", + " range: string\n", + " given_name:\n", + " range: string\n", + " age_in_years:\n", + " range: integer\n", + " height_in_cm:\n", + " range: float\n", + "classes:\n", + " Person:\n", + " slots:\n", + " - family_name\n", + " - given_name\n", + " - age_in_years\n", + " - height_in_cm\n" + ] + } + ], + "source": [ + "from linkml.utils.schema_builder import SchemaBuilder\n", + "from linkml_runtime.linkml_model import SlotDefinition\n", + "\n", + "sb = SchemaBuilder()\n", + "sb.add_class(\"Person\", slots=[SlotDefinition(\"family_name\", range=\"string\"), \n", + " SlotDefinition(\"given_name\", range=\"string\"),\n", + " SlotDefinition(\"age_in_years\", range=\"integer\"),\n", + " SlotDefinition(\"height_in_cm\", range=\"float\"),\n", + " ])\n", + "sb.add_defaults()\n", + "print(yaml.dump(sb.as_dict(), sort_keys=False))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:24.139985Z", + "start_time": "2024-03-23T02:12:23.842320Z" + } + }, + "id": "ef2c60ef7fbcbe20" + }, + { + "cell_type": "markdown", + "source": [ + "## Creating a Transformer Session object\n", + "\n", + "We will use a `Session` object which conveniently wraps a number of different capabilities;\n", + "the first of these capabilities is to map (transform) data objects from one schema to another\n", + "(implicit) schema using a *transformer specification*).\n", + "\n", + "Our initial transformer specification will be a trivial isomorphic one that:\n", + "\n", + "- maps the `Person` class to an `Individual` class\n", + "- passes through `name` fields as-is\n", + "- renames measurement fields (`age_in_years` and `height_in_cm` to `age` and `height`)" + ], + "metadata": { + "collapsed": false + }, + "id": "d4228629dd7e2ef2" + }, + { + "cell_type": "code", + "execution_count": 3, + "outputs": [], + "source": [ + "from linkml_transformer.session import Session\n", + "\n", + "session = Session()\n", + "session.set_source_schema(sb.as_dict())" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:24.847826Z", + "start_time": "2024-03-23T02:12:24.138432Z" + } + }, + "id": "a6257aa9e6ab021e" + }, + { + "cell_type": "code", + "execution_count": 4, + "outputs": [], + "source": [ + "# Transformer specification (in YAML)\n", + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " family_name:\n", + " populated_from: family_name\n", + " given_name:\n", + " populated_from: given_name\n", + " age:\n", + " populated_from: age_in_years\n", + " height:\n", + " populated_from: height_in_cm\n", + "\"\"\")" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.094008Z", + "start_time": "2024-03-23T02:12:24.897951Z" + } + }, + "id": "47b95e209790b423" + }, + { + "cell_type": "markdown", + "source": [ + "## Visualizing transformer specifications\n", + "\n", + "We can visualize the transformer specification using graphviz:" + ], + "metadata": { + "collapsed": false + }, + "id": "8313d6acb588178e" + }, + { + "cell_type": "code", + "execution_count": 5, + "outputs": [ + { + "data": { + "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nfamily_name : string\n\ngiven_name : string\n\nage : integer\n\nheight : float\n\n\n\nsourcePerson:family_name->targetIndividual:family_name\n\n\n\n\n\nsourcePerson:given_name->targetIndividual:given_name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height\n\n\n\n\n\n", + "text/plain": "" + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.graphviz()" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.426050Z", + "start_time": "2024-03-23T02:12:25.096688Z" + } + }, + "id": "1c623cdc3c1cfbca" + }, + { + "cell_type": "markdown", + "source": [ + "## Transforming objects\n", + "\n", + "We'll next make a simple `Person` object. Note that for simplicity we are specifying this\n", + "using a Python dictionary. The framework also works with objects instantiating either\n", + "Pydantic or Dataclasses classes (use the `transform_object` method instead of `transform`)." + ], + "metadata": { + "collapsed": false + }, + "id": "a15707b9cd2d3db5" + }, + { + "cell_type": "code", + "execution_count": 6, + "outputs": [ + { + "data": { + "text/plain": "{'family_name': 'Doe', 'given_name': 'Jane', 'age': 42, 'height': 180.0}" + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj = {\n", + " \"given_name\": \"Jane\",\n", + " \"family_name\": \"Doe\",\n", + " \"age_in_years\": 42,\n", + " \"height_in_cm\": 180.0,\n", + " }\n", + "session.transform(obj)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.435969Z", + "start_time": "2024-03-23T02:12:25.431387Z" + } + }, + "id": "9f4d1fc4ca97f80c" + }, + { + "cell_type": "markdown", + "source": [ + "This does what we expect - it renames the two fields, but leaves all values intact.\n", + "\n", + "Note that because we use using dictionaries here, the renaming of the class has no effect,\n", + "as this is implicit with JSON/dictionaries.\n", + "\n", + "TODO: docs on type designator fields\n", + "\n", + "For command line users, the same thing can be achieved with the `map-data` command." + ], + "metadata": { + "collapsed": false + }, + "id": "b3826284a497d04e" + }, + { + "cell_type": "markdown", + "source": [ + "## Deriving target schemas\n", + "\n", + "LinkML-Transformer is intended as a *declarative* framework, in contrast to writing Python\n", + "transformation code. This allows tools to introspect mappings and perform other kinds of inference.\n", + "An example of this is *deriving the (implicit) target schema*\n", + "\n", + "Here we use the `target_schema` method on the session object to derive the target schema:" + ], + "metadata": { + "collapsed": false + }, + "id": "d6aa71d062e96aa1" + }, + { + "cell_type": "code", + "execution_count": 7, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema-derived\n", + "id: http://example.org/test-schema-derived\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml:\n", + " prefix_prefix: linkml\n", + " prefix_reference: https://w3id.org/linkml/\n", + " test_schema:\n", + " prefix_prefix: test_schema\n", + " prefix_reference: http://example.org/test-schema/\n", + "default_prefix: http://example.org/test-schema-derived/\n", + "default_range: string\n", + "classes:\n", + " Individual:\n", + " name: Individual\n", + " attributes:\n", + " family_name:\n", + " name: family_name\n", + " range: string\n", + " given_name:\n", + " name: given_name\n", + " range: string\n", + " age:\n", + " name: age\n", + " range: integer\n", + " height:\n", + " name: height\n", + " range: float\n" + ] + } + ], + "source": [ + "from linkml_runtime.dumpers import yaml_dumper\n", + "\n", + "print(yaml_dumper.dumps(session.target_schema))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.442750Z", + "start_time": "2024-03-23T02:12:25.434388Z" + } + }, + "id": "687912c18bf6752" + }, + { + "cell_type": "markdown", + "source": [ + "As expected, this is isomorphic to the original (source) schema, with fields and classes renamed." + ], + "metadata": { + "collapsed": false + }, + "id": "2c89abbd8e298981" + }, + { + "cell_type": "markdown", + "source": [ + "## Using Expressions\n", + "\n", + "In addition to renaming fields, we can derive field values via evaluation of function *expressions*.\n", + "\n", + "You are encouraged to follow the subset of Python defined by the LinkML expression language. This provides\n", + "both safety, and declarativity. However, if you need\n", + "to, you can include arbitrary Python code, provided you configure the session to allow this.\n", + "\n", + "We'll keep the original schema, and will provide a new Transformer specification, \n", + "giving an example of both string manipulation functions and arithmetic functions; the latter\n", + "perform unit conversions (later on we will see more flexible and declarative ways to perform unit conversions).\n", + "\n" + ], + "metadata": { + "collapsed": false + }, + "id": "4562b534b6f23910" + }, + { + "cell_type": "code", + "execution_count": 8, + "outputs": [], + "source": [ + "\n", + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " name:\n", + " expr: \"{given_name} + ' ' + {family_name}\"\n", + " description: Concatenating given and family names\n", + " note this is a bad assumption for names in general,\n", + " this is just for demonstration\n", + " age_in_months:\n", + " expr: age_in_years * 12\n", + " height_in_meters:\n", + " expr: height_in_cm / 100\n", + "\"\"\")\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.502675Z", + "start_time": "2024-03-23T02:12:25.460193Z" + } + }, + "id": "789a7b6535ab410f" + }, + { + "cell_type": "markdown", + "source": [ + "Note that when we visualize this specification, dotted lines are shown indicating a relationship\n", + "between source and target that is different from direct copy:" + ], + "metadata": { + "collapsed": false + }, + "id": "e02eaa2cde3172c8" + }, + { + "cell_type": "code", + "execution_count": 9, + "outputs": [ + { + "data": { + "image/svg+xml": "\n\n\n\n\n\n\n\n\nsourcePerson\n\nPerson\n\nfamily_name : string\n\ngiven_name : string\n\nage_in_years : integer\n\nheight_in_cm : float\n\n\n\ntargetIndividual\n\nIndividual\n\nname : string\n\nage_in_months : string\n\nheight_in_meters : string\n\n\n\nsourcePerson:given_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:family_name->targetIndividual:name\n\n\n\n\n\nsourcePerson:age_in_years->targetIndividual:age_in_months\n\n\n\n\n\nsourcePerson:height_in_cm->targetIndividual:height_in_meters\n\n\n\n\n\n", + "text/plain": "" + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.graphviz()" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.810836Z", + "start_time": "2024-03-23T02:12:25.509345Z" + } + }, + "id": "2a18ccb5d7dc469b" + }, + { + "cell_type": "markdown", + "source": [ + "Now we'll transform the same object as before, and see the results:" + ], + "metadata": { + "collapsed": false + }, + "id": "f7019db8d391ab97" + }, + { + "cell_type": "code", + "execution_count": 10, + "outputs": [ + { + "data": { + "text/plain": "{'name': 'Jane Doe', 'age_in_months': 504, 'height_in_meters': 1.8}" + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.transform(obj)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.816826Z", + "start_time": "2024-03-23T02:12:25.812549Z" + } + }, + "id": "5e20e98e2b23751f" + }, + { + "cell_type": "markdown", + "source": [ + "As expected, we concatenated the name fields, and converted the age and height fields to different units.\n", + "\n", + "Let's take a look at the derived schema for this new transformation:" + ], + "metadata": { + "collapsed": false + }, + "id": "ad9fd0f70178fd26" + }, + { + "cell_type": "code", + "execution_count": 11, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema-derived\n", + "id: http://example.org/test-schema-derived\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml:\n", + " prefix_prefix: linkml\n", + " prefix_reference: https://w3id.org/linkml/\n", + " test_schema:\n", + " prefix_prefix: test_schema\n", + " prefix_reference: http://example.org/test-schema/\n", + "default_prefix: http://example.org/test-schema-derived/\n", + "default_range: string\n", + "classes:\n", + " Individual:\n", + " name: Individual\n", + " attributes:\n", + " name:\n", + " name: name\n", + " age_in_months:\n", + " name: age_in_months\n", + " height_in_meters:\n", + " name: height_in_meters\n" + ] + } + ], + "source": [ + "print(yaml_dumper.dumps(session.target_schema))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.825306Z", + "start_time": "2024-03-23T02:12:25.820116Z" + } + }, + "id": "7c1f7efef1836364" + }, + { + "cell_type": "markdown", + "source": [ + "Note that at this time, deriving ranges using expressions is not supported, so the two measurement fields\n", + "are erroneously typed as having the `default_range` of `string`. However, in principle, if you use the\n", + "linkml subset of Python it should be possible to infer the range of the derived field, and this may be added\n", + "in future versions. Currently the tool chain is at an early stage of development." + ], + "metadata": { + "collapsed": false + }, + "id": "e87b7f45dc137a68" + }, + { + "cell_type": "markdown", + "source": [ + "## Unit conversions\n", + "\n", + "Next we will look at a different way of doing unit conversions. The LinkML specification allows\n", + "schemas to explicitly declare the units of slots, so let's modify our schema to do this, adding\n", + "a UCUM code for our `height_in_cm` slot:" + ], + "metadata": { + "collapsed": false + }, + "id": "ff3d20924263ec15" + }, + { + "cell_type": "code", + "execution_count": 12, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema\n", + "id: http://example.org/test-schema\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml: https://w3id.org/linkml/\n", + " test_schema: http://example.org/test-schema/\n", + "default_prefix: test_schema\n", + "default_range: string\n", + "slots:\n", + " family_name:\n", + " range: string\n", + " given_name:\n", + " range: string\n", + " age_in_years:\n", + " range: integer\n", + " height_in_cm:\n", + " range: float\n", + " unit:\n", + " ucum_code: cm\n", + "classes:\n", + " Person:\n", + " slots:\n", + " - family_name\n", + " - given_name\n", + " - age_in_years\n", + " - height_in_cm\n" + ] + } + ], + "source": [ + "from linkml_runtime.linkml_model.units import UnitOfMeasure\n", + "sb.schema.slots['height_in_cm'].unit = UnitOfMeasure(ucum_code='cm')\n", + "session.set_source_schema(sb.as_dict())\n", + "print(yaml.dump(sb.as_dict(), sort_keys=False))" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.850932Z", + "start_time": "2024-03-23T02:12:25.833403Z" + } + }, + "id": "65a5ce5d97e27f76" + }, + { + "cell_type": "markdown", + "source": [ + "## Adding target_unit to transformer specification\n", + "\n", + "We will create a new transformer specification, focusing on the `height_in_cm` field. We will\n", + "transform this into a `height_in_meters` field, and will use the `target_unit` field to specify\n", + "the target unit." + ], + "metadata": { + "collapsed": false + }, + "id": "c5cf59ec9ac3148e" + }, + { + "cell_type": "code", + "execution_count": 13, + "outputs": [], + "source": [ + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " name:\n", + " expr: \"{given_name} + ' ' + {family_name}\"\n", + " height_in_meters:\n", + " populated_from: height_in_cm\n", + " unit_conversion:\n", + " target_unit: m\n", + "\"\"\")" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:25.901551Z", + "start_time": "2024-03-23T02:12:25.853769Z" + } + }, + "id": "bc99bad97970b1b7" + }, + { + "cell_type": "code", + "execution_count": 14, + "outputs": [ + { + "data": { + "text/plain": "{'name': 'Jane Doe', 'height_in_meters': 1.8}" + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.transform(obj)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.176193Z", + "start_time": "2024-03-23T02:12:25.901292Z" + } + }, + "id": "831b444d9c47e0ea" + }, + { + "cell_type": "markdown", + "source": [ + "## Units in derived schema\n", + "\n", + "Next we'll look at the derived target schema, and as expected we see that it has inferred\n", + "the target unit for the `height_in_meters` field:" + ], + "metadata": { + "collapsed": false + }, + "id": "6f37087c6dfc30ef" + }, + { + "cell_type": "code", + "execution_count": 15, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name: test-schema-derived\n", + "id: http://example.org/test-schema-derived\n", + "imports:\n", + "- linkml:types\n", + "prefixes:\n", + " linkml:\n", + " prefix_prefix: linkml\n", + " prefix_reference: https://w3id.org/linkml/\n", + " test_schema:\n", + " prefix_prefix: test_schema\n", + " prefix_reference: http://example.org/test-schema/\n", + "default_prefix: http://example.org/test-schema-derived/\n", + "default_range: string\n", + "classes:\n", + " Individual:\n", + " name: Individual\n", + " attributes:\n", + " name:\n", + " name: name\n", + " height_in_meters:\n", + " name: height_in_meters\n", + " range: float\n", + " unit:\n", + " ucum_code: m\n" + ] + } + ], + "source": [ + "print(yaml_dumper.dumps(session.target_schema))\n" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.176598Z", + "start_time": "2024-03-23T02:12:26.152743Z" + } + }, + "id": "b589e0e95550962d" + }, + { + "cell_type": "markdown", + "source": [ + "## Tabular serialization" + ], + "metadata": { + "collapsed": false + }, + "id": "8f4c4cb125aade0b" + }, + { + "cell_type": "code", + "execution_count": 16, + "outputs": [], + "source": [ + "slot = sb.add_slot(\"aliases\", multivalued=True, range=\"string\", replace_if_present=True)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.176672Z", + "start_time": "2024-03-23T02:12:26.156764Z" + } + }, + "id": "f492b27c0f0fbf88" + }, + { + "cell_type": "code", + "execution_count": 17, + "outputs": [], + "source": [ + "sb.schema.classes['Person'].slots.append(slot.name)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.176741Z", + "start_time": "2024-03-23T02:12:26.159739Z" + } + }, + "id": "3ac3f93ab8561300" + }, + { + "cell_type": "code", + "execution_count": 18, + "outputs": [], + "source": [ + "session.set_source_schema(sb.as_dict())" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.177256Z", + "start_time": "2024-03-23T02:12:26.168743Z" + } + }, + "id": "84262d357323f76e" + }, + { + "cell_type": "code", + "execution_count": 19, + "outputs": [], + "source": [ + "session.set_object_transformer(\"\"\"\n", + "class_derivations:\n", + " Individual:\n", + " populated_from: Person\n", + " slot_derivations:\n", + " family_name:\n", + " populated_from: family_name\n", + " given_name:\n", + " populated_from: given_name\n", + " age:\n", + " populated_from: age_in_years\n", + " height:\n", + " populated_from: height_in_cm\n", + " aliases:\n", + " populated_from: aliases\n", + " stringification:\n", + " delimiter: '|'\n", + "\"\"\") " + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.249455Z", + "start_time": "2024-03-23T02:12:26.222590Z" + } + }, + "id": "2f282430f48e13c0" + }, + { + "cell_type": "code", + "execution_count": 20, + "outputs": [ + { + "data": { + "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age': 42,\n 'height': 180.0,\n 'aliases': 'Jane|Janie|Janey'}" + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj = {\n", + " \"given_name\": \"Jane\",\n", + " \"family_name\": \"Doe\",\n", + " \"age_in_years\": 42,\n", + " \"height_in_cm\": 180.0,\n", + " \"aliases\": [\"Jane\", \"Janie\", \"Janey\"]\n", + " }\n", + "flattened = session.transform(obj)\n", + "flattened" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.279106Z", + "start_time": "2024-03-23T02:12:26.242965Z" + } + }, + "id": "fdd23ae82909770e" + }, + { + "cell_type": "markdown", + "source": [ + "this can easily be serialized to a CSV/TSV" + ], + "metadata": { + "collapsed": false + }, + "id": "c5174dcbf7dd0c43" + }, + { + "cell_type": "markdown", + "source": [ + "## Reverse transform\n", + "\n", + "If a transform does not contain one-way functions,\n", + "it can be *reversed*.\n", + "\n", + "In this case, reversing the transform allows us to map\n", + "from the tabular form back to the richer original representation." + ], + "metadata": { + "collapsed": false + }, + "id": "fae8392b02526408" + }, + { + "cell_type": "code", + "execution_count": 21, + "outputs": [ + { + "data": { + "text/plain": "{'family_name': 'Doe',\n 'given_name': 'Jane',\n 'age_in_years': 42,\n 'height_in_cm': 180.0,\n 'aliases': ['Jane', 'Janie', 'Janey']}" + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.reverse_transform(flattened)" + ], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.339410Z", + "start_time": "2024-03-23T02:12:26.280636Z" + } + }, + "id": "e8c1c3f98081d38" + }, + { + "cell_type": "code", + "execution_count": 21, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false, + "ExecuteTime": { + "end_time": "2024-03-23T02:12:26.339637Z", + "start_time": "2024-03-23T02:12:26.317148Z" + } + }, + "id": "ee14ace4b1c7d256" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 04ee6cdbeb0f3e3ac5c57203d6d6865976c5a973 Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Mon, 25 Mar 2024 07:34:54 -0700 Subject: [PATCH 6/7] format --- src/linkml_transformer/compiler/sql_compiler.py | 2 +- src/linkml_transformer/session.py | 1 - .../transformer/duckdb_transformer.py | 6 ++---- tests/test_compiler/test_duckdb_compiler.py | 3 --- tests/test_transformer/test_duckdb_transformer.py | 13 +------------ 5 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/linkml_transformer/compiler/sql_compiler.py b/src/linkml_transformer/compiler/sql_compiler.py index 95faae9..80d44e5 100644 --- a/src/linkml_transformer/compiler/sql_compiler.py +++ b/src/linkml_transformer/compiler/sql_compiler.py @@ -54,7 +54,7 @@ def compile_class( """ stmt = "" if self.new_table_when_transforming: - stmt += f"CREATE TABLE " + stmt += "CREATE TABLE " if self.add_if_not_exists: stmt += "IF NOT EXISTS " stmt += f"{cd.name} \n" diff --git a/src/linkml_transformer/session.py b/src/linkml_transformer/session.py index 74c297c..f7aa8cf 100644 --- a/src/linkml_transformer/session.py +++ b/src/linkml_transformer/session.py @@ -1,7 +1,6 @@ import logging from dataclasses import dataclass from pathlib import Path -from types import ModuleType from typing import Any, Optional, Type, Union import yaml diff --git a/src/linkml_transformer/transformer/duckdb_transformer.py b/src/linkml_transformer/transformer/duckdb_transformer.py index 45bb41f..f156e09 100644 --- a/src/linkml_transformer/transformer/duckdb_transformer.py +++ b/src/linkml_transformer/transformer/duckdb_transformer.py @@ -1,7 +1,6 @@ -import json import logging from dataclasses import dataclass -from typing import Any, Dict, List, Optional, Type, Union +from typing import Any, Dict, Optional, Union from duckdb import DuckDBPyConnection @@ -36,8 +35,7 @@ def map_object( :param target_type: target_obj instantiates this (may be class, type, or enum) :return: transformed data, either as type target_type or a dictionary """ - - sv = self.source_schemaview + # sv = self.source_schemaview raise NotImplementedError("DuckDBTransformer.transform") def map_database( diff --git a/tests/test_compiler/test_duckdb_compiler.py b/tests/test_compiler/test_duckdb_compiler.py index f3d3837..09f4441 100644 --- a/tests/test_compiler/test_duckdb_compiler.py +++ b/tests/test_compiler/test_duckdb_compiler.py @@ -5,12 +5,9 @@ import pytest from linkml_runtime import SchemaView from linkml_runtime.dumpers import yaml_dumper -from linkml_runtime.utils.compile_python import compile_python -import tests.input.examples.personinfo_basic.model.personinfo_model as src from linkml_transformer.compiler.sql_compiler import SQLCompiler from linkml_transformer.session import Session -from linkml_transformer.utils.loaders import load_specification from tests import SCHEMA1, SPECIFICATION diff --git a/tests/test_transformer/test_duckdb_transformer.py b/tests/test_transformer/test_duckdb_transformer.py index c7953f7..b48b7c8 100644 --- a/tests/test_transformer/test_duckdb_transformer.py +++ b/tests/test_transformer/test_duckdb_transformer.py @@ -4,21 +4,10 @@ import pytest from linkml_runtime import SchemaView -from linkml_runtime.dumpers import yaml_dumper -from linkml_runtime.utils.compile_python import compile_python -import tests.input.examples.personinfo_basic.model.personinfo_model as src -from linkml_transformer.compiler.sql_compiler import SQLCompiler from linkml_transformer.session import Session from linkml_transformer.transformer.duckdb_transformer import DuckDBTransformer -from linkml_transformer.utils.loaders import load_specification -from tests import ( - PERSONINFO_SRC_SCHEMA, - PERSONINFO_TGT_SCHEMA, - PERSONINFO_TR, - SCHEMA1, - SPECIFICATION, -) +from tests import PERSONINFO_SRC_SCHEMA, PERSONINFO_TGT_SCHEMA, PERSONINFO_TR @pytest.fixture From 238d38306b0151ce242b8f3f172aefb75ca2cf5d Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Mon, 25 Mar 2024 07:48:59 -0700 Subject: [PATCH 7/7] fix syntax --- tests/input/examples/biolink/source/biolink-model.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/input/examples/biolink/source/biolink-model.yaml b/tests/input/examples/biolink/source/biolink-model.yaml index 1819b89..0065382 100644 --- a/tests/input/examples/biolink/source/biolink-model.yaml +++ b/tests/input/examples/biolink/source/biolink-model.yaml @@ -5605,7 +5605,7 @@ classes: chemical role: is_a: attribute description: >- - A role played by the molecular entity or part thereof within a chemical context. + A role played by the molecular entity or part thereof within a chemical context. id_prefixes: - CHEBI exact_mappings: