lib-x17-fintech 2.1.3__py3-none-any.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 (282) hide show
  1. lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
  2. lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
  3. lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
  4. lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
  5. lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
  6. xfintech/__init__.py +0 -0
  7. xfintech/connect/__init__.py +18 -0
  8. xfintech/connect/artifact/__init__.py +5 -0
  9. xfintech/connect/artifact/artifact.py +168 -0
  10. xfintech/connect/artifact/tests/__init__.py +3 -0
  11. xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
  12. xfintech/connect/common/__init__.py +12 -0
  13. xfintech/connect/common/connect.py +49 -0
  14. xfintech/connect/common/connectref.py +119 -0
  15. xfintech/connect/common/error.py +62 -0
  16. xfintech/connect/common/tests/__init__.py +1 -0
  17. xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
  18. xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
  19. xfintech/connect/common/tests/test_class_errors_all.py +524 -0
  20. xfintech/connect/instance/__init__.py +7 -0
  21. xfintech/connect/instance/macos.py +121 -0
  22. xfintech/connect/instance/s3.py +176 -0
  23. xfintech/connect/instance/tests/__init__.py +1 -0
  24. xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
  25. xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
  26. xfintech/data/__init__.py +20 -0
  27. xfintech/data/common/__init__.py +15 -0
  28. xfintech/data/common/cache.py +186 -0
  29. xfintech/data/common/coolant.py +171 -0
  30. xfintech/data/common/metric.py +138 -0
  31. xfintech/data/common/paginate.py +132 -0
  32. xfintech/data/common/params.py +162 -0
  33. xfintech/data/common/retry.py +201 -0
  34. xfintech/data/common/tests/__init__.py +1 -0
  35. xfintech/data/common/tests/test_class_cache_all.py +681 -0
  36. xfintech/data/common/tests/test_class_coolant_all.py +534 -0
  37. xfintech/data/common/tests/test_class_metric_all.py +705 -0
  38. xfintech/data/common/tests/test_class_paginate_all.py +508 -0
  39. xfintech/data/common/tests/test_class_params_all.py +891 -0
  40. xfintech/data/common/tests/test_class_retry_all.py +714 -0
  41. xfintech/data/job/__init__.py +17 -0
  42. xfintech/data/job/errors.py +112 -0
  43. xfintech/data/job/house.py +156 -0
  44. xfintech/data/job/job.py +247 -0
  45. xfintech/data/job/joblike.py +47 -0
  46. xfintech/data/job/tests/__init__.py +1 -0
  47. xfintech/data/job/tests/test_class_errors_all.py +275 -0
  48. xfintech/data/job/tests/test_class_house_all.py +801 -0
  49. xfintech/data/job/tests/test_class_job_all.py +684 -0
  50. xfintech/data/job/tests/test_class_joblike_all.py +482 -0
  51. xfintech/data/relay/__init__.py +7 -0
  52. xfintech/data/relay/client.py +114 -0
  53. xfintech/data/relay/clientlike.py +45 -0
  54. xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
  55. xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
  56. xfintech/data/source/__init__.py +7 -0
  57. xfintech/data/source/baostock/__init__.py +21 -0
  58. xfintech/data/source/baostock/job/__init__.py +5 -0
  59. xfintech/data/source/baostock/job/job.py +217 -0
  60. xfintech/data/source/baostock/job/tests/__init__.py +0 -0
  61. xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
  62. xfintech/data/source/baostock/session/__init__.py +8 -0
  63. xfintech/data/source/baostock/session/relay.py +223 -0
  64. xfintech/data/source/baostock/session/session.py +241 -0
  65. xfintech/data/source/baostock/session/tests/__init__.py +0 -0
  66. xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
  67. xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
  68. xfintech/data/source/baostock/stock/__init__.py +0 -0
  69. xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
  70. xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
  71. xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
  72. xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
  73. xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
  74. xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
  75. xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
  76. xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
  77. xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
  78. xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
  79. xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
  80. xfintech/data/source/baostock/stock/stock/constant.py +55 -0
  81. xfintech/data/source/baostock/stock/stock/stock.py +149 -0
  82. xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
  83. xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
  84. xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
  85. xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
  86. xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
  87. xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
  88. xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
  89. xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
  90. xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
  91. xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
  92. xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
  93. xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
  94. xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
  95. xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
  96. xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
  97. xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
  98. xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
  99. xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
  100. xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
  101. xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
  102. xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
  103. xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
  104. xfintech/data/source/tushare/__init__.py +61 -0
  105. xfintech/data/source/tushare/job/__init__.py +5 -0
  106. xfintech/data/source/tushare/job/job.py +257 -0
  107. xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
  108. xfintech/data/source/tushare/session/__init__.py +5 -0
  109. xfintech/data/source/tushare/session/relay.py +231 -0
  110. xfintech/data/source/tushare/session/session.py +239 -0
  111. xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
  112. xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
  113. xfintech/data/source/tushare/stock/__init__.py +55 -0
  114. xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
  115. xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
  116. xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
  117. xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
  118. xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
  119. xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
  120. xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
  121. xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
  122. xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
  123. xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
  124. xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
  125. xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
  126. xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
  127. xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
  128. xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
  129. xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
  130. xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
  131. xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
  132. xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
  133. xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
  134. xfintech/data/source/tushare/stock/company/__init__.py +19 -0
  135. xfintech/data/source/tushare/stock/company/company.py +188 -0
  136. xfintech/data/source/tushare/stock/company/constant.py +92 -0
  137. xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
  138. xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
  139. xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
  140. xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
  141. xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
  142. xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
  143. xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
  144. xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
  145. xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
  146. xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
  147. xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
  148. xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
  149. xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
  150. xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
  151. xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
  152. xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
  153. xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
  154. xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
  155. xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
  156. xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
  157. xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
  158. xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
  159. xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
  160. xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
  161. xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
  162. xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
  163. xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
  164. xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
  165. xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
  166. xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
  167. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
  168. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
  169. xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
  170. xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
  171. xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
  172. xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
  173. xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
  174. xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
  175. xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
  176. xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
  177. xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
  178. xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
  179. xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
  180. xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
  181. xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
  182. xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
  183. xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
  184. xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
  185. xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
  186. xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
  187. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
  188. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
  189. xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
  190. xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
  191. xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
  192. xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
  193. xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
  194. xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
  195. xfintech/data/source/tushare/stock/stock/constant.py +105 -0
  196. xfintech/data/source/tushare/stock/stock/stock.py +193 -0
  197. xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
  198. xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
  199. xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
  200. xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
  201. xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
  202. xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
  203. xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
  204. xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
  205. xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
  206. xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
  207. xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
  208. xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
  209. xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
  210. xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
  211. xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
  212. xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
  213. xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
  214. xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
  215. xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
  216. xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
  217. xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
  218. xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
  219. xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
  220. xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
  221. xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
  222. xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
  223. xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
  224. xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
  225. xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
  226. xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
  227. xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
  228. xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
  229. xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
  230. xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
  231. xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
  232. xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
  233. xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
  234. xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
  235. xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
  236. xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
  237. xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
  238. xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
  239. xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
  240. xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
  241. xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
  242. xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
  243. xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
  244. xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
  245. xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
  246. xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
  247. xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
  248. xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
  249. xfintech/fabric/__init__.py +18 -0
  250. xfintech/fabric/column/__init__.py +7 -0
  251. xfintech/fabric/column/info.py +202 -0
  252. xfintech/fabric/column/kind.py +102 -0
  253. xfintech/fabric/column/tests/__init__.py +0 -0
  254. xfintech/fabric/column/tests/test_class_info_all.py +207 -0
  255. xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
  256. xfintech/fabric/table/__init__.py +5 -0
  257. xfintech/fabric/table/info.py +263 -0
  258. xfintech/fabric/table/tests/__init__.py +0 -0
  259. xfintech/fabric/table/tests/test_class_info_all.py +547 -0
  260. xfintech/serde/__init__.py +35 -0
  261. xfintech/serde/common/__init__.py +9 -0
  262. xfintech/serde/common/dataformat.py +78 -0
  263. xfintech/serde/common/deserialiserlike.py +38 -0
  264. xfintech/serde/common/error.py +182 -0
  265. xfintech/serde/common/serialiserlike.py +38 -0
  266. xfintech/serde/common/tests/__init__.py +1 -0
  267. xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
  268. xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
  269. xfintech/serde/common/tests/test_class_errors_all.py +518 -0
  270. xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
  271. xfintech/serde/deserialiser/__init__.py +7 -0
  272. xfintech/serde/deserialiser/pandas.py +113 -0
  273. xfintech/serde/deserialiser/python.py +68 -0
  274. xfintech/serde/deserialiser/tests/__init__.py +1 -0
  275. xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
  276. xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
  277. xfintech/serde/serialiser/__init__.py +7 -0
  278. xfintech/serde/serialiser/pandas.py +116 -0
  279. xfintech/serde/serialiser/python.py +71 -0
  280. xfintech/serde/serialiser/tests/__init__.py +1 -0
  281. xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
  282. xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
@@ -0,0 +1,162 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import json
5
+ from datetime import datetime
6
+ from typing import Any, Dict, Optional
7
+
8
+
9
+ class Params:
10
+ """
11
+ 描述:
12
+ - 动态参数容器类,用于灵活存储和管理键值对数据。
13
+ - 支持通过属性访问和字典访问两种方式操作数据。
14
+ - 提供数据序列化功能,确保复杂对象可转换为 JSON 兼容格式。
15
+ - 可用于 API 请求参数、配置管理等场景。
16
+
17
+ 属性:
18
+ - 动态属性: 通过 **kwargs 传入的任意键值对都会成为实例属性。
19
+
20
+ 方法:
21
+ - from_dict(data): 从字典创建 Params 实例。
22
+ - get(key, default): 获取属性值,如果不存在返回默认值。
23
+ - set(key, value): 设置属性值。
24
+ - describe(): 返回序列化后的字典,所有值转换为 JSON 兼容格式。
25
+ - to_dict(): 返回原始值的字典表示。
26
+ - ensure_serialisable(value): 静态方法,将复杂对象转换为可序列化格式。
27
+
28
+ 例子:
29
+ ```python
30
+ from xfintech.data.common.params import Params
31
+ from datetime import datetime
32
+
33
+ # 创建参数实例
34
+ params = Params(symbol="AAPL", start_date=datetime(2024, 1, 1), limit=100)
35
+
36
+ # 通过属性访问
37
+ print(params.symbol) # 输出: AAPL
38
+
39
+ # 通过 get 方法访问
40
+ limit = params.get("limit", 50)
41
+ print(limit) # 输出: 100
42
+
43
+ # 检查属性是否存在
44
+ if "symbol" in params:
45
+ print("包含 symbol 属性")
46
+
47
+ # 序列化为字典(日期转换为字符串)
48
+ serialized = params.describe()
49
+ print(serialized) # 输出: {'symbol': 'AAPL', 'start_date': '2024-01-01', 'limit': 100}
50
+
51
+ # 从字典创建实例
52
+ new_params = Params.from_dict({"ticker": "TSLA", "quantity": 10})
53
+ print(new_params.ticker) # 输出: TSLA
54
+ ```
55
+ """
56
+
57
+ @classmethod
58
+ def from_dict(
59
+ cls,
60
+ data: Dict[str, Any],
61
+ ) -> Params:
62
+ if isinstance(data, Params):
63
+ return data
64
+ return cls(**data)
65
+
66
+ def __init__(
67
+ self,
68
+ **kwargs: Any,
69
+ ) -> None:
70
+ for key, value in kwargs.items():
71
+ setattr(self, key, value)
72
+
73
+ @property
74
+ def identifier(self) -> str:
75
+ result = self.describe()
76
+ dna = json.dumps(
77
+ result,
78
+ sort_keys=True,
79
+ ensure_ascii=False,
80
+ separators=(",", ":"),
81
+ )
82
+ return hashlib.sha256(dna.encode("utf-8")).hexdigest()
83
+
84
+ def __contains__(
85
+ self,
86
+ key: str,
87
+ ) -> bool:
88
+ return hasattr(self, key)
89
+
90
+ def __str__(self) -> str:
91
+ return str(self.to_dict())
92
+
93
+ def __repr__(self) -> str:
94
+ return f"{self.__class__.__name__}({self.to_dict()})"
95
+
96
+ def keys(self) -> Any:
97
+ result = []
98
+ for key in self.__dict__.keys():
99
+ if not key.startswith("_"):
100
+ result.append(key)
101
+ return result
102
+
103
+ def values(self) -> Any:
104
+ result = []
105
+ for key, value in self.__dict__.items():
106
+ if not key.startswith("_"):
107
+ result.append(value)
108
+ return result
109
+
110
+ def get(
111
+ self,
112
+ key: str,
113
+ default: Optional[Any] = None,
114
+ ) -> Any:
115
+ return getattr(self, key, default)
116
+
117
+ def set(
118
+ self,
119
+ key: str,
120
+ value: Any,
121
+ ) -> None:
122
+ setattr(self, key, value)
123
+
124
+ def items(
125
+ self,
126
+ ) -> Dict[str, Any]:
127
+ result = {}
128
+ for key, value in self.__dict__.items():
129
+ if not key.startswith("_"):
130
+ result[key] = value
131
+ return result
132
+
133
+ @staticmethod
134
+ def ensure_serialisable(
135
+ value: Any,
136
+ ) -> Any:
137
+ if isinstance(value, datetime):
138
+ return value.strftime("%Y-%m-%d")
139
+ elif isinstance(value, Params):
140
+ return value.to_dict()
141
+ elif isinstance(value, dict):
142
+ return {k: Params.ensure_serialisable(v) for k, v in value.items()}
143
+ elif isinstance(value, list):
144
+ return [Params.ensure_serialisable(v) for v in value]
145
+ elif isinstance(value, (int, float, str, bool, type(None))):
146
+ return value
147
+ else:
148
+ return str(value)
149
+
150
+ def describe(self) -> Dict[str, Any]:
151
+ result = {}
152
+ for key, value in self.__dict__.items():
153
+ if not key.startswith("_"):
154
+ result[key] = self.ensure_serialisable(value)
155
+ return result
156
+
157
+ def to_dict(self) -> Dict[str, Any]:
158
+ result = {}
159
+ for key, value in self.__dict__.items():
160
+ if not key.startswith("_"):
161
+ result[key] = value
162
+ return result
@@ -0,0 +1,201 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import wraps
4
+ from typing import Any, Callable, Dict, Iterable, List, Tuple, Type
5
+
6
+ import backoff
7
+
8
+
9
+ class Retry:
10
+ """
11
+ 描述:
12
+ - 函数重试装饰器类,用于自动重试失败的函数调用。
13
+ - 支持固定间隔和指数退避两种重试策略。
14
+ - 可配置重试次数、等待时间、退避系数和异常类型。
15
+ - 支持添加随机抖动(jitter)以避免重试风暴。
16
+ - 基于 backoff 库实现,提供可靠的重试机制。
17
+
18
+ 属性:
19
+ - retry: int, 最大重试次数,0 表示不重试。
20
+ - wait: float, 等待时间(秒),在固定间隔模式下为间隔时间,在指数退避模式下为基础时间。
21
+ - rate: float, 退避系数,1.0 使用固定间隔,其他值使用指数退避。
22
+ - exceptions: tuple[Type[BaseException], ...], 需要触发重试的异常类型元组。
23
+ - jitter: bool, 是否启用随机抖动。
24
+ - jitter_fn: Callable[[float], float] | None, 抖动函数,None 表示不使用抖动。
25
+
26
+ 方法:
27
+ - __call__(func): 装饰器方法,将重试逻辑应用到目标函数。
28
+ - __str__(): 返回重试次数的字符串表示。
29
+ - __repr__(): 返回对象的完整字符串表示。
30
+ - describe(): 返回配置信息的字典。
31
+ - to_dict(): 返回包含所有配置信息的字典。
32
+
33
+ 例子:
34
+ ```python
35
+ from xfintech.data.common.retry import Retry
36
+
37
+ # 指数退避重试
38
+ @Retry(retry=5, wait=1.0, rate=2.0)
39
+ def api_call():
40
+ # 失败时等待时间:1s, 2s, 4s, 8s, 16s
41
+ return "API 响应"
42
+
43
+ # 不使用抖动
44
+ @Retry(retry=3, wait=1.0, jitter=False)
45
+ def precise_timing_call():
46
+ # 精确的固定间隔,无随机抖动
47
+ return "结果"
48
+
49
+ # 不重试(retry=0)
50
+ @Retry(retry=0)
51
+ def no_retry_func():
52
+ # 等同于没有装饰器,直接执行
53
+ return "立即执行"
54
+
55
+ # 使用 Retry 类作为变量
56
+ def my_function():
57
+ pass
58
+ retry = Retry(retry=3, wait=1.0)
59
+ wrapped = retry(my_function)
60
+ ```
61
+ """
62
+
63
+ DEFAULT_RETRY = 0
64
+ DEFAULT_WAIT = 0.0
65
+ DEFAULT_RATE = 1.0
66
+
67
+ @classmethod
68
+ def from_dict(
69
+ cls,
70
+ data: Dict[str, Any],
71
+ ) -> Retry:
72
+ return cls(
73
+ retry=data.get("retry"),
74
+ wait=data.get("wait"),
75
+ rate=data.get("rate"),
76
+ exceptions=data.get("exceptions"),
77
+ jitter=data.get("jitter"),
78
+ )
79
+
80
+ def __init__(
81
+ self,
82
+ retry: int = 0,
83
+ wait: float = 0,
84
+ rate: float = 1.0,
85
+ exceptions: Iterable[Type[BaseException] | str] = None,
86
+ jitter: bool = True,
87
+ ) -> None:
88
+ self.retry = self._resolve_retry(retry)
89
+ self.wait = self._resolve_wait(wait)
90
+ self.rate = self._resolve_rate(rate)
91
+ self.exceptions = self._resolve_exceptions(exceptions)
92
+ self.jitter = self._resolve_jitter(jitter)
93
+ self.jitter_fn = self._resolve_jitter_fn()
94
+
95
+ def _resolve_retry(
96
+ self,
97
+ retry: int,
98
+ ) -> int:
99
+ if retry is None:
100
+ return self.DEFAULT_RETRY
101
+ else:
102
+ return max(0, retry)
103
+
104
+ def _resolve_wait(
105
+ self,
106
+ wait: float,
107
+ ) -> float:
108
+ if wait is None:
109
+ return self.DEFAULT_WAIT
110
+ return max(0.0, float(wait))
111
+
112
+ def _resolve_rate(
113
+ self,
114
+ rate: float,
115
+ ) -> float:
116
+ if rate is None:
117
+ return self.DEFAULT_RATE
118
+ return max(1.0, float(rate))
119
+
120
+ def _resolve_jitter(
121
+ self,
122
+ jitter: bool,
123
+ ) -> bool:
124
+ if jitter is None:
125
+ return True
126
+ return jitter
127
+
128
+ def _resolve_jitter_fn(
129
+ self,
130
+ ) -> Callable[[float], float] | None:
131
+ if self.jitter:
132
+ return backoff.full_jitter
133
+ return None
134
+
135
+ def _resolve_exceptions(
136
+ self,
137
+ exceptions: Iterable[Type[BaseException] | str] | None,
138
+ ) -> Tuple[Type[BaseException], ...]:
139
+ if not exceptions:
140
+ return (Exception,)
141
+ resolved: List[Type[BaseException]] = []
142
+ for exc in exceptions:
143
+ if isinstance(exc, str):
144
+ exc_type = globals().get(exc)
145
+ if exc_type and issubclass(exc_type, BaseException):
146
+ resolved.append(exc_type)
147
+ elif issubclass(exc, BaseException):
148
+ resolved.append(exc)
149
+ return tuple(resolved)
150
+
151
+ def __call__(
152
+ self,
153
+ func: Callable,
154
+ ) -> Callable:
155
+ if self.retry <= 0:
156
+ return func
157
+ if self.rate == 1.0:
158
+ deco = backoff.on_exception(
159
+ backoff.constant,
160
+ self.exceptions,
161
+ max_tries=self.retry,
162
+ interval=self.wait,
163
+ jitter=self.jitter_fn,
164
+ )
165
+ else:
166
+ deco = backoff.on_exception(
167
+ backoff.expo,
168
+ self.exceptions,
169
+ max_tries=self.retry,
170
+ base=self.wait,
171
+ factor=self.rate,
172
+ jitter=self.jitter_fn,
173
+ )
174
+ wrapped_function = deco(func)
175
+
176
+ @wraps(func)
177
+ def wrapper(*args, **kwargs):
178
+ return wrapped_function(*args, **kwargs)
179
+
180
+ return wrapper
181
+
182
+ def __str__(self) -> str:
183
+ return f"{self.retry}"
184
+
185
+ def __repr__(self) -> str:
186
+ return (
187
+ f"{self.__class__.__name__}(retry={self.retry}, "
188
+ f"wait={self.wait}, rate={self.rate}, "
189
+ f"exceptions={self.exceptions})"
190
+ )
191
+
192
+ def describe(self) -> Dict[str, Any]:
193
+ return self.to_dict()
194
+
195
+ def to_dict(self) -> Dict[str, Any]:
196
+ return {
197
+ "retry": self.retry,
198
+ "wait": self.wait,
199
+ "rate": self.rate,
200
+ "exceptions": [exc.__name__ for exc in self.exceptions],
201
+ }
@@ -0,0 +1 @@
1
+ # Test package for xfintech.data.common module