sqlspec 0.47.0__cp314-cp314-win_amd64.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 (621) hide show
  1. f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
  2. sqlspec/__init__.py +167 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_typing.py +714 -0
  6. sqlspec/adapters/__init__.py +0 -0
  7. sqlspec/adapters/adbc/__init__.py +13 -0
  8. sqlspec/adapters/adbc/_typing.py +106 -0
  9. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  10. sqlspec/adapters/adbc/adk/store.py +1280 -0
  11. sqlspec/adapters/adbc/config.py +378 -0
  12. sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
  13. sqlspec/adapters/adbc/core.py +922 -0
  14. sqlspec/adapters/adbc/data_dictionary.py +339 -0
  15. sqlspec/adapters/adbc/driver.py +534 -0
  16. sqlspec/adapters/adbc/events/__init__.py +5 -0
  17. sqlspec/adapters/adbc/events/store.py +285 -0
  18. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  19. sqlspec/adapters/adbc/litestar/store.py +534 -0
  20. sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
  21. sqlspec/adapters/adbc/type_converter.py +142 -0
  22. sqlspec/adapters/aiomysql/__init__.py +21 -0
  23. sqlspec/adapters/aiomysql/_typing.py +137 -0
  24. sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
  25. sqlspec/adapters/aiomysql/adk/store.py +678 -0
  26. sqlspec/adapters/aiomysql/config.py +305 -0
  27. sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
  28. sqlspec/adapters/aiomysql/core.py +536 -0
  29. sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
  30. sqlspec/adapters/aiomysql/driver.py +386 -0
  31. sqlspec/adapters/aiomysql/events/__init__.py +5 -0
  32. sqlspec/adapters/aiomysql/events/store.py +104 -0
  33. sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
  34. sqlspec/adapters/aiomysql/litestar/store.py +314 -0
  35. sqlspec/adapters/aiosqlite/__init__.py +26 -0
  36. sqlspec/adapters/aiosqlite/_typing.py +109 -0
  37. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  38. sqlspec/adapters/aiosqlite/adk/store.py +829 -0
  39. sqlspec/adapters/aiosqlite/config.py +315 -0
  40. sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
  41. sqlspec/adapters/aiosqlite/core.py +315 -0
  42. sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
  43. sqlspec/adapters/aiosqlite/driver.py +311 -0
  44. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  45. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  46. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  47. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  48. sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
  49. sqlspec/adapters/aiosqlite/pool.py +734 -0
  50. sqlspec/adapters/asyncmy/__init__.py +21 -0
  51. sqlspec/adapters/asyncmy/_typing.py +113 -0
  52. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncmy/adk/store.py +644 -0
  54. sqlspec/adapters/asyncmy/config.py +307 -0
  55. sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
  56. sqlspec/adapters/asyncmy/core.py +538 -0
  57. sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
  58. sqlspec/adapters/asyncmy/driver.py +391 -0
  59. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  60. sqlspec/adapters/asyncmy/events/store.py +104 -0
  61. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  62. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  63. sqlspec/adapters/asyncpg/__init__.py +26 -0
  64. sqlspec/adapters/asyncpg/_typing.py +103 -0
  65. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  66. sqlspec/adapters/asyncpg/adk/store.py +483 -0
  67. sqlspec/adapters/asyncpg/config.py +575 -0
  68. sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
  69. sqlspec/adapters/asyncpg/core.py +480 -0
  70. sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
  71. sqlspec/adapters/asyncpg/driver.py +487 -0
  72. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  73. sqlspec/adapters/asyncpg/events/_hub.py +181 -0
  74. sqlspec/adapters/asyncpg/events/backend.py +210 -0
  75. sqlspec/adapters/asyncpg/events/store.py +40 -0
  76. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  77. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  78. sqlspec/adapters/bigquery/__init__.py +15 -0
  79. sqlspec/adapters/bigquery/_typing.py +108 -0
  80. sqlspec/adapters/bigquery/config.py +362 -0
  81. sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
  82. sqlspec/adapters/bigquery/core.py +768 -0
  83. sqlspec/adapters/bigquery/data_dictionary.py +120 -0
  84. sqlspec/adapters/bigquery/driver.py +542 -0
  85. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  86. sqlspec/adapters/bigquery/events/store.py +139 -0
  87. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  88. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  89. sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
  90. sqlspec/adapters/bigquery/type_converter.py +107 -0
  91. sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
  92. sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
  93. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  94. sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
  95. sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
  96. sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
  97. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  98. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
  99. sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
  100. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  101. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  102. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  103. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  104. sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
  105. sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
  106. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  107. sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
  108. sqlspec/adapters/cockroach_psycopg/config.py +511 -0
  109. sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
  110. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  111. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
  112. sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
  113. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  114. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  115. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  116. sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
  117. sqlspec/adapters/duckdb/__init__.py +29 -0
  118. sqlspec/adapters/duckdb/_typing.py +104 -0
  119. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  120. sqlspec/adapters/duckdb/adk/store.py +935 -0
  121. sqlspec/adapters/duckdb/config.py +386 -0
  122. sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
  123. sqlspec/adapters/duckdb/core.py +332 -0
  124. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  125. sqlspec/adapters/duckdb/driver.py +426 -0
  126. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  127. sqlspec/adapters/duckdb/events/store.py +57 -0
  128. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  129. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  130. sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
  131. sqlspec/adapters/duckdb/pool.py +350 -0
  132. sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
  133. sqlspec/adapters/duckdb/type_converter.py +118 -0
  134. sqlspec/adapters/mysqlconnector/__init__.py +39 -0
  135. sqlspec/adapters/mysqlconnector/_typing.py +186 -0
  136. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  137. sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
  138. sqlspec/adapters/mysqlconnector/config.py +421 -0
  139. sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
  140. sqlspec/adapters/mysqlconnector/core.py +472 -0
  141. sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
  142. sqlspec/adapters/mysqlconnector/driver.py +516 -0
  143. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  144. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  145. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  146. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  147. sqlspec/adapters/oracledb/__init__.py +39 -0
  148. sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
  149. sqlspec/adapters/oracledb/_json_handlers.py +196 -0
  150. sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
  151. sqlspec/adapters/oracledb/_param_types.py +46 -0
  152. sqlspec/adapters/oracledb/_typing.py +258 -0
  153. sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
  154. sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
  155. sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
  156. sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
  157. sqlspec/adapters/oracledb/adk/__init__.py +21 -0
  158. sqlspec/adapters/oracledb/adk/store.py +2453 -0
  159. sqlspec/adapters/oracledb/config.py +575 -0
  160. sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
  161. sqlspec/adapters/oracledb/core.py +820 -0
  162. sqlspec/adapters/oracledb/data_dictionary.py +404 -0
  163. sqlspec/adapters/oracledb/driver.py +1277 -0
  164. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  165. sqlspec/adapters/oracledb/events/_hub.py +345 -0
  166. sqlspec/adapters/oracledb/events/backend.py +300 -0
  167. sqlspec/adapters/oracledb/events/store.py +420 -0
  168. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  169. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  170. sqlspec/adapters/oracledb/migrations.py +539 -0
  171. sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
  172. sqlspec/adapters/oracledb/type_converter.py +211 -0
  173. sqlspec/adapters/psqlpy/__init__.py +18 -0
  174. sqlspec/adapters/psqlpy/_typing.py +121 -0
  175. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  176. sqlspec/adapters/psqlpy/adk/store.py +591 -0
  177. sqlspec/adapters/psqlpy/config.py +376 -0
  178. sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
  179. sqlspec/adapters/psqlpy/core.py +694 -0
  180. sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
  181. sqlspec/adapters/psqlpy/driver.py +411 -0
  182. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  183. sqlspec/adapters/psqlpy/events/_hub.py +204 -0
  184. sqlspec/adapters/psqlpy/events/backend.py +210 -0
  185. sqlspec/adapters/psqlpy/events/store.py +20 -0
  186. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  187. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  188. sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
  189. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  190. sqlspec/adapters/psycopg/__init__.py +38 -0
  191. sqlspec/adapters/psycopg/_typing.py +218 -0
  192. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  193. sqlspec/adapters/psycopg/adk/store.py +1106 -0
  194. sqlspec/adapters/psycopg/config.py +695 -0
  195. sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
  196. sqlspec/adapters/psycopg/core.py +520 -0
  197. sqlspec/adapters/psycopg/data_dictionary.py +278 -0
  198. sqlspec/adapters/psycopg/driver.py +1033 -0
  199. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  200. sqlspec/adapters/psycopg/events/_hub.py +388 -0
  201. sqlspec/adapters/psycopg/events/backend.py +398 -0
  202. sqlspec/adapters/psycopg/events/store.py +42 -0
  203. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  204. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  205. sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
  206. sqlspec/adapters/psycopg/type_converter.py +93 -0
  207. sqlspec/adapters/pymysql/__init__.py +21 -0
  208. sqlspec/adapters/pymysql/_typing.py +92 -0
  209. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  210. sqlspec/adapters/pymysql/adk/store.py +657 -0
  211. sqlspec/adapters/pymysql/config.py +176 -0
  212. sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
  213. sqlspec/adapters/pymysql/core.py +469 -0
  214. sqlspec/adapters/pymysql/data_dictionary.py +120 -0
  215. sqlspec/adapters/pymysql/driver.py +271 -0
  216. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  217. sqlspec/adapters/pymysql/events/store.py +50 -0
  218. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  219. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  220. sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
  221. sqlspec/adapters/pymysql/pool.py +184 -0
  222. sqlspec/adapters/spanner/__init__.py +33 -0
  223. sqlspec/adapters/spanner/_typing.py +102 -0
  224. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  225. sqlspec/adapters/spanner/adk/store.py +758 -0
  226. sqlspec/adapters/spanner/config.py +355 -0
  227. sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
  228. sqlspec/adapters/spanner/core.py +263 -0
  229. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  230. sqlspec/adapters/spanner/driver.py +407 -0
  231. sqlspec/adapters/spanner/events/__init__.py +5 -0
  232. sqlspec/adapters/spanner/events/store.py +187 -0
  233. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  234. sqlspec/adapters/spanner/litestar/store.py +291 -0
  235. sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
  236. sqlspec/adapters/spanner/type_converter.py +342 -0
  237. sqlspec/adapters/sqlite/__init__.py +19 -0
  238. sqlspec/adapters/sqlite/_typing.py +123 -0
  239. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  240. sqlspec/adapters/sqlite/adk/store.py +992 -0
  241. sqlspec/adapters/sqlite/config.py +240 -0
  242. sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
  243. sqlspec/adapters/sqlite/core.py +357 -0
  244. sqlspec/adapters/sqlite/data_dictionary.py +198 -0
  245. sqlspec/adapters/sqlite/driver.py +527 -0
  246. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  247. sqlspec/adapters/sqlite/events/store.py +20 -0
  248. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  249. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  250. sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
  251. sqlspec/adapters/sqlite/pool.py +237 -0
  252. sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
  253. sqlspec/adapters/sqlite/type_converter.py +114 -0
  254. sqlspec/base.py +832 -0
  255. sqlspec/builder/__init__.py +181 -0
  256. sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
  257. sqlspec/builder/_base.py +1071 -0
  258. sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
  259. sqlspec/builder/_column.py +521 -0
  260. sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
  261. sqlspec/builder/_ddl.py +1691 -0
  262. sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
  263. sqlspec/builder/_delete.py +95 -0
  264. sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
  265. sqlspec/builder/_dml.py +386 -0
  266. sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
  267. sqlspec/builder/_explain.py +579 -0
  268. sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
  269. sqlspec/builder/_expression_wrappers.py +46 -0
  270. sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
  271. sqlspec/builder/_factory.py +1884 -0
  272. sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
  273. sqlspec/builder/_insert.py +405 -0
  274. sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
  275. sqlspec/builder/_join.py +489 -0
  276. sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
  277. sqlspec/builder/_merge.py +823 -0
  278. sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
  279. sqlspec/builder/_parsing_utils.py +295 -0
  280. sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
  281. sqlspec/builder/_select.py +1666 -0
  282. sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
  283. sqlspec/builder/_temporal.py +167 -0
  284. sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
  285. sqlspec/builder/_update.py +173 -0
  286. sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
  287. sqlspec/builder/_vector_distance.py +330 -0
  288. sqlspec/cli.py +1095 -0
  289. sqlspec/config.py +2383 -0
  290. sqlspec/core/__init__.py +372 -0
  291. sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
  292. sqlspec/core/_correlation.py +176 -0
  293. sqlspec/core/_pagination.py +42 -0
  294. sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
  295. sqlspec/core/_pool.py +76 -0
  296. sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
  297. sqlspec/core/cache.py +1085 -0
  298. sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
  299. sqlspec/core/compiler.py +1090 -0
  300. sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
  301. sqlspec/core/config_runtime.py +174 -0
  302. sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
  303. sqlspec/core/explain.py +275 -0
  304. sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
  305. sqlspec/core/filters.py +969 -0
  306. sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
  307. sqlspec/core/hashing.py +266 -0
  308. sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
  309. sqlspec/core/metrics.py +83 -0
  310. sqlspec/core/parameters/__init__.py +72 -0
  311. sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
  312. sqlspec/core/parameters/_alignment.py +283 -0
  313. sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
  314. sqlspec/core/parameters/_converter.py +554 -0
  315. sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
  316. sqlspec/core/parameters/_processor.py +1182 -0
  317. sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
  318. sqlspec/core/parameters/_registry.py +206 -0
  319. sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
  320. sqlspec/core/parameters/_transformers.py +324 -0
  321. sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
  322. sqlspec/core/parameters/_types.py +536 -0
  323. sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
  324. sqlspec/core/parameters/_validator.py +171 -0
  325. sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
  326. sqlspec/core/pipeline.py +333 -0
  327. sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
  328. sqlspec/core/query_modifiers.py +508 -0
  329. sqlspec/core/result/__init__.py +25 -0
  330. sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
  331. sqlspec/core/result/_base.py +1232 -0
  332. sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
  333. sqlspec/core/result/_io.py +28 -0
  334. sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
  335. sqlspec/core/splitter.py +1021 -0
  336. sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
  337. sqlspec/core/sqlcommenter.py +249 -0
  338. sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
  339. sqlspec/core/stack.py +163 -0
  340. sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
  341. sqlspec/core/statement.py +1865 -0
  342. sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
  343. sqlspec/core/type_converter.py +340 -0
  344. sqlspec/data_dictionary/__init__.py +22 -0
  345. sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
  346. sqlspec/data_dictionary/_loader.py +138 -0
  347. sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
  348. sqlspec/data_dictionary/_registry.py +74 -0
  349. sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
  350. sqlspec/data_dictionary/_types.py +121 -0
  351. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  352. sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
  353. sqlspec/data_dictionary/dialects/bigquery.py +81 -0
  354. sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
  355. sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
  356. sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
  357. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  358. sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
  359. sqlspec/data_dictionary/dialects/mysql.py +53 -0
  360. sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
  361. sqlspec/data_dictionary/dialects/oracle.py +197 -0
  362. sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
  363. sqlspec/data_dictionary/dialects/postgres.py +69 -0
  364. sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
  365. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  366. sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
  367. sqlspec/data_dictionary/dialects/sqlite.py +59 -0
  368. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  369. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  370. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  371. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  372. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  373. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  374. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  375. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  376. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  377. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  378. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  379. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  380. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  381. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  382. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  383. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  384. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  385. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  386. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  387. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  388. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  389. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  390. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  391. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  392. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  393. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  394. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  395. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  396. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  397. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  398. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  399. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  400. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  401. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  402. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  403. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  404. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  405. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  406. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  407. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  408. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  409. sqlspec/dialects/__init__.py +22 -0
  410. sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
  411. sqlspec/dialects/_compat.py +14 -0
  412. sqlspec/dialects/postgres/__init__.py +9 -0
  413. sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
  414. sqlspec/dialects/postgres/_generators.py +57 -0
  415. sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
  416. sqlspec/dialects/postgres/_operators.py +81 -0
  417. sqlspec/dialects/postgres/_paradedb.py +50 -0
  418. sqlspec/dialects/postgres/_pgvector.py +36 -0
  419. sqlspec/dialects/spanner/__init__.py +6 -0
  420. sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
  421. sqlspec/dialects/spanner/_generators.py +206 -0
  422. sqlspec/dialects/spanner/_spangres.py +77 -0
  423. sqlspec/dialects/spanner/_spanner.py +179 -0
  424. sqlspec/driver/__init__.py +49 -0
  425. sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
  426. sqlspec/driver/_async.py +1830 -0
  427. sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
  428. sqlspec/driver/_common.py +2292 -0
  429. sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
  430. sqlspec/driver/_exception_handler.py +108 -0
  431. sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
  432. sqlspec/driver/_query_cache.py +96 -0
  433. sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
  434. sqlspec/driver/_sql_helpers.py +139 -0
  435. sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
  436. sqlspec/driver/_storage_helpers.py +153 -0
  437. sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
  438. sqlspec/driver/_sync.py +1817 -0
  439. sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
  440. sqlspec/exceptions.py +480 -0
  441. sqlspec/extensions/__init__.py +0 -0
  442. sqlspec/extensions/adk/__init__.py +84 -0
  443. sqlspec/extensions/adk/_config_utils.py +199 -0
  444. sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
  445. sqlspec/extensions/adk/_types.py +41 -0
  446. sqlspec/extensions/adk/artifact/__init__.py +57 -0
  447. sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
  448. sqlspec/extensions/adk/artifact/_types.py +32 -0
  449. sqlspec/extensions/adk/artifact/service.py +508 -0
  450. sqlspec/extensions/adk/artifact/store.py +361 -0
  451. sqlspec/extensions/adk/converters.py +212 -0
  452. sqlspec/extensions/adk/memory/__init__.py +69 -0
  453. sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
  454. sqlspec/extensions/adk/memory/_types.py +30 -0
  455. sqlspec/extensions/adk/memory/converters.py +225 -0
  456. sqlspec/extensions/adk/memory/service.py +316 -0
  457. sqlspec/extensions/adk/memory/store.py +525 -0
  458. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
  459. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  460. sqlspec/extensions/adk/service.py +279 -0
  461. sqlspec/extensions/adk/store.py +590 -0
  462. sqlspec/extensions/events/__init__.py +51 -0
  463. sqlspec/extensions/events/_channel.py +703 -0
  464. sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
  465. sqlspec/extensions/events/_hints.py +45 -0
  466. sqlspec/extensions/events/_models.py +23 -0
  467. sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
  468. sqlspec/extensions/events/_payload.py +69 -0
  469. sqlspec/extensions/events/_protocols.py +134 -0
  470. sqlspec/extensions/events/_queue.py +462 -0
  471. sqlspec/extensions/events/_store.py +209 -0
  472. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  473. sqlspec/extensions/events/migrations/__init__.py +3 -0
  474. sqlspec/extensions/fastapi/__init__.py +22 -0
  475. sqlspec/extensions/fastapi/extension.py +391 -0
  476. sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
  477. sqlspec/extensions/fastapi/providers.py +712 -0
  478. sqlspec/extensions/flask/__init__.py +38 -0
  479. sqlspec/extensions/flask/_state.py +87 -0
  480. sqlspec/extensions/flask/_utils.py +71 -0
  481. sqlspec/extensions/flask/extension.py +539 -0
  482. sqlspec/extensions/litestar/__init__.py +31 -0
  483. sqlspec/extensions/litestar/_utils.py +52 -0
  484. sqlspec/extensions/litestar/channels.py +165 -0
  485. sqlspec/extensions/litestar/cli.py +102 -0
  486. sqlspec/extensions/litestar/config.py +90 -0
  487. sqlspec/extensions/litestar/handlers.py +316 -0
  488. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  489. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  490. sqlspec/extensions/litestar/plugin.py +1066 -0
  491. sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
  492. sqlspec/extensions/litestar/providers.py +784 -0
  493. sqlspec/extensions/litestar/store.py +298 -0
  494. sqlspec/extensions/otel/__init__.py +58 -0
  495. sqlspec/extensions/prometheus/__init__.py +113 -0
  496. sqlspec/extensions/sanic/__init__.py +19 -0
  497. sqlspec/extensions/sanic/_state.py +43 -0
  498. sqlspec/extensions/sanic/_utils.py +127 -0
  499. sqlspec/extensions/sanic/extension.py +647 -0
  500. sqlspec/extensions/starlette/__init__.py +22 -0
  501. sqlspec/extensions/starlette/_state.py +42 -0
  502. sqlspec/extensions/starlette/_utils.py +96 -0
  503. sqlspec/extensions/starlette/extension.py +374 -0
  504. sqlspec/extensions/starlette/middleware.py +281 -0
  505. sqlspec/loader.cp314-win_amd64.pyd +0 -0
  506. sqlspec/loader.py +727 -0
  507. sqlspec/migrations/__init__.py +39 -0
  508. sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
  509. sqlspec/migrations/base.py +862 -0
  510. sqlspec/migrations/commands.py +2151 -0
  511. sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
  512. sqlspec/migrations/context.py +157 -0
  513. sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
  514. sqlspec/migrations/fix.py +204 -0
  515. sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
  516. sqlspec/migrations/loaders.py +443 -0
  517. sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
  518. sqlspec/migrations/runner.py +1195 -0
  519. sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
  520. sqlspec/migrations/squash.py +490 -0
  521. sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
  522. sqlspec/migrations/templates.py +234 -0
  523. sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
  524. sqlspec/migrations/tracker.py +792 -0
  525. sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
  526. sqlspec/migrations/utils.py +256 -0
  527. sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
  528. sqlspec/migrations/validation.py +359 -0
  529. sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
  530. sqlspec/migrations/version.py +446 -0
  531. sqlspec/observability/__init__.py +57 -0
  532. sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
  533. sqlspec/observability/_common.py +77 -0
  534. sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
  535. sqlspec/observability/_config.py +364 -0
  536. sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
  537. sqlspec/observability/_diagnostics.py +74 -0
  538. sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
  539. sqlspec/observability/_dispatcher.py +200 -0
  540. sqlspec/observability/_formatters/__init__.py +13 -0
  541. sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
  542. sqlspec/observability/_formatters/_aws.py +102 -0
  543. sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
  544. sqlspec/observability/_formatters/_azure.py +96 -0
  545. sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
  546. sqlspec/observability/_formatters/_base.py +57 -0
  547. sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
  548. sqlspec/observability/_formatters/_gcp.py +131 -0
  549. sqlspec/observability/_formatting.py +58 -0
  550. sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
  551. sqlspec/observability/_observer.py +361 -0
  552. sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
  553. sqlspec/observability/_runtime.py +461 -0
  554. sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
  555. sqlspec/observability/_sampling.py +188 -0
  556. sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
  557. sqlspec/observability/_spans.py +161 -0
  558. sqlspec/protocols.py +955 -0
  559. sqlspec/py.typed +0 -0
  560. sqlspec/service.py +433 -0
  561. sqlspec/storage/__init__.py +48 -0
  562. sqlspec/storage/_arrow_payload.py +68 -0
  563. sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
  564. sqlspec/storage/_paths.py +58 -0
  565. sqlspec/storage/_utils.py +46 -0
  566. sqlspec/storage/backends/__init__.py +1 -0
  567. sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
  568. sqlspec/storage/backends/base.py +374 -0
  569. sqlspec/storage/backends/fsspec.py +574 -0
  570. sqlspec/storage/backends/local.py +468 -0
  571. sqlspec/storage/backends/obstore.py +956 -0
  572. sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
  573. sqlspec/storage/errors.py +102 -0
  574. sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
  575. sqlspec/storage/pipeline.py +628 -0
  576. sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
  577. sqlspec/storage/registry.py +329 -0
  578. sqlspec/typing.py +405 -0
  579. sqlspec/utils/__init__.py +7 -0
  580. sqlspec/utils/arrow_helpers.py +384 -0
  581. sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
  582. sqlspec/utils/config_tools.py +314 -0
  583. sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
  584. sqlspec/utils/correlation.py +134 -0
  585. sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
  586. sqlspec/utils/deprecation.py +157 -0
  587. sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
  588. sqlspec/utils/dispatch.py +101 -0
  589. sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
  590. sqlspec/utils/fixtures.py +260 -0
  591. sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
  592. sqlspec/utils/logging.py +251 -0
  593. sqlspec/utils/module_loader.py +306 -0
  594. sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
  595. sqlspec/utils/portal.py +377 -0
  596. sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
  597. sqlspec/utils/schema.py +1040 -0
  598. sqlspec/utils/serializers/__init__.py +30 -0
  599. sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
  600. sqlspec/utils/serializers/_json.py +415 -0
  601. sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
  602. sqlspec/utils/serializers/_numpy.py +65 -0
  603. sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
  604. sqlspec/utils/serializers/_schema.py +285 -0
  605. sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
  606. sqlspec/utils/singleton.py +41 -0
  607. sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
  608. sqlspec/utils/sync_tools.py +316 -0
  609. sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
  610. sqlspec/utils/text.py +109 -0
  611. sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
  612. sqlspec/utils/type_converters.py +216 -0
  613. sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
  614. sqlspec/utils/type_guards.py +1508 -0
  615. sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
  616. sqlspec/utils/uuids.py +241 -0
  617. sqlspec-0.47.0.dist-info/METADATA +202 -0
  618. sqlspec-0.47.0.dist-info/RECORD +621 -0
  619. sqlspec-0.47.0.dist-info/WHEEL +4 -0
  620. sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
  621. sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,461 @@
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, StatementObserver
8
+ from sqlspec.observability._dispatcher import LifecycleDispatcher, LifecycleHook
9
+ from sqlspec.observability._observer import 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
+ if TYPE_CHECKING:
15
+ from collections.abc import Iterable
16
+
17
+ from sqlspec.storage import StorageTelemetry
18
+
19
+ __all__ = ("ObservabilityRuntime",)
20
+
21
+
22
+ _LITERAL_PATTERN = re.compile(r"'(?:''|[^'])*'")
23
+
24
+
25
+ class ObservabilityRuntime:
26
+ """Aggregates dispatchers, observers, spans, and custom metrics."""
27
+
28
+ __slots__ = (
29
+ "_is_idle_cached",
30
+ "_metrics",
31
+ "_redaction",
32
+ "_statement_observers",
33
+ "bind_key",
34
+ "config",
35
+ "config_name",
36
+ "lifecycle",
37
+ "span_manager",
38
+ )
39
+
40
+ # Allow test injection with fake span managers (mypyc strict typing workaround)
41
+ span_manager: "Any"
42
+
43
+ def __init__(
44
+ self, config: ObservabilityConfig | None = None, *, bind_key: str | None = None, config_name: str | None = None
45
+ ) -> None:
46
+ config = config.copy() if config else ObservabilityConfig()
47
+ if config.logging is None:
48
+ config.logging = LoggingConfig()
49
+ self.config = config
50
+ self.bind_key = bind_key
51
+ self.config_name = config_name or "SQLSpecConfig"
52
+ lifecycle_config = cast("dict[str, Iterable[LifecycleHook]] | None", config.lifecycle)
53
+ self.lifecycle = LifecycleDispatcher(lifecycle_config)
54
+ self.span_manager = SpanManager(config.telemetry)
55
+ observers: list[StatementObserver] = []
56
+ if config.statement_observers:
57
+ observers.extend(config.statement_observers)
58
+ if config.print_sql:
59
+ observers.append(create_statement_observer(config.logging))
60
+ self._statement_observers = tuple(observers)
61
+ self._redaction = config.redaction.copy() if config.redaction else None
62
+ self._metrics: dict[str, float] = {}
63
+ # Pre-compute the non-span idle state (lifecycle and observers are immutable)
64
+ # span_manager can be replaced for testing so we check it separately
65
+ self._is_idle_cached = not self.lifecycle.is_enabled and not self._statement_observers
66
+
67
+ @property
68
+ def is_idle(self) -> bool:
69
+ """Return True when no observability features are active.
70
+
71
+ A runtime is idle if it has no lifecycle hooks, no statement observers,
72
+ and telemetry spans are disabled. Drivers can use this to skip
73
+ expensive context construction.
74
+ """
75
+ # Fast path: lifecycle and observers state is cached (immutable after init)
76
+ # span_manager is checked each time as it can be replaced for testing
77
+ return self._is_idle_cached and not self.span_manager.is_enabled
78
+
79
+ @property
80
+ def has_statement_observers(self) -> bool:
81
+ """Return True when any observers are registered."""
82
+
83
+ return bool(self._statement_observers)
84
+
85
+ @property
86
+ def diagnostics_key(self) -> str:
87
+ """Derive diagnostics key from bind key or configuration name."""
88
+
89
+ if self.bind_key:
90
+ return self.bind_key
91
+ return self.config_name
92
+
93
+ def base_context(self) -> dict[str, Any]:
94
+ """Return the base payload for lifecycle events."""
95
+
96
+ context = {"config": self.config_name}
97
+ if self.bind_key:
98
+ context["bind_key"] = self.bind_key
99
+ correlation_id = CorrelationContext.get()
100
+ if correlation_id:
101
+ context["correlation_id"] = correlation_id
102
+ return context
103
+
104
+ def _build_context(self, **extras: Any) -> dict[str, Any]:
105
+ context = self.base_context()
106
+ context.update({key: value for key, value in extras.items() if value is not None})
107
+ return context
108
+
109
+ def lifecycle_snapshot(self) -> dict[str, int]:
110
+ """Return lifecycle counters keyed under the diagnostics prefix."""
111
+
112
+ return self.lifecycle.snapshot(prefix=self.diagnostics_key)
113
+
114
+ def metrics_snapshot(self) -> dict[str, float]:
115
+ """Return accumulated custom metrics with diagnostics prefix."""
116
+
117
+ if not self._metrics:
118
+ return {}
119
+ prefix = self.diagnostics_key
120
+ return {f"{prefix}.{name}": value for name, value in self._metrics.items()}
121
+
122
+ def increment_metric(self, name: str, amount: float = 1.0) -> None:
123
+ """Increment a custom metric counter."""
124
+
125
+ self._metrics[name] = self._metrics.get(name, 0.0) + amount
126
+
127
+ def record_metric(self, name: str, value: float) -> None:
128
+ """Set a custom metric to an explicit value."""
129
+
130
+ self._metrics[name] = value
131
+
132
+ def start_migration_span(
133
+ self, event: str, *, version: "str | None" = None, metadata: "dict[str, Any] | None" = None
134
+ ) -> Any:
135
+ """Start a migration span when telemetry is enabled."""
136
+
137
+ if not self.span_manager.is_enabled:
138
+ return None
139
+ attributes: dict[str, Any] = {"sqlspec.migration.event": event, "sqlspec.config": self.config_name}
140
+ if self.bind_key:
141
+ attributes["sqlspec.bind_key"] = self.bind_key
142
+ correlation_id = CorrelationContext.get()
143
+ if correlation_id:
144
+ attributes["sqlspec.correlation_id"] = correlation_id
145
+ if version:
146
+ attributes["sqlspec.migration.version"] = version
147
+ if metadata:
148
+ for key, value in metadata.items():
149
+ if value is not None:
150
+ attributes[f"sqlspec.migration.{key}"] = value
151
+ return self.span_manager.start_span(f"sqlspec.migration.{event}", attributes)
152
+
153
+ def end_migration_span(
154
+ self, span: Any, *, duration_ms: "int | None" = None, error: "Exception | None" = None
155
+ ) -> None:
156
+ """Finish a migration span, attaching optional duration metadata."""
157
+
158
+ if span is None:
159
+ return
160
+ if duration_ms is not None and has_span_attribute(span):
161
+ span.set_attribute("sqlspec.migration.duration_ms", duration_ms)
162
+ self.span_manager.end_span(span, error=error)
163
+
164
+ def emit_pool_create(self, pool: Any) -> None:
165
+ span = self._start_lifecycle_span("pool.create", subject=pool)
166
+ try:
167
+ if self.lifecycle.has_pool_create:
168
+ self.lifecycle.emit_pool_create(self._build_context(pool=pool))
169
+ finally:
170
+ self.span_manager.end_span(span)
171
+
172
+ def emit_pool_destroying_sync(self, pool: Any) -> None:
173
+ """Fire pre-destruction lifecycle hooks synchronously."""
174
+ if not self.lifecycle.has_pool_destroying:
175
+ return
176
+ self.lifecycle.emit_pool_destroying_sync(self._build_context(pool=pool))
177
+
178
+ async def emit_pool_destroying_async(self, pool: Any) -> None:
179
+ """Fire pre-destruction lifecycle hooks, awaiting any awaitables."""
180
+ if not self.lifecycle.has_pool_destroying:
181
+ return
182
+ await self.lifecycle.emit_pool_destroying_async(self._build_context(pool=pool))
183
+
184
+ def emit_pool_destroy(self, pool: Any) -> None:
185
+ span = self._start_lifecycle_span("pool.destroy", subject=pool)
186
+ try:
187
+ if self.lifecycle.has_pool_destroy:
188
+ self.lifecycle.emit_pool_destroy(self._build_context(pool=pool))
189
+ finally:
190
+ self.span_manager.end_span(span)
191
+
192
+ def register_lifecycle_hook(self, event: str, callback: "LifecycleHook") -> None:
193
+ """Append a lifecycle hook at runtime.
194
+
195
+ Intended for components that acquire long-lived resources after config
196
+ construction (e.g., persistent LISTEN/NOTIFY hubs) and need to plug into
197
+ teardown. Currently used with ``on_pool_destroying``; other events accept
198
+ registrations too but most lifecycle hooks are wired declaratively.
199
+ """
200
+ self.lifecycle.register_hook(event, callback) # type: ignore[arg-type]
201
+
202
+ def emit_connection_create(self, connection: Any) -> None:
203
+ span = self._start_lifecycle_span("connection.create", subject=connection)
204
+ try:
205
+ if self.lifecycle.has_connection_create:
206
+ self.lifecycle.emit_connection_create(self._build_context(connection=connection))
207
+ finally:
208
+ self.span_manager.end_span(span)
209
+
210
+ def emit_connection_destroy(self, connection: Any) -> None:
211
+ span = self._start_lifecycle_span("connection.destroy", subject=connection)
212
+ try:
213
+ if self.lifecycle.has_connection_destroy:
214
+ self.lifecycle.emit_connection_destroy(self._build_context(connection=connection))
215
+ finally:
216
+ self.span_manager.end_span(span)
217
+
218
+ def emit_session_start(self, session: Any) -> None:
219
+ span = self._start_lifecycle_span("session.start", subject=session)
220
+ try:
221
+ if self.lifecycle.has_session_start:
222
+ self.lifecycle.emit_session_start(self._build_context(session=session))
223
+ finally:
224
+ self.span_manager.end_span(span)
225
+
226
+ def emit_session_end(self, session: Any) -> None:
227
+ span = self._start_lifecycle_span("session.end", subject=session)
228
+ try:
229
+ if self.lifecycle.has_session_end:
230
+ self.lifecycle.emit_session_end(self._build_context(session=session))
231
+ finally:
232
+ self.span_manager.end_span(span)
233
+
234
+ def emit_query_start(self, **extras: Any) -> None:
235
+ if self.lifecycle.has_query_start:
236
+ self.lifecycle.emit_query_start(self._build_context(**extras))
237
+
238
+ def emit_query_complete(self, **extras: Any) -> None:
239
+ if self.lifecycle.has_query_complete:
240
+ self.lifecycle.emit_query_complete(self._build_context(**extras))
241
+
242
+ def emit_error(self, exception: Exception, **extras: Any) -> None:
243
+ if self.lifecycle.has_error:
244
+ payload = self._build_context(exception=exception)
245
+ payload.update({key: value for key, value in extras.items() if value is not None})
246
+ self.lifecycle.emit_error(payload)
247
+ self.increment_metric("errors", 1.0)
248
+
249
+ def emit_statement_event(
250
+ self,
251
+ *,
252
+ sql: str,
253
+ parameters: Any,
254
+ driver: str,
255
+ operation: str,
256
+ execution_mode: str | None,
257
+ is_many: bool,
258
+ is_script: bool,
259
+ rows_affected: int | None,
260
+ duration_s: float,
261
+ storage_backend: str | None,
262
+ started_at: float | None = None,
263
+ ) -> None:
264
+ """Emit a statement event to all registered observers."""
265
+
266
+ if not self._statement_observers:
267
+ return
268
+ sanitized_sql = self._redact_sql(sql)
269
+ sanitized_params = self._redact_parameters(parameters)
270
+ correlation_id = CorrelationContext.get()
271
+ logging_config = self.config.logging
272
+ db_system = resolve_db_system(self.config_name)
273
+ sql_hash = None
274
+ if logging_config and logging_config.include_sql_hash:
275
+ sql_hash = compute_sql_hash(sanitized_sql)
276
+ sql_truncation_length = logging_config.sql_truncation_length if logging_config else 2000
277
+ sql_original_length = len(sanitized_sql)
278
+ sql_truncated = sql_original_length > sql_truncation_length
279
+ trace_id = None
280
+ span_id = None
281
+ if logging_config and logging_config.include_trace_context:
282
+ trace_id, span_id = get_trace_context()
283
+ event = create_event(
284
+ sql=sanitized_sql,
285
+ parameters=sanitized_params,
286
+ driver=driver,
287
+ adapter=self.config_name,
288
+ bind_key=self.bind_key,
289
+ db_system=db_system,
290
+ operation=operation,
291
+ execution_mode=execution_mode,
292
+ is_many=is_many,
293
+ is_script=is_script,
294
+ rows_affected=rows_affected,
295
+ duration_s=duration_s,
296
+ correlation_id=correlation_id,
297
+ storage_backend=storage_backend,
298
+ started_at=started_at,
299
+ sql_hash=sql_hash,
300
+ sql_truncated=sql_truncated,
301
+ sql_original_length=sql_original_length,
302
+ trace_id=trace_id,
303
+ span_id=span_id,
304
+ )
305
+ for observer in self._statement_observers:
306
+ observer(event)
307
+
308
+ def start_query_span(self, sql: str, operation: str, driver: str) -> Any:
309
+ """Start a query span with runtime metadata."""
310
+
311
+ if not self.span_manager.is_enabled:
312
+ return None
313
+
314
+ sql_hash = compute_sql_hash(sql)
315
+ connection_info = {"sqlspec.statement.hash": sql_hash, "sqlspec.statement.length": len(sql)}
316
+ sql_payload = ""
317
+ if self.config.print_sql:
318
+ sql_payload = self._redact_sql(sql)
319
+ sql_payload, truncated = _truncate_text(sql_payload, max_chars=4096)
320
+ if truncated:
321
+ connection_info["sqlspec.statement.truncated"] = True
322
+
323
+ correlation_id = CorrelationContext.get()
324
+ return self.span_manager.start_query_span(
325
+ driver=driver,
326
+ adapter=self.config_name,
327
+ bind_key=self.bind_key,
328
+ sql=sql_payload,
329
+ operation=operation,
330
+ connection_info=connection_info,
331
+ correlation_id=correlation_id,
332
+ )
333
+
334
+ def start_storage_span(
335
+ self, operation: str, *, destination: str | None = None, format_label: str | None = None
336
+ ) -> Any:
337
+ """Start a storage bridge span for read/write operations."""
338
+
339
+ if not self.span_manager.is_enabled:
340
+ return None
341
+ attributes: dict[str, Any] = {"sqlspec.storage.operation": operation, "sqlspec.config": self.config_name}
342
+ if self.bind_key:
343
+ attributes["sqlspec.bind_key"] = self.bind_key
344
+ correlation_id = CorrelationContext.get()
345
+ if correlation_id:
346
+ attributes["sqlspec.correlation_id"] = correlation_id
347
+ if destination:
348
+ attributes["sqlspec.storage.destination"] = destination
349
+ if format_label:
350
+ attributes["sqlspec.storage.format"] = format_label
351
+ return self.span_manager.start_span(f"sqlspec.storage.{operation}", attributes)
352
+
353
+ def start_span(self, name: str, *, attributes: dict[str, Any] | None = None) -> Any:
354
+ """Start a custom span enriched with configuration context."""
355
+
356
+ if not self.span_manager.is_enabled:
357
+ return None
358
+ merged: dict[str, Any] = attributes.copy() if attributes else {}
359
+ merged.setdefault("sqlspec.config", self.config_name)
360
+ if self.bind_key:
361
+ merged.setdefault("sqlspec.bind_key", self.bind_key)
362
+ correlation_id = CorrelationContext.get()
363
+ if correlation_id:
364
+ merged.setdefault("sqlspec.correlation_id", correlation_id)
365
+ return self.span_manager.start_span(name, merged)
366
+
367
+ def end_span(self, span: Any, *, error: Exception | None = None) -> None:
368
+ """Finish a custom span."""
369
+
370
+ self.span_manager.end_span(span, error=error)
371
+
372
+ def end_storage_span(
373
+ self, span: Any, *, telemetry: "StorageTelemetry | None" = None, error: Exception | None = None
374
+ ) -> None:
375
+ """Finish a storage span, attaching telemetry metadata when available."""
376
+
377
+ if span is None:
378
+ return
379
+ if telemetry:
380
+ telemetry = self.annotate_storage_telemetry(telemetry)
381
+ self._attach_storage_telemetry(span, telemetry)
382
+ self.span_manager.end_span(span, error=error)
383
+
384
+ def annotate_storage_telemetry(self, telemetry: "StorageTelemetry") -> "StorageTelemetry":
385
+ """Add bind key / config / correlation metadata to telemetry payloads."""
386
+
387
+ annotated = telemetry
388
+ base = self.base_context()
389
+ correlation_id = base.get("correlation_id")
390
+ if correlation_id and not annotated.get("correlation_id"):
391
+ annotated["correlation_id"] = correlation_id
392
+ annotated.setdefault("config", self.config_name)
393
+ if self.bind_key and not annotated.get("bind_key"):
394
+ annotated["bind_key"] = self.bind_key
395
+ return annotated
396
+
397
+ def _start_lifecycle_span(self, event: str, subject: Any | None = None) -> Any:
398
+ if not self.span_manager.is_enabled:
399
+ return None
400
+ attributes: dict[str, Any] = {"sqlspec.lifecycle.event": event, "sqlspec.config": self.config_name}
401
+ if self.bind_key:
402
+ attributes["sqlspec.bind_key"] = self.bind_key
403
+ correlation_id = CorrelationContext.get()
404
+ if correlation_id:
405
+ attributes["sqlspec.correlation_id"] = correlation_id
406
+ if subject is not None:
407
+ attributes["sqlspec.lifecycle.subject_type"] = type(subject).__name__
408
+ return self.span_manager.start_span(f"sqlspec.lifecycle.{event}", attributes)
409
+
410
+ def _attach_storage_telemetry(self, span: Any, telemetry: "StorageTelemetry") -> None:
411
+ if not has_span_attribute(span):
412
+ return
413
+ if "backend" in telemetry and telemetry["backend"] is not None:
414
+ span.set_attribute("sqlspec.storage.backend", telemetry["backend"])
415
+ if "bytes_processed" in telemetry and telemetry["bytes_processed"] is not None:
416
+ span.set_attribute("sqlspec.storage.bytes_processed", telemetry["bytes_processed"])
417
+ if "rows_processed" in telemetry and telemetry["rows_processed"] is not None:
418
+ span.set_attribute("sqlspec.storage.rows_processed", telemetry["rows_processed"])
419
+ if "destination" in telemetry and telemetry["destination"] is not None:
420
+ span.set_attribute("sqlspec.storage.destination", telemetry["destination"])
421
+ if "format" in telemetry and telemetry["format"] is not None:
422
+ span.set_attribute("sqlspec.storage.format", telemetry["format"])
423
+ if "duration_s" in telemetry and telemetry["duration_s"] is not None:
424
+ span.set_attribute("sqlspec.storage.duration_s", telemetry["duration_s"])
425
+ if "correlation_id" in telemetry and telemetry["correlation_id"] is not None:
426
+ span.set_attribute("sqlspec.correlation_id", telemetry["correlation_id"])
427
+
428
+ def _redact_sql(self, sql: str) -> str:
429
+ config = self._redaction
430
+ if config is None or not config.mask_literals:
431
+ return sql
432
+ return _LITERAL_PATTERN.sub("'***'", sql)
433
+
434
+ def _redact_parameters(self, parameters: Any) -> Any:
435
+ config = self._redaction
436
+ if config is None or not config.mask_parameters:
437
+ return parameters
438
+ allow_list = set(config.parameter_allow_list or ())
439
+ return _mask_parameters(parameters, allow_list)
440
+
441
+
442
+ def _mask_parameters(value: Any, allow_list: set[str]) -> Any:
443
+ if isinstance(value, dict):
444
+ masked: dict[str, Any] = {}
445
+ for key, item in value.items():
446
+ if allow_list and key in allow_list:
447
+ masked[key] = _mask_parameters(item, allow_list)
448
+ else:
449
+ masked[key] = "***"
450
+ return masked
451
+ if isinstance(value, list):
452
+ return [_mask_parameters(item, allow_list) for item in value]
453
+ if isinstance(value, tuple):
454
+ return tuple(_mask_parameters(item, allow_list) for item in value)
455
+ return "***"
456
+
457
+
458
+ def _truncate_text(value: str, *, max_chars: int) -> tuple[str, bool]:
459
+ if len(value) <= max_chars:
460
+ return value, False
461
+ return value[:max_chars], True
@@ -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)