fin-infra 0.1.86__tar.gz → 0.1.88__tar.gz

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 (180) hide show
  1. {fin_infra-0.1.86 → fin_infra-0.1.88}/PKG-INFO +8 -3
  2. {fin_infra-0.1.86 → fin_infra-0.1.88}/README.md +7 -2
  3. {fin_infra-0.1.86 → fin_infra-0.1.88}/pyproject.toml +20 -1
  4. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/utils/__init__.py +15 -1
  5. fin_infra-0.1.88/src/fin_infra/utils/deprecation.py +161 -0
  6. {fin_infra-0.1.86 → fin_infra-0.1.88}/LICENSE +0 -0
  7. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/__init__.py +0 -0
  8. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/__main__.py +0 -0
  9. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/__init__.py +0 -0
  10. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/add.py +0 -0
  11. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/cash_flow.py +0 -0
  12. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/ease.py +0 -0
  13. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/models.py +0 -0
  14. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/portfolio.py +0 -0
  15. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/projections.py +0 -0
  16. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/rebalancing.py +0 -0
  17. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/savings.py +0 -0
  18. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/scenarios.py +0 -0
  19. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/analytics/spending.py +0 -0
  20. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/banking/__init__.py +0 -0
  21. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/banking/history.py +0 -0
  22. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/banking/utils.py +0 -0
  23. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/brokerage/__init__.py +0 -0
  24. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/__init__.py +0 -0
  25. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/add.py +0 -0
  26. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/alerts.py +0 -0
  27. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/ease.py +0 -0
  28. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/models.py +0 -0
  29. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/scaffold_templates/README.md +0 -0
  30. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/scaffold_templates/__init__.py +0 -0
  31. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/scaffold_templates/models.py.tmpl +0 -0
  32. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/scaffold_templates/repository.py.tmpl +0 -0
  33. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/scaffold_templates/schemas.py.tmpl +0 -0
  34. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/templates.py +0 -0
  35. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/budgets/tracker.py +0 -0
  36. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/cashflows/__init__.py +0 -0
  37. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/cashflows/core.py +0 -0
  38. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/__init__.py +0 -0
  39. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/add.py +0 -0
  40. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/ease.py +0 -0
  41. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/engine.py +0 -0
  42. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/llm_layer.py +0 -0
  43. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/models.py +0 -0
  44. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/rules.py +0 -0
  45. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/categorization/taxonomy.py +0 -0
  46. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/chat/__init__.py +0 -0
  47. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/chat/ease.py +0 -0
  48. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/chat/planning.py +0 -0
  49. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/cli/__init__.py +0 -0
  50. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/cli/cmds/__init__.py +0 -0
  51. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/cli/cmds/scaffold_cmds.py +0 -0
  52. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/clients/__init__.py +0 -0
  53. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/clients/base.py +0 -0
  54. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/clients/plaid.py +0 -0
  55. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/compliance/__init__.py +0 -0
  56. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/__init__.py +0 -0
  57. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/add.py +0 -0
  58. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/experian/__init__.py +0 -0
  59. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/experian/auth.py +0 -0
  60. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/experian/client.py +0 -0
  61. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/experian/parser.py +0 -0
  62. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/experian/provider.py +0 -0
  63. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/credit/mock.py +0 -0
  64. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/crypto/__init__.py +0 -0
  65. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/crypto/insights.py +0 -0
  66. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/__init__.py +0 -0
  67. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/add.py +0 -0
  68. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/analysis.py +0 -0
  69. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/ease.py +0 -0
  70. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/models.py +0 -0
  71. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/ocr.py +0 -0
  72. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/documents/storage.py +0 -0
  73. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/exceptions.py +0 -0
  74. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/__init__.py +0 -0
  75. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/add.py +0 -0
  76. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/funding.py +0 -0
  77. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/management.py +0 -0
  78. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/milestones.py +0 -0
  79. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/models.py +0 -0
  80. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/scaffold_templates/README.md +0 -0
  81. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/scaffold_templates/__init__.py +0 -0
  82. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/scaffold_templates/models.py.tmpl +0 -0
  83. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/scaffold_templates/repository.py.tmpl +0 -0
  84. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/goals/scaffold_templates/schemas.py.tmpl +0 -0
  85. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/insights/__init__.py +0 -0
  86. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/insights/aggregator.py +0 -0
  87. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/insights/models.py +0 -0
  88. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/__init__.py +0 -0
  89. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/add.py +0 -0
  90. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/ease.py +0 -0
  91. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/models.py +0 -0
  92. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/providers/__init__.py +0 -0
  93. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/providers/base.py +0 -0
  94. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/providers/plaid.py +0 -0
  95. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/providers/snaptrade.py +0 -0
  96. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/scaffold_templates/README.md +0 -0
  97. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/scaffold_templates/__init__.py +0 -0
  98. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/scaffold_templates/models.py.tmpl +0 -0
  99. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/scaffold_templates/repository.py.tmpl +0 -0
  100. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/investments/scaffold_templates/schemas.py.tmpl +0 -0
  101. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/markets/__init__.py +0 -0
  102. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/__init__.py +0 -0
  103. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/accounts.py +0 -0
  104. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/brokerage.py +0 -0
  105. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/candle.py +0 -0
  106. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/credit.py +0 -0
  107. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/money.py +0 -0
  108. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/quotes.py +0 -0
  109. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/tax.py +0 -0
  110. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/models/transactions.py +0 -0
  111. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/__init__.py +0 -0
  112. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/add.py +0 -0
  113. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/aggregator.py +0 -0
  114. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/calculator.py +0 -0
  115. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/ease.py +0 -0
  116. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/goals.py +0 -0
  117. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/insights.py +0 -0
  118. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/models.py +0 -0
  119. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/scaffold_templates/README.md +0 -0
  120. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/scaffold_templates/__init__.py +0 -0
  121. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/scaffold_templates/models.py.tmpl +0 -0
  122. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/scaffold_templates/repository.py.tmpl +0 -0
  123. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/net_worth/scaffold_templates/schemas.py.tmpl +0 -0
  124. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/__init__.py +0 -0
  125. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/currency_converter.py +0 -0
  126. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/models.py +0 -0
  127. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/providers/__init__.py +0 -0
  128. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/providers/exchangerate.py +0 -0
  129. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/providers/static_mappings.py +0 -0
  130. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/normalization/symbol_resolver.py +0 -0
  131. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/obs/__init__.py +0 -0
  132. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/obs/classifier.py +0 -0
  133. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/__init__.py +0 -0
  134. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/banking/base.py +0 -0
  135. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/banking/plaid_client.py +0 -0
  136. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/banking/teller_client.py +0 -0
  137. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/base.py +0 -0
  138. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/brokerage/alpaca.py +0 -0
  139. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/brokerage/base.py +0 -0
  140. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/credit/experian.py +0 -0
  141. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/identity/stripe_identity.py +0 -0
  142. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/market/alphavantage.py +0 -0
  143. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/market/base.py +0 -0
  144. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/market/ccxt_crypto.py +0 -0
  145. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/market/coingecko.py +0 -0
  146. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/market/yahoo.py +0 -0
  147. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/registry.py +0 -0
  148. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/tax/__init__.py +0 -0
  149. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/tax/irs.py +0 -0
  150. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/tax/mock.py +0 -0
  151. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/providers/tax/taxbit.py +0 -0
  152. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/py.typed +0 -0
  153. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/__init__.py +0 -0
  154. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/add.py +0 -0
  155. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/detector.py +0 -0
  156. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/detectors_llm.py +0 -0
  157. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/ease.py +0 -0
  158. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/insights.py +0 -0
  159. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/models.py +0 -0
  160. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/normalizer.py +0 -0
  161. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/normalizers.py +0 -0
  162. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/recurring/summary.py +0 -0
  163. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/scaffold/__init__.py +0 -0
  164. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/scaffold/budgets.py +0 -0
  165. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/scaffold/goals.py +0 -0
  166. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/__init__.py +0 -0
  167. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/add.py +0 -0
  168. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/audit.py +0 -0
  169. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/encryption.py +0 -0
  170. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/models.py +0 -0
  171. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/pii_filter.py +0 -0
  172. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/pii_patterns.py +0 -0
  173. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/security/token_store.py +0 -0
  174. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/settings.py +0 -0
  175. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/tax/__init__.py +0 -0
  176. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/tax/add.py +0 -0
  177. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/tax/tlh.py +0 -0
  178. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/utils/http.py +0 -0
  179. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/utils/retry.py +0 -0
  180. {fin_infra-0.1.86 → fin_infra-0.1.88}/src/fin_infra/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fin-infra
3
- Version: 0.1.86
3
+ Version: 0.1.88
4
4
  Summary: Financial infrastructure toolkit: banking connections, market data, credit, cashflows, and brokerage integrations
5
5
  License: MIT
6
6
  Keywords: finance,banking,plaid,brokerage,markets,credit,tax,cashflow,fintech,infra
@@ -49,9 +49,14 @@ Description-Content-Type: text/markdown
49
49
 
50
50
  # fin-infra
51
51
 
52
- ### Financial data infrastructure for fintech apps
52
+ [![CI](https://github.com/nfraxlab/fin-infra/actions/workflows/ci.yml/badge.svg)](https://github.com/nfraxlab/fin-infra/actions/workflows/ci.yml)
53
+ [![PyPI](https://img.shields.io/pypi/v/fin-infra.svg)](https://pypi.org/project/fin-infra/)
54
+ [![Python](https://img.shields.io/pypi/pyversions/fin-infra.svg)](https://pypi.org/project/fin-infra/)
55
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
56
+ [![Downloads](https://img.shields.io/pypi/dm/fin-infra.svg)](https://pypi.org/project/fin-infra/)
57
+ [![codecov](https://codecov.io/gh/nfraxlab/fin-infra/branch/main/graph/badge.svg)](https://codecov.io/gh/nfraxlab/fin-infra)
53
58
 
54
- [![PyPI](https://img.shields.io/pypi/v/fin-infra.svg)](https://pypi.org/project/fin-infra/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://static.pepy.tech/badge/fin-infra/month)](https://pepy.tech/project/fin-infra)
59
+ ### Financial data infrastructure for fintech apps
55
60
 
56
61
  **Banking, investments, market data, credit scores, and financial calculations in one toolkit.**
57
62
 
@@ -2,9 +2,14 @@
2
2
 
3
3
  # fin-infra
4
4
 
5
- ### Financial data infrastructure for fintech apps
5
+ [![CI](https://github.com/nfraxlab/fin-infra/actions/workflows/ci.yml/badge.svg)](https://github.com/nfraxlab/fin-infra/actions/workflows/ci.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/fin-infra.svg)](https://pypi.org/project/fin-infra/)
7
+ [![Python](https://img.shields.io/pypi/pyversions/fin-infra.svg)](https://pypi.org/project/fin-infra/)
8
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
+ [![Downloads](https://img.shields.io/pypi/dm/fin-infra.svg)](https://pypi.org/project/fin-infra/)
10
+ [![codecov](https://codecov.io/gh/nfraxlab/fin-infra/branch/main/graph/badge.svg)](https://codecov.io/gh/nfraxlab/fin-infra)
6
11
 
7
- [![PyPI](https://img.shields.io/pypi/v/fin-infra.svg)](https://pypi.org/project/fin-infra/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://static.pepy.tech/badge/fin-infra/month)](https://pepy.tech/project/fin-infra)
12
+ ### Financial data infrastructure for fintech apps
8
13
 
9
14
  **Banking, investments, market data, credit scores, and financial calculations in one toolkit.**
10
15
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "fin-infra"
3
- version = "0.1.86"
3
+ version = "0.1.88"
4
4
  description = "Financial infrastructure toolkit: banking connections, market data, credit, cashflows, and brokerage integrations"
5
5
  authors = ["Ali Khatami <aliikhatami94@gmail.com>"]
6
6
  license = "MIT"
@@ -78,6 +78,7 @@ black = ">=24.0.0"
78
78
  isort = ">=5.13.0"
79
79
  flake8 = ">=7.0.0"
80
80
  pre-commit = ">=3.0.0"
81
+ bandit = ">=1.7.0"
81
82
  types-requests = ">=2.31.0"
82
83
  pytest-cov = ">=4.0.0"
83
84
  aiosqlite = ">=0.20.0"
@@ -150,6 +151,24 @@ known-first-party = ["fin_infra"]
150
151
  [tool.ruff.lint.pydocstyle]
151
152
  convention = "google"
152
153
 
154
+ [tool.bandit]
155
+ exclude_dirs = ["tests", ".venv", "venv"]
156
+ skips = [
157
+ "B101", # assert used (intentional in tests and contracts)
158
+ "B311", # random for non-crypto (intentional)
159
+ "B324", # MD5 hash - used for cache keys only, not security
160
+ ]
161
+
162
+ [tool.coverage.run]
163
+ source = ["src/fin_infra"]
164
+ branch = true
165
+ omit = ["*/tests/*", "*/__pycache__/*"]
166
+
167
+ [tool.coverage.report]
168
+ exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:", "raise NotImplementedError"]
169
+ fail_under = 70
170
+ show_missing = true
171
+
153
172
  [tool.mypy]
154
173
  python_version = "3.13"
155
174
  ignore_missing_imports = true
@@ -10,8 +10,22 @@ and should be imported from there:
10
10
 
11
11
  For async retry with exponential backoff:
12
12
  from fin_infra.utils.retry import retry_async, RetryError
13
+
14
+ For deprecation utilities:
15
+ from fin_infra.utils.deprecation import deprecated, deprecated_parameter
13
16
  """
14
17
 
18
+ from fin_infra.utils.deprecation import (
19
+ DeprecatedWarning,
20
+ deprecated,
21
+ deprecated_parameter,
22
+ )
15
23
  from fin_infra.utils.retry import RetryError, retry_async
16
24
 
17
- __all__ = ["RetryError", "retry_async"]
25
+ __all__ = [
26
+ "RetryError",
27
+ "retry_async",
28
+ "deprecated",
29
+ "deprecated_parameter",
30
+ "DeprecatedWarning",
31
+ ]
@@ -0,0 +1,161 @@
1
+ """Deprecation utilities for fin-infra.
2
+
3
+ This module provides decorators and functions for marking features as deprecated,
4
+ following the deprecation policy defined in DEPRECATION.md.
5
+
6
+ Example:
7
+ >>> from fin_infra.utils.deprecation import deprecated
8
+ >>>
9
+ >>> @deprecated(
10
+ ... version="1.2.0",
11
+ ... reason="Use new_function() instead",
12
+ ... removal_version="1.4.0"
13
+ ... )
14
+ ... def old_function():
15
+ ... pass
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import functools
21
+ import warnings
22
+ from collections.abc import Callable
23
+ from typing import Any, TypeVar
24
+
25
+ __all__ = [
26
+ "deprecated",
27
+ "deprecated_parameter",
28
+ "DeprecatedWarning",
29
+ ]
30
+
31
+ F = TypeVar("F", bound=Callable[..., Any])
32
+
33
+
34
+ class DeprecatedWarning(DeprecationWarning):
35
+ """Custom deprecation warning for fin-infra.
36
+
37
+ This warning is used to distinguish fin-infra deprecations from
38
+ Python's built-in DeprecationWarning.
39
+ """
40
+
41
+ pass
42
+
43
+
44
+ def deprecated(
45
+ version: str,
46
+ reason: str,
47
+ removal_version: str | None = None,
48
+ *,
49
+ stacklevel: int = 2,
50
+ ) -> Callable[[F], F]:
51
+ """Decorator to mark a function or class as deprecated.
52
+
53
+ The decorated function/class will emit a DeprecationWarning when called/instantiated.
54
+
55
+ Args:
56
+ version: The version in which the feature was deprecated (e.g., "1.2.0").
57
+ reason: The reason for deprecation and recommended alternative.
58
+ removal_version: The version in which the feature will be removed (e.g., "1.4.0").
59
+ stacklevel: Stack level for the warning (default 2 for immediate caller).
60
+
61
+ Returns:
62
+ A decorator that wraps the function/class with deprecation warning.
63
+
64
+ Example:
65
+ >>> @deprecated(
66
+ ... version="1.2.0",
67
+ ... reason="Use new_function() instead",
68
+ ... removal_version="1.4.0"
69
+ ... )
70
+ ... def old_function():
71
+ ... return "result"
72
+ >>>
73
+ >>> old_function() # Emits DeprecationWarning
74
+ 'result'
75
+ """
76
+
77
+ def decorator(func: F) -> F:
78
+ # Build the warning message
79
+ name = getattr(func, "__qualname__", getattr(func, "__name__", str(func)))
80
+ message = f"{name} is deprecated since version {version}."
81
+
82
+ if removal_version:
83
+ message += f" It will be removed in version {removal_version}."
84
+
85
+ message += f" {reason}"
86
+
87
+ if isinstance(func, type):
88
+ # Handle class deprecation
89
+ original_init = func.__init__ # type: ignore[misc]
90
+
91
+ @functools.wraps(original_init)
92
+ def new_init(self: Any, *args: Any, **kwargs: Any) -> None:
93
+ warnings.warn(message, DeprecatedWarning, stacklevel=stacklevel)
94
+ original_init(self, *args, **kwargs)
95
+
96
+ func.__init__ = new_init # type: ignore[misc]
97
+
98
+ # Add deprecation info to docstring
99
+ if func.__doc__:
100
+ func.__doc__ = f".. deprecated:: {version}\n {reason}\n\n{func.__doc__}"
101
+ else:
102
+ func.__doc__ = f".. deprecated:: {version}\n {reason}"
103
+
104
+ return func # type: ignore[return-value]
105
+ else:
106
+ # Handle function deprecation
107
+ @functools.wraps(func)
108
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
109
+ warnings.warn(message, DeprecatedWarning, stacklevel=stacklevel)
110
+ return func(*args, **kwargs)
111
+
112
+ # Add deprecation info to docstring
113
+ if wrapper.__doc__:
114
+ wrapper.__doc__ = f".. deprecated:: {version}\n {reason}\n\n{wrapper.__doc__}"
115
+ else:
116
+ wrapper.__doc__ = f".. deprecated:: {version}\n {reason}"
117
+
118
+ return wrapper # type: ignore[return-value]
119
+
120
+ return decorator
121
+
122
+
123
+ def deprecated_parameter(
124
+ name: str,
125
+ version: str,
126
+ reason: str,
127
+ removal_version: str | None = None,
128
+ *,
129
+ stacklevel: int = 2,
130
+ ) -> None:
131
+ """Emit a deprecation warning for a deprecated parameter.
132
+
133
+ Call this function when a deprecated parameter is used. This should be
134
+ called at the beginning of a function that has deprecated parameters.
135
+
136
+ Args:
137
+ name: The name of the deprecated parameter.
138
+ version: The version in which the parameter was deprecated.
139
+ reason: The reason for deprecation and recommended alternative.
140
+ removal_version: The version in which the parameter will be removed.
141
+ stacklevel: Stack level for the warning (default 2 for immediate caller).
142
+
143
+ Example:
144
+ >>> def my_function(new_param: str, old_param: str | None = None):
145
+ ... if old_param is not None:
146
+ ... deprecated_parameter(
147
+ ... name="old_param",
148
+ ... version="1.2.0",
149
+ ... reason="Use new_param instead"
150
+ ... )
151
+ ... new_param = old_param
152
+ ... return new_param
153
+ """
154
+ message = f"Parameter '{name}' is deprecated since version {version}."
155
+
156
+ if removal_version:
157
+ message += f" It will be removed in version {removal_version}."
158
+
159
+ message += f" {reason}"
160
+
161
+ warnings.warn(message, DeprecatedWarning, stacklevel=stacklevel + 1)
File without changes