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.
Files changed (531) hide show
  1. ac8f31065839703b4e70__mypyc.cpython-310-aarch64-linux-gnu.so +0 -0
  2. sqlspec/__init__.py +140 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_serialization.py +315 -0
  6. sqlspec/_typing.py +700 -0
  7. sqlspec/adapters/__init__.py +0 -0
  8. sqlspec/adapters/adbc/__init__.py +5 -0
  9. sqlspec/adapters/adbc/_typing.py +82 -0
  10. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  11. sqlspec/adapters/adbc/adk/store.py +1273 -0
  12. sqlspec/adapters/adbc/config.py +295 -0
  13. sqlspec/adapters/adbc/core.cpython-310-aarch64-linux-gnu.so +0 -0
  14. sqlspec/adapters/adbc/core.py +735 -0
  15. sqlspec/adapters/adbc/data_dictionary.py +334 -0
  16. sqlspec/adapters/adbc/driver.py +529 -0
  17. sqlspec/adapters/adbc/events/__init__.py +5 -0
  18. sqlspec/adapters/adbc/events/store.py +285 -0
  19. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  20. sqlspec/adapters/adbc/litestar/store.py +502 -0
  21. sqlspec/adapters/adbc/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  22. sqlspec/adapters/adbc/type_converter.py +140 -0
  23. sqlspec/adapters/aiosqlite/__init__.py +25 -0
  24. sqlspec/adapters/aiosqlite/_typing.py +82 -0
  25. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  26. sqlspec/adapters/aiosqlite/adk/store.py +818 -0
  27. sqlspec/adapters/aiosqlite/config.py +334 -0
  28. sqlspec/adapters/aiosqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
  29. sqlspec/adapters/aiosqlite/core.py +315 -0
  30. sqlspec/adapters/aiosqlite/data_dictionary.py +208 -0
  31. sqlspec/adapters/aiosqlite/driver.py +313 -0
  32. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  33. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  34. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  35. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  36. sqlspec/adapters/aiosqlite/pool.py +533 -0
  37. sqlspec/adapters/asyncmy/__init__.py +21 -0
  38. sqlspec/adapters/asyncmy/_typing.py +87 -0
  39. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  40. sqlspec/adapters/asyncmy/adk/store.py +703 -0
  41. sqlspec/adapters/asyncmy/config.py +302 -0
  42. sqlspec/adapters/asyncmy/core.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sqlspec/adapters/asyncmy/core.py +360 -0
  44. sqlspec/adapters/asyncmy/data_dictionary.py +124 -0
  45. sqlspec/adapters/asyncmy/driver.py +383 -0
  46. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  47. sqlspec/adapters/asyncmy/events/store.py +104 -0
  48. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  49. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  50. sqlspec/adapters/asyncpg/__init__.py +19 -0
  51. sqlspec/adapters/asyncpg/_typing.py +88 -0
  52. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncpg/adk/store.py +748 -0
  54. sqlspec/adapters/asyncpg/config.py +569 -0
  55. sqlspec/adapters/asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  56. sqlspec/adapters/asyncpg/core.py +367 -0
  57. sqlspec/adapters/asyncpg/data_dictionary.py +162 -0
  58. sqlspec/adapters/asyncpg/driver.py +487 -0
  59. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  60. sqlspec/adapters/asyncpg/events/backend.py +286 -0
  61. sqlspec/adapters/asyncpg/events/store.py +40 -0
  62. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  63. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  64. sqlspec/adapters/bigquery/__init__.py +14 -0
  65. sqlspec/adapters/bigquery/_typing.py +86 -0
  66. sqlspec/adapters/bigquery/adk/__init__.py +5 -0
  67. sqlspec/adapters/bigquery/adk/store.py +827 -0
  68. sqlspec/adapters/bigquery/config.py +353 -0
  69. sqlspec/adapters/bigquery/core.cpython-310-aarch64-linux-gnu.so +0 -0
  70. sqlspec/adapters/bigquery/core.py +715 -0
  71. sqlspec/adapters/bigquery/data_dictionary.py +128 -0
  72. sqlspec/adapters/bigquery/driver.py +548 -0
  73. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  74. sqlspec/adapters/bigquery/events/store.py +139 -0
  75. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  76. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  77. sqlspec/adapters/bigquery/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  78. sqlspec/adapters/bigquery/type_converter.py +107 -0
  79. sqlspec/adapters/cockroach_asyncpg/__init__.py +24 -0
  80. sqlspec/adapters/cockroach_asyncpg/_typing.py +72 -0
  81. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  82. sqlspec/adapters/cockroach_asyncpg/adk/store.py +410 -0
  83. sqlspec/adapters/cockroach_asyncpg/config.py +238 -0
  84. sqlspec/adapters/cockroach_asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  85. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  86. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +107 -0
  87. sqlspec/adapters/cockroach_asyncpg/driver.py +144 -0
  88. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  89. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  90. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  91. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  92. sqlspec/adapters/cockroach_psycopg/__init__.py +38 -0
  93. sqlspec/adapters/cockroach_psycopg/_typing.py +129 -0
  94. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  95. sqlspec/adapters/cockroach_psycopg/adk/store.py +868 -0
  96. sqlspec/adapters/cockroach_psycopg/config.py +484 -0
  97. sqlspec/adapters/cockroach_psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  99. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +215 -0
  100. sqlspec/adapters/cockroach_psycopg/driver.py +284 -0
  101. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  102. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  103. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  104. sqlspec/adapters/cockroach_psycopg/litestar/store.py +325 -0
  105. sqlspec/adapters/duckdb/__init__.py +25 -0
  106. sqlspec/adapters/duckdb/_typing.py +81 -0
  107. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  108. sqlspec/adapters/duckdb/adk/store.py +850 -0
  109. sqlspec/adapters/duckdb/config.py +463 -0
  110. sqlspec/adapters/duckdb/core.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sqlspec/adapters/duckdb/core.py +257 -0
  112. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  113. sqlspec/adapters/duckdb/driver.py +430 -0
  114. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  115. sqlspec/adapters/duckdb/events/store.py +57 -0
  116. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  117. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  118. sqlspec/adapters/duckdb/pool.py +293 -0
  119. sqlspec/adapters/duckdb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  120. sqlspec/adapters/duckdb/type_converter.py +118 -0
  121. sqlspec/adapters/mock/__init__.py +72 -0
  122. sqlspec/adapters/mock/_typing.py +147 -0
  123. sqlspec/adapters/mock/config.py +483 -0
  124. sqlspec/adapters/mock/core.py +319 -0
  125. sqlspec/adapters/mock/data_dictionary.py +366 -0
  126. sqlspec/adapters/mock/driver.py +721 -0
  127. sqlspec/adapters/mysqlconnector/__init__.py +36 -0
  128. sqlspec/adapters/mysqlconnector/_typing.py +141 -0
  129. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  130. sqlspec/adapters/mysqlconnector/adk/store.py +1060 -0
  131. sqlspec/adapters/mysqlconnector/config.py +394 -0
  132. sqlspec/adapters/mysqlconnector/core.cpython-310-aarch64-linux-gnu.so +0 -0
  133. sqlspec/adapters/mysqlconnector/core.py +303 -0
  134. sqlspec/adapters/mysqlconnector/data_dictionary.py +235 -0
  135. sqlspec/adapters/mysqlconnector/driver.py +483 -0
  136. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  137. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  138. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  139. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  140. sqlspec/adapters/oracledb/__init__.py +60 -0
  141. sqlspec/adapters/oracledb/_numpy_handlers.py +141 -0
  142. sqlspec/adapters/oracledb/_typing.py +182 -0
  143. sqlspec/adapters/oracledb/_uuid_handlers.py +166 -0
  144. sqlspec/adapters/oracledb/adk/__init__.py +10 -0
  145. sqlspec/adapters/oracledb/adk/store.py +2369 -0
  146. sqlspec/adapters/oracledb/config.py +550 -0
  147. sqlspec/adapters/oracledb/core.cpython-310-aarch64-linux-gnu.so +0 -0
  148. sqlspec/adapters/oracledb/core.py +543 -0
  149. sqlspec/adapters/oracledb/data_dictionary.py +536 -0
  150. sqlspec/adapters/oracledb/driver.py +1229 -0
  151. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  152. sqlspec/adapters/oracledb/events/backend.py +347 -0
  153. sqlspec/adapters/oracledb/events/store.py +420 -0
  154. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  155. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  156. sqlspec/adapters/oracledb/migrations.py +535 -0
  157. sqlspec/adapters/oracledb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sqlspec/adapters/oracledb/type_converter.py +211 -0
  159. sqlspec/adapters/psqlpy/__init__.py +17 -0
  160. sqlspec/adapters/psqlpy/_typing.py +79 -0
  161. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  162. sqlspec/adapters/psqlpy/adk/store.py +766 -0
  163. sqlspec/adapters/psqlpy/config.py +304 -0
  164. sqlspec/adapters/psqlpy/core.cpython-310-aarch64-linux-gnu.so +0 -0
  165. sqlspec/adapters/psqlpy/core.py +480 -0
  166. sqlspec/adapters/psqlpy/data_dictionary.py +126 -0
  167. sqlspec/adapters/psqlpy/driver.py +438 -0
  168. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  169. sqlspec/adapters/psqlpy/events/backend.py +310 -0
  170. sqlspec/adapters/psqlpy/events/store.py +20 -0
  171. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  172. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  173. sqlspec/adapters/psqlpy/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  174. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  175. sqlspec/adapters/psycopg/__init__.py +32 -0
  176. sqlspec/adapters/psycopg/_typing.py +164 -0
  177. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  178. sqlspec/adapters/psycopg/adk/store.py +1387 -0
  179. sqlspec/adapters/psycopg/config.py +576 -0
  180. sqlspec/adapters/psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  181. sqlspec/adapters/psycopg/core.py +450 -0
  182. sqlspec/adapters/psycopg/data_dictionary.py +289 -0
  183. sqlspec/adapters/psycopg/driver.py +975 -0
  184. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  185. sqlspec/adapters/psycopg/events/backend.py +458 -0
  186. sqlspec/adapters/psycopg/events/store.py +42 -0
  187. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  188. sqlspec/adapters/psycopg/litestar/store.py +552 -0
  189. sqlspec/adapters/psycopg/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  190. sqlspec/adapters/psycopg/type_converter.py +93 -0
  191. sqlspec/adapters/pymysql/__init__.py +21 -0
  192. sqlspec/adapters/pymysql/_typing.py +71 -0
  193. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  194. sqlspec/adapters/pymysql/adk/store.py +540 -0
  195. sqlspec/adapters/pymysql/config.py +195 -0
  196. sqlspec/adapters/pymysql/core.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sqlspec/adapters/pymysql/core.py +299 -0
  198. sqlspec/adapters/pymysql/data_dictionary.py +122 -0
  199. sqlspec/adapters/pymysql/driver.py +259 -0
  200. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  201. sqlspec/adapters/pymysql/events/store.py +50 -0
  202. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  203. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  204. sqlspec/adapters/pymysql/pool.py +137 -0
  205. sqlspec/adapters/spanner/__init__.py +40 -0
  206. sqlspec/adapters/spanner/_typing.py +86 -0
  207. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  208. sqlspec/adapters/spanner/adk/store.py +732 -0
  209. sqlspec/adapters/spanner/config.py +352 -0
  210. sqlspec/adapters/spanner/core.cpython-310-aarch64-linux-gnu.so +0 -0
  211. sqlspec/adapters/spanner/core.py +188 -0
  212. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  213. sqlspec/adapters/spanner/dialect/__init__.py +6 -0
  214. sqlspec/adapters/spanner/dialect/_spangres.py +57 -0
  215. sqlspec/adapters/spanner/dialect/_spanner.py +130 -0
  216. sqlspec/adapters/spanner/driver.py +373 -0
  217. sqlspec/adapters/spanner/events/__init__.py +5 -0
  218. sqlspec/adapters/spanner/events/store.py +187 -0
  219. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  220. sqlspec/adapters/spanner/litestar/store.py +291 -0
  221. sqlspec/adapters/spanner/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sqlspec/adapters/spanner/type_converter.py +331 -0
  223. sqlspec/adapters/sqlite/__init__.py +19 -0
  224. sqlspec/adapters/sqlite/_typing.py +80 -0
  225. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  226. sqlspec/adapters/sqlite/adk/store.py +958 -0
  227. sqlspec/adapters/sqlite/config.py +280 -0
  228. sqlspec/adapters/sqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
  229. sqlspec/adapters/sqlite/core.py +312 -0
  230. sqlspec/adapters/sqlite/data_dictionary.py +202 -0
  231. sqlspec/adapters/sqlite/driver.py +359 -0
  232. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  233. sqlspec/adapters/sqlite/events/store.py +20 -0
  234. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  235. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  236. sqlspec/adapters/sqlite/pool.py +198 -0
  237. sqlspec/adapters/sqlite/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  238. sqlspec/adapters/sqlite/type_converter.py +114 -0
  239. sqlspec/base.py +747 -0
  240. sqlspec/builder/__init__.py +179 -0
  241. sqlspec/builder/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  242. sqlspec/builder/_base.py +1022 -0
  243. sqlspec/builder/_column.cpython-310-aarch64-linux-gnu.so +0 -0
  244. sqlspec/builder/_column.py +521 -0
  245. sqlspec/builder/_ddl.cpython-310-aarch64-linux-gnu.so +0 -0
  246. sqlspec/builder/_ddl.py +1642 -0
  247. sqlspec/builder/_delete.cpython-310-aarch64-linux-gnu.so +0 -0
  248. sqlspec/builder/_delete.py +95 -0
  249. sqlspec/builder/_dml.cpython-310-aarch64-linux-gnu.so +0 -0
  250. sqlspec/builder/_dml.py +365 -0
  251. sqlspec/builder/_explain.cpython-310-aarch64-linux-gnu.so +0 -0
  252. sqlspec/builder/_explain.py +579 -0
  253. sqlspec/builder/_expression_wrappers.cpython-310-aarch64-linux-gnu.so +0 -0
  254. sqlspec/builder/_expression_wrappers.py +46 -0
  255. sqlspec/builder/_factory.cpython-310-aarch64-linux-gnu.so +0 -0
  256. sqlspec/builder/_factory.py +1697 -0
  257. sqlspec/builder/_insert.cpython-310-aarch64-linux-gnu.so +0 -0
  258. sqlspec/builder/_insert.py +328 -0
  259. sqlspec/builder/_join.cpython-310-aarch64-linux-gnu.so +0 -0
  260. sqlspec/builder/_join.py +499 -0
  261. sqlspec/builder/_merge.cpython-310-aarch64-linux-gnu.so +0 -0
  262. sqlspec/builder/_merge.py +821 -0
  263. sqlspec/builder/_parsing_utils.cpython-310-aarch64-linux-gnu.so +0 -0
  264. sqlspec/builder/_parsing_utils.py +297 -0
  265. sqlspec/builder/_select.cpython-310-aarch64-linux-gnu.so +0 -0
  266. sqlspec/builder/_select.py +1660 -0
  267. sqlspec/builder/_temporal.cpython-310-aarch64-linux-gnu.so +0 -0
  268. sqlspec/builder/_temporal.py +139 -0
  269. sqlspec/builder/_update.cpython-310-aarch64-linux-gnu.so +0 -0
  270. sqlspec/builder/_update.py +173 -0
  271. sqlspec/builder/_vector_expressions.py +267 -0
  272. sqlspec/cli.py +911 -0
  273. sqlspec/config.py +1755 -0
  274. sqlspec/core/__init__.py +374 -0
  275. sqlspec/core/_correlation.cpython-310-aarch64-linux-gnu.so +0 -0
  276. sqlspec/core/_correlation.py +176 -0
  277. sqlspec/core/cache.cpython-310-aarch64-linux-gnu.so +0 -0
  278. sqlspec/core/cache.py +1069 -0
  279. sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
  280. sqlspec/core/compiler.py +954 -0
  281. sqlspec/core/explain.cpython-310-aarch64-linux-gnu.so +0 -0
  282. sqlspec/core/explain.py +275 -0
  283. sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
  284. sqlspec/core/filters.py +952 -0
  285. sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
  286. sqlspec/core/hashing.py +262 -0
  287. sqlspec/core/metrics.cpython-310-aarch64-linux-gnu.so +0 -0
  288. sqlspec/core/metrics.py +83 -0
  289. sqlspec/core/parameters/__init__.py +71 -0
  290. sqlspec/core/parameters/_alignment.cpython-310-aarch64-linux-gnu.so +0 -0
  291. sqlspec/core/parameters/_alignment.py +270 -0
  292. sqlspec/core/parameters/_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  293. sqlspec/core/parameters/_converter.py +543 -0
  294. sqlspec/core/parameters/_processor.cpython-310-aarch64-linux-gnu.so +0 -0
  295. sqlspec/core/parameters/_processor.py +505 -0
  296. sqlspec/core/parameters/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
  297. sqlspec/core/parameters/_registry.py +206 -0
  298. sqlspec/core/parameters/_transformers.cpython-310-aarch64-linux-gnu.so +0 -0
  299. sqlspec/core/parameters/_transformers.py +292 -0
  300. sqlspec/core/parameters/_types.cpython-310-aarch64-linux-gnu.so +0 -0
  301. sqlspec/core/parameters/_types.py +499 -0
  302. sqlspec/core/parameters/_validator.cpython-310-aarch64-linux-gnu.so +0 -0
  303. sqlspec/core/parameters/_validator.py +180 -0
  304. sqlspec/core/pipeline.cpython-310-aarch64-linux-gnu.so +0 -0
  305. sqlspec/core/pipeline.py +319 -0
  306. sqlspec/core/query_modifiers.cpython-310-aarch64-linux-gnu.so +0 -0
  307. sqlspec/core/query_modifiers.py +437 -0
  308. sqlspec/core/result/__init__.py +23 -0
  309. sqlspec/core/result/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  310. sqlspec/core/result/_base.py +1121 -0
  311. sqlspec/core/result/_io.cpython-310-aarch64-linux-gnu.so +0 -0
  312. sqlspec/core/result/_io.py +28 -0
  313. sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
  314. sqlspec/core/splitter.py +966 -0
  315. sqlspec/core/stack.cpython-310-aarch64-linux-gnu.so +0 -0
  316. sqlspec/core/stack.py +163 -0
  317. sqlspec/core/statement.cpython-310-aarch64-linux-gnu.so +0 -0
  318. sqlspec/core/statement.py +1503 -0
  319. sqlspec/core/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  320. sqlspec/core/type_converter.py +339 -0
  321. sqlspec/data_dictionary/__init__.py +22 -0
  322. sqlspec/data_dictionary/_loader.py +123 -0
  323. sqlspec/data_dictionary/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
  324. sqlspec/data_dictionary/_registry.py +74 -0
  325. sqlspec/data_dictionary/_types.cpython-310-aarch64-linux-gnu.so +0 -0
  326. sqlspec/data_dictionary/_types.py +121 -0
  327. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  328. sqlspec/data_dictionary/dialects/bigquery.cpython-310-aarch64-linux-gnu.so +0 -0
  329. sqlspec/data_dictionary/dialects/bigquery.py +49 -0
  330. sqlspec/data_dictionary/dialects/cockroachdb.cpython-310-aarch64-linux-gnu.so +0 -0
  331. sqlspec/data_dictionary/dialects/cockroachdb.py +43 -0
  332. sqlspec/data_dictionary/dialects/duckdb.cpython-310-aarch64-linux-gnu.so +0 -0
  333. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  334. sqlspec/data_dictionary/dialects/mysql.cpython-310-aarch64-linux-gnu.so +0 -0
  335. sqlspec/data_dictionary/dialects/mysql.py +42 -0
  336. sqlspec/data_dictionary/dialects/oracle.cpython-310-aarch64-linux-gnu.so +0 -0
  337. sqlspec/data_dictionary/dialects/oracle.py +34 -0
  338. sqlspec/data_dictionary/dialects/postgres.cpython-310-aarch64-linux-gnu.so +0 -0
  339. sqlspec/data_dictionary/dialects/postgres.py +46 -0
  340. sqlspec/data_dictionary/dialects/spanner.cpython-310-aarch64-linux-gnu.so +0 -0
  341. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  342. sqlspec/data_dictionary/dialects/sqlite.cpython-310-aarch64-linux-gnu.so +0 -0
  343. sqlspec/data_dictionary/dialects/sqlite.py +42 -0
  344. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  345. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  346. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  347. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  348. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  349. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  350. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  351. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  352. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  353. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  354. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  355. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  356. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  357. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  358. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  359. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  360. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  361. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  362. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  363. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  364. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  365. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  366. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  367. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  368. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  369. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  370. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  371. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  372. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  373. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  374. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  375. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  376. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  377. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  378. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  379. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  380. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  381. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  382. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  383. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  384. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  385. sqlspec/driver/__init__.py +32 -0
  386. sqlspec/driver/_async.cpython-310-aarch64-linux-gnu.so +0 -0
  387. sqlspec/driver/_async.py +1737 -0
  388. sqlspec/driver/_common.cpython-310-aarch64-linux-gnu.so +0 -0
  389. sqlspec/driver/_common.py +1478 -0
  390. sqlspec/driver/_sql_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
  391. sqlspec/driver/_sql_helpers.py +148 -0
  392. sqlspec/driver/_storage_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
  393. sqlspec/driver/_storage_helpers.py +144 -0
  394. sqlspec/driver/_sync.cpython-310-aarch64-linux-gnu.so +0 -0
  395. sqlspec/driver/_sync.py +1710 -0
  396. sqlspec/exceptions.py +338 -0
  397. sqlspec/extensions/__init__.py +0 -0
  398. sqlspec/extensions/adk/__init__.py +70 -0
  399. sqlspec/extensions/adk/_types.py +51 -0
  400. sqlspec/extensions/adk/converters.py +172 -0
  401. sqlspec/extensions/adk/memory/__init__.py +69 -0
  402. sqlspec/extensions/adk/memory/_types.py +30 -0
  403. sqlspec/extensions/adk/memory/converters.py +149 -0
  404. sqlspec/extensions/adk/memory/service.py +217 -0
  405. sqlspec/extensions/adk/memory/store.py +569 -0
  406. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +246 -0
  407. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  408. sqlspec/extensions/adk/service.py +225 -0
  409. sqlspec/extensions/adk/store.py +567 -0
  410. sqlspec/extensions/events/__init__.py +51 -0
  411. sqlspec/extensions/events/_channel.py +703 -0
  412. sqlspec/extensions/events/_hints.py +45 -0
  413. sqlspec/extensions/events/_models.py +23 -0
  414. sqlspec/extensions/events/_payload.py +69 -0
  415. sqlspec/extensions/events/_protocols.py +134 -0
  416. sqlspec/extensions/events/_queue.py +461 -0
  417. sqlspec/extensions/events/_store.py +209 -0
  418. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  419. sqlspec/extensions/events/migrations/__init__.py +3 -0
  420. sqlspec/extensions/fastapi/__init__.py +19 -0
  421. sqlspec/extensions/fastapi/extension.py +351 -0
  422. sqlspec/extensions/fastapi/providers.py +607 -0
  423. sqlspec/extensions/flask/__init__.py +37 -0
  424. sqlspec/extensions/flask/_state.py +76 -0
  425. sqlspec/extensions/flask/_utils.py +71 -0
  426. sqlspec/extensions/flask/extension.py +519 -0
  427. sqlspec/extensions/litestar/__init__.py +28 -0
  428. sqlspec/extensions/litestar/_utils.py +52 -0
  429. sqlspec/extensions/litestar/channels.py +165 -0
  430. sqlspec/extensions/litestar/cli.py +102 -0
  431. sqlspec/extensions/litestar/config.py +90 -0
  432. sqlspec/extensions/litestar/handlers.py +316 -0
  433. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  434. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  435. sqlspec/extensions/litestar/plugin.py +671 -0
  436. sqlspec/extensions/litestar/providers.py +526 -0
  437. sqlspec/extensions/litestar/store.py +296 -0
  438. sqlspec/extensions/otel/__init__.py +58 -0
  439. sqlspec/extensions/prometheus/__init__.py +113 -0
  440. sqlspec/extensions/starlette/__init__.py +19 -0
  441. sqlspec/extensions/starlette/_state.py +30 -0
  442. sqlspec/extensions/starlette/_utils.py +96 -0
  443. sqlspec/extensions/starlette/extension.py +346 -0
  444. sqlspec/extensions/starlette/middleware.py +235 -0
  445. sqlspec/loader.cpython-310-aarch64-linux-gnu.so +0 -0
  446. sqlspec/loader.py +702 -0
  447. sqlspec/migrations/__init__.py +36 -0
  448. sqlspec/migrations/base.py +731 -0
  449. sqlspec/migrations/commands.py +1232 -0
  450. sqlspec/migrations/context.py +157 -0
  451. sqlspec/migrations/fix.py +204 -0
  452. sqlspec/migrations/loaders.py +443 -0
  453. sqlspec/migrations/runner.py +1172 -0
  454. sqlspec/migrations/templates.py +234 -0
  455. sqlspec/migrations/tracker.py +611 -0
  456. sqlspec/migrations/utils.py +256 -0
  457. sqlspec/migrations/validation.py +207 -0
  458. sqlspec/migrations/version.py +446 -0
  459. sqlspec/observability/__init__.py +55 -0
  460. sqlspec/observability/_common.cpython-310-aarch64-linux-gnu.so +0 -0
  461. sqlspec/observability/_common.py +77 -0
  462. sqlspec/observability/_config.cpython-310-aarch64-linux-gnu.so +0 -0
  463. sqlspec/observability/_config.py +348 -0
  464. sqlspec/observability/_diagnostics.cpython-310-aarch64-linux-gnu.so +0 -0
  465. sqlspec/observability/_diagnostics.py +74 -0
  466. sqlspec/observability/_dispatcher.cpython-310-aarch64-linux-gnu.so +0 -0
  467. sqlspec/observability/_dispatcher.py +152 -0
  468. sqlspec/observability/_formatters/__init__.py +13 -0
  469. sqlspec/observability/_formatters/_aws.cpython-310-aarch64-linux-gnu.so +0 -0
  470. sqlspec/observability/_formatters/_aws.py +102 -0
  471. sqlspec/observability/_formatters/_azure.cpython-310-aarch64-linux-gnu.so +0 -0
  472. sqlspec/observability/_formatters/_azure.py +96 -0
  473. sqlspec/observability/_formatters/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  474. sqlspec/observability/_formatters/_base.py +57 -0
  475. sqlspec/observability/_formatters/_gcp.cpython-310-aarch64-linux-gnu.so +0 -0
  476. sqlspec/observability/_formatters/_gcp.py +131 -0
  477. sqlspec/observability/_formatting.py +58 -0
  478. sqlspec/observability/_observer.cpython-310-aarch64-linux-gnu.so +0 -0
  479. sqlspec/observability/_observer.py +357 -0
  480. sqlspec/observability/_runtime.cpython-310-aarch64-linux-gnu.so +0 -0
  481. sqlspec/observability/_runtime.py +420 -0
  482. sqlspec/observability/_sampling.cpython-310-aarch64-linux-gnu.so +0 -0
  483. sqlspec/observability/_sampling.py +188 -0
  484. sqlspec/observability/_spans.cpython-310-aarch64-linux-gnu.so +0 -0
  485. sqlspec/observability/_spans.py +161 -0
  486. sqlspec/protocols.py +916 -0
  487. sqlspec/py.typed +0 -0
  488. sqlspec/storage/__init__.py +48 -0
  489. sqlspec/storage/_utils.py +104 -0
  490. sqlspec/storage/backends/__init__.py +1 -0
  491. sqlspec/storage/backends/base.py +253 -0
  492. sqlspec/storage/backends/fsspec.py +529 -0
  493. sqlspec/storage/backends/local.py +441 -0
  494. sqlspec/storage/backends/obstore.py +916 -0
  495. sqlspec/storage/errors.py +104 -0
  496. sqlspec/storage/pipeline.py +582 -0
  497. sqlspec/storage/registry.py +301 -0
  498. sqlspec/typing.py +395 -0
  499. sqlspec/utils/__init__.py +7 -0
  500. sqlspec/utils/arrow_helpers.py +318 -0
  501. sqlspec/utils/config_tools.py +332 -0
  502. sqlspec/utils/correlation.cpython-310-aarch64-linux-gnu.so +0 -0
  503. sqlspec/utils/correlation.py +134 -0
  504. sqlspec/utils/deprecation.py +190 -0
  505. sqlspec/utils/fixtures.cpython-310-aarch64-linux-gnu.so +0 -0
  506. sqlspec/utils/fixtures.py +258 -0
  507. sqlspec/utils/logging.py +222 -0
  508. sqlspec/utils/module_loader.py +306 -0
  509. sqlspec/utils/portal.cpython-310-aarch64-linux-gnu.so +0 -0
  510. sqlspec/utils/portal.py +375 -0
  511. sqlspec/utils/schema.cpython-310-aarch64-linux-gnu.so +0 -0
  512. sqlspec/utils/schema.py +485 -0
  513. sqlspec/utils/serializers.cpython-310-aarch64-linux-gnu.so +0 -0
  514. sqlspec/utils/serializers.py +408 -0
  515. sqlspec/utils/singleton.cpython-310-aarch64-linux-gnu.so +0 -0
  516. sqlspec/utils/singleton.py +41 -0
  517. sqlspec/utils/sync_tools.cpython-310-aarch64-linux-gnu.so +0 -0
  518. sqlspec/utils/sync_tools.py +311 -0
  519. sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
  520. sqlspec/utils/text.py +108 -0
  521. sqlspec/utils/type_converters.cpython-310-aarch64-linux-gnu.so +0 -0
  522. sqlspec/utils/type_converters.py +128 -0
  523. sqlspec/utils/type_guards.cpython-310-aarch64-linux-gnu.so +0 -0
  524. sqlspec/utils/type_guards.py +1360 -0
  525. sqlspec/utils/uuids.cpython-310-aarch64-linux-gnu.so +0 -0
  526. sqlspec/utils/uuids.py +225 -0
  527. sqlspec-0.36.0.dist-info/METADATA +205 -0
  528. sqlspec-0.36.0.dist-info/RECORD +531 -0
  529. sqlspec-0.36.0.dist-info/WHEEL +7 -0
  530. sqlspec-0.36.0.dist-info/entry_points.txt +2 -0
  531. sqlspec-0.36.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,420 @@
1
+ """Runtime helpers that bundle lifecycle, observer, and span orchestration."""
2
+
3
+ import re
4
+ from typing import TYPE_CHECKING, Any, cast
5
+
6
+ from sqlspec.observability._common import compute_sql_hash, get_trace_context, resolve_db_system
7
+ from sqlspec.observability._config import LoggingConfig, ObservabilityConfig
8
+ from sqlspec.observability._dispatcher import LifecycleDispatcher, LifecycleHook
9
+ from sqlspec.observability._observer import StatementObserver, create_event, create_statement_observer
10
+ from sqlspec.observability._spans import SpanManager
11
+ from sqlspec.utils.correlation import CorrelationContext
12
+ from sqlspec.utils.type_guards import has_span_attribute
13
+
14
+ _LITERAL_PATTERN = re.compile(r"'(?:''|[^'])*'")
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Iterable
18
+
19
+ from sqlspec.storage import StorageTelemetry
20
+
21
+
22
+ class ObservabilityRuntime:
23
+ """Aggregates dispatchers, observers, spans, and custom metrics."""
24
+
25
+ __slots__ = (
26
+ "_metrics",
27
+ "_redaction",
28
+ "_statement_observers",
29
+ "bind_key",
30
+ "config",
31
+ "config_name",
32
+ "lifecycle",
33
+ "span_manager",
34
+ )
35
+
36
+ # Allow test injection with fake span managers (mypyc strict typing workaround)
37
+ span_manager: "Any"
38
+
39
+ def __init__(
40
+ self, config: ObservabilityConfig | None = None, *, bind_key: str | None = None, config_name: str | None = None
41
+ ) -> None:
42
+ config = config.copy() if config else ObservabilityConfig()
43
+ if config.logging is None:
44
+ config.logging = LoggingConfig()
45
+ self.config = config
46
+ self.bind_key = bind_key
47
+ self.config_name = config_name or "SQLSpecConfig"
48
+ lifecycle_config = cast("dict[str, Iterable[LifecycleHook]] | None", config.lifecycle)
49
+ self.lifecycle = LifecycleDispatcher(lifecycle_config)
50
+ self.span_manager = SpanManager(config.telemetry)
51
+ observers: list[StatementObserver] = []
52
+ if config.statement_observers:
53
+ observers.extend(config.statement_observers)
54
+ if config.print_sql:
55
+ observers.append(create_statement_observer(config.logging))
56
+ self._statement_observers = tuple(observers)
57
+ self._redaction = config.redaction.copy() if config.redaction else None
58
+ self._metrics: dict[str, float] = {}
59
+
60
+ @property
61
+ def has_statement_observers(self) -> bool:
62
+ """Return True when any observers are registered."""
63
+
64
+ return bool(self._statement_observers)
65
+
66
+ @property
67
+ def diagnostics_key(self) -> str:
68
+ """Derive diagnostics key from bind key or configuration name."""
69
+
70
+ if self.bind_key:
71
+ return self.bind_key
72
+ return self.config_name
73
+
74
+ def base_context(self) -> dict[str, Any]:
75
+ """Return the base payload for lifecycle events."""
76
+
77
+ context = {"config": self.config_name}
78
+ if self.bind_key:
79
+ context["bind_key"] = self.bind_key
80
+ correlation_id = CorrelationContext.get()
81
+ if correlation_id:
82
+ context["correlation_id"] = correlation_id
83
+ return context
84
+
85
+ def _build_context(self, **extras: Any) -> dict[str, Any]:
86
+ context = self.base_context()
87
+ context.update({key: value for key, value in extras.items() if value is not None})
88
+ return context
89
+
90
+ def lifecycle_snapshot(self) -> dict[str, int]:
91
+ """Return lifecycle counters keyed under the diagnostics prefix."""
92
+
93
+ return self.lifecycle.snapshot(prefix=self.diagnostics_key)
94
+
95
+ def metrics_snapshot(self) -> dict[str, float]:
96
+ """Return accumulated custom metrics with diagnostics prefix."""
97
+
98
+ if not self._metrics:
99
+ return {}
100
+ prefix = self.diagnostics_key
101
+ return {f"{prefix}.{name}": value for name, value in self._metrics.items()}
102
+
103
+ def increment_metric(self, name: str, amount: float = 1.0) -> None:
104
+ """Increment a custom metric counter."""
105
+
106
+ self._metrics[name] = self._metrics.get(name, 0.0) + amount
107
+
108
+ def record_metric(self, name: str, value: float) -> None:
109
+ """Set a custom metric to an explicit value."""
110
+
111
+ self._metrics[name] = value
112
+
113
+ def start_migration_span(
114
+ self, event: str, *, version: "str | None" = None, metadata: "dict[str, Any] | None" = None
115
+ ) -> Any:
116
+ """Start a migration span when telemetry is enabled."""
117
+
118
+ if not self.span_manager.is_enabled:
119
+ return None
120
+ attributes: dict[str, Any] = {"sqlspec.migration.event": event, "sqlspec.config": self.config_name}
121
+ if self.bind_key:
122
+ attributes["sqlspec.bind_key"] = self.bind_key
123
+ correlation_id = CorrelationContext.get()
124
+ if correlation_id:
125
+ attributes["sqlspec.correlation_id"] = correlation_id
126
+ if version:
127
+ attributes["sqlspec.migration.version"] = version
128
+ if metadata:
129
+ for key, value in metadata.items():
130
+ if value is not None:
131
+ attributes[f"sqlspec.migration.{key}"] = value
132
+ return self.span_manager.start_span(f"sqlspec.migration.{event}", attributes)
133
+
134
+ def end_migration_span(
135
+ self, span: Any, *, duration_ms: "int | None" = None, error: "Exception | None" = None
136
+ ) -> None:
137
+ """Finish a migration span, attaching optional duration metadata."""
138
+
139
+ if span is None:
140
+ return
141
+ if duration_ms is not None and has_span_attribute(span):
142
+ span.set_attribute("sqlspec.migration.duration_ms", duration_ms)
143
+ self.span_manager.end_span(span, error=error)
144
+
145
+ def emit_pool_create(self, pool: Any) -> None:
146
+ span = self._start_lifecycle_span("pool.create", subject=pool)
147
+ try:
148
+ if self.lifecycle.has_pool_create:
149
+ self.lifecycle.emit_pool_create(self._build_context(pool=pool))
150
+ finally:
151
+ self.span_manager.end_span(span)
152
+
153
+ def emit_pool_destroy(self, pool: Any) -> None:
154
+ span = self._start_lifecycle_span("pool.destroy", subject=pool)
155
+ try:
156
+ if self.lifecycle.has_pool_destroy:
157
+ self.lifecycle.emit_pool_destroy(self._build_context(pool=pool))
158
+ finally:
159
+ self.span_manager.end_span(span)
160
+
161
+ def emit_connection_create(self, connection: Any) -> None:
162
+ span = self._start_lifecycle_span("connection.create", subject=connection)
163
+ try:
164
+ if self.lifecycle.has_connection_create:
165
+ self.lifecycle.emit_connection_create(self._build_context(connection=connection))
166
+ finally:
167
+ self.span_manager.end_span(span)
168
+
169
+ def emit_connection_destroy(self, connection: Any) -> None:
170
+ span = self._start_lifecycle_span("connection.destroy", subject=connection)
171
+ try:
172
+ if self.lifecycle.has_connection_destroy:
173
+ self.lifecycle.emit_connection_destroy(self._build_context(connection=connection))
174
+ finally:
175
+ self.span_manager.end_span(span)
176
+
177
+ def emit_session_start(self, session: Any) -> None:
178
+ span = self._start_lifecycle_span("session.start", subject=session)
179
+ try:
180
+ if self.lifecycle.has_session_start:
181
+ self.lifecycle.emit_session_start(self._build_context(session=session))
182
+ finally:
183
+ self.span_manager.end_span(span)
184
+
185
+ def emit_session_end(self, session: Any) -> None:
186
+ span = self._start_lifecycle_span("session.end", subject=session)
187
+ try:
188
+ if self.lifecycle.has_session_end:
189
+ self.lifecycle.emit_session_end(self._build_context(session=session))
190
+ finally:
191
+ self.span_manager.end_span(span)
192
+
193
+ def emit_query_start(self, **extras: Any) -> None:
194
+ if self.lifecycle.has_query_start:
195
+ self.lifecycle.emit_query_start(self._build_context(**extras))
196
+
197
+ def emit_query_complete(self, **extras: Any) -> None:
198
+ if self.lifecycle.has_query_complete:
199
+ self.lifecycle.emit_query_complete(self._build_context(**extras))
200
+
201
+ def emit_error(self, exception: Exception, **extras: Any) -> None:
202
+ if self.lifecycle.has_error:
203
+ payload = self._build_context(exception=exception)
204
+ payload.update({key: value for key, value in extras.items() if value is not None})
205
+ self.lifecycle.emit_error(payload)
206
+ self.increment_metric("errors", 1.0)
207
+
208
+ def emit_statement_event(
209
+ self,
210
+ *,
211
+ sql: str,
212
+ parameters: Any,
213
+ driver: str,
214
+ operation: str,
215
+ execution_mode: str | None,
216
+ is_many: bool,
217
+ is_script: bool,
218
+ rows_affected: int | None,
219
+ duration_s: float,
220
+ storage_backend: str | None,
221
+ started_at: float | None = None,
222
+ ) -> None:
223
+ """Emit a statement event to all registered observers."""
224
+
225
+ if not self._statement_observers:
226
+ return
227
+ sanitized_sql = self._redact_sql(sql)
228
+ sanitized_params = self._redact_parameters(parameters)
229
+ correlation_id = CorrelationContext.get()
230
+ logging_config = self.config.logging
231
+ db_system = resolve_db_system(self.config_name)
232
+ sql_hash = None
233
+ if logging_config and logging_config.include_sql_hash:
234
+ sql_hash = compute_sql_hash(sanitized_sql)
235
+ sql_truncation_length = logging_config.sql_truncation_length if logging_config else 2000
236
+ sql_original_length = len(sanitized_sql)
237
+ sql_truncated = sql_original_length > sql_truncation_length
238
+ trace_id = None
239
+ span_id = None
240
+ if logging_config and logging_config.include_trace_context:
241
+ trace_id, span_id = get_trace_context()
242
+ event = create_event(
243
+ sql=sanitized_sql,
244
+ parameters=sanitized_params,
245
+ driver=driver,
246
+ adapter=self.config_name,
247
+ bind_key=self.bind_key,
248
+ db_system=db_system,
249
+ operation=operation,
250
+ execution_mode=execution_mode,
251
+ is_many=is_many,
252
+ is_script=is_script,
253
+ rows_affected=rows_affected,
254
+ duration_s=duration_s,
255
+ correlation_id=correlation_id,
256
+ storage_backend=storage_backend,
257
+ started_at=started_at,
258
+ sql_hash=sql_hash,
259
+ sql_truncated=sql_truncated,
260
+ sql_original_length=sql_original_length,
261
+ trace_id=trace_id,
262
+ span_id=span_id,
263
+ )
264
+ for observer in self._statement_observers:
265
+ observer(event)
266
+
267
+ def start_query_span(self, sql: str, operation: str, driver: str) -> Any:
268
+ """Start a query span with runtime metadata."""
269
+
270
+ sql_hash = compute_sql_hash(sql)
271
+ connection_info = {"sqlspec.statement.hash": sql_hash, "sqlspec.statement.length": len(sql)}
272
+ sql_payload = ""
273
+ if self.config.print_sql:
274
+ sql_payload = self._redact_sql(sql)
275
+ sql_payload, truncated = _truncate_text(sql_payload, max_chars=4096)
276
+ if truncated:
277
+ connection_info["sqlspec.statement.truncated"] = True
278
+
279
+ correlation_id = CorrelationContext.get()
280
+ return self.span_manager.start_query_span(
281
+ driver=driver,
282
+ adapter=self.config_name,
283
+ bind_key=self.bind_key,
284
+ sql=sql_payload,
285
+ operation=operation,
286
+ connection_info=connection_info,
287
+ correlation_id=correlation_id,
288
+ )
289
+
290
+ def start_storage_span(
291
+ self, operation: str, *, destination: str | None = None, format_label: str | None = None
292
+ ) -> Any:
293
+ """Start a storage bridge span for read/write operations."""
294
+
295
+ if not self.span_manager.is_enabled:
296
+ return None
297
+ attributes: dict[str, Any] = {"sqlspec.storage.operation": operation, "sqlspec.config": self.config_name}
298
+ if self.bind_key:
299
+ attributes["sqlspec.bind_key"] = self.bind_key
300
+ correlation_id = CorrelationContext.get()
301
+ if correlation_id:
302
+ attributes["sqlspec.correlation_id"] = correlation_id
303
+ if destination:
304
+ attributes["sqlspec.storage.destination"] = destination
305
+ if format_label:
306
+ attributes["sqlspec.storage.format"] = format_label
307
+ return self.span_manager.start_span(f"sqlspec.storage.{operation}", attributes)
308
+
309
+ def start_span(self, name: str, *, attributes: dict[str, Any] | None = None) -> Any:
310
+ """Start a custom span enriched with configuration context."""
311
+
312
+ if not self.span_manager.is_enabled:
313
+ return None
314
+ merged: dict[str, Any] = attributes.copy() if attributes else {}
315
+ merged.setdefault("sqlspec.config", self.config_name)
316
+ if self.bind_key:
317
+ merged.setdefault("sqlspec.bind_key", self.bind_key)
318
+ correlation_id = CorrelationContext.get()
319
+ if correlation_id:
320
+ merged.setdefault("sqlspec.correlation_id", correlation_id)
321
+ return self.span_manager.start_span(name, merged)
322
+
323
+ def end_span(self, span: Any, *, error: Exception | None = None) -> None:
324
+ """Finish a custom span."""
325
+
326
+ self.span_manager.end_span(span, error=error)
327
+
328
+ def end_storage_span(
329
+ self, span: Any, *, telemetry: "StorageTelemetry | None" = None, error: Exception | None = None
330
+ ) -> None:
331
+ """Finish a storage span, attaching telemetry metadata when available."""
332
+
333
+ if span is None:
334
+ return
335
+ if telemetry:
336
+ telemetry = self.annotate_storage_telemetry(telemetry)
337
+ self._attach_storage_telemetry(span, telemetry)
338
+ self.span_manager.end_span(span, error=error)
339
+
340
+ def annotate_storage_telemetry(self, telemetry: "StorageTelemetry") -> "StorageTelemetry":
341
+ """Add bind key / config / correlation metadata to telemetry payloads."""
342
+
343
+ annotated = telemetry
344
+ base = self.base_context()
345
+ correlation_id = base.get("correlation_id")
346
+ if correlation_id and not annotated.get("correlation_id"):
347
+ annotated["correlation_id"] = correlation_id
348
+ annotated.setdefault("config", self.config_name)
349
+ if self.bind_key and not annotated.get("bind_key"):
350
+ annotated["bind_key"] = self.bind_key
351
+ return annotated
352
+
353
+ def _start_lifecycle_span(self, event: str, subject: Any | None = None) -> Any:
354
+ if not self.span_manager.is_enabled:
355
+ return None
356
+ attributes: dict[str, Any] = {"sqlspec.lifecycle.event": event, "sqlspec.config": self.config_name}
357
+ if self.bind_key:
358
+ attributes["sqlspec.bind_key"] = self.bind_key
359
+ correlation_id = CorrelationContext.get()
360
+ if correlation_id:
361
+ attributes["sqlspec.correlation_id"] = correlation_id
362
+ if subject is not None:
363
+ attributes["sqlspec.lifecycle.subject_type"] = type(subject).__name__
364
+ return self.span_manager.start_span(f"sqlspec.lifecycle.{event}", attributes)
365
+
366
+ def _attach_storage_telemetry(self, span: Any, telemetry: "StorageTelemetry") -> None:
367
+ if not has_span_attribute(span):
368
+ return
369
+ if "backend" in telemetry and telemetry["backend"] is not None:
370
+ span.set_attribute("sqlspec.storage.backend", telemetry["backend"])
371
+ if "bytes_processed" in telemetry and telemetry["bytes_processed"] is not None:
372
+ span.set_attribute("sqlspec.storage.bytes_processed", telemetry["bytes_processed"])
373
+ if "rows_processed" in telemetry and telemetry["rows_processed"] is not None:
374
+ span.set_attribute("sqlspec.storage.rows_processed", telemetry["rows_processed"])
375
+ if "destination" in telemetry and telemetry["destination"] is not None:
376
+ span.set_attribute("sqlspec.storage.destination", telemetry["destination"])
377
+ if "format" in telemetry and telemetry["format"] is not None:
378
+ span.set_attribute("sqlspec.storage.format", telemetry["format"])
379
+ if "duration_s" in telemetry and telemetry["duration_s"] is not None:
380
+ span.set_attribute("sqlspec.storage.duration_s", telemetry["duration_s"])
381
+ if "correlation_id" in telemetry and telemetry["correlation_id"] is not None:
382
+ span.set_attribute("sqlspec.correlation_id", telemetry["correlation_id"])
383
+
384
+ def _redact_sql(self, sql: str) -> str:
385
+ config = self._redaction
386
+ if config is None or not config.mask_literals:
387
+ return sql
388
+ return _LITERAL_PATTERN.sub("'***'", sql)
389
+
390
+ def _redact_parameters(self, parameters: Any) -> Any:
391
+ config = self._redaction
392
+ if config is None or not config.mask_parameters:
393
+ return parameters
394
+ allow_list = set(config.parameter_allow_list or ())
395
+ return _mask_parameters(parameters, allow_list)
396
+
397
+
398
+ def _mask_parameters(value: Any, allow_list: set[str]) -> Any:
399
+ if isinstance(value, dict):
400
+ masked: dict[str, Any] = {}
401
+ for key, item in value.items():
402
+ if allow_list and key in allow_list:
403
+ masked[key] = _mask_parameters(item, allow_list)
404
+ else:
405
+ masked[key] = "***"
406
+ return masked
407
+ if isinstance(value, list):
408
+ return [_mask_parameters(item, allow_list) for item in value]
409
+ if isinstance(value, tuple):
410
+ return tuple(_mask_parameters(item, allow_list) for item in value)
411
+ return "***"
412
+
413
+
414
+ def _truncate_text(value: str, *, max_chars: int) -> tuple[str, bool]:
415
+ if len(value) <= max_chars:
416
+ return value, False
417
+ return value[:max_chars], True
418
+
419
+
420
+ __all__ = ("ObservabilityRuntime",)
@@ -0,0 +1,188 @@
1
+ """Sampling configuration for observability data.
2
+
3
+ This module provides sampling configuration to control the volume of
4
+ logs, metrics, and traces emitted by the observability system.
5
+ Sampling can significantly reduce cloud logging costs while maintaining
6
+ visibility into errors and slow queries.
7
+ """
8
+
9
+ import random
10
+ from typing import ClassVar
11
+
12
+ __all__ = ("SamplingConfig",)
13
+
14
+
15
+ class SamplingConfig:
16
+ """Configuration for log and metric sampling.
17
+
18
+ Controls when observability data (logs, spans, metrics) is emitted.
19
+ Supports both random and deterministic sampling modes, with
20
+ force-sample conditions for errors and slow queries.
21
+
22
+ Attributes:
23
+ sample_rate: Probability of sampling (0.0 to 1.0). 1.0 means always sample.
24
+ force_sample_on_error: If True, always sample when an error occurs.
25
+ force_sample_slow_queries_ms: If set, always sample queries slower than this threshold.
26
+ deterministic: If True, use hash-based sampling for consistency across distributed systems.
27
+
28
+ Example:
29
+ ```python
30
+ # Sample 10% of requests, but always sample errors and slow queries
31
+ config = SamplingConfig(
32
+ sample_rate=0.1,
33
+ force_sample_on_error=True,
34
+ force_sample_slow_queries_ms=100.0,
35
+ deterministic=True,
36
+ )
37
+
38
+ # Check if a request should be sampled
39
+ if config.should_sample(
40
+ correlation_id="abc-123",
41
+ is_error=False,
42
+ duration_ms=50.0,
43
+ ):
44
+ emit_logs()
45
+ ```
46
+ """
47
+
48
+ __slots__ = ("deterministic", "force_sample_on_error", "force_sample_slow_queries_ms", "sample_rate")
49
+
50
+ DEFAULT_SAMPLE_RATE: ClassVar[float] = 1.0
51
+ """Default sample rate (100% - sample everything)."""
52
+
53
+ DEFAULT_SLOW_QUERY_THRESHOLD_MS: ClassVar[float] = 100.0
54
+ """Default threshold in milliseconds for slow query detection."""
55
+
56
+ HASH_MODULUS: ClassVar[int] = 10000
57
+ """Modulus for deterministic hash-based sampling."""
58
+
59
+ def __init__(
60
+ self,
61
+ *,
62
+ sample_rate: float = 1.0,
63
+ force_sample_on_error: bool = True,
64
+ force_sample_slow_queries_ms: float | None = 100.0,
65
+ deterministic: bool = True,
66
+ ) -> None:
67
+ """Initialize sampling configuration.
68
+
69
+ Args:
70
+ sample_rate: Probability of sampling (0.0 to 1.0). Values outside
71
+ this range are clamped. Defaults to 1.0 (always sample).
72
+ force_sample_on_error: If True, always sample when an error occurs.
73
+ Defaults to True.
74
+ force_sample_slow_queries_ms: If set, always sample queries that take
75
+ longer than this threshold in milliseconds. Defaults to 100.0ms.
76
+ Set to None to disable.
77
+ deterministic: If True, use hash-based sampling that produces consistent
78
+ results for the same correlation ID across distributed systems.
79
+ If False, use random sampling. Defaults to True.
80
+ """
81
+ self.sample_rate = max(0.0, min(1.0, sample_rate))
82
+ self.force_sample_on_error = force_sample_on_error
83
+ self.force_sample_slow_queries_ms = force_sample_slow_queries_ms
84
+ self.deterministic = deterministic
85
+
86
+ def should_sample(
87
+ self,
88
+ correlation_id: str | None = None,
89
+ *,
90
+ is_error: bool = False,
91
+ duration_ms: float | None = None,
92
+ force: bool = False,
93
+ ) -> bool:
94
+ """Determine if this request should be sampled.
95
+
96
+ Evaluates force-sample conditions first (errors, slow queries, explicit force),
97
+ then falls back to rate-based sampling.
98
+
99
+ Args:
100
+ correlation_id: The correlation ID for deterministic sampling.
101
+ If None and deterministic=True, falls back to random sampling.
102
+ is_error: Whether this request resulted in an error.
103
+ duration_ms: Query duration in milliseconds, if known.
104
+ force: Explicit force-sample flag from application code.
105
+
106
+ Returns:
107
+ True if the request should be sampled, False otherwise.
108
+
109
+ Example:
110
+ ```python
111
+ # Always sampled due to error
112
+ config.should_sample(is_error=True) # True
113
+
114
+ # Always sampled due to slow query (>100ms default)
115
+ config.should_sample(duration_ms=150.0) # True
116
+
117
+ # Rate-based sampling
118
+ config.should_sample(
119
+ correlation_id="abc-123"
120
+ ) # depends on rate
121
+ ```
122
+ """
123
+ # Force sample conditions take precedence
124
+ if force:
125
+ return True
126
+
127
+ if is_error and self.force_sample_on_error:
128
+ return True
129
+
130
+ if (
131
+ duration_ms is not None
132
+ and self.force_sample_slow_queries_ms is not None
133
+ and duration_ms >= self.force_sample_slow_queries_ms
134
+ ):
135
+ return True
136
+
137
+ # Rate-based sampling
138
+ if self.sample_rate >= 1.0:
139
+ return True
140
+
141
+ if self.sample_rate <= 0.0:
142
+ return False
143
+
144
+ # Deterministic or random sampling
145
+ if self.deterministic and correlation_id:
146
+ # Hash-based sampling for consistency across distributed systems
147
+ hash_value = hash(correlation_id) % self.HASH_MODULUS
148
+ threshold = int(self.sample_rate * self.HASH_MODULUS)
149
+ return hash_value < threshold
150
+
151
+ # Fall back to random sampling
152
+ return random.random() < self.sample_rate # noqa: S311
153
+
154
+ def copy(self) -> "SamplingConfig":
155
+ """Return a copy of the sampling configuration.
156
+
157
+ Returns:
158
+ A new SamplingConfig instance with the same values.
159
+ """
160
+ return SamplingConfig(
161
+ sample_rate=self.sample_rate,
162
+ force_sample_on_error=self.force_sample_on_error,
163
+ force_sample_slow_queries_ms=self.force_sample_slow_queries_ms,
164
+ deterministic=self.deterministic,
165
+ )
166
+
167
+ def __repr__(self) -> str:
168
+ return (
169
+ f"SamplingConfig(sample_rate={self.sample_rate!r}, "
170
+ f"force_sample_on_error={self.force_sample_on_error!r}, "
171
+ f"force_sample_slow_queries_ms={self.force_sample_slow_queries_ms!r}, "
172
+ f"deterministic={self.deterministic!r})"
173
+ )
174
+
175
+ def __eq__(self, other: object) -> bool:
176
+ if not isinstance(other, SamplingConfig):
177
+ return NotImplemented
178
+ return (
179
+ self.sample_rate == other.sample_rate
180
+ and self.force_sample_on_error == other.force_sample_on_error
181
+ and self.force_sample_slow_queries_ms == other.force_sample_slow_queries_ms
182
+ and self.deterministic == other.deterministic
183
+ )
184
+
185
+ def __hash__(self) -> int:
186
+ # SamplingConfig is mutable, so it should not be hashable
187
+ msg = "SamplingConfig objects are mutable and unhashable"
188
+ raise TypeError(msg)