sqlspec 0.36.0__cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ac8f31065839703b4e70__mypyc.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/__init__.py +140 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_serialization.py +315 -0
- sqlspec/_typing.py +700 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +5 -0
- sqlspec/adapters/adbc/_typing.py +82 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1273 -0
- sqlspec/adapters/adbc/config.py +295 -0
- sqlspec/adapters/adbc/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/core.py +735 -0
- sqlspec/adapters/adbc/data_dictionary.py +334 -0
- sqlspec/adapters/adbc/driver.py +529 -0
- sqlspec/adapters/adbc/events/__init__.py +5 -0
- sqlspec/adapters/adbc/events/store.py +285 -0
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +502 -0
- sqlspec/adapters/adbc/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/type_converter.py +140 -0
- sqlspec/adapters/aiosqlite/__init__.py +25 -0
- sqlspec/adapters/aiosqlite/_typing.py +82 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +818 -0
- sqlspec/adapters/aiosqlite/config.py +334 -0
- sqlspec/adapters/aiosqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +208 -0
- sqlspec/adapters/aiosqlite/driver.py +313 -0
- sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/events/store.py +20 -0
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
- sqlspec/adapters/aiosqlite/pool.py +533 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +87 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +703 -0
- sqlspec/adapters/asyncmy/config.py +302 -0
- sqlspec/adapters/asyncmy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncmy/core.py +360 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +124 -0
- sqlspec/adapters/asyncmy/driver.py +383 -0
- sqlspec/adapters/asyncmy/events/__init__.py +5 -0
- sqlspec/adapters/asyncmy/events/store.py +104 -0
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +19 -0
- sqlspec/adapters/asyncpg/_typing.py +88 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +748 -0
- sqlspec/adapters/asyncpg/config.py +569 -0
- sqlspec/adapters/asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncpg/core.py +367 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +162 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/backend.py +286 -0
- sqlspec/adapters/asyncpg/events/store.py +40 -0
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +251 -0
- sqlspec/adapters/bigquery/__init__.py +14 -0
- sqlspec/adapters/bigquery/_typing.py +86 -0
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +827 -0
- sqlspec/adapters/bigquery/config.py +353 -0
- sqlspec/adapters/bigquery/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/core.py +715 -0
- sqlspec/adapters/bigquery/data_dictionary.py +128 -0
- sqlspec/adapters/bigquery/driver.py +548 -0
- sqlspec/adapters/bigquery/events/__init__.py +5 -0
- sqlspec/adapters/bigquery/events/store.py +139 -0
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +325 -0
- sqlspec/adapters/bigquery/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +24 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +72 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +410 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +238 -0
- sqlspec/adapters/cockroach_asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +144 -0
- sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
- sqlspec/adapters/cockroach_psycopg/__init__.py +38 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +129 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +868 -0
- sqlspec/adapters/cockroach_psycopg/config.py +484 -0
- sqlspec/adapters/cockroach_psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +215 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +284 -0
- sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
- sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
- sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_psycopg/litestar/store.py +325 -0
- sqlspec/adapters/duckdb/__init__.py +25 -0
- sqlspec/adapters/duckdb/_typing.py +81 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +850 -0
- sqlspec/adapters/duckdb/config.py +463 -0
- sqlspec/adapters/duckdb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/core.py +257 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +430 -0
- sqlspec/adapters/duckdb/events/__init__.py +5 -0
- sqlspec/adapters/duckdb/events/store.py +57 -0
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +330 -0
- sqlspec/adapters/duckdb/pool.py +293 -0
- sqlspec/adapters/duckdb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mock/__init__.py +72 -0
- sqlspec/adapters/mock/_typing.py +147 -0
- sqlspec/adapters/mock/config.py +483 -0
- sqlspec/adapters/mock/core.py +319 -0
- sqlspec/adapters/mock/data_dictionary.py +366 -0
- sqlspec/adapters/mock/driver.py +721 -0
- sqlspec/adapters/mysqlconnector/__init__.py +36 -0
- sqlspec/adapters/mysqlconnector/_typing.py +141 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1060 -0
- sqlspec/adapters/mysqlconnector/config.py +394 -0
- sqlspec/adapters/mysqlconnector/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/mysqlconnector/core.py +303 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +235 -0
- sqlspec/adapters/mysqlconnector/driver.py +483 -0
- sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
- sqlspec/adapters/mysqlconnector/events/store.py +98 -0
- sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
- sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
- sqlspec/adapters/oracledb/__init__.py +60 -0
- sqlspec/adapters/oracledb/_numpy_handlers.py +141 -0
- sqlspec/adapters/oracledb/_typing.py +182 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +166 -0
- sqlspec/adapters/oracledb/adk/__init__.py +10 -0
- sqlspec/adapters/oracledb/adk/store.py +2369 -0
- sqlspec/adapters/oracledb/config.py +550 -0
- sqlspec/adapters/oracledb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/core.py +543 -0
- sqlspec/adapters/oracledb/data_dictionary.py +536 -0
- sqlspec/adapters/oracledb/driver.py +1229 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/backend.py +347 -0
- sqlspec/adapters/oracledb/events/store.py +420 -0
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +781 -0
- sqlspec/adapters/oracledb/migrations.py +535 -0
- sqlspec/adapters/oracledb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +17 -0
- sqlspec/adapters/psqlpy/_typing.py +79 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +766 -0
- sqlspec/adapters/psqlpy/config.py +304 -0
- sqlspec/adapters/psqlpy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/core.py +480 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +126 -0
- sqlspec/adapters/psqlpy/driver.py +438 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/backend.py +310 -0
- sqlspec/adapters/psqlpy/events/store.py +20 -0
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +270 -0
- sqlspec/adapters/psqlpy/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +32 -0
- sqlspec/adapters/psycopg/_typing.py +164 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1387 -0
- sqlspec/adapters/psycopg/config.py +576 -0
- sqlspec/adapters/psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/core.py +450 -0
- sqlspec/adapters/psycopg/data_dictionary.py +289 -0
- sqlspec/adapters/psycopg/driver.py +975 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/backend.py +458 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +552 -0
- sqlspec/adapters/psycopg/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +71 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +540 -0
- sqlspec/adapters/pymysql/config.py +195 -0
- sqlspec/adapters/pymysql/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/pymysql/core.py +299 -0
- sqlspec/adapters/pymysql/data_dictionary.py +122 -0
- sqlspec/adapters/pymysql/driver.py +259 -0
- sqlspec/adapters/pymysql/events/__init__.py +5 -0
- sqlspec/adapters/pymysql/events/store.py +50 -0
- sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
- sqlspec/adapters/pymysql/litestar/store.py +232 -0
- sqlspec/adapters/pymysql/pool.py +137 -0
- sqlspec/adapters/spanner/__init__.py +40 -0
- sqlspec/adapters/spanner/_typing.py +86 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +732 -0
- sqlspec/adapters/spanner/config.py +352 -0
- sqlspec/adapters/spanner/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/core.py +188 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/dialect/__init__.py +6 -0
- sqlspec/adapters/spanner/dialect/_spangres.py +57 -0
- sqlspec/adapters/spanner/dialect/_spanner.py +130 -0
- sqlspec/adapters/spanner/driver.py +373 -0
- sqlspec/adapters/spanner/events/__init__.py +5 -0
- sqlspec/adapters/spanner/events/store.py +187 -0
- sqlspec/adapters/spanner/litestar/__init__.py +5 -0
- sqlspec/adapters/spanner/litestar/store.py +291 -0
- sqlspec/adapters/spanner/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/type_converter.py +331 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +80 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +958 -0
- sqlspec/adapters/sqlite/config.py +280 -0
- sqlspec/adapters/sqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/core.py +312 -0
- sqlspec/adapters/sqlite/data_dictionary.py +202 -0
- sqlspec/adapters/sqlite/driver.py +359 -0
- sqlspec/adapters/sqlite/events/__init__.py +5 -0
- sqlspec/adapters/sqlite/events/store.py +20 -0
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +316 -0
- sqlspec/adapters/sqlite/pool.py +198 -0
- sqlspec/adapters/sqlite/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +747 -0
- sqlspec/builder/__init__.py +179 -0
- sqlspec/builder/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_base.py +1022 -0
- sqlspec/builder/_column.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_ddl.py +1642 -0
- sqlspec/builder/_delete.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_dml.py +365 -0
- sqlspec/builder/_explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_factory.py +1697 -0
- sqlspec/builder/_insert.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_insert.py +328 -0
- sqlspec/builder/_join.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_join.py +499 -0
- sqlspec/builder/_merge.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_merge.py +821 -0
- sqlspec/builder/_parsing_utils.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_parsing_utils.py +297 -0
- sqlspec/builder/_select.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_select.py +1660 -0
- sqlspec/builder/_temporal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_temporal.py +139 -0
- sqlspec/builder/_update.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_expressions.py +267 -0
- sqlspec/cli.py +911 -0
- sqlspec/config.py +1755 -0
- sqlspec/core/__init__.py +374 -0
- sqlspec/core/_correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/cache.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/cache.py +1069 -0
- sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/compiler.py +954 -0
- sqlspec/core/explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/filters.py +952 -0
- sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/hashing.py +262 -0
- sqlspec/core/metrics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +71 -0
- sqlspec/core/parameters/_alignment.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_alignment.py +270 -0
- sqlspec/core/parameters/_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_converter.py +543 -0
- sqlspec/core/parameters/_processor.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_processor.py +505 -0
- sqlspec/core/parameters/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_transformers.py +292 -0
- sqlspec/core/parameters/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_types.py +499 -0
- sqlspec/core/parameters/_validator.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_validator.py +180 -0
- sqlspec/core/pipeline.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/pipeline.py +319 -0
- sqlspec/core/query_modifiers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/query_modifiers.py +437 -0
- sqlspec/core/result/__init__.py +23 -0
- sqlspec/core/result/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_base.py +1121 -0
- sqlspec/core/result/_io.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/splitter.py +966 -0
- sqlspec/core/stack.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/statement.py +1503 -0
- sqlspec/core/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/type_converter.py +339 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.py +123 -0
- sqlspec/data_dictionary/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +49 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +43 -0
- sqlspec/data_dictionary/dialects/duckdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +42 -0
- sqlspec/data_dictionary/dialects/oracle.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +34 -0
- sqlspec/data_dictionary/dialects/postgres.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +46 -0
- sqlspec/data_dictionary/dialects/spanner.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +42 -0
- sqlspec/data_dictionary/sql/.gitkeep +0 -0
- sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
- sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
- sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
- sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
- sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
- sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
- sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
- sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
- sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
- sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
- sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
- sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
- sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
- sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
- sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
- sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
- sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
- sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
- sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
- sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
- sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
- sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
- sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
- sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
- sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
- sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
- sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
- sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
- sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
- sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
- sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
- sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
- sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
- sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
- sqlspec/driver/__init__.py +32 -0
- sqlspec/driver/_async.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_async.py +1737 -0
- sqlspec/driver/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_common.py +1478 -0
- sqlspec/driver/_sql_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sql_helpers.py +148 -0
- sqlspec/driver/_storage_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_storage_helpers.py +144 -0
- sqlspec/driver/_sync.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sync.py +1710 -0
- sqlspec/exceptions.py +338 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +70 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +149 -0
- sqlspec/extensions/adk/memory/service.py +217 -0
- sqlspec/extensions/adk/memory/store.py +569 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +246 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +225 -0
- sqlspec/extensions/adk/store.py +567 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +461 -0
- sqlspec/extensions/events/_store.py +209 -0
- sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
- sqlspec/extensions/events/migrations/__init__.py +3 -0
- sqlspec/extensions/fastapi/__init__.py +19 -0
- sqlspec/extensions/fastapi/extension.py +351 -0
- sqlspec/extensions/fastapi/providers.py +607 -0
- sqlspec/extensions/flask/__init__.py +37 -0
- sqlspec/extensions/flask/_state.py +76 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +519 -0
- sqlspec/extensions/litestar/__init__.py +28 -0
- sqlspec/extensions/litestar/_utils.py +52 -0
- sqlspec/extensions/litestar/channels.py +165 -0
- sqlspec/extensions/litestar/cli.py +102 -0
- sqlspec/extensions/litestar/config.py +90 -0
- sqlspec/extensions/litestar/handlers.py +316 -0
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +671 -0
- sqlspec/extensions/litestar/providers.py +526 -0
- sqlspec/extensions/litestar/store.py +296 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/starlette/__init__.py +19 -0
- sqlspec/extensions/starlette/_state.py +30 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +346 -0
- sqlspec/extensions/starlette/middleware.py +235 -0
- sqlspec/loader.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/loader.py +702 -0
- sqlspec/migrations/__init__.py +36 -0
- sqlspec/migrations/base.py +731 -0
- sqlspec/migrations/commands.py +1232 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.py +1172 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.py +611 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.py +207 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +55 -0
- sqlspec/observability/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_config.py +348 -0
- sqlspec/observability/_diagnostics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_dispatcher.py +152 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_observer.py +357 -0
- sqlspec/observability/_runtime.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_runtime.py +420 -0
- sqlspec/observability/_sampling.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +916 -0
- sqlspec/py.typed +0 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_utils.py +104 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.py +253 -0
- sqlspec/storage/backends/fsspec.py +529 -0
- sqlspec/storage/backends/local.py +441 -0
- sqlspec/storage/backends/obstore.py +916 -0
- sqlspec/storage/errors.py +104 -0
- sqlspec/storage/pipeline.py +582 -0
- sqlspec/storage/registry.py +301 -0
- sqlspec/typing.py +395 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +318 -0
- sqlspec/utils/config_tools.py +332 -0
- sqlspec/utils/correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.py +190 -0
- sqlspec/utils/fixtures.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/fixtures.py +258 -0
- sqlspec/utils/logging.py +222 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/portal.py +375 -0
- sqlspec/utils/schema.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/schema.py +485 -0
- sqlspec/utils/serializers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/serializers.py +408 -0
- sqlspec/utils/singleton.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/sync_tools.py +311 -0
- sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/text.py +108 -0
- sqlspec/utils/type_converters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_converters.py +128 -0
- sqlspec/utils/type_guards.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_guards.py +1360 -0
- sqlspec/utils/uuids.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/uuids.py +225 -0
- sqlspec-0.36.0.dist-info/METADATA +205 -0
- sqlspec-0.36.0.dist-info/RECORD +531 -0
- sqlspec-0.36.0.dist-info/WHEEL +7 -0
- sqlspec-0.36.0.dist-info/entry_points.txt +2 -0
- sqlspec-0.36.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""Utilities for async/sync interoperability in SQLSpec.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for converting between async and sync functions,
|
|
4
|
+
managing concurrency limits, and handling context managers. Used primarily
|
|
5
|
+
for adapter implementations that need to support both sync and async patterns.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import concurrent.futures
|
|
10
|
+
import functools
|
|
11
|
+
import inspect
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
15
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
|
|
16
|
+
|
|
17
|
+
from typing_extensions import ParamSpec
|
|
18
|
+
|
|
19
|
+
from sqlspec.utils.module_loader import module_available
|
|
20
|
+
from sqlspec.utils.portal import get_global_portal
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Awaitable, Callable, Coroutine
|
|
24
|
+
from types import TracebackType
|
|
25
|
+
|
|
26
|
+
if module_available("uvloop"):
|
|
27
|
+
import uvloop # pyright: ignore[reportMissingImports]
|
|
28
|
+
else:
|
|
29
|
+
uvloop = None # type: ignore[assignment,unused-ignore]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
ReturnT = TypeVar("ReturnT")
|
|
33
|
+
ParamSpecT = ParamSpec("ParamSpecT")
|
|
34
|
+
T = TypeVar("T")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class NoValue:
|
|
38
|
+
"""Sentinel class for missing values."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
NO_VALUE = NoValue()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CapacityLimiter:
|
|
45
|
+
"""Limits the number of concurrent operations using a semaphore."""
|
|
46
|
+
|
|
47
|
+
def __init__(self, total_tokens: int) -> None:
|
|
48
|
+
"""Initialize the capacity limiter.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
total_tokens: Maximum number of concurrent operations allowed
|
|
52
|
+
"""
|
|
53
|
+
self._total_tokens = total_tokens
|
|
54
|
+
self._semaphore_instance: asyncio.Semaphore | None = None
|
|
55
|
+
self._pid: int | None = None
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def _semaphore(self) -> asyncio.Semaphore:
|
|
59
|
+
"""Lazy initialization of asyncio.Semaphore with per-process tracking.
|
|
60
|
+
|
|
61
|
+
Reinitializes the semaphore if running in a new process (detected via PID).
|
|
62
|
+
This ensures pytest-xdist workers each get their own semaphore bound to
|
|
63
|
+
their event loop, preventing cross-process deadlocks.
|
|
64
|
+
"""
|
|
65
|
+
current_pid = os.getpid()
|
|
66
|
+
if self._semaphore_instance is None or self._pid != current_pid:
|
|
67
|
+
self._semaphore_instance = asyncio.Semaphore(self._total_tokens)
|
|
68
|
+
self._pid = current_pid
|
|
69
|
+
return self._semaphore_instance
|
|
70
|
+
|
|
71
|
+
async def acquire(self) -> None:
|
|
72
|
+
"""Acquire a token from the semaphore."""
|
|
73
|
+
await self._semaphore.acquire()
|
|
74
|
+
|
|
75
|
+
def release(self) -> None:
|
|
76
|
+
"""Release a token back to the semaphore."""
|
|
77
|
+
self._semaphore.release()
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def total_tokens(self) -> int:
|
|
81
|
+
"""Get the total number of tokens available."""
|
|
82
|
+
return self._total_tokens
|
|
83
|
+
|
|
84
|
+
@total_tokens.setter
|
|
85
|
+
def total_tokens(self, value: int) -> None:
|
|
86
|
+
self._total_tokens = value
|
|
87
|
+
self._semaphore_instance = None
|
|
88
|
+
self._pid = None
|
|
89
|
+
|
|
90
|
+
async def __aenter__(self) -> None:
|
|
91
|
+
"""Async context manager entry."""
|
|
92
|
+
await self.acquire()
|
|
93
|
+
|
|
94
|
+
async def __aexit__(
|
|
95
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Async context manager exit."""
|
|
98
|
+
self.release()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
_default_limiter = CapacityLimiter(1000)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _return_value(value: Any) -> Any:
|
|
105
|
+
return value
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class _RunWrapper(Generic[ParamSpecT, ReturnT]):
|
|
109
|
+
__slots__ = ("__dict__", "_function")
|
|
110
|
+
|
|
111
|
+
def __init__(self, async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]") -> None:
|
|
112
|
+
self._function = async_function
|
|
113
|
+
functools.update_wrapper(self, async_function)
|
|
114
|
+
|
|
115
|
+
def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
116
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
117
|
+
try:
|
|
118
|
+
loop = asyncio.get_running_loop()
|
|
119
|
+
except RuntimeError:
|
|
120
|
+
loop = None
|
|
121
|
+
|
|
122
|
+
if loop is not None:
|
|
123
|
+
if loop.is_running():
|
|
124
|
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
125
|
+
future = executor.submit(asyncio.run, partial_f())
|
|
126
|
+
return future.result()
|
|
127
|
+
return asyncio.run(partial_f())
|
|
128
|
+
if uvloop and sys.platform != "win32":
|
|
129
|
+
uvloop.install() # pyright: ignore[reportUnknownMemberType]
|
|
130
|
+
return asyncio.run(partial_f())
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def run_(async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]") -> "Callable[ParamSpecT, ReturnT]":
|
|
134
|
+
"""Convert an async function to a blocking function using asyncio.run().
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
async_function: The async function to convert.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
A blocking function that runs the async function.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
return _RunWrapper(async_function)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def await_(
|
|
147
|
+
async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]", raise_sync_error: bool = False
|
|
148
|
+
) -> "Callable[ParamSpecT, ReturnT]":
|
|
149
|
+
"""Convert an async function to a blocking one, running in the main async loop.
|
|
150
|
+
|
|
151
|
+
When no event loop exists, automatically creates and uses a global portal for
|
|
152
|
+
async-to-sync bridging via background thread. Set raise_sync_error=True to
|
|
153
|
+
disable this behavior and raise errors instead.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
async_function: The async function to convert.
|
|
157
|
+
raise_sync_error: If True, raises RuntimeError when no loop exists.
|
|
158
|
+
If False (default), uses portal pattern for automatic bridging.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
A blocking function that runs the async function.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
return _AwaitWrapper(async_function, raise_sync_error)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def async_(
|
|
168
|
+
function: "Callable[ParamSpecT, ReturnT]", *, limiter: "CapacityLimiter | None" = None
|
|
169
|
+
) -> "Callable[ParamSpecT, Awaitable[ReturnT]]":
|
|
170
|
+
"""Convert a blocking function to an async one using asyncio.to_thread().
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
function: The blocking function to convert.
|
|
174
|
+
limiter: Limit the total number of threads.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
An async function that runs the original function in a thread.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
return _AsyncWrapper(function, limiter)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def ensure_async_(
|
|
184
|
+
function: "Callable[ParamSpecT, Awaitable[ReturnT] | ReturnT]",
|
|
185
|
+
) -> "Callable[ParamSpecT, Awaitable[ReturnT]]":
|
|
186
|
+
"""Convert a function to an async one if it is not already.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
function: The function to convert.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
An async function that runs the original function.
|
|
193
|
+
"""
|
|
194
|
+
if inspect.iscoroutinefunction(function):
|
|
195
|
+
return function
|
|
196
|
+
|
|
197
|
+
return _EnsureAsyncWrapper(function)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class _AwaitWrapper(Generic[ParamSpecT, ReturnT]):
|
|
201
|
+
__slots__ = ("__dict__", "_function", "_raise_sync_error")
|
|
202
|
+
|
|
203
|
+
def __init__(
|
|
204
|
+
self, async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]", raise_sync_error: bool
|
|
205
|
+
) -> None:
|
|
206
|
+
self._function = async_function
|
|
207
|
+
self._raise_sync_error = raise_sync_error
|
|
208
|
+
functools.update_wrapper(self, async_function)
|
|
209
|
+
|
|
210
|
+
def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
211
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
212
|
+
try:
|
|
213
|
+
loop = asyncio.get_running_loop()
|
|
214
|
+
except RuntimeError:
|
|
215
|
+
if self._raise_sync_error:
|
|
216
|
+
msg = "Cannot run async function"
|
|
217
|
+
raise RuntimeError(msg) from None
|
|
218
|
+
portal = get_global_portal()
|
|
219
|
+
typed_partial = cast("Callable[[], Coroutine[Any, Any, ReturnT]]", partial_f)
|
|
220
|
+
return portal.call(typed_partial)
|
|
221
|
+
if loop.is_running():
|
|
222
|
+
try:
|
|
223
|
+
current_task = asyncio.current_task(loop=loop)
|
|
224
|
+
except RuntimeError:
|
|
225
|
+
current_task = None
|
|
226
|
+
|
|
227
|
+
if current_task is not None:
|
|
228
|
+
msg = "await_ cannot be called from within an async task running on the same event loop. Use 'await' instead."
|
|
229
|
+
raise RuntimeError(msg)
|
|
230
|
+
future = asyncio.run_coroutine_threadsafe(partial_f(), loop)
|
|
231
|
+
return future.result()
|
|
232
|
+
if self._raise_sync_error:
|
|
233
|
+
msg = "Cannot run async function"
|
|
234
|
+
raise RuntimeError(msg)
|
|
235
|
+
portal = get_global_portal()
|
|
236
|
+
typed_partial = cast("Callable[[], Coroutine[Any, Any, ReturnT]]", partial_f)
|
|
237
|
+
return portal.call(typed_partial)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class _AsyncWrapper(Generic[ParamSpecT, ReturnT]):
|
|
241
|
+
__slots__ = ("__dict__", "_function", "_limiter")
|
|
242
|
+
|
|
243
|
+
def __init__(self, function: "Callable[ParamSpecT, ReturnT]", limiter: "CapacityLimiter | None") -> None:
|
|
244
|
+
self._function = function
|
|
245
|
+
self._limiter = limiter
|
|
246
|
+
functools.update_wrapper(self, function)
|
|
247
|
+
|
|
248
|
+
async def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
249
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
250
|
+
used_limiter = self._limiter or _default_limiter
|
|
251
|
+
async with used_limiter:
|
|
252
|
+
return await asyncio.to_thread(partial_f)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class _EnsureAsyncWrapper(Generic[ParamSpecT, ReturnT]):
|
|
256
|
+
__slots__ = ("__dict__", "_function")
|
|
257
|
+
|
|
258
|
+
def __init__(self, function: "Callable[ParamSpecT, Awaitable[ReturnT] | ReturnT]") -> None:
|
|
259
|
+
self._function = function
|
|
260
|
+
functools.update_wrapper(self, function)
|
|
261
|
+
|
|
262
|
+
async def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
263
|
+
result = self._function(*args, **kwargs)
|
|
264
|
+
if inspect.isawaitable(result):
|
|
265
|
+
return await cast("Awaitable[ReturnT]", result)
|
|
266
|
+
return result
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class _ContextManagerWrapper(Generic[T]):
|
|
270
|
+
def __init__(self, cm: AbstractContextManager[T]) -> None:
|
|
271
|
+
self._cm = cm
|
|
272
|
+
|
|
273
|
+
async def __aenter__(self) -> T:
|
|
274
|
+
return self._cm.__enter__()
|
|
275
|
+
|
|
276
|
+
async def __aexit__(
|
|
277
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
278
|
+
) -> "bool | None":
|
|
279
|
+
return self._cm.__exit__(exc_type, exc_val, exc_tb)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def with_ensure_async_(
|
|
283
|
+
obj: "AbstractContextManager[T] | AbstractAsyncContextManager[T]",
|
|
284
|
+
) -> "AbstractAsyncContextManager[T]":
|
|
285
|
+
"""Convert a context manager to an async one if it is not already.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
obj: The context manager to convert.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
An async context manager that runs the original context manager.
|
|
292
|
+
"""
|
|
293
|
+
if isinstance(obj, AbstractContextManager):
|
|
294
|
+
return cast("AbstractAsyncContextManager[T]", _ContextManagerWrapper(obj))
|
|
295
|
+
return obj
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
async def get_next(iterable: Any, default: Any = NO_VALUE, *args: Any) -> Any: # pragma: no cover
|
|
299
|
+
"""Return the next item from an async iterator.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
iterable: An async iterable.
|
|
303
|
+
default: An optional default value to return if the iterable is empty.
|
|
304
|
+
*args: The remaining args
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
The next value of the iterable.
|
|
308
|
+
"""
|
|
309
|
+
if isinstance(default, NoValue):
|
|
310
|
+
return await anext(iterable)
|
|
311
|
+
return await anext(iterable, default)
|
|
Binary file
|
sqlspec/utils/text.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Text processing utilities for SQLSpec.
|
|
2
|
+
|
|
3
|
+
Provides functions for string manipulation including case conversion,
|
|
4
|
+
slugification, and email validation. Used primarily for identifier
|
|
5
|
+
generation and data validation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
import unicodedata
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
|
|
12
|
+
_SLUGIFY_REMOVE_NON_ALPHANUMERIC = re.compile(r"[^\w]+", re.UNICODE)
|
|
13
|
+
_SLUGIFY_HYPHEN_COLLAPSE = re.compile(r"-+")
|
|
14
|
+
|
|
15
|
+
_SNAKE_CASE_LOWER_OR_DIGIT_TO_UPPER = re.compile(r"(?<=[a-z0-9])(?=[A-Z])", re.UNICODE)
|
|
16
|
+
_SNAKE_CASE_UPPER_TO_UPPER_LOWER = re.compile(r"(?<=[A-Z])(?=[A-Z][a-z])", re.UNICODE)
|
|
17
|
+
_SNAKE_CASE_HYPHEN_SPACE = re.compile(r"[.\s@-]+", re.UNICODE)
|
|
18
|
+
_SNAKE_CASE_REMOVE_NON_WORD = re.compile(r"[^\w]+", re.UNICODE)
|
|
19
|
+
_SNAKE_CASE_MULTIPLE_UNDERSCORES = re.compile(r"__+", re.UNICODE)
|
|
20
|
+
|
|
21
|
+
__all__ = ("camelize", "kebabize", "pascalize", "slugify", "snake_case")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def slugify(value: str, allow_unicode: bool = False, separator: str | None = None) -> str:
|
|
25
|
+
"""Convert a string to a URL-friendly slug.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
value: The string to slugify
|
|
29
|
+
allow_unicode: Allow unicode characters in slug.
|
|
30
|
+
separator: Separator character for word boundaries. Defaults to "-".
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
A slugified string.
|
|
34
|
+
"""
|
|
35
|
+
if allow_unicode:
|
|
36
|
+
value = unicodedata.normalize("NFKC", value)
|
|
37
|
+
else:
|
|
38
|
+
value = unicodedata.normalize("NFKD", value).encode("ascii", "ignore").decode("ascii")
|
|
39
|
+
value = value.lower().strip()
|
|
40
|
+
sep = separator if separator is not None else "-"
|
|
41
|
+
if not sep:
|
|
42
|
+
return _SLUGIFY_REMOVE_NON_ALPHANUMERIC.sub("", value)
|
|
43
|
+
value = _SLUGIFY_REMOVE_NON_ALPHANUMERIC.sub(sep, value)
|
|
44
|
+
if sep == "-":
|
|
45
|
+
value = value.strip("-")
|
|
46
|
+
return _SLUGIFY_HYPHEN_COLLAPSE.sub("-", value)
|
|
47
|
+
value = re.sub(rf"^{re.escape(sep)}+|{re.escape(sep)}+$", "", value)
|
|
48
|
+
return re.sub(rf"{re.escape(sep)}+", sep, value)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@lru_cache(maxsize=100)
|
|
52
|
+
def camelize(string: str) -> str:
|
|
53
|
+
"""Convert a string to camel case.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
string: The string to convert.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The converted string.
|
|
60
|
+
"""
|
|
61
|
+
return "".join(word if index == 0 else word.capitalize() for index, word in enumerate(string.split("_")))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@lru_cache(maxsize=100)
|
|
65
|
+
def kebabize(string: str) -> str:
|
|
66
|
+
"""Convert a string to kebab-case.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
string: The string to convert.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The kebab-case version of the string.
|
|
73
|
+
"""
|
|
74
|
+
return "-".join(word.lower() for word in string.split("_") if word)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@lru_cache(maxsize=100)
|
|
78
|
+
def pascalize(string: str) -> str:
|
|
79
|
+
"""Convert a string to PascalCase.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
string: The string to convert.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
The PascalCase version of the string.
|
|
86
|
+
"""
|
|
87
|
+
return "".join(word.capitalize() for word in string.split("_") if word)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@lru_cache(maxsize=100)
|
|
91
|
+
def snake_case(string: str) -> str:
|
|
92
|
+
"""Convert a string to snake_case.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
string: The string to convert.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
The snake_case version of the string.
|
|
99
|
+
"""
|
|
100
|
+
if not string:
|
|
101
|
+
return ""
|
|
102
|
+
s = _SNAKE_CASE_HYPHEN_SPACE.sub("_", string)
|
|
103
|
+
s = _SNAKE_CASE_REMOVE_NON_WORD.sub("", s)
|
|
104
|
+
s = _SNAKE_CASE_LOWER_OR_DIGIT_TO_UPPER.sub("_", s)
|
|
105
|
+
s = _SNAKE_CASE_UPPER_TO_UPPER_LOWER.sub("_", s)
|
|
106
|
+
s = s.lower()
|
|
107
|
+
s = s.strip("_")
|
|
108
|
+
return _SNAKE_CASE_MULTIPLE_UNDERSCORES.sub("_", s)
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Reusable converter builders for parameter configuration."""
|
|
2
|
+
|
|
3
|
+
import decimal
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
import datetime
|
|
8
|
+
from collections.abc import Callable, Sequence
|
|
9
|
+
|
|
10
|
+
__all__ = (
|
|
11
|
+
"DEFAULT_DECIMAL_MODE",
|
|
12
|
+
"build_decimal_converter",
|
|
13
|
+
"build_json_list_converter",
|
|
14
|
+
"build_json_tuple_converter",
|
|
15
|
+
"build_nested_decimal_normalizer",
|
|
16
|
+
"build_time_iso_converter",
|
|
17
|
+
"should_json_encode_sequence",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
JSON_NESTED_TYPES: "tuple[type[Any], ...]" = (dict, list, tuple)
|
|
21
|
+
DEFAULT_DECIMAL_MODE: str = "preserve"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _decimal_identity(value: "decimal.Decimal") -> "decimal.Decimal":
|
|
25
|
+
return value
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _decimal_to_string(value: "decimal.Decimal") -> str:
|
|
29
|
+
return str(value)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _decimal_to_float(value: "decimal.Decimal") -> float:
|
|
33
|
+
return float(value)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class _JsonListConverter:
|
|
37
|
+
__slots__ = ("_preserve_arrays", "_serializer")
|
|
38
|
+
|
|
39
|
+
def __init__(self, serializer: "Callable[[Any], str]", preserve_arrays: bool) -> None:
|
|
40
|
+
self._serializer = serializer
|
|
41
|
+
self._preserve_arrays = preserve_arrays
|
|
42
|
+
|
|
43
|
+
def __call__(self, value: "list[Any]") -> Any:
|
|
44
|
+
if not value:
|
|
45
|
+
return value
|
|
46
|
+
if self._preserve_arrays and not should_json_encode_sequence(value):
|
|
47
|
+
return value
|
|
48
|
+
return self._serializer(value)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class _JsonTupleConverter:
|
|
52
|
+
__slots__ = ("_list_converter",)
|
|
53
|
+
|
|
54
|
+
def __init__(self, list_converter: _JsonListConverter) -> None:
|
|
55
|
+
self._list_converter = list_converter
|
|
56
|
+
|
|
57
|
+
def __call__(self, value: "tuple[Any, ...]") -> Any:
|
|
58
|
+
if not value:
|
|
59
|
+
return value
|
|
60
|
+
return self._list_converter(list(value))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class _DecimalNormalizer:
|
|
64
|
+
__slots__ = ("_decimal_converter",)
|
|
65
|
+
|
|
66
|
+
def __init__(self, decimal_converter: "Callable[[decimal.Decimal], Any]") -> None:
|
|
67
|
+
self._decimal_converter = decimal_converter
|
|
68
|
+
|
|
69
|
+
def __call__(self, value: Any) -> Any:
|
|
70
|
+
if isinstance(value, decimal.Decimal):
|
|
71
|
+
return self._decimal_converter(value)
|
|
72
|
+
if isinstance(value, list):
|
|
73
|
+
return [self(item) for item in value]
|
|
74
|
+
if isinstance(value, tuple):
|
|
75
|
+
return tuple(self(item) for item in value)
|
|
76
|
+
if isinstance(value, dict):
|
|
77
|
+
return {key: self(item) for key, item in value.items()}
|
|
78
|
+
return value
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _time_iso_convert(value: "datetime.date | datetime.datetime | datetime.time") -> str:
|
|
82
|
+
return value.isoformat()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def should_json_encode_sequence(sequence: "Sequence[Any]") -> bool:
|
|
86
|
+
"""Return ``True`` when a sequence should be JSON serialized."""
|
|
87
|
+
|
|
88
|
+
return any(isinstance(item, JSON_NESTED_TYPES) for item in sequence if item is not None)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def build_json_list_converter(
|
|
92
|
+
serializer: "Callable[[Any], str]", *, preserve_arrays: bool = True
|
|
93
|
+
) -> "Callable[[list[Any]], Any]":
|
|
94
|
+
"""Create a converter that serializes lists containing nested structures."""
|
|
95
|
+
return _JsonListConverter(serializer, preserve_arrays)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def build_json_tuple_converter(
|
|
99
|
+
serializer: "Callable[[Any], str]", *, preserve_arrays: bool = True
|
|
100
|
+
) -> "Callable[[tuple[Any, ...]], Any]":
|
|
101
|
+
"""Create a converter that mirrors list handling for tuples."""
|
|
102
|
+
list_converter = _JsonListConverter(serializer, preserve_arrays)
|
|
103
|
+
return _JsonTupleConverter(list_converter)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def build_decimal_converter(*, mode: str = DEFAULT_DECIMAL_MODE) -> "Callable[[decimal.Decimal], Any]":
|
|
107
|
+
"""Create a Decimal converter according to the desired mode."""
|
|
108
|
+
|
|
109
|
+
if mode == "preserve":
|
|
110
|
+
return _decimal_identity
|
|
111
|
+
if mode == "string":
|
|
112
|
+
return _decimal_to_string
|
|
113
|
+
if mode == "float":
|
|
114
|
+
return _decimal_to_float
|
|
115
|
+
|
|
116
|
+
msg = f"Unsupported decimal converter mode: {mode}"
|
|
117
|
+
raise ValueError(msg)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def build_nested_decimal_normalizer(*, mode: str = DEFAULT_DECIMAL_MODE) -> "Callable[[Any], Any]":
|
|
121
|
+
"""Return a callable that coerces ``Decimal`` values within nested structures."""
|
|
122
|
+
decimal_converter = build_decimal_converter(mode=mode)
|
|
123
|
+
return _DecimalNormalizer(decimal_converter)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def build_time_iso_converter() -> "Callable[[datetime.date | datetime.datetime | datetime.time], str]":
|
|
127
|
+
"""Return a converter that formats temporal values using ISO 8601."""
|
|
128
|
+
return _time_iso_convert
|
|
Binary file
|