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
sqlspec/utils/portal.py
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"""Portal provider for calling async functions from synchronous contexts.
|
|
2
|
+
|
|
3
|
+
Provides a background thread with an event loop to execute async database operations
|
|
4
|
+
from sync frameworks like Flask. Based on the portal pattern from Advanced Alchemy.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import atexit
|
|
9
|
+
import functools
|
|
10
|
+
import os
|
|
11
|
+
import queue
|
|
12
|
+
import threading
|
|
13
|
+
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, cast
|
|
14
|
+
|
|
15
|
+
from sqlspec.exceptions import ImproperConfigurationError
|
|
16
|
+
from sqlspec.utils.logging import get_logger
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from collections.abc import Callable, Coroutine
|
|
20
|
+
|
|
21
|
+
__all__ = ("Portal", "PortalManager", "PortalProvider", "get_global_portal")
|
|
22
|
+
|
|
23
|
+
logger = get_logger("sqlspec.utils.portal")
|
|
24
|
+
|
|
25
|
+
_R = TypeVar("_R")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PortalProvider:
|
|
29
|
+
"""Manages a background thread with event loop for async operations.
|
|
30
|
+
|
|
31
|
+
Creates a daemon thread running an event loop to execute async functions
|
|
32
|
+
from synchronous contexts (Flask routes, etc.).
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self) -> None:
|
|
36
|
+
"""Initialize the PortalProvider."""
|
|
37
|
+
self._request_queue: queue.Queue[
|
|
38
|
+
tuple[
|
|
39
|
+
Callable[..., Coroutine[Any, Any, Any]],
|
|
40
|
+
tuple[Any, ...],
|
|
41
|
+
dict[str, Any],
|
|
42
|
+
queue.Queue[tuple[Any | None, Exception | None]],
|
|
43
|
+
]
|
|
44
|
+
] = queue.Queue()
|
|
45
|
+
self._loop: asyncio.AbstractEventLoop | None = None
|
|
46
|
+
self._loop_thread: threading.Thread | None = None
|
|
47
|
+
self._ready_event: threading.Event = threading.Event()
|
|
48
|
+
self._pid: int | None = None
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def portal(self) -> "Portal":
|
|
52
|
+
"""The portal instance for calling async functions.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Portal instance.
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
return Portal(self)
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def is_running(self) -> bool:
|
|
62
|
+
"""Check if portal provider is running.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
True if thread is alive, False otherwise.
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
return self._loop_thread is not None and self._loop_thread.is_alive()
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def is_ready(self) -> bool:
|
|
72
|
+
"""Check if portal provider is ready.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
True if ready event is set, False otherwise.
|
|
76
|
+
|
|
77
|
+
"""
|
|
78
|
+
return self._ready_event.is_set()
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def loop(self) -> "asyncio.AbstractEventLoop":
|
|
82
|
+
"""Get the event loop.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
The event loop.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
ImproperConfigurationError: If portal provider not started.
|
|
89
|
+
|
|
90
|
+
"""
|
|
91
|
+
if self._loop is None:
|
|
92
|
+
msg = "Portal provider not started. Call start() first."
|
|
93
|
+
raise ImproperConfigurationError(msg)
|
|
94
|
+
return self._loop
|
|
95
|
+
|
|
96
|
+
def start(self) -> None:
|
|
97
|
+
"""Start the background thread and event loop.
|
|
98
|
+
|
|
99
|
+
Creates a daemon thread running an event loop for async operations.
|
|
100
|
+
"""
|
|
101
|
+
if self._loop_thread is not None:
|
|
102
|
+
logger.debug("Portal provider already started")
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
self._loop_thread = threading.Thread(target=self._run_event_loop, daemon=True)
|
|
106
|
+
self._loop_thread.start()
|
|
107
|
+
self._ready_event.wait()
|
|
108
|
+
self._pid = os.getpid()
|
|
109
|
+
logger.debug("Portal provider started")
|
|
110
|
+
|
|
111
|
+
def stop(self) -> None:
|
|
112
|
+
"""Stop the background thread and event loop.
|
|
113
|
+
|
|
114
|
+
Gracefully shuts down the event loop and waits for thread to finish.
|
|
115
|
+
Only closes the loop after the thread has terminated to avoid
|
|
116
|
+
undefined behavior from closing a running loop.
|
|
117
|
+
"""
|
|
118
|
+
if self._loop is None or self._loop_thread is None:
|
|
119
|
+
logger.debug("Portal provider not running")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
self._loop.call_soon_threadsafe(self._loop.stop)
|
|
123
|
+
self._loop_thread.join(timeout=5)
|
|
124
|
+
|
|
125
|
+
if self._loop_thread.is_alive():
|
|
126
|
+
logger.warning("Portal thread did not stop within 5 seconds, skipping loop.close()")
|
|
127
|
+
else:
|
|
128
|
+
self._loop.close()
|
|
129
|
+
|
|
130
|
+
self._loop = None
|
|
131
|
+
self._loop_thread = None
|
|
132
|
+
self._ready_event.clear()
|
|
133
|
+
self._pid = None
|
|
134
|
+
logger.debug("Portal provider stopped")
|
|
135
|
+
|
|
136
|
+
def _run_event_loop(self) -> None:
|
|
137
|
+
if self._loop is None:
|
|
138
|
+
self._loop = asyncio.new_event_loop()
|
|
139
|
+
|
|
140
|
+
asyncio.set_event_loop(self._loop)
|
|
141
|
+
self._ready_event.set()
|
|
142
|
+
self._loop.run_forever()
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
async def _async_caller(
|
|
146
|
+
func: "Callable[..., Coroutine[Any, Any, _R]]", args: "tuple[Any, ...]", kwargs: "dict[str, Any]"
|
|
147
|
+
) -> _R:
|
|
148
|
+
result: _R = await func(*args, **kwargs)
|
|
149
|
+
return result
|
|
150
|
+
|
|
151
|
+
def call(self, func: "Callable[..., Coroutine[Any, Any, _R]]", *args: Any, **kwargs: Any) -> _R:
|
|
152
|
+
"""Call an async function from synchronous context.
|
|
153
|
+
|
|
154
|
+
Executes the async function in the background event loop and blocks
|
|
155
|
+
until the result is available or timeout is reached.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
func: The async function to call.
|
|
159
|
+
*args: Positional arguments to the function.
|
|
160
|
+
**kwargs: Keyword arguments. Supports 'timeout' (float, default 300.0).
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Result of the async function.
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
ImproperConfigurationError: If portal provider not started or timeout reached.
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
timeout: float = float(kwargs.pop("timeout", 300.0))
|
|
170
|
+
if self._loop is None or not self.is_running:
|
|
171
|
+
msg = "Portal provider not running. Call start() first."
|
|
172
|
+
raise ImproperConfigurationError(msg)
|
|
173
|
+
|
|
174
|
+
local_result_queue: queue.Queue[tuple[_R | None, Exception | None]] = queue.Queue()
|
|
175
|
+
|
|
176
|
+
self._request_queue.put((func, args, kwargs, local_result_queue))
|
|
177
|
+
|
|
178
|
+
self._loop.call_soon_threadsafe(self._process_request)
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
result, exception = local_result_queue.get(timeout=timeout)
|
|
182
|
+
except queue.Empty:
|
|
183
|
+
msg = f"Portal call timed out after {timeout} seconds"
|
|
184
|
+
raise ImproperConfigurationError(msg) from None
|
|
185
|
+
|
|
186
|
+
if exception:
|
|
187
|
+
raise exception
|
|
188
|
+
return result # type: ignore[return-value]
|
|
189
|
+
|
|
190
|
+
def _process_request(self) -> None:
|
|
191
|
+
"""Process a request from the request queue in the event loop."""
|
|
192
|
+
if self._loop is None:
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
if not self._request_queue.empty():
|
|
196
|
+
func, args, kwargs, local_result_queue = self._request_queue.get()
|
|
197
|
+
future = asyncio.run_coroutine_threadsafe(self._async_caller(func, args, kwargs), self._loop)
|
|
198
|
+
|
|
199
|
+
future.add_done_callback(
|
|
200
|
+
functools.partial(self._handle_future_result, local_result_queue=local_result_queue) # pyright: ignore[reportArgumentType]
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
@staticmethod
|
|
204
|
+
def _handle_future_result(
|
|
205
|
+
future: "asyncio.Future[Any]", local_result_queue: "queue.Queue[tuple[Any | None, Exception | None]]"
|
|
206
|
+
) -> None:
|
|
207
|
+
"""Handle result or exception from completed future.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
future: The completed future.
|
|
211
|
+
local_result_queue: Queue to put result in.
|
|
212
|
+
|
|
213
|
+
"""
|
|
214
|
+
try:
|
|
215
|
+
result = future.result()
|
|
216
|
+
local_result_queue.put((result, None))
|
|
217
|
+
except Exception as exc:
|
|
218
|
+
local_result_queue.put((None, exc))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class Portal:
|
|
222
|
+
"""Portal for calling async functions using PortalProvider."""
|
|
223
|
+
|
|
224
|
+
def __init__(self, provider: "PortalProvider") -> None:
|
|
225
|
+
"""Initialize Portal with provider.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
provider: The portal provider instance.
|
|
229
|
+
|
|
230
|
+
"""
|
|
231
|
+
self._provider = provider
|
|
232
|
+
|
|
233
|
+
def call(self, func: "Callable[..., Coroutine[Any, Any, _R]]", *args: Any, **kwargs: Any) -> _R:
|
|
234
|
+
"""Call an async function using the portal provider.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
func: The async function to call.
|
|
238
|
+
*args: Positional arguments to the function.
|
|
239
|
+
**kwargs: Keyword arguments. Supports 'timeout' (float, default 300.0).
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Result of the async function.
|
|
243
|
+
|
|
244
|
+
"""
|
|
245
|
+
return self._provider.call(func, *args, **kwargs)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class PortalManager:
|
|
249
|
+
"""Singleton manager for global portal instance.
|
|
250
|
+
|
|
251
|
+
Provides a global portal for use by sync_tools and other utilities
|
|
252
|
+
that need to call async functions from synchronous contexts without
|
|
253
|
+
an existing event loop.
|
|
254
|
+
|
|
255
|
+
Example:
|
|
256
|
+
manager = PortalManager()
|
|
257
|
+
portal = manager.get_or_create_portal()
|
|
258
|
+
result = portal.call(some_async_function, arg1, arg2)
|
|
259
|
+
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
_instance: "ClassVar[PortalManager | None]" = None
|
|
263
|
+
_singleton_lock: "ClassVar[threading.Lock]" = threading.Lock()
|
|
264
|
+
_initialized: bool = False
|
|
265
|
+
|
|
266
|
+
def __new__(cls) -> "PortalManager":
|
|
267
|
+
"""Get the singleton instance of PortalManager."""
|
|
268
|
+
if cls._instance is None:
|
|
269
|
+
with cls._singleton_lock:
|
|
270
|
+
if cls._instance is None:
|
|
271
|
+
cls._instance = super().__new__(cls)
|
|
272
|
+
return cls._instance
|
|
273
|
+
|
|
274
|
+
def __init__(self) -> None:
|
|
275
|
+
"""Initialize the PortalManager singleton."""
|
|
276
|
+
if hasattr(self, "_initialized") and self._initialized:
|
|
277
|
+
return
|
|
278
|
+
|
|
279
|
+
self._provider: PortalProvider | None = None
|
|
280
|
+
self._portal: Portal | None = None
|
|
281
|
+
self._lock = threading.Lock()
|
|
282
|
+
self._pid: int | None = None
|
|
283
|
+
self._atexit_registered: bool = False
|
|
284
|
+
self._initialized = True
|
|
285
|
+
|
|
286
|
+
def get_or_create_portal(self) -> Portal:
|
|
287
|
+
"""Get or create the global portal instance.
|
|
288
|
+
|
|
289
|
+
Lazily creates and starts the portal provider on first access.
|
|
290
|
+
Thread-safe via locking. Registers an atexit handler for cleanup.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
Global portal instance.
|
|
294
|
+
|
|
295
|
+
"""
|
|
296
|
+
current_pid = os.getpid()
|
|
297
|
+
if self._needs_restart(current_pid):
|
|
298
|
+
with self._lock:
|
|
299
|
+
if self._needs_restart(current_pid):
|
|
300
|
+
if self._provider is not None:
|
|
301
|
+
self._provider.stop()
|
|
302
|
+
self._provider = PortalProvider()
|
|
303
|
+
self._provider.start()
|
|
304
|
+
self._portal = Portal(self._provider)
|
|
305
|
+
self._pid = current_pid
|
|
306
|
+
self._register_atexit()
|
|
307
|
+
logger.debug("Global portal provider created and started")
|
|
308
|
+
|
|
309
|
+
return cast("Portal", self._portal)
|
|
310
|
+
|
|
311
|
+
def _register_atexit(self) -> None:
|
|
312
|
+
"""Register atexit handler for graceful shutdown.
|
|
313
|
+
|
|
314
|
+
Only registers once per process to avoid duplicate cleanup.
|
|
315
|
+
"""
|
|
316
|
+
if not self._atexit_registered:
|
|
317
|
+
atexit.register(self._atexit_cleanup)
|
|
318
|
+
self._atexit_registered = True
|
|
319
|
+
logger.debug("Portal atexit handler registered")
|
|
320
|
+
|
|
321
|
+
def _atexit_cleanup(self) -> None:
|
|
322
|
+
"""Cleanup handler called at interpreter shutdown.
|
|
323
|
+
|
|
324
|
+
Gracefully stops the portal provider to ensure pending
|
|
325
|
+
async operations complete before the process exits.
|
|
326
|
+
"""
|
|
327
|
+
if self._provider is not None and self._provider.is_running:
|
|
328
|
+
logger.debug("Portal atexit cleanup: stopping provider")
|
|
329
|
+
self.stop()
|
|
330
|
+
|
|
331
|
+
@property
|
|
332
|
+
def is_running(self) -> bool:
|
|
333
|
+
"""Check if global portal is running.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
True if portal provider exists and is running, False otherwise.
|
|
337
|
+
|
|
338
|
+
"""
|
|
339
|
+
return self._provider is not None and self._provider.is_running
|
|
340
|
+
|
|
341
|
+
def stop(self) -> None:
|
|
342
|
+
"""Stop the global portal provider.
|
|
343
|
+
|
|
344
|
+
Should typically only be called during application shutdown.
|
|
345
|
+
"""
|
|
346
|
+
if self._provider is not None:
|
|
347
|
+
self._provider.stop()
|
|
348
|
+
self._provider = None
|
|
349
|
+
self._portal = None
|
|
350
|
+
self._pid = None
|
|
351
|
+
logger.debug("Global portal provider stopped")
|
|
352
|
+
|
|
353
|
+
def _needs_restart(self, current_pid: int) -> bool:
|
|
354
|
+
provider_missing = self._provider is None or not self._provider.is_running
|
|
355
|
+
portal_missing = self._portal is None
|
|
356
|
+
pid_changed = self._pid is not None and self._pid != current_pid
|
|
357
|
+
return portal_missing or provider_missing or pid_changed
|
|
358
|
+
|
|
359
|
+
@classmethod
|
|
360
|
+
def get_instance(cls) -> "PortalManager":
|
|
361
|
+
"""Get the singleton instance."""
|
|
362
|
+
return cls()
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def get_global_portal() -> Portal:
|
|
366
|
+
"""Get the global portal instance for async-to-sync bridging.
|
|
367
|
+
|
|
368
|
+
Convenience function that creates and returns the singleton portal.
|
|
369
|
+
Used by sync_tools and other utilities.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
Global portal instance.
|
|
373
|
+
|
|
374
|
+
"""
|
|
375
|
+
return PortalManager().get_or_create_portal()
|
|
Binary file
|