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,511 @@
1
+ """CockroachDB configuration using psycopg."""
2
+
3
+ from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast
4
+
5
+ from psycopg import crdb as psycopg_crdb
6
+ from psycopg_pool import AsyncConnectionPool, ConnectionPool
7
+ from typing_extensions import NotRequired
8
+
9
+ from sqlspec.adapters.cockroach_psycopg._typing import (
10
+ CockroachAsyncConnection,
11
+ CockroachPsycopgAsyncSessionContext,
12
+ CockroachPsycopgSyncSessionContext,
13
+ CockroachSyncConnection,
14
+ )
15
+ from sqlspec.adapters.cockroach_psycopg.core import apply_driver_features, build_statement_config
16
+ from sqlspec.adapters.cockroach_psycopg.driver import (
17
+ CockroachPsycopgAsyncDriver,
18
+ CockroachPsycopgAsyncExceptionHandler,
19
+ CockroachPsycopgSyncDriver,
20
+ CockroachPsycopgSyncExceptionHandler,
21
+ )
22
+ from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs, SyncDatabaseConfig
23
+ from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
24
+ from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
25
+ from sqlspec.exceptions import ImproperConfigurationError
26
+ from sqlspec.extensions.events import EventRuntimeHints
27
+ from sqlspec.utils.config_tools import normalize_connection_config
28
+
29
+ if TYPE_CHECKING:
30
+ from collections.abc import Awaitable, Callable
31
+ from types import TracebackType
32
+
33
+ from sqlspec.core import StatementConfig
34
+ from sqlspec.observability import ObservabilityConfig
35
+
36
+ __all__ = (
37
+ "CockroachPsycopgAsyncConfig",
38
+ "CockroachPsycopgConnectionConfig",
39
+ "CockroachPsycopgDriverFeatures",
40
+ "CockroachPsycopgPoolConfig",
41
+ "CockroachPsycopgSyncConfig",
42
+ )
43
+
44
+ default_statement_config = build_statement_config()
45
+
46
+
47
+ class CockroachPsycopgConnectionConfig(TypedDict):
48
+ """CockroachDB connection parameters."""
49
+
50
+ conninfo: NotRequired[str]
51
+ host: NotRequired[str]
52
+ port: NotRequired[int]
53
+ user: NotRequired[str]
54
+ password: NotRequired[str]
55
+ dbname: NotRequired[str]
56
+ connect_timeout: NotRequired[int]
57
+ options: NotRequired[str]
58
+ application_name: NotRequired[str]
59
+ sslmode: NotRequired[str]
60
+ sslcert: NotRequired[str]
61
+ sslkey: NotRequired[str]
62
+ sslrootcert: NotRequired[str]
63
+ autocommit: NotRequired[bool]
64
+ cluster: NotRequired[str]
65
+ extra: NotRequired["dict[str, Any]"]
66
+
67
+
68
+ class CockroachPsycopgPoolConfig(CockroachPsycopgConnectionConfig):
69
+ """CockroachDB pool parameters."""
70
+
71
+ min_size: NotRequired[int]
72
+ max_size: NotRequired[int]
73
+ name: NotRequired[str]
74
+ timeout: NotRequired[float]
75
+ max_waiting: NotRequired[int]
76
+ max_lifetime: NotRequired[float]
77
+ max_idle: NotRequired[float]
78
+ reconnect_timeout: NotRequired[float]
79
+ num_workers: NotRequired[int]
80
+ configure: NotRequired["Callable[..., Any]"]
81
+ kwargs: NotRequired["dict[str, Any]"]
82
+
83
+
84
+ class CockroachPsycopgDriverFeatures(TypedDict):
85
+ """CockroachDB driver feature configuration.
86
+
87
+ on_connection_create: Callback executed when a connection is acquired from pool.
88
+ For sync: Callable[[CockroachSyncConnection], None]
89
+ For async: Callable[[CockroachAsyncConnection], Awaitable[None]]
90
+ Called after internal setup.
91
+ """
92
+
93
+ enable_auto_retry: NotRequired[bool]
94
+ max_retries: NotRequired[int]
95
+ retry_delay_base_ms: NotRequired[float]
96
+ retry_delay_max_ms: NotRequired[float]
97
+ enable_retry_logging: NotRequired[bool]
98
+ enable_follower_reads: NotRequired[bool]
99
+ default_staleness: NotRequired[str]
100
+ prefer_uuid_keys: NotRequired[bool]
101
+ json_serializer: NotRequired["Callable[[Any], str]"]
102
+ json_deserializer: NotRequired["Callable[[str], Any]"]
103
+ on_connection_create: "NotRequired[Callable[..., Any]]"
104
+ enable_events: NotRequired[bool]
105
+ events_backend: NotRequired[str]
106
+
107
+
108
+ class CockroachPsycopgSyncConnectionContext(SyncPoolConnectionContext):
109
+ """Context manager for CockroachDB psycopg connections."""
110
+
111
+ __slots__ = ()
112
+
113
+ def __init__(self, config: "CockroachPsycopgSyncConfig") -> None:
114
+ super().__init__(config)
115
+
116
+ def __enter__(self) -> "CockroachSyncConnection":
117
+ if self._config.connection_instance:
118
+ self._ctx = self._config.connection_instance.connection()
119
+ return cast("CockroachSyncConnection", self._ctx.__enter__())
120
+ self._ctx = self._config.create_connection()
121
+ return cast("CockroachSyncConnection", self._ctx)
122
+
123
+ def __exit__(
124
+ self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
125
+ ) -> bool | None:
126
+ if self._config.connection_instance and self._ctx:
127
+ return cast("bool | None", self._ctx.__exit__(exc_type, exc_val, exc_tb))
128
+ if self._ctx:
129
+ self._ctx.close()
130
+ return None
131
+
132
+
133
+ class _CockroachPsycopgSyncSessionConnectionHandler(SyncPoolSessionFactory):
134
+ __slots__ = ("_conn",)
135
+
136
+ def __init__(self, config: "CockroachPsycopgSyncConfig") -> None:
137
+ super().__init__(config)
138
+ self._conn: CockroachSyncConnection | None = None
139
+
140
+ def acquire_connection(self) -> "CockroachSyncConnection":
141
+ if self._config.connection_instance:
142
+ self._ctx = self._config.connection_instance.connection()
143
+ return cast("CockroachSyncConnection", self._ctx.__enter__())
144
+ self._conn = self._config.create_connection()
145
+ return cast("CockroachSyncConnection", self._conn)
146
+
147
+ def release_connection(self, _conn: "CockroachSyncConnection", **kwargs: Any) -> None:
148
+ if self._ctx is not None:
149
+ self._ctx.__exit__(None, None, None)
150
+ self._ctx = None
151
+ return
152
+ if self._conn is not None:
153
+ self._conn.close()
154
+ self._conn = None
155
+
156
+
157
+ class CockroachPsycopgSyncConfig(
158
+ SyncDatabaseConfig[CockroachSyncConnection, ConnectionPool, CockroachPsycopgSyncDriver]
159
+ ):
160
+ """Configuration for CockroachDB synchronous connections using psycopg."""
161
+
162
+ driver_type: "ClassVar[type[CockroachPsycopgSyncDriver]]" = CockroachPsycopgSyncDriver
163
+ connection_type: "ClassVar[type[CockroachSyncConnection]]" = CockroachSyncConnection
164
+ supports_transactional_ddl: "ClassVar[bool]" = True
165
+ supports_native_arrow_export: "ClassVar[bool]" = True
166
+ supports_native_arrow_import: "ClassVar[bool]" = True
167
+ supports_native_parquet_export: "ClassVar[bool]" = True
168
+ supports_native_parquet_import: "ClassVar[bool]" = True
169
+ _connection_context_class: "ClassVar[type[CockroachPsycopgSyncConnectionContext]]" = (
170
+ CockroachPsycopgSyncConnectionContext
171
+ )
172
+ _session_factory_class: "ClassVar[type[_CockroachPsycopgSyncSessionConnectionHandler]]" = (
173
+ _CockroachPsycopgSyncSessionConnectionHandler
174
+ )
175
+ _session_context_class: "ClassVar[type[CockroachPsycopgSyncSessionContext]]" = CockroachPsycopgSyncSessionContext
176
+ _default_statement_config = default_statement_config
177
+
178
+ def __init__(
179
+ self,
180
+ *,
181
+ connection_config: "CockroachPsycopgPoolConfig | dict[str, Any] | None" = None,
182
+ connection_instance: "ConnectionPool | None" = None,
183
+ migration_config: "dict[str, Any] | None" = None,
184
+ statement_config: "StatementConfig | None" = None,
185
+ driver_features: "CockroachPsycopgDriverFeatures | dict[str, Any] | None" = None,
186
+ bind_key: "str | None" = None,
187
+ extension_config: "ExtensionConfigs | None" = None,
188
+ observability_config: "ObservabilityConfig | None" = None,
189
+ **kwargs: Any,
190
+ ) -> None:
191
+ connection_config = normalize_connection_config(connection_config)
192
+ statement_config = statement_config or default_statement_config
193
+ statement_config, driver_features = apply_driver_features(statement_config, driver_features)
194
+
195
+ driver_features.setdefault("enable_auto_retry", True)
196
+
197
+ # Extract user connection hook before storing driver_features
198
+ features_dict = dict(driver_features) if driver_features else {}
199
+ self._user_connection_hook: Callable[[CockroachSyncConnection], None] | None = features_dict.pop(
200
+ "on_connection_create", None
201
+ )
202
+
203
+ super().__init__(
204
+ connection_config=connection_config,
205
+ connection_instance=connection_instance,
206
+ migration_config=migration_config,
207
+ statement_config=statement_config,
208
+ driver_features=features_dict,
209
+ bind_key=bind_key,
210
+ extension_config=extension_config,
211
+ observability_config=observability_config,
212
+ **kwargs,
213
+ )
214
+
215
+ def _create_pool(self) -> "ConnectionPool":
216
+ all_config = dict(self.connection_config)
217
+
218
+ pool_parameters = {
219
+ "min_size": all_config.pop("min_size", 4),
220
+ "max_size": all_config.pop("max_size", None),
221
+ "name": all_config.pop("name", None),
222
+ "timeout": all_config.pop("timeout", 30.0),
223
+ "max_waiting": all_config.pop("max_waiting", 0),
224
+ "max_lifetime": all_config.pop("max_lifetime", 3600.0),
225
+ "max_idle": all_config.pop("max_idle", 600.0),
226
+ "reconnect_timeout": all_config.pop("reconnect_timeout", 300.0),
227
+ "num_workers": all_config.pop("num_workers", 3),
228
+ }
229
+
230
+ pool_parameters["configure"] = all_config.pop("configure", self._configure_connection)
231
+ pool_parameters = {k: v for k, v in pool_parameters.items() if v is not None}
232
+
233
+ conninfo = all_config.pop("conninfo", None)
234
+ if conninfo:
235
+ return ConnectionPool(conninfo, open=True, connection_class=psycopg_crdb.CrdbConnection, **pool_parameters)
236
+
237
+ kwargs = all_config.pop("kwargs", {})
238
+ all_config.update(kwargs)
239
+ return ConnectionPool(
240
+ "", kwargs=all_config, open=True, connection_class=psycopg_crdb.CrdbConnection, **pool_parameters
241
+ )
242
+
243
+ def _configure_connection(self, conn: "CockroachSyncConnection") -> None:
244
+ autocommit_setting = self.connection_config.get("autocommit")
245
+ if autocommit_setting is not None:
246
+ conn.autocommit = autocommit_setting
247
+
248
+ # Call user-provided callback after internal setup
249
+ if self._user_connection_hook is not None:
250
+ self._user_connection_hook(conn)
251
+
252
+ def _close_pool(self) -> None:
253
+ if not self.connection_instance:
254
+ return
255
+ try:
256
+ self.connection_instance.close()
257
+ finally:
258
+ self.connection_instance = None
259
+
260
+ def create_connection(self) -> "CockroachSyncConnection":
261
+ if self.connection_instance is None:
262
+ self.connection_instance = self.create_pool()
263
+ return cast("CockroachSyncConnection", self.connection_instance.getconn())
264
+
265
+ def provide_session(
266
+ self,
267
+ *_args: Any,
268
+ statement_config: "StatementConfig | None" = None,
269
+ follower_reads: bool | None = None,
270
+ staleness: str | None = None,
271
+ **_kwargs: Any,
272
+ ) -> "CockroachPsycopgSyncSessionContext":
273
+ handler = _CockroachPsycopgSyncSessionConnectionHandler(self)
274
+ driver_features = dict(self.driver_features)
275
+ if follower_reads is not None:
276
+ driver_features["enable_follower_reads"] = follower_reads
277
+ if staleness is not None:
278
+ driver_features["default_staleness"] = staleness
279
+
280
+ return CockroachPsycopgSyncSessionContext(
281
+ acquire_connection=handler.acquire_connection,
282
+ release_connection=handler.release_connection,
283
+ statement_config=statement_config or self.statement_config or default_statement_config,
284
+ driver_features=driver_features,
285
+ prepare_driver=self._prepare_driver,
286
+ )
287
+
288
+ def provide_pool(self, *args: Any, **kwargs: Any) -> "ConnectionPool":
289
+ if not self.connection_instance:
290
+ self.connection_instance = self.create_pool()
291
+ return self.connection_instance
292
+
293
+ def get_signature_namespace(self) -> "dict[str, Any]":
294
+ namespace = super().get_signature_namespace()
295
+ namespace.update({
296
+ "CockroachPsycopgConnectionConfig": CockroachPsycopgConnectionConfig,
297
+ "CockroachPsycopgPoolConfig": CockroachPsycopgPoolConfig,
298
+ "CockroachSyncConnection": CockroachSyncConnection,
299
+ "CockroachPsycopgSyncDriver": CockroachPsycopgSyncDriver,
300
+ "CockroachPsycopgSyncExceptionHandler": CockroachPsycopgSyncExceptionHandler,
301
+ "CockroachPsycopgSyncSessionContext": CockroachPsycopgSyncSessionContext,
302
+ })
303
+ return namespace
304
+
305
+ def get_event_runtime_hints(self) -> "EventRuntimeHints":
306
+ return EventRuntimeHints(poll_interval=0.5, select_for_update=True, skip_locked=True)
307
+
308
+
309
+ class CockroachPsycopgAsyncConnectionContext(AsyncPoolConnectionContext):
310
+ """Async context manager for CockroachDB psycopg connections."""
311
+
312
+ __slots__ = ("_ctx",)
313
+
314
+ def __init__(self, config: "CockroachPsycopgAsyncConfig") -> None:
315
+ super().__init__(config)
316
+ self._ctx: Any = None
317
+
318
+ async def __aenter__(self) -> "CockroachAsyncConnection":
319
+ if self._config.connection_instance is None:
320
+ self._config.connection_instance = await self._config.create_pool()
321
+ if self._config.connection_instance:
322
+ self._ctx = self._config.connection_instance.connection()
323
+ return cast("CockroachAsyncConnection", await self._ctx.__aenter__())
324
+ msg = "Connection pool is not initialized"
325
+ raise ImproperConfigurationError(msg)
326
+
327
+ async def __aexit__(
328
+ self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
329
+ ) -> bool | None:
330
+ if self._ctx:
331
+ return cast("bool | None", await self._ctx.__aexit__(exc_type, exc_val, exc_tb))
332
+ return None
333
+
334
+
335
+ class _CockroachPsycopgAsyncSessionConnectionHandler(AsyncPoolSessionFactory):
336
+ __slots__ = ("_ctx",)
337
+
338
+ def __init__(self, config: "CockroachPsycopgAsyncConfig") -> None:
339
+ super().__init__(config)
340
+ self._ctx: Any = None
341
+
342
+ async def acquire_connection(self) -> "CockroachAsyncConnection":
343
+ pool = self._config.connection_instance
344
+ if pool is None:
345
+ pool = await self._config.create_pool()
346
+ self._config.connection_instance = pool
347
+ ctx = pool.connection()
348
+ self._ctx = ctx
349
+ return cast("CockroachAsyncConnection", await ctx.__aenter__())
350
+
351
+ async def release_connection(self, _conn: "CockroachAsyncConnection", **kwargs: Any) -> None:
352
+ if self._ctx is not None:
353
+ await self._ctx.__aexit__(None, None, None)
354
+ self._ctx = None
355
+
356
+
357
+ class CockroachPsycopgAsyncConfig(
358
+ AsyncDatabaseConfig[CockroachAsyncConnection, AsyncConnectionPool, CockroachPsycopgAsyncDriver]
359
+ ):
360
+ """Configuration for CockroachDB async connections using psycopg."""
361
+
362
+ driver_type: "ClassVar[type[CockroachPsycopgAsyncDriver]]" = CockroachPsycopgAsyncDriver
363
+ connection_type: "ClassVar[type[CockroachAsyncConnection]]" = CockroachAsyncConnection
364
+ supports_transactional_ddl: "ClassVar[bool]" = True
365
+ supports_native_arrow_export: "ClassVar[bool]" = True
366
+ supports_native_arrow_import: "ClassVar[bool]" = True
367
+ supports_native_parquet_export: "ClassVar[bool]" = True
368
+ supports_native_parquet_import: "ClassVar[bool]" = True
369
+ _connection_context_class: "ClassVar[type[CockroachPsycopgAsyncConnectionContext]]" = (
370
+ CockroachPsycopgAsyncConnectionContext
371
+ )
372
+ _session_factory_class: "ClassVar[type[_CockroachPsycopgAsyncSessionConnectionHandler]]" = (
373
+ _CockroachPsycopgAsyncSessionConnectionHandler
374
+ )
375
+ _session_context_class: "ClassVar[type[CockroachPsycopgAsyncSessionContext]]" = CockroachPsycopgAsyncSessionContext
376
+ _default_statement_config = default_statement_config
377
+
378
+ def __init__(
379
+ self,
380
+ *,
381
+ connection_config: "CockroachPsycopgPoolConfig | dict[str, Any] | None" = None,
382
+ connection_instance: "AsyncConnectionPool | None" = None,
383
+ migration_config: "dict[str, Any] | None" = None,
384
+ statement_config: "StatementConfig | None" = None,
385
+ driver_features: "CockroachPsycopgDriverFeatures | dict[str, Any] | None" = None,
386
+ bind_key: "str | None" = None,
387
+ extension_config: "ExtensionConfigs | None" = None,
388
+ observability_config: "ObservabilityConfig | None" = None,
389
+ **kwargs: Any,
390
+ ) -> None:
391
+ connection_config = normalize_connection_config(connection_config)
392
+ statement_config = statement_config or default_statement_config
393
+ statement_config, driver_features = apply_driver_features(statement_config, driver_features)
394
+
395
+ driver_features.setdefault("enable_auto_retry", True)
396
+
397
+ # Extract user connection hook before storing driver_features
398
+ features_dict = dict(driver_features) if driver_features else {}
399
+ self._user_connection_hook: Callable[[CockroachAsyncConnection], Awaitable[None]] | None = features_dict.pop(
400
+ "on_connection_create", None
401
+ )
402
+
403
+ super().__init__(
404
+ connection_config=connection_config,
405
+ connection_instance=connection_instance,
406
+ migration_config=migration_config,
407
+ statement_config=statement_config,
408
+ driver_features=features_dict,
409
+ bind_key=bind_key,
410
+ extension_config=extension_config,
411
+ observability_config=observability_config,
412
+ **kwargs,
413
+ )
414
+
415
+ async def _create_pool(self) -> "AsyncConnectionPool":
416
+ all_config = dict(self.connection_config)
417
+
418
+ pool_parameters = {
419
+ "min_size": all_config.pop("min_size", 4),
420
+ "max_size": all_config.pop("max_size", None),
421
+ "name": all_config.pop("name", None),
422
+ "timeout": all_config.pop("timeout", 30.0),
423
+ "max_waiting": all_config.pop("max_waiting", 0),
424
+ "max_lifetime": all_config.pop("max_lifetime", 3600.0),
425
+ "max_idle": all_config.pop("max_idle", 600.0),
426
+ "reconnect_timeout": all_config.pop("reconnect_timeout", 300.0),
427
+ "num_workers": all_config.pop("num_workers", 3),
428
+ }
429
+
430
+ pool_parameters["configure"] = all_config.pop("configure", self._configure_async_connection)
431
+ pool_parameters = {k: v for k, v in pool_parameters.items() if v is not None}
432
+
433
+ conninfo = all_config.pop("conninfo", None)
434
+ if conninfo:
435
+ pool = AsyncConnectionPool(
436
+ conninfo, open=False, connection_class=psycopg_crdb.AsyncCrdbConnection, **pool_parameters
437
+ )
438
+ else:
439
+ kwargs = all_config.pop("kwargs", {})
440
+ all_config.update(kwargs)
441
+ pool = AsyncConnectionPool(
442
+ "", kwargs=all_config, open=False, connection_class=psycopg_crdb.AsyncCrdbConnection, **pool_parameters
443
+ )
444
+
445
+ await pool.open()
446
+ return cast("AsyncConnectionPool", pool)
447
+
448
+ async def _configure_async_connection(self, conn: "CockroachAsyncConnection") -> None:
449
+ autocommit_setting = self.connection_config.get("autocommit")
450
+ if autocommit_setting is not None:
451
+ await conn.set_autocommit(autocommit_setting)
452
+
453
+ # Call user-provided callback after internal setup
454
+ if self._user_connection_hook is not None:
455
+ await self._user_connection_hook(conn)
456
+
457
+ async def _close_pool(self) -> None:
458
+ if not self.connection_instance:
459
+ return
460
+ try:
461
+ await self.connection_instance.close()
462
+ finally:
463
+ self.connection_instance = None
464
+
465
+ async def create_connection(self) -> "CockroachAsyncConnection":
466
+ if self.connection_instance is None:
467
+ self.connection_instance = await self.create_pool()
468
+ return cast("CockroachAsyncConnection", await self.connection_instance.getconn())
469
+
470
+ def provide_session(
471
+ self,
472
+ *_args: Any,
473
+ statement_config: "StatementConfig | None" = None,
474
+ follower_reads: bool | None = None,
475
+ staleness: str | None = None,
476
+ **_kwargs: Any,
477
+ ) -> "CockroachPsycopgAsyncSessionContext":
478
+ handler = _CockroachPsycopgAsyncSessionConnectionHandler(self)
479
+ driver_features = dict(self.driver_features)
480
+ if follower_reads is not None:
481
+ driver_features["enable_follower_reads"] = follower_reads
482
+ if staleness is not None:
483
+ driver_features["default_staleness"] = staleness
484
+
485
+ return CockroachPsycopgAsyncSessionContext(
486
+ acquire_connection=handler.acquire_connection,
487
+ release_connection=handler.release_connection,
488
+ statement_config=statement_config or self.statement_config or build_statement_config(),
489
+ driver_features=driver_features,
490
+ prepare_driver=self._prepare_driver,
491
+ )
492
+
493
+ async def provide_pool(self, *args: Any, **kwargs: Any) -> "AsyncConnectionPool":
494
+ if not self.connection_instance:
495
+ self.connection_instance = await self.create_pool()
496
+ return self.connection_instance
497
+
498
+ def get_signature_namespace(self) -> "dict[str, Any]":
499
+ namespace = super().get_signature_namespace()
500
+ namespace.update({
501
+ "CockroachAsyncConnection": CockroachAsyncConnection,
502
+ "CockroachPsycopgAsyncDriver": CockroachPsycopgAsyncDriver,
503
+ "CockroachPsycopgAsyncExceptionHandler": CockroachPsycopgAsyncExceptionHandler,
504
+ "CockroachPsycopgAsyncSessionContext": CockroachPsycopgAsyncSessionContext,
505
+ "CockroachPsycopgConnectionConfig": CockroachPsycopgConnectionConfig,
506
+ "CockroachPsycopgPoolConfig": CockroachPsycopgPoolConfig,
507
+ })
508
+ return namespace
509
+
510
+ def get_event_runtime_hints(self) -> "EventRuntimeHints":
511
+ return EventRuntimeHints(poll_interval=0.5, select_for_update=True, skip_locked=True)
@@ -0,0 +1,63 @@
1
+ """CockroachDB psycopg adapter compiled helpers."""
2
+
3
+ import secrets
4
+ from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING, Any, Final
6
+
7
+ from sqlspec.adapters.psycopg.core import apply_driver_features, build_statement_config, driver_profile
8
+ from sqlspec.utils.type_guards import has_sqlstate
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Mapping
12
+
13
+ __all__ = (
14
+ "CockroachPsycopgRetryConfig",
15
+ "apply_driver_features",
16
+ "build_statement_config",
17
+ "calculate_backoff_seconds",
18
+ "driver_profile",
19
+ "is_retryable_error",
20
+ )
21
+
22
+ # Retry configuration defaults (module-level for mypyc compatibility)
23
+ _DEFAULT_MAX_RETRIES: Final[int] = 10
24
+ _DEFAULT_BASE_DELAY_MS: Final[float] = 50.0
25
+ _DEFAULT_MAX_DELAY_MS: Final[float] = 5000.0
26
+ _DEFAULT_ENABLE_LOGGING: Final[bool] = True
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class CockroachPsycopgRetryConfig:
31
+ """CockroachDB psycopg transaction retry configuration."""
32
+
33
+ max_retries: int = _DEFAULT_MAX_RETRIES
34
+ base_delay_ms: float = _DEFAULT_BASE_DELAY_MS
35
+ max_delay_ms: float = _DEFAULT_MAX_DELAY_MS
36
+ enable_logging: bool = _DEFAULT_ENABLE_LOGGING
37
+
38
+ @classmethod
39
+ def from_features(cls, driver_features: "Mapping[str, Any]") -> "CockroachPsycopgRetryConfig":
40
+ """Build retry config from driver feature mappings."""
41
+ return cls(
42
+ max_retries=int(driver_features.get("max_retries", _DEFAULT_MAX_RETRIES)),
43
+ base_delay_ms=float(driver_features.get("retry_delay_base_ms", _DEFAULT_BASE_DELAY_MS)),
44
+ max_delay_ms=float(driver_features.get("retry_delay_max_ms", _DEFAULT_MAX_DELAY_MS)),
45
+ enable_logging=bool(driver_features.get("enable_retry_logging", _DEFAULT_ENABLE_LOGGING)),
46
+ )
47
+
48
+
49
+ def is_retryable_error(error: BaseException) -> bool:
50
+ """Return True when the error should trigger a CockroachDB retry."""
51
+ if has_sqlstate(error):
52
+ return str(error.sqlstate) == "40001"
53
+ return False
54
+
55
+
56
+ def calculate_backoff_seconds(attempt: int, config: "CockroachPsycopgRetryConfig") -> float:
57
+ """Calculate exponential backoff delay in seconds."""
58
+ base: float = config.base_delay_ms * (2**attempt)
59
+ scale: int = 1000
60
+ max_jitter: int = max(int(base * scale), 0)
61
+ jitter: float = secrets.randbelow(max_jitter + 1) / scale if max_jitter else 0.0
62
+ delay_ms: float = min(base + jitter, config.max_delay_ms)
63
+ return delay_ms / 1000.0