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,346 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from contextlib import asynccontextmanager
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from sqlspec.base import SQLSpec
|
|
6
|
+
from sqlspec.exceptions import ImproperConfigurationError
|
|
7
|
+
from sqlspec.extensions.starlette._state import SQLSpecConfigState
|
|
8
|
+
from sqlspec.extensions.starlette._utils import get_or_create_session, get_state_value
|
|
9
|
+
from sqlspec.extensions.starlette.middleware import (
|
|
10
|
+
CorrelationMiddleware,
|
|
11
|
+
SQLSpecAutocommitMiddleware,
|
|
12
|
+
SQLSpecManualMiddleware,
|
|
13
|
+
)
|
|
14
|
+
from sqlspec.utils.logging import get_logger, log_with_context
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from collections.abc import AsyncGenerator
|
|
18
|
+
|
|
19
|
+
from starlette.applications import Starlette
|
|
20
|
+
from starlette.requests import Request
|
|
21
|
+
|
|
22
|
+
__all__ = ("SQLSpecPlugin",)
|
|
23
|
+
|
|
24
|
+
logger = get_logger("sqlspec.extensions.starlette")
|
|
25
|
+
|
|
26
|
+
DEFAULT_COMMIT_MODE = "manual"
|
|
27
|
+
DEFAULT_CONNECTION_KEY = "db_connection"
|
|
28
|
+
DEFAULT_POOL_KEY = "db_pool"
|
|
29
|
+
DEFAULT_SESSION_KEY = "db_session"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SQLSpecPlugin:
|
|
33
|
+
"""SQLSpec integration for Starlette applications.
|
|
34
|
+
|
|
35
|
+
Provides middleware-based session management, automatic transaction handling,
|
|
36
|
+
and connection pooling lifecycle management.
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
from starlette.applications import Starlette
|
|
40
|
+
from sqlspec import SQLSpec
|
|
41
|
+
from sqlspec.adapters.asyncpg import AsyncpgConfig
|
|
42
|
+
from sqlspec.extensions.starlette import SQLSpecPlugin
|
|
43
|
+
|
|
44
|
+
sqlspec = SQLSpec()
|
|
45
|
+
sqlspec.add_config(AsyncpgConfig(
|
|
46
|
+
bind_key="default",
|
|
47
|
+
connection_config={"dsn": "postgresql://localhost/mydb"},
|
|
48
|
+
extension_config={
|
|
49
|
+
"starlette": {
|
|
50
|
+
"commit_mode": "autocommit",
|
|
51
|
+
"session_key": "db"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
))
|
|
55
|
+
|
|
56
|
+
app = Starlette()
|
|
57
|
+
db_ext = SQLSpecPlugin(sqlspec, app)
|
|
58
|
+
|
|
59
|
+
@app.route("/users")
|
|
60
|
+
async def list_users(request):
|
|
61
|
+
db = db_ext.get_session(request)
|
|
62
|
+
result = await db.execute("SELECT * FROM users")
|
|
63
|
+
return JSONResponse({"users": result.all()})
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
__slots__ = ("_config_states", "_correlation_middleware_added", "_sqlspec")
|
|
67
|
+
|
|
68
|
+
def __init__(self, sqlspec: SQLSpec, app: "Starlette | None" = None) -> None:
|
|
69
|
+
"""Initialize SQLSpec Starlette extension.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
sqlspec: Pre-configured SQLSpec instance with registered configs.
|
|
73
|
+
app: Optional Starlette application to initialize immediately.
|
|
74
|
+
"""
|
|
75
|
+
self._sqlspec = sqlspec
|
|
76
|
+
self._config_states: list[SQLSpecConfigState] = []
|
|
77
|
+
self._correlation_middleware_added = False
|
|
78
|
+
|
|
79
|
+
for cfg in self._sqlspec.configs.values():
|
|
80
|
+
settings = self._extract_starlette_settings(cfg)
|
|
81
|
+
state = self._create_config_state(cfg, settings)
|
|
82
|
+
self._config_states.append(state)
|
|
83
|
+
|
|
84
|
+
if app is not None:
|
|
85
|
+
self.init_app(app)
|
|
86
|
+
log_with_context(
|
|
87
|
+
logger,
|
|
88
|
+
logging.DEBUG,
|
|
89
|
+
"extension.init",
|
|
90
|
+
framework="starlette",
|
|
91
|
+
stage="init",
|
|
92
|
+
config_count=len(self._config_states),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def _extract_starlette_settings(self, config: Any) -> "dict[str, Any]":
|
|
96
|
+
"""Extract Starlette settings from config.extension_config.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
config: Database configuration instance.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Dictionary of Starlette-specific settings.
|
|
103
|
+
"""
|
|
104
|
+
starlette_config = config.extension_config.get("starlette", {})
|
|
105
|
+
|
|
106
|
+
connection_key = starlette_config.get("connection_key", DEFAULT_CONNECTION_KEY)
|
|
107
|
+
pool_key = starlette_config.get("pool_key", DEFAULT_POOL_KEY)
|
|
108
|
+
session_key = starlette_config.get("session_key", DEFAULT_SESSION_KEY)
|
|
109
|
+
commit_mode = starlette_config.get("commit_mode", DEFAULT_COMMIT_MODE)
|
|
110
|
+
|
|
111
|
+
if not config.supports_connection_pooling and pool_key == DEFAULT_POOL_KEY:
|
|
112
|
+
pool_key = f"_{DEFAULT_POOL_KEY}_{id(config)}"
|
|
113
|
+
|
|
114
|
+
enable_correlation = starlette_config.get("enable_correlation_middleware", False)
|
|
115
|
+
correlation_header = starlette_config.get("correlation_header", "x-request-id")
|
|
116
|
+
correlation_headers = starlette_config.get("correlation_headers")
|
|
117
|
+
if correlation_headers is not None:
|
|
118
|
+
correlation_headers = tuple(correlation_headers)
|
|
119
|
+
auto_trace_headers = starlette_config.get("auto_trace_headers", True)
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
"connection_key": connection_key,
|
|
123
|
+
"pool_key": pool_key,
|
|
124
|
+
"session_key": session_key,
|
|
125
|
+
"commit_mode": commit_mode,
|
|
126
|
+
"extra_commit_statuses": starlette_config.get("extra_commit_statuses"),
|
|
127
|
+
"extra_rollback_statuses": starlette_config.get("extra_rollback_statuses"),
|
|
128
|
+
"disable_di": starlette_config.get("disable_di", False),
|
|
129
|
+
"enable_correlation_middleware": enable_correlation,
|
|
130
|
+
"correlation_header": correlation_header,
|
|
131
|
+
"correlation_headers": correlation_headers,
|
|
132
|
+
"auto_trace_headers": auto_trace_headers,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def _create_config_state(self, config: Any, settings: "dict[str, Any]") -> SQLSpecConfigState:
|
|
136
|
+
"""Create configuration state object.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
config: Database configuration instance.
|
|
140
|
+
settings: Extracted Starlette settings.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Configuration state instance.
|
|
144
|
+
"""
|
|
145
|
+
return SQLSpecConfigState(
|
|
146
|
+
config=config,
|
|
147
|
+
connection_key=settings["connection_key"],
|
|
148
|
+
pool_key=settings["pool_key"],
|
|
149
|
+
session_key=settings["session_key"],
|
|
150
|
+
commit_mode=settings["commit_mode"],
|
|
151
|
+
extra_commit_statuses=settings["extra_commit_statuses"],
|
|
152
|
+
extra_rollback_statuses=settings["extra_rollback_statuses"],
|
|
153
|
+
disable_di=settings["disable_di"],
|
|
154
|
+
enable_correlation_middleware=settings["enable_correlation_middleware"],
|
|
155
|
+
correlation_header=settings["correlation_header"],
|
|
156
|
+
correlation_headers=settings["correlation_headers"],
|
|
157
|
+
auto_trace_headers=settings["auto_trace_headers"],
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
def init_app(self, app: "Starlette") -> None:
|
|
161
|
+
"""Initialize Starlette application with SQLSpec.
|
|
162
|
+
|
|
163
|
+
Validates configuration, wraps lifespan, and adds middleware.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
app: Starlette application instance.
|
|
167
|
+
"""
|
|
168
|
+
self._validate_unique_keys()
|
|
169
|
+
|
|
170
|
+
original_lifespan = app.router.lifespan_context
|
|
171
|
+
|
|
172
|
+
@asynccontextmanager
|
|
173
|
+
async def combined_lifespan(app: "Starlette") -> "AsyncGenerator[None, None]":
|
|
174
|
+
async with self.lifespan(app), original_lifespan(app):
|
|
175
|
+
yield
|
|
176
|
+
|
|
177
|
+
app.router.lifespan_context = combined_lifespan
|
|
178
|
+
|
|
179
|
+
for config_state in self._config_states:
|
|
180
|
+
if not config_state.disable_di:
|
|
181
|
+
self._add_middleware(app, config_state)
|
|
182
|
+
|
|
183
|
+
# Add correlation middleware if any config enables it (only add once)
|
|
184
|
+
self._add_correlation_middleware(app)
|
|
185
|
+
|
|
186
|
+
log_with_context(
|
|
187
|
+
logger,
|
|
188
|
+
logging.DEBUG,
|
|
189
|
+
"extension.init",
|
|
190
|
+
framework="starlette",
|
|
191
|
+
stage="configured",
|
|
192
|
+
config_count=len(self._config_states),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def _validate_unique_keys(self) -> None:
|
|
196
|
+
"""Validate that all state keys are unique across configs.
|
|
197
|
+
|
|
198
|
+
Raises:
|
|
199
|
+
ImproperConfigurationError: If duplicate keys found.
|
|
200
|
+
"""
|
|
201
|
+
all_keys: set[str] = set()
|
|
202
|
+
|
|
203
|
+
for state in self._config_states:
|
|
204
|
+
keys = {state.connection_key, state.pool_key, state.session_key}
|
|
205
|
+
duplicates = all_keys & keys
|
|
206
|
+
|
|
207
|
+
if duplicates:
|
|
208
|
+
msg = f"Duplicate state keys found: {duplicates}"
|
|
209
|
+
raise ImproperConfigurationError(msg)
|
|
210
|
+
|
|
211
|
+
all_keys.update(keys)
|
|
212
|
+
|
|
213
|
+
def _add_middleware(self, app: "Starlette", config_state: SQLSpecConfigState) -> None:
|
|
214
|
+
"""Add transaction middleware for configuration.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
app: Starlette application instance.
|
|
218
|
+
config_state: Configuration state.
|
|
219
|
+
"""
|
|
220
|
+
if config_state.commit_mode == "manual":
|
|
221
|
+
app.add_middleware(SQLSpecManualMiddleware, config_state=config_state)
|
|
222
|
+
elif config_state.commit_mode == "autocommit":
|
|
223
|
+
app.add_middleware(SQLSpecAutocommitMiddleware, config_state=config_state, include_redirect=False)
|
|
224
|
+
elif config_state.commit_mode == "autocommit_include_redirect":
|
|
225
|
+
app.add_middleware(SQLSpecAutocommitMiddleware, config_state=config_state, include_redirect=True)
|
|
226
|
+
|
|
227
|
+
def _add_correlation_middleware(self, app: "Starlette") -> None:
|
|
228
|
+
"""Add correlation middleware if any config enables it.
|
|
229
|
+
|
|
230
|
+
Only adds the middleware once, using settings from the first config
|
|
231
|
+
that enables it.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
app: Starlette application instance.
|
|
235
|
+
"""
|
|
236
|
+
if self._correlation_middleware_added:
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
# Find first config that enables correlation middleware
|
|
240
|
+
for config_state in self._config_states:
|
|
241
|
+
if config_state.enable_correlation_middleware:
|
|
242
|
+
app.add_middleware(
|
|
243
|
+
CorrelationMiddleware,
|
|
244
|
+
primary_header=config_state.correlation_header,
|
|
245
|
+
additional_headers=config_state.correlation_headers,
|
|
246
|
+
auto_trace_headers=config_state.auto_trace_headers,
|
|
247
|
+
)
|
|
248
|
+
self._correlation_middleware_added = True
|
|
249
|
+
log_with_context(
|
|
250
|
+
logger,
|
|
251
|
+
logging.DEBUG,
|
|
252
|
+
"extension.init",
|
|
253
|
+
framework="starlette",
|
|
254
|
+
stage="correlation_middleware",
|
|
255
|
+
primary_header=config_state.correlation_header,
|
|
256
|
+
)
|
|
257
|
+
break
|
|
258
|
+
|
|
259
|
+
@asynccontextmanager
|
|
260
|
+
async def lifespan(self, app: "Starlette") -> "AsyncGenerator[None, None]":
|
|
261
|
+
"""Manage connection pool lifecycle.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
app: Starlette application instance.
|
|
265
|
+
|
|
266
|
+
Yields:
|
|
267
|
+
None
|
|
268
|
+
"""
|
|
269
|
+
for config_state in self._config_states:
|
|
270
|
+
if config_state.config.supports_connection_pooling:
|
|
271
|
+
pool = await config_state.config.create_pool()
|
|
272
|
+
setattr(app.state, config_state.pool_key, pool)
|
|
273
|
+
log_with_context(
|
|
274
|
+
logger,
|
|
275
|
+
logging.DEBUG,
|
|
276
|
+
"session.create",
|
|
277
|
+
framework="starlette",
|
|
278
|
+
session_key=config_state.session_key,
|
|
279
|
+
pool_key=config_state.pool_key,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
try:
|
|
283
|
+
yield
|
|
284
|
+
finally:
|
|
285
|
+
for config_state in self._config_states:
|
|
286
|
+
if config_state.config.supports_connection_pooling:
|
|
287
|
+
close_result = config_state.config.close_pool()
|
|
288
|
+
if close_result is not None:
|
|
289
|
+
await close_result
|
|
290
|
+
log_with_context(
|
|
291
|
+
logger,
|
|
292
|
+
logging.DEBUG,
|
|
293
|
+
"session.close",
|
|
294
|
+
framework="starlette",
|
|
295
|
+
session_key=config_state.session_key,
|
|
296
|
+
pool_key=config_state.pool_key,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def get_session(self, request: "Request", key: "str | None" = None) -> Any:
|
|
300
|
+
"""Get or create database session for request.
|
|
301
|
+
|
|
302
|
+
Sessions are cached per request to ensure consistency.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
request: Starlette request instance.
|
|
306
|
+
key: Optional session key to retrieve specific database session.
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
Database session (driver instance).
|
|
310
|
+
"""
|
|
311
|
+
config_state = self._config_states[0] if key is None else self._get_config_state_by_key(key)
|
|
312
|
+
|
|
313
|
+
return get_or_create_session(request, config_state)
|
|
314
|
+
|
|
315
|
+
def get_connection(self, request: "Request", key: "str | None" = None) -> Any:
|
|
316
|
+
"""Get database connection from request state.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
request: Starlette request instance.
|
|
320
|
+
key: Optional session key to retrieve specific database connection.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
Database connection object.
|
|
324
|
+
"""
|
|
325
|
+
config_state = self._config_states[0] if key is None else self._get_config_state_by_key(key)
|
|
326
|
+
|
|
327
|
+
return get_state_value(request.state, config_state.connection_key)
|
|
328
|
+
|
|
329
|
+
def _get_config_state_by_key(self, key: str) -> SQLSpecConfigState:
|
|
330
|
+
"""Get configuration state by session key.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
key: Session key to search for.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
Configuration state matching the key.
|
|
337
|
+
|
|
338
|
+
Raises:
|
|
339
|
+
ValueError: If no configuration found with the specified key.
|
|
340
|
+
"""
|
|
341
|
+
for state in self._config_states:
|
|
342
|
+
if state.session_key == key:
|
|
343
|
+
return state
|
|
344
|
+
|
|
345
|
+
msg = f"No configuration found with session_key: {key}"
|
|
346
|
+
raise ValueError(msg)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any
|
|
2
|
+
|
|
3
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
4
|
+
|
|
5
|
+
from sqlspec.core import CorrelationExtractor
|
|
6
|
+
from sqlspec.extensions.starlette._utils import get_state_value, pop_state_value, set_state_value
|
|
7
|
+
from sqlspec.utils.correlation import CorrelationContext
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from starlette.requests import Request
|
|
11
|
+
from starlette.responses import Response
|
|
12
|
+
|
|
13
|
+
from sqlspec.extensions.starlette._state import SQLSpecConfigState
|
|
14
|
+
|
|
15
|
+
__all__ = ("CorrelationMiddleware", "SQLSpecAutocommitMiddleware", "SQLSpecManualMiddleware")
|
|
16
|
+
|
|
17
|
+
HTTP_200_OK = 200
|
|
18
|
+
HTTP_300_MULTIPLE_CHOICES = 300
|
|
19
|
+
HTTP_400_BAD_REQUEST = 400
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SQLSpecManualMiddleware(BaseHTTPMiddleware):
|
|
23
|
+
"""Middleware for manual transaction mode.
|
|
24
|
+
|
|
25
|
+
Acquires connection from pool, stores in request.state, releases after request.
|
|
26
|
+
No automatic commit or rollback - user code must handle transactions.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, app: Any, config_state: "SQLSpecConfigState") -> None:
|
|
30
|
+
"""Initialize middleware.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
app: Starlette application instance.
|
|
34
|
+
config_state: Configuration state for this database.
|
|
35
|
+
"""
|
|
36
|
+
super().__init__(app)
|
|
37
|
+
self.config_state = config_state
|
|
38
|
+
|
|
39
|
+
async def dispatch(self, request: "Request", call_next: Any) -> Any:
|
|
40
|
+
"""Process request with manual transaction mode.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
request: Incoming HTTP request.
|
|
44
|
+
call_next: Next middleware or route handler.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
HTTP response.
|
|
48
|
+
"""
|
|
49
|
+
config = self.config_state.config
|
|
50
|
+
connection_key = self.config_state.connection_key
|
|
51
|
+
|
|
52
|
+
if config.supports_connection_pooling:
|
|
53
|
+
pool = get_state_value(request.app.state, self.config_state.pool_key)
|
|
54
|
+
async with config.provide_connection(pool) as connection: # type: ignore[union-attr]
|
|
55
|
+
set_state_value(request.state, connection_key, connection)
|
|
56
|
+
try:
|
|
57
|
+
return await call_next(request)
|
|
58
|
+
finally:
|
|
59
|
+
pop_state_value(request.state, connection_key)
|
|
60
|
+
else:
|
|
61
|
+
connection = await config.create_connection()
|
|
62
|
+
set_state_value(request.state, connection_key, connection)
|
|
63
|
+
try:
|
|
64
|
+
return await call_next(request)
|
|
65
|
+
finally:
|
|
66
|
+
await connection.close()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class SQLSpecAutocommitMiddleware(BaseHTTPMiddleware):
|
|
70
|
+
"""Middleware for autocommit transaction mode.
|
|
71
|
+
|
|
72
|
+
Acquires connection, commits on success status codes, rollbacks on error status codes.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self, app: Any, config_state: "SQLSpecConfigState", include_redirect: bool = False) -> None:
|
|
76
|
+
"""Initialize middleware.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
app: Starlette application instance.
|
|
80
|
+
config_state: Configuration state for this database.
|
|
81
|
+
include_redirect: If True, commit on 3xx status codes as well.
|
|
82
|
+
"""
|
|
83
|
+
super().__init__(app)
|
|
84
|
+
self.config_state = config_state
|
|
85
|
+
self.include_redirect = include_redirect
|
|
86
|
+
|
|
87
|
+
async def dispatch(self, request: "Request", call_next: Any) -> Any:
|
|
88
|
+
"""Process request with autocommit transaction mode.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
request: Incoming HTTP request.
|
|
92
|
+
call_next: Next middleware or route handler.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
HTTP response.
|
|
96
|
+
"""
|
|
97
|
+
config = self.config_state.config
|
|
98
|
+
connection_key = self.config_state.connection_key
|
|
99
|
+
|
|
100
|
+
if config.supports_connection_pooling:
|
|
101
|
+
pool = get_state_value(request.app.state, self.config_state.pool_key)
|
|
102
|
+
async with config.provide_connection(pool) as connection: # type: ignore[union-attr]
|
|
103
|
+
set_state_value(request.state, connection_key, connection)
|
|
104
|
+
try:
|
|
105
|
+
response = await call_next(request)
|
|
106
|
+
|
|
107
|
+
if self._should_commit(response.status_code):
|
|
108
|
+
await connection.commit()
|
|
109
|
+
else:
|
|
110
|
+
await connection.rollback()
|
|
111
|
+
except Exception:
|
|
112
|
+
await connection.rollback()
|
|
113
|
+
raise
|
|
114
|
+
else:
|
|
115
|
+
return response
|
|
116
|
+
finally:
|
|
117
|
+
pop_state_value(request.state, connection_key)
|
|
118
|
+
else:
|
|
119
|
+
connection = await config.create_connection()
|
|
120
|
+
set_state_value(request.state, connection_key, connection)
|
|
121
|
+
try:
|
|
122
|
+
response = await call_next(request)
|
|
123
|
+
|
|
124
|
+
if self._should_commit(response.status_code):
|
|
125
|
+
await connection.commit()
|
|
126
|
+
else:
|
|
127
|
+
await connection.rollback()
|
|
128
|
+
except Exception:
|
|
129
|
+
await connection.rollback()
|
|
130
|
+
raise
|
|
131
|
+
else:
|
|
132
|
+
return response
|
|
133
|
+
finally:
|
|
134
|
+
await connection.close()
|
|
135
|
+
|
|
136
|
+
def _should_commit(self, status_code: int) -> bool:
|
|
137
|
+
"""Determine if response status code should trigger commit.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
status_code: HTTP status code.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
True if should commit, False if should rollback.
|
|
144
|
+
"""
|
|
145
|
+
extra_commit = self.config_state.extra_commit_statuses or set()
|
|
146
|
+
extra_rollback = self.config_state.extra_rollback_statuses or set()
|
|
147
|
+
|
|
148
|
+
if status_code in extra_commit:
|
|
149
|
+
return True
|
|
150
|
+
if status_code in extra_rollback:
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
if HTTP_200_OK <= status_code < HTTP_300_MULTIPLE_CHOICES:
|
|
154
|
+
return True
|
|
155
|
+
return bool(self.include_redirect and HTTP_300_MULTIPLE_CHOICES <= status_code < HTTP_400_BAD_REQUEST)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class CorrelationMiddleware(BaseHTTPMiddleware):
|
|
159
|
+
"""Middleware for correlation ID extraction and propagation.
|
|
160
|
+
|
|
161
|
+
Extracts correlation IDs from request headers (or generates new ones)
|
|
162
|
+
and propagates them through the request lifecycle via CorrelationContext.
|
|
163
|
+
|
|
164
|
+
The middleware:
|
|
165
|
+
1. Extracts correlation ID from configurable headers
|
|
166
|
+
2. Sets it in the CorrelationContext for async/sync access
|
|
167
|
+
3. Stores it in request.state.correlation_id
|
|
168
|
+
4. Adds X-Correlation-ID header to the response
|
|
169
|
+
5. Cleans up the context on request completion
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
```python
|
|
173
|
+
from starlette.applications import Starlette
|
|
174
|
+
from sqlspec.extensions.starlette.middleware import (
|
|
175
|
+
CorrelationMiddleware,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
app = Starlette()
|
|
179
|
+
app.add_middleware(
|
|
180
|
+
CorrelationMiddleware,
|
|
181
|
+
primary_header="x-request-id",
|
|
182
|
+
auto_trace_headers=True,
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
def __init__(
|
|
188
|
+
self,
|
|
189
|
+
app: Any,
|
|
190
|
+
*,
|
|
191
|
+
primary_header: str = "x-request-id",
|
|
192
|
+
additional_headers: tuple[str, ...] | None = None,
|
|
193
|
+
auto_trace_headers: bool = True,
|
|
194
|
+
max_length: int = 128,
|
|
195
|
+
) -> None:
|
|
196
|
+
"""Initialize correlation middleware.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
app: Starlette application instance.
|
|
200
|
+
primary_header: The primary header to check first. Defaults to "x-request-id".
|
|
201
|
+
additional_headers: Additional headers to check after the primary header.
|
|
202
|
+
auto_trace_headers: If True, include standard trace context headers as fallbacks.
|
|
203
|
+
max_length: Maximum length for correlation IDs. Defaults to 128.
|
|
204
|
+
"""
|
|
205
|
+
super().__init__(app)
|
|
206
|
+
self._extractor = CorrelationExtractor(
|
|
207
|
+
primary_header=primary_header,
|
|
208
|
+
additional_headers=additional_headers,
|
|
209
|
+
auto_trace_headers=auto_trace_headers,
|
|
210
|
+
max_length=max_length,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
async def dispatch(self, request: "Request", call_next: Any) -> "Response":
|
|
214
|
+
"""Extract correlation ID and propagate through request lifecycle.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
request: Incoming HTTP request.
|
|
218
|
+
call_next: Next middleware or route handler.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
HTTP response with X-Correlation-ID header.
|
|
222
|
+
"""
|
|
223
|
+
correlation_id = self._extractor.extract(lambda h: request.headers.get(h))
|
|
224
|
+
previous_id = CorrelationContext.get()
|
|
225
|
+
|
|
226
|
+
CorrelationContext.set(correlation_id)
|
|
227
|
+
set_state_value(request.state, "correlation_id", correlation_id)
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
response: Response = await call_next(request)
|
|
231
|
+
response.headers["X-Correlation-ID"] = correlation_id
|
|
232
|
+
return response
|
|
233
|
+
finally:
|
|
234
|
+
CorrelationContext.set(previous_id)
|
|
235
|
+
pop_state_value(request.state, "correlation_id")
|
|
Binary file
|