fin-infra 0.1.66__py3-none-any.whl → 0.1.68__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.
- fin_infra/analytics/add.py +9 -11
- fin_infra/analytics/portfolio.py +12 -18
- fin_infra/analytics/rebalancing.py +2 -4
- fin_infra/analytics/savings.py +1 -1
- fin_infra/analytics/spending.py +3 -1
- fin_infra/banking/history.py +3 -3
- fin_infra/banking/utils.py +88 -82
- fin_infra/brokerage/__init__.py +1 -1
- fin_infra/budgets/tracker.py +2 -3
- fin_infra/categorization/ease.py +2 -3
- fin_infra/categorization/llm_layer.py +2 -2
- fin_infra/cli/cmds/scaffold_cmds.py +1 -1
- fin_infra/credit/experian/provider.py +14 -14
- fin_infra/crypto/__init__.py +1 -1
- fin_infra/documents/add.py +4 -4
- fin_infra/documents/ease.py +4 -3
- fin_infra/documents/models.py +3 -3
- fin_infra/documents/ocr.py +1 -1
- fin_infra/documents/storage.py +2 -1
- fin_infra/exceptions.py +1 -1
- fin_infra/goals/management.py +3 -3
- fin_infra/insights/__init__.py +0 -1
- fin_infra/investments/__init__.py +2 -4
- fin_infra/investments/add.py +37 -56
- fin_infra/investments/ease.py +7 -8
- fin_infra/investments/models.py +29 -17
- fin_infra/investments/providers/base.py +3 -8
- fin_infra/investments/providers/plaid.py +19 -29
- fin_infra/investments/providers/snaptrade.py +18 -36
- fin_infra/markets/__init__.py +4 -2
- fin_infra/models/accounts.py +2 -1
- fin_infra/models/transactions.py +2 -1
- fin_infra/net_worth/calculator.py +8 -6
- fin_infra/net_worth/ease.py +2 -2
- fin_infra/net_worth/insights.py +4 -4
- fin_infra/normalization/__init__.py +3 -1
- fin_infra/providers/banking/plaid_client.py +16 -16
- fin_infra/providers/base.py +5 -5
- fin_infra/providers/brokerage/alpaca.py +2 -2
- fin_infra/providers/market/ccxt_crypto.py +4 -1
- fin_infra/recurring/add.py +3 -1
- fin_infra/recurring/detector.py +1 -1
- fin_infra/recurring/normalizer.py +1 -1
- fin_infra/scaffold/__init__.py +1 -1
- fin_infra/tax/__init__.py +1 -1
- {fin_infra-0.1.66.dist-info → fin_infra-0.1.68.dist-info}/METADATA +1 -1
- {fin_infra-0.1.66.dist-info → fin_infra-0.1.68.dist-info}/RECORD +50 -50
- {fin_infra-0.1.66.dist-info → fin_infra-0.1.68.dist-info}/LICENSE +0 -0
- {fin_infra-0.1.66.dist-info → fin_infra-0.1.68.dist-info}/WHEEL +0 -0
- {fin_infra-0.1.66.dist-info → fin_infra-0.1.68.dist-info}/entry_points.txt +0 -0
|
@@ -34,7 +34,7 @@ class PlaidClient(BankingProvider):
|
|
|
34
34
|
environment: str | None = None,
|
|
35
35
|
) -> None:
|
|
36
36
|
"""Initialize Plaid client with either Settings object or individual parameters.
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
Args:
|
|
39
39
|
settings: Settings object (legacy pattern)
|
|
40
40
|
client_id: Plaid client ID (preferred - from env or passed directly)
|
|
@@ -45,14 +45,14 @@ class PlaidClient(BankingProvider):
|
|
|
45
45
|
raise RuntimeError(
|
|
46
46
|
"plaid-python SDK not available or import failed; check installed version (requires v25+)"
|
|
47
47
|
)
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
# Support both patterns: Settings object or individual params
|
|
50
50
|
if settings is not None:
|
|
51
51
|
# Legacy pattern with Settings object
|
|
52
52
|
client_id = client_id or settings.plaid_client_id
|
|
53
53
|
secret = secret or settings.plaid_secret
|
|
54
54
|
environment = environment or settings.plaid_env
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
# Map environment string to Plaid Environment enum
|
|
57
57
|
# Note: Plaid only has Sandbox and Production (no Development in SDK)
|
|
58
58
|
env_str = environment or "sandbox"
|
|
@@ -61,22 +61,22 @@ class PlaidClient(BankingProvider):
|
|
|
61
61
|
"development": plaid.Environment.Sandbox, # Map development to sandbox (Plaid SDK limitation)
|
|
62
62
|
"production": plaid.Environment.Production,
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
if env_str not in env_map:
|
|
66
66
|
raise ValueError(
|
|
67
67
|
f"Invalid Plaid environment: '{env_str}'. "
|
|
68
68
|
f"Must be one of: sandbox, development, production"
|
|
69
69
|
)
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
host = env_map[env_str]
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
# Configure Plaid client (v8.0.0+ API)
|
|
74
74
|
configuration = plaid.Configuration(
|
|
75
75
|
host=host,
|
|
76
76
|
api_key={
|
|
77
77
|
"clientId": client_id,
|
|
78
78
|
"secret": secret,
|
|
79
|
-
}
|
|
79
|
+
},
|
|
80
80
|
)
|
|
81
81
|
api_client = plaid.ApiClient(configuration)
|
|
82
82
|
self.client = plaid_api.PlaidApi(api_client)
|
|
@@ -86,12 +86,12 @@ class PlaidClient(BankingProvider):
|
|
|
86
86
|
user=LinkTokenCreateRequestUser(client_user_id=user_id),
|
|
87
87
|
client_name="fin-infra",
|
|
88
88
|
products=[
|
|
89
|
-
Products("auth"),
|
|
90
|
-
Products("transactions"),
|
|
91
|
-
Products("liabilities"),
|
|
92
|
-
Products("investments"),
|
|
93
|
-
Products("assets"),
|
|
94
|
-
Products("identity"),
|
|
89
|
+
Products("auth"), # Account/routing numbers for ACH
|
|
90
|
+
Products("transactions"), # Transaction history
|
|
91
|
+
Products("liabilities"), # Credit cards, loans, student loans
|
|
92
|
+
Products("investments"), # Brokerage, retirement accounts
|
|
93
|
+
Products("assets"), # Asset reports for lending/verification
|
|
94
|
+
Products("identity"), # Account holder info (name, email, phone)
|
|
95
95
|
],
|
|
96
96
|
country_codes=[CountryCode("US")],
|
|
97
97
|
language="en",
|
|
@@ -122,7 +122,7 @@ class PlaidClient(BankingProvider):
|
|
|
122
122
|
start = end - timedelta(days=30)
|
|
123
123
|
start_date = start_date or start.isoformat()
|
|
124
124
|
end_date = end_date or end.isoformat()
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
request = TransactionsGetRequest(
|
|
127
127
|
access_token=access_token,
|
|
128
128
|
start_date=date.fromisoformat(start_date),
|
|
@@ -136,14 +136,14 @@ class PlaidClient(BankingProvider):
|
|
|
136
136
|
request = AccountsBalanceGetRequest(access_token=access_token)
|
|
137
137
|
response = self.client.accounts_balance_get(request)
|
|
138
138
|
accounts = [acc.to_dict() for acc in response["accounts"]]
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
if account_id:
|
|
141
141
|
# Filter to specific account
|
|
142
142
|
for account in accounts:
|
|
143
143
|
if account.get("account_id") == account_id:
|
|
144
144
|
return {"balances": [account.get("balances", {})]}
|
|
145
145
|
return {"balances": []}
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
# Return all balances
|
|
148
148
|
return {"balances": [acc.get("balances", {}) for acc in accounts]}
|
|
149
149
|
|
fin_infra/providers/base.py
CHANGED
|
@@ -205,27 +205,27 @@ class TaxProvider(ABC):
|
|
|
205
205
|
|
|
206
206
|
class InvestmentProvider(ABC):
|
|
207
207
|
"""Provider for investment holdings and portfolio data (Plaid, SnapTrade).
|
|
208
|
-
|
|
208
|
+
|
|
209
209
|
This is a minimal ABC for type checking. The full implementation with
|
|
210
210
|
all abstract methods is in fin_infra.investments.providers.base.InvestmentProvider.
|
|
211
|
-
|
|
211
|
+
|
|
212
212
|
Abstract Methods (defined in full implementation):
|
|
213
213
|
- get_holdings(access_token, account_ids) -> List[Holding]
|
|
214
214
|
- get_transactions(access_token, start_date, end_date, account_ids) -> List[InvestmentTransaction]
|
|
215
215
|
- get_securities(access_token, security_ids) -> List[Security]
|
|
216
216
|
- get_investment_accounts(access_token) -> List[InvestmentAccount]
|
|
217
|
-
|
|
217
|
+
|
|
218
218
|
Example:
|
|
219
219
|
>>> from fin_infra.investments import easy_investments
|
|
220
220
|
>>> provider = easy_investments(provider="plaid")
|
|
221
221
|
>>> holdings = await provider.get_holdings(access_token)
|
|
222
222
|
"""
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
@abstractmethod
|
|
225
225
|
async def get_holdings(self, access_token: str, account_ids: list[str] | None = None) -> list:
|
|
226
226
|
"""Fetch holdings for investment accounts."""
|
|
227
227
|
pass
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
@abstractmethod
|
|
230
230
|
async def get_investment_accounts(self, access_token: str) -> list:
|
|
231
231
|
"""Fetch investment accounts with aggregated holdings."""
|
|
@@ -55,8 +55,7 @@ class AlpacaBrokerage(BrokerageProvider):
|
|
|
55
55
|
) -> None:
|
|
56
56
|
if not ALPACA_AVAILABLE:
|
|
57
57
|
raise ImportError(
|
|
58
|
-
"alpaca-trade-api is not installed. "
|
|
59
|
-
"Install it with: pip install alpaca-trade-api"
|
|
58
|
+
"alpaca-trade-api is not installed. Install it with: pip install alpaca-trade-api"
|
|
60
59
|
)
|
|
61
60
|
|
|
62
61
|
# Get credentials from args or environment
|
|
@@ -128,6 +127,7 @@ class AlpacaBrokerage(BrokerageProvider):
|
|
|
128
127
|
# Without this, network retries can cause duplicate order execution = MONEY LOSS.
|
|
129
128
|
if client_order_id is None:
|
|
130
129
|
import uuid
|
|
130
|
+
|
|
131
131
|
client_order_id = str(uuid.uuid4())
|
|
132
132
|
|
|
133
133
|
order = self.client.submit_order(
|
|
@@ -27,4 +27,7 @@ class CCXTCryptoData(CryptoDataProvider):
|
|
|
27
27
|
if not self._markets_loaded:
|
|
28
28
|
self.exchange.load_markets()
|
|
29
29
|
self._markets_loaded = True
|
|
30
|
-
return cast(
|
|
30
|
+
return cast(
|
|
31
|
+
list[list[float]],
|
|
32
|
+
self.exchange.fetch_ohlcv(symbol_pair, timeframe=timeframe, limit=limit),
|
|
33
|
+
)
|
fin_infra/recurring/add.py
CHANGED
|
@@ -321,7 +321,9 @@ def add_recurring_detection(
|
|
|
321
321
|
from .summary import get_recurring_summary
|
|
322
322
|
|
|
323
323
|
# Get detected patterns for user
|
|
324
|
-
transactions: list[
|
|
324
|
+
transactions: list[
|
|
325
|
+
dict[str, Any]
|
|
326
|
+
] = [] # Placeholder - in production: get_user_transactions(user_id)
|
|
325
327
|
patterns = detector.detect_patterns(transactions)
|
|
326
328
|
|
|
327
329
|
# Generate summary
|
fin_infra/recurring/detector.py
CHANGED
|
@@ -450,7 +450,7 @@ class PatternDetector:
|
|
|
450
450
|
min_amt, max_amt = pattern.amount_range or (0, 0)
|
|
451
451
|
return (
|
|
452
452
|
f"Variable amount ${min_amt:.2f}-${max_amt:.2f} charged {pattern.cadence.value} "
|
|
453
|
-
f"({pattern.amount_variance_pct*100:.1f}% variance, "
|
|
453
|
+
f"({pattern.amount_variance_pct * 100:.1f}% variance, "
|
|
454
454
|
f"{pattern.occurrence_count} occurrences)"
|
|
455
455
|
)
|
|
456
456
|
else: # IRREGULAR
|
|
@@ -96,7 +96,7 @@ class FuzzyMatcher:
|
|
|
96
96
|
"""
|
|
97
97
|
if not RAPIDFUZZ_AVAILABLE:
|
|
98
98
|
raise ImportError(
|
|
99
|
-
"rapidfuzz is required for fuzzy matching.
|
|
99
|
+
"rapidfuzz is required for fuzzy matching. Install with: pip install rapidfuzz"
|
|
100
100
|
)
|
|
101
101
|
self.similarity_threshold = similarity_threshold
|
|
102
102
|
|
fin_infra/scaffold/__init__.py
CHANGED
fin_infra/tax/__init__.py
CHANGED
|
@@ -144,7 +144,7 @@ def easy_tax(provider: str | TaxProvider = "mock", **config) -> TaxProvider:
|
|
|
144
144
|
|
|
145
145
|
else:
|
|
146
146
|
raise ValueError(
|
|
147
|
-
f"Unknown tax provider: {provider}.
|
|
147
|
+
f"Unknown tax provider: {provider}. Supported providers: 'mock', 'irs', 'taxbit'"
|
|
148
148
|
)
|
|
149
149
|
|
|
150
150
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fin-infra
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.68
|
|
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
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
fin_infra/__init__.py,sha256=5vcHN0u9CE43mnK2VgiMyWTiyANupUISawvxx-2AfqE,480
|
|
2
2
|
fin_infra/__main__.py,sha256=1qNP7j0ffw0wFs1dBwDcJ9TNXlC6FcYuulzoV87pMi8,262
|
|
3
3
|
fin_infra/analytics/__init__.py,sha256=aiuNnii0vc34XlNzrSiMbz33lzgmR7W1nHkmAEXavCY,1870
|
|
4
|
-
fin_infra/analytics/add.py,sha256=
|
|
4
|
+
fin_infra/analytics/add.py,sha256=YhNxFAH0m-GiLxgNzwZY09wt6kmy4n88Xa9DrYBLB6E,12709
|
|
5
5
|
fin_infra/analytics/cash_flow.py,sha256=lH-J6RIUzcV9Fuy56i12N6vuIdPaGz-rhWquSgjkldU,10300
|
|
6
6
|
fin_infra/analytics/ease.py,sha256=p8WwFP4ivvFsvZzYRCZZVHgnPThiODve9r4-m0xnxQQ,14343
|
|
7
7
|
fin_infra/analytics/models.py,sha256=cK6VKLZ763zXfn9REXOnLGx0v3Q8bUa-vH8aoNs2w-A,8215
|
|
8
|
-
fin_infra/analytics/portfolio.py,sha256
|
|
8
|
+
fin_infra/analytics/portfolio.py,sha256=-QAG1HCTXPZPgZ0rD4076B-_jLxPcTJBjvseYeZ3Kqk,26459
|
|
9
9
|
fin_infra/analytics/projections.py,sha256=7cuG6w1KXq8sd3UNufu5aOcxG5n-foswrHqrgWWKQUM,9186
|
|
10
|
-
fin_infra/analytics/rebalancing.py,sha256=
|
|
11
|
-
fin_infra/analytics/savings.py,sha256=
|
|
10
|
+
fin_infra/analytics/rebalancing.py,sha256=VM8MgoJofmrCXPK1rbmVqWGB4FauNmHCL5HOEbrZR2g,14610
|
|
11
|
+
fin_infra/analytics/savings.py,sha256=n3rGNFP8TU5mW-uz9kOuqX_mDiVnDyAeDN06Q7Abotw,7570
|
|
12
12
|
fin_infra/analytics/scenarios.py,sha256=LE_dZVkbxxAx5sxitGhiOhZfWTlYtVbIvS9pEXkijLc,12246
|
|
13
|
-
fin_infra/analytics/spending.py,sha256=
|
|
13
|
+
fin_infra/analytics/spending.py,sha256=wCa8mhtdMTnI3eG9W28ljCgB_AQRVGxkrRA2ZwLi_RQ,26249
|
|
14
14
|
fin_infra/banking/__init__.py,sha256=6brdnsK6ddLhypk4h0sblM1yv6BkQ46Nyq8Zvf5AewY,22570
|
|
15
|
-
fin_infra/banking/history.py,sha256=
|
|
16
|
-
fin_infra/banking/utils.py,sha256=
|
|
17
|
-
fin_infra/brokerage/__init__.py,sha256=
|
|
15
|
+
fin_infra/banking/history.py,sha256=2C3R9rZMYSyPtR0oe-kCZ14SMhPAy_M9v_Xc5XzBVLs,10618
|
|
16
|
+
fin_infra/banking/utils.py,sha256=mCDwU34SpwTqeXoDYhNGAUqxooVxW6TAtqYorzFmPfQ,15341
|
|
17
|
+
fin_infra/brokerage/__init__.py,sha256=8-q1NfKZW9fUQ_2_49Vc19sskZkmHo67TJ5GQDcXqTQ,17259
|
|
18
18
|
fin_infra/budgets/__init__.py,sha256=V6euagDkFHvWyjHeI64fxfddhOHDlIWwOc-PnTyyQb4,3986
|
|
19
19
|
fin_infra/budgets/add.py,sha256=tdfNXD9deEEzy0xCRbTwbx70SX9wiJkWj0Huk_uCjFg,13584
|
|
20
20
|
fin_infra/budgets/alerts.py,sha256=i0lQa3mLWuLQorWL-77VKhXQG2F_0U1cpdZnK3g1y3M,9720
|
|
@@ -26,14 +26,14 @@ fin_infra/budgets/scaffold_templates/models.py.tmpl,sha256=rpKhXwnx1gQjV_GGVqs8C
|
|
|
26
26
|
fin_infra/budgets/scaffold_templates/repository.py.tmpl,sha256=khFgnQnVNnOo8DWYDmYz58MvdeSJpoS9QvTXcGhsa8g,10023
|
|
27
27
|
fin_infra/budgets/scaffold_templates/schemas.py.tmpl,sha256=x5gSQ7Kiuq08tum5joKmeY0ib2r3ekLKk09dFOl0PS0,5658
|
|
28
28
|
fin_infra/budgets/templates.py,sha256=Sbc7RcHXscq34g4t7J8OXM2Kfkt5DHuvqVnFU0Jiddc,12112
|
|
29
|
-
fin_infra/budgets/tracker.py,sha256=
|
|
29
|
+
fin_infra/budgets/tracker.py,sha256=mSa4K8_OxV0lZ9hIeBGrNh_5mytMaFDiPxQaehSODSE,16466
|
|
30
30
|
fin_infra/cashflows/__init__.py,sha256=zwuST5PYHJHXwfqKaKo19ubvD0T3lR54RVOvzjOCNPI,8521
|
|
31
31
|
fin_infra/cashflows/core.py,sha256=Or0hPqCvY_ypV0YiMXh-mle6xWK0tE8WuPPAqHGUp8E,532
|
|
32
32
|
fin_infra/categorization/__init__.py,sha256=efLje12AW-ec9Vs5ynb41r4XCIWx5a-Z9WoGb3kQdIE,2030
|
|
33
33
|
fin_infra/categorization/add.py,sha256=JDOvxngh-7oWHTddOyP4GAse9vLuxSTfoIhrDKUHOKg,6278
|
|
34
|
-
fin_infra/categorization/ease.py,sha256=
|
|
34
|
+
fin_infra/categorization/ease.py,sha256=bomEtJAgwk9uiemNt1rk-IsTjJIhyJn0GJ_c58YEmJs,5836
|
|
35
35
|
fin_infra/categorization/engine.py,sha256=Qk14HQQB6rBwEZ0cSz47l_jD4eFpWlSJzHg8kjC0KK8,12107
|
|
36
|
-
fin_infra/categorization/llm_layer.py,sha256=
|
|
36
|
+
fin_infra/categorization/llm_layer.py,sha256=KbX7o2c-BqWDbPdQXD6qxk98gHRNtEDvf3-Q3kniT9k,12699
|
|
37
37
|
fin_infra/categorization/models.py,sha256=-rGXR0RW2EU_FQ7ZfDWBIXxx8QGJDxeBF9zKGYyVgqY,5931
|
|
38
38
|
fin_infra/categorization/rules.py,sha256=m3OogJY0hJe5BrmZqOvOKS2-HRdW4Y5jvvtlPDn9Pn8,12884
|
|
39
39
|
fin_infra/categorization/taxonomy.py,sha256=qsgo7VJkM6GFBBOaTRHWP82vl5SinRKnMsj4ICarEyQ,13281
|
|
@@ -42,7 +42,7 @@ fin_infra/chat/ease.py,sha256=8T0BQUkWQVpaTooD5-ZtinackkciqGargXnzWzayj3M,3113
|
|
|
42
42
|
fin_infra/chat/planning.py,sha256=eKUW6VDHJS-xQTks7bgjNQaO32Fr5gA_oP5NLt2y5Zs,19916
|
|
43
43
|
fin_infra/cli/__init__.py,sha256=7M8gKULnui4__9kXRKRHgETuFwZlacK9xrq5rSZ31CM,376
|
|
44
44
|
fin_infra/cli/cmds/__init__.py,sha256=BvL3wRoUl3cO5wesv1Cqoatup7VeYMhq82tS19iNZHE,136
|
|
45
|
-
fin_infra/cli/cmds/scaffold_cmds.py,sha256=
|
|
45
|
+
fin_infra/cli/cmds/scaffold_cmds.py,sha256=SwNE8AnszmsjyUXDpmn-bauQx8HAQB_fw-6er2QaTCU,7655
|
|
46
46
|
fin_infra/clients/__init__.py,sha256=EiKkAW8WY5dWtu7DDmpf3DBNcjJArxcQnE_wTAtVRho,129
|
|
47
47
|
fin_infra/clients/base.py,sha256=K5nI4GJzT36oUUYGynV3b4eywJdTTa5EX26QK7XdTcc,970
|
|
48
48
|
fin_infra/clients/plaid.py,sha256=jwcLdQe0G7afLO5JH5jsBosE4iz_cFsb04I8_hCbIb0,807
|
|
@@ -53,22 +53,22 @@ fin_infra/credit/experian/__init__.py,sha256=g3IJGvDOMsnB0er0Uwdvl6hGKKTOazqJxSD
|
|
|
53
53
|
fin_infra/credit/experian/auth.py,sha256=e9AF-HCNga-561END4kOYtANUvPKLfK1HUoFA-jpBys,5608
|
|
54
54
|
fin_infra/credit/experian/client.py,sha256=p_NUMNyEpXEAoXTQo91je12bysn_EswbJxJOzGIwsO0,8643
|
|
55
55
|
fin_infra/credit/experian/parser.py,sha256=7ptdLyTWWqHWqCo1CXn6L7XaIn9ZRRuOaATbFmMZZ64,7489
|
|
56
|
-
fin_infra/credit/experian/provider.py,sha256=
|
|
56
|
+
fin_infra/credit/experian/provider.py,sha256=QqnxFN0WIKyxV5y5jzIB_gv2djNpR-rTUiIhMtTWq8k,13701
|
|
57
57
|
fin_infra/credit/mock.py,sha256=xKWZk3fhuIYRfiZkNc9fbHUNViNKjmOLSj0MTI1f4ik,5356
|
|
58
|
-
fin_infra/crypto/__init__.py,sha256=
|
|
58
|
+
fin_infra/crypto/__init__.py,sha256=p-gEoF59XzyV1RouubW4onl5mE62XvXSAw9isMc48qc,8314
|
|
59
59
|
fin_infra/crypto/insights.py,sha256=BBC7SSxD6FJAXKPvOkC8KK4HNy7Gtzfn0egUx_wzVJM,11444
|
|
60
60
|
fin_infra/documents/__init__.py,sha256=Ub1hbX3PTrBSsBdcbL8PFf6oq8jSH4pYxW45-qOYPqs,1909
|
|
61
|
-
fin_infra/documents/add.py,sha256=
|
|
61
|
+
fin_infra/documents/add.py,sha256=dxzhdCsDcVVyTYKrgM30j-Wr0BAG797p4xa4j9UXST8,8118
|
|
62
62
|
fin_infra/documents/analysis.py,sha256=zY5OQEIlq3JLNND_cg2KheFdryUmIecPOR2lR6oKhPw,13992
|
|
63
|
-
fin_infra/documents/ease.py,sha256=
|
|
64
|
-
fin_infra/documents/models.py,sha256=
|
|
65
|
-
fin_infra/documents/ocr.py,sha256=
|
|
66
|
-
fin_infra/documents/storage.py,sha256=
|
|
67
|
-
fin_infra/exceptions.py,sha256=
|
|
63
|
+
fin_infra/documents/ease.py,sha256=YutA7EDYzysH6ppf6iVFhe4v1XOzhmUM3tDwtQPku28,9621
|
|
64
|
+
fin_infra/documents/models.py,sha256=h__Ln3lfQ50F5q3MurpThTrBEnoxJPbc_eL-NwzdZ7E,6877
|
|
65
|
+
fin_infra/documents/ocr.py,sha256=NxVWT4SB8bWK6EGXCWvATejYyIzZLZCh0fDCWT0KZ1Y,9594
|
|
66
|
+
fin_infra/documents/storage.py,sha256=AM2MjVYuZ-77MxXGuvV6NFcWAH6Y_kMRe7xH1lZ29qQ,10174
|
|
67
|
+
fin_infra/exceptions.py,sha256=va2rZnGhAkAi5LUqk93iGhpfkChUBaBLUNnCx6bykSM,16952
|
|
68
68
|
fin_infra/goals/__init__.py,sha256=Vg8LKLlDoRiWHsJX7wu5Zcc-86NNLpHoLTjYVkGi2c4,2130
|
|
69
69
|
fin_infra/goals/add.py,sha256=vhExYtXrIId4ZMBr3WH9iLsCT3gAvuAxeHHE8xNTT0U,20605
|
|
70
70
|
fin_infra/goals/funding.py,sha256=6wn25N0VTYfKLzZWhEn0xdC0ft49qdElkQFc9IwmdPk,9334
|
|
71
|
-
fin_infra/goals/management.py,sha256=
|
|
71
|
+
fin_infra/goals/management.py,sha256=Rj-yCcXk4HK5Tg8VauRU3osbK3kRh5O-YR-tupULx8A,33865
|
|
72
72
|
fin_infra/goals/milestones.py,sha256=LEJ9M7yOKJ-8thPuH0byHACabCUA9qW7mMATsPomaJA,9995
|
|
73
73
|
fin_infra/goals/models.py,sha256=DxUrYJqlfKdrmFBucNikLbto3NgxoiJAmsL3v0LR4DQ,10237
|
|
74
74
|
fin_infra/goals/scaffold_templates/README.md,sha256=CoE_3I2K32orOFH6CvfVBaJBTGDYIESd5-48V7vU1FI,9974
|
|
@@ -76,46 +76,46 @@ fin_infra/goals/scaffold_templates/__init__.py,sha256=rLFam-mRsj8LvJu5kRBEIJtw9r
|
|
|
76
76
|
fin_infra/goals/scaffold_templates/models.py.tmpl,sha256=b23Nlwm05MFMQE4qkrylTPXqulsN6cuFzNev2liY7DI,5714
|
|
77
77
|
fin_infra/goals/scaffold_templates/repository.py.tmpl,sha256=4BFy-fPBR412p8wb8VzsekxM3uGno-odqZP_BuMAXBU,11046
|
|
78
78
|
fin_infra/goals/scaffold_templates/schemas.py.tmpl,sha256=M1hS1pK9UDXcNqPW-NGu9804hTFe4FPdUDVgDSMcQl4,5331
|
|
79
|
-
fin_infra/insights/__init__.py,sha256=
|
|
79
|
+
fin_infra/insights/__init__.py,sha256=SNpgW8xe_wOKiGad5ubWCS-jRjqj6ODxe9dRsoAHxBc,3958
|
|
80
80
|
fin_infra/insights/aggregator.py,sha256=XG32mN5w5Nc4AZllmfl1esL4q44mFAf0Fvj9mWev_zk,10249
|
|
81
81
|
fin_infra/insights/models.py,sha256=xov_YV8oBLJt3YdyVjbryRfcXqmGeGiPvZsZHSbvtl8,3202
|
|
82
|
-
fin_infra/investments/__init__.py,sha256=
|
|
83
|
-
fin_infra/investments/add.py,sha256=
|
|
84
|
-
fin_infra/investments/ease.py,sha256=
|
|
85
|
-
fin_infra/investments/models.py,sha256=
|
|
82
|
+
fin_infra/investments/__init__.py,sha256=o4p_8slq-CzIK0ditVhNfcyoWsDdyFaxRl-IMBHtLNE,6732
|
|
83
|
+
fin_infra/investments/add.py,sha256=Yyh3VIjJ5OBJbvEZQboFDqlYkzrHoEPnWzSY2iBAJiM,17263
|
|
84
|
+
fin_infra/investments/ease.py,sha256=d5ISfxpCius6JM2LZNReztW6-IizaqoxNU4aEbXWA74,9487
|
|
85
|
+
fin_infra/investments/models.py,sha256=y3OgetML7OGRQqdESxt8eNv3ifPBHtBMtsFAf0vz5NQ,18424
|
|
86
86
|
fin_infra/investments/providers/__init__.py,sha256=V1eIzz6EnGJ-pq-9L3S2-evmcExF-YdZfd5P6JMyDtc,383
|
|
87
|
-
fin_infra/investments/providers/base.py,sha256=
|
|
88
|
-
fin_infra/investments/providers/plaid.py,sha256=
|
|
89
|
-
fin_infra/investments/providers/snaptrade.py,sha256=
|
|
87
|
+
fin_infra/investments/providers/base.py,sha256=MwwwVaijq-8SpM6oR_HYwFWkONCiTV6zyteVP3RMM_s,9850
|
|
88
|
+
fin_infra/investments/providers/plaid.py,sha256=GWNRc2nFG2nWJw-JuWE49kzfi1TJ-tkjj4t_lx0UUgQ,17959
|
|
89
|
+
fin_infra/investments/providers/snaptrade.py,sha256=RMkYzmQba0NKw4xlaHT7w0j1e5zSqmlTfWL36M28zJE,23290
|
|
90
90
|
fin_infra/investments/scaffold_templates/README.md,sha256=PhgxfMLrro2Jz83b7XEnBi7lexiWKqlMrd2UU2Rbs8A,12149
|
|
91
91
|
fin_infra/investments/scaffold_templates/__init__.py,sha256=iR0oiAzXFYXHBnVJjaEnAzk6omncYOLg0TKMJ7xomBc,82
|
|
92
92
|
fin_infra/investments/scaffold_templates/models.py.tmpl,sha256=5inP5-jw-qEfPYxSN71tn4AojZ9PesOIeuHTw181N-c,5849
|
|
93
93
|
fin_infra/investments/scaffold_templates/repository.py.tmpl,sha256=XwOEpQZfuXut1WLiq-GSSvv0oX0iYCW54eJNL0Cav94,14656
|
|
94
94
|
fin_infra/investments/scaffold_templates/schemas.py.tmpl,sha256=knWmn-Kyr7AdgPD4ZPMb6T49ZuPXeuOMqmjYNyA0CA0,5451
|
|
95
|
-
fin_infra/markets/__init__.py,sha256=
|
|
95
|
+
fin_infra/markets/__init__.py,sha256=NWIHMchN4tndjAsxvd8KMnu-pmVaW8Qc0Qu1ooqIZXY,9828
|
|
96
96
|
fin_infra/models/__init__.py,sha256=q3SkGzDGFkoAMxwqJw8i4cHWt5NGU5ypjOgntxDGVKo,860
|
|
97
|
-
fin_infra/models/accounts.py,sha256=
|
|
97
|
+
fin_infra/models/accounts.py,sha256=ExQimE2O5dyugFMW7nCboWbWcaX3Nnl5Gg-B1XLSdIk,1138
|
|
98
98
|
fin_infra/models/brokerage.py,sha256=z6Zyf0N5zmmXtrN2y_4fNmtIP5wNq40H8lrHLBwY7rc,8311
|
|
99
99
|
fin_infra/models/candle.py,sha256=7vrDxR1JFZodMUG8OGB0ft1_oaGW16gZtawjZ_2OwhA,535
|
|
100
100
|
fin_infra/models/credit.py,sha256=rSdSURsMe9_i2gxmwPTDwNQWOuM2zutL-OhvHsnbtmw,12144
|
|
101
101
|
fin_infra/models/money.py,sha256=5BX8IQZkrNtjjnGIQAK2tyKnVim0R-yc1F_EBxUhcr0,400
|
|
102
102
|
fin_infra/models/quotes.py,sha256=_2cDJS8_RLo4tLpJlqWd32J8uFNP0bbf1V_0u3NuLwo,543
|
|
103
103
|
fin_infra/models/tax.py,sha256=lhNVIW650CdtpfgmSyMMJdojV7QnpHOUFQKiwMLTT4A,15656
|
|
104
|
-
fin_infra/models/transactions.py,sha256
|
|
104
|
+
fin_infra/models/transactions.py,sha256=NtIHk3RDM58wYHQiHNOsvU5K6lgpfZodrL7scDRKP6E,865
|
|
105
105
|
fin_infra/net_worth/__init__.py,sha256=EjEuHNg8gEfFwbfko1-o5j-gSUZ2FcO9h7l05C-zAJM,3101
|
|
106
106
|
fin_infra/net_worth/add.py,sha256=QWfHIHJs2CV99WRBqjQ2OteiOrn5cR9nurmxTF9v5rg,23191
|
|
107
107
|
fin_infra/net_worth/aggregator.py,sha256=3iZGPE3AlS2Za90Mnw9XfKa2-BmCWLKkTUmDLztP9EQ,12779
|
|
108
|
-
fin_infra/net_worth/calculator.py,sha256=
|
|
109
|
-
fin_infra/net_worth/ease.py,sha256=
|
|
108
|
+
fin_infra/net_worth/calculator.py,sha256=SQJGJDok5HgvoAhKBxeeqt8vhGMchABU3zPmNRpqNy4,13139
|
|
109
|
+
fin_infra/net_worth/ease.py,sha256=ERdFrUjjb5l5BRp_c2tEfE1obTpRc_-FA9LnV7BTiEw,15883
|
|
110
110
|
fin_infra/net_worth/goals.py,sha256=BJGxdsMjvgQDELFEJo-ai3DvsAzUNXvzMXkwovHr8yQ,1238
|
|
111
|
-
fin_infra/net_worth/insights.py,sha256=
|
|
111
|
+
fin_infra/net_worth/insights.py,sha256=CkZuNU-YaFeVAd6f37XNVYkqdVOaqgC7u0tq9i2Yuk4,25222
|
|
112
112
|
fin_infra/net_worth/models.py,sha256=sZv3dGw5zwckE2XQ7n5ehK7sv4jdGCo9c2g4ZtZHwCI,26880
|
|
113
113
|
fin_infra/net_worth/scaffold_templates/README.md,sha256=Wqd6ksqFjmtNdDFOWVV_duuAcePWwiu3_YgkVM9N_WY,14363
|
|
114
114
|
fin_infra/net_worth/scaffold_templates/__init__.py,sha256=OKeMCC_JNw6m8rBWr_wesOIJ1OR9LCBeIkXKahbCGC4,132
|
|
115
115
|
fin_infra/net_worth/scaffold_templates/models.py.tmpl,sha256=9BKsoD08RZbSdOm0wFTbx5OzKfAEtuA1NcWyS1Aywx4,5934
|
|
116
116
|
fin_infra/net_worth/scaffold_templates/repository.py.tmpl,sha256=DSErnNxeAe4pWeefARRK3bU0hHltqdIFffENfVwdd7c,12798
|
|
117
117
|
fin_infra/net_worth/scaffold_templates/schemas.py.tmpl,sha256=VkFsxyZx4DFDhXDhn-7KT0IgrXCvgaS5ZdWbjyezWj0,4709
|
|
118
|
-
fin_infra/normalization/__init__.py,sha256=
|
|
118
|
+
fin_infra/normalization/__init__.py,sha256=X3qXIxqWLW7t3O_H0HuW0rMSy1AO2uRsJj3--qBFZbw,6246
|
|
119
119
|
fin_infra/normalization/currency_converter.py,sha256=uuu8ASa5ppEniWLEVEpiDxXjZzln9nopWrhrATcD6Z4,7058
|
|
120
120
|
fin_infra/normalization/models.py,sha256=gNC9chpbQPRN58V2j__VEPVNReO1N8jH_AHObwGPWu0,1928
|
|
121
121
|
fin_infra/normalization/providers/__init__.py,sha256=LFU1tB2hVO42Yrkw-IDpPexD4mIlxob9lRrJEeGYqpE,559
|
|
@@ -126,16 +126,16 @@ fin_infra/obs/__init__.py,sha256=kMMVl0fdwtJtZeKiusTuw0iO61Jo9-HNXsLmn3ffLRE,631
|
|
|
126
126
|
fin_infra/obs/classifier.py,sha256=FEwL1lEV_f9bFBr36PaZsV4DxU3spwIXPoegwBgzSMc,5146
|
|
127
127
|
fin_infra/providers/__init__.py,sha256=jxhQm79T6DVXf7Wpy7luL-p50cE_IMUbjt4o3apzJQU,768
|
|
128
128
|
fin_infra/providers/banking/base.py,sha256=KeNU4ur3zLKHVsBF1LQifcs2AKX06IEE-Rx_SetFeAs,102
|
|
129
|
-
fin_infra/providers/banking/plaid_client.py,sha256=
|
|
129
|
+
fin_infra/providers/banking/plaid_client.py,sha256=LiBIwQLJp-5bA98oEQtTZpkQMC7kwhShq0mPATa9wD8,6520
|
|
130
130
|
fin_infra/providers/banking/teller_client.py,sha256=QmrsBlk3_rHT-pTQPrIAA74kjIjcgdi-gOb8NA3oBO8,10268
|
|
131
|
-
fin_infra/providers/base.py,sha256=
|
|
132
|
-
fin_infra/providers/brokerage/alpaca.py,sha256=
|
|
131
|
+
fin_infra/providers/base.py,sha256=_EmC37Bt8LA2JmVxMIy2poJyQsuD6FpAawkHPreq0M8,6678
|
|
132
|
+
fin_infra/providers/brokerage/alpaca.py,sha256=M8Z2i6dY9mgrU4-SDei2nYRKgbxHuPDMHubMb7ZMbEY,9920
|
|
133
133
|
fin_infra/providers/brokerage/base.py,sha256=JJFH0Cqca4Rg4rmxfiwcQt-peRoBf4JpG3g6jx8DVks,106
|
|
134
134
|
fin_infra/providers/credit/experian.py,sha256=r7lpFecgOdNEhb_Lxz2Z-BG8R3p2n0XlqDKL7y8NZ-0,482
|
|
135
135
|
fin_infra/providers/identity/stripe_identity.py,sha256=JQGJRuQdWP5dWDcROgtz1RrmpkytRv95H6Fn-x1kifU,501
|
|
136
136
|
fin_infra/providers/market/alphavantage.py,sha256=srZdkf-frBuKyPTdWasMmVrpnh76BEBDXa-nsYtLzNc,8963
|
|
137
137
|
fin_infra/providers/market/base.py,sha256=ljBzZTfjYQS9tXahmxFic7JQSZeyoiDMUZ1NY0R7yto,108
|
|
138
|
-
fin_infra/providers/market/ccxt_crypto.py,sha256=
|
|
138
|
+
fin_infra/providers/market/ccxt_crypto.py,sha256=knxcgTwZX0rRVoO7f-2eMVzFUbu-qIjtoIXdNulRvLQ,1176
|
|
139
139
|
fin_infra/providers/market/coingecko.py,sha256=F1Bwdk28xSsIaFEuT7lhT3F6Vkd0Lp-CMp1rnYiLfaE,2702
|
|
140
140
|
fin_infra/providers/market/yahoo.py,sha256=FNhqkCFC0In-Z3zpzmuknEORHLRK5Evk2KSk0yysKjg,4954
|
|
141
141
|
fin_infra/providers/registry.py,sha256=yPFmHHaSQERXZTcGkdXAtMU7rL7VwAzW4FOr14o6KS8,8409
|
|
@@ -145,16 +145,16 @@ fin_infra/providers/tax/mock.py,sha256=AxI3RmEn3exdQeeUNkQYqZ-war5PS--WnLGXfRRee
|
|
|
145
145
|
fin_infra/providers/tax/taxbit.py,sha256=DEA7vgQPYMjz4ZdC0DpY7112FLZJ2kvwgAbDZnpHFy0,4271
|
|
146
146
|
fin_infra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
147
147
|
fin_infra/recurring/__init__.py,sha256=ihMPywft8pGqzMu6EXxbQCU7ByoMl_dvad00gWV1mnk,2308
|
|
148
|
-
fin_infra/recurring/add.py,sha256=
|
|
149
|
-
fin_infra/recurring/detector.py,sha256=
|
|
148
|
+
fin_infra/recurring/add.py,sha256=tnW-duL6k1Lk0Rxuq_6os2Cif1mkWd7uLNWnnD7gnes,19072
|
|
149
|
+
fin_infra/recurring/detector.py,sha256=FvxWSzvaGWByNpUgy_jN9Zjc2L8-qmU0ggqpSz-RXQA,20156
|
|
150
150
|
fin_infra/recurring/detectors_llm.py,sha256=YNG3GOvto8ua9yNacmejYcDOHZzN9UUpDtRdrzDsLSY,11504
|
|
151
151
|
fin_infra/recurring/ease.py,sha256=Vsg_AnTLjb5QXfFjijH2C50Or9hJGIVLtczk0U71h74,11189
|
|
152
152
|
fin_infra/recurring/insights.py,sha256=a4fhASyiNQTdUl2ijaxi2HqhWDhf-aJND2c62d9lgEo,15886
|
|
153
153
|
fin_infra/recurring/models.py,sha256=o0N8G-QhVb4zILEyry6M1VZ7liFJIOHwlejvn6p4K8M,8894
|
|
154
|
-
fin_infra/recurring/normalizer.py,sha256=
|
|
154
|
+
fin_infra/recurring/normalizer.py,sha256=HZ4N7lXaeOZqphjSbjRmaneONJ5ELOSrqBlM5WM1tww,9758
|
|
155
155
|
fin_infra/recurring/normalizers.py,sha256=37-ER4deeJhywrNVEe9KteecC_eH7xesTl2CWhRbdi0,15928
|
|
156
156
|
fin_infra/recurring/summary.py,sha256=1Wte58ZZkEFulkb-nnpwfC5h7C_JrqByy47itdVdWwc,14665
|
|
157
|
-
fin_infra/scaffold/__init__.py,sha256=
|
|
157
|
+
fin_infra/scaffold/__init__.py,sha256=IfL_CHHMpQB1efqY37BlIu07356tLaeVI2Mv3C0qYDs,827
|
|
158
158
|
fin_infra/scaffold/budgets.py,sha256=XXOLlEcyBXVwdbJB__qObRXJ0oe1okwDT_-5tG8c9Yk,9515
|
|
159
159
|
fin_infra/scaffold/goals.py,sha256=uVYzbbfbXGrf8qeGvq8mtY6o_YIk17aZ0DfSGQx6Y58,9690
|
|
160
160
|
fin_infra/security/__init__.py,sha256=ZXGa7IeoOg50f41KsA7tt9rKTUeg910AagQYXh0MIbs,1363
|
|
@@ -166,15 +166,15 @@ fin_infra/security/pii_filter.py,sha256=lfARBmPRekkyXKJV0tWI_0KVaDsdV61VH-8RHxvb
|
|
|
166
166
|
fin_infra/security/pii_patterns.py,sha256=SM-o7cL6NdgkOmtBedsN2nJZ5QPbeYehZdYmAujk8Y8,3070
|
|
167
167
|
fin_infra/security/token_store.py,sha256=qgxhBKwhtVpchyHv30mM-cttuGZlzZvZLC4Oa-gTTeg,6075
|
|
168
168
|
fin_infra/settings.py,sha256=xitpBQJmuvSy9prQhvXOW1scbwB1KAyGD8XqYgU_hQU,1388
|
|
169
|
-
fin_infra/tax/__init__.py,sha256=
|
|
169
|
+
fin_infra/tax/__init__.py,sha256=S0TijDOqENzRhZbh-byJuOaV6VB-ESsD1Hu9wQ5ZOo4,6103
|
|
170
170
|
fin_infra/tax/add.py,sha256=8INSAv721ir9ICQxQ_oA0hL-Bjg6wLyrtj9tafrcCsA,14552
|
|
171
171
|
fin_infra/tax/tlh.py,sha256=6OlZ3Gb13rSFrmW7vPqVTq_NB45D110iHgCwzYp2nTA,21523
|
|
172
172
|
fin_infra/utils/__init__.py,sha256=gKacLSWMAis--pasd8AuVN7ap0e9Z1TjRGur0J23EDo,648
|
|
173
173
|
fin_infra/utils/http.py,sha256=pvcxbNQ9oisoGPkNe3xX9aAgWzEN6mmdtr1w-L02Xj8,629
|
|
174
174
|
fin_infra/utils/retry.py,sha256=ISBrup5XCuXqHZh9kjTGvGQYcuyYyqZE4u26wW7r3CM,1030
|
|
175
175
|
fin_infra/version.py,sha256=4t_crzhrLum--oyowUMxtjBTzUtWp7oRTF22ewEvJG4,49
|
|
176
|
-
fin_infra-0.1.
|
|
177
|
-
fin_infra-0.1.
|
|
178
|
-
fin_infra-0.1.
|
|
179
|
-
fin_infra-0.1.
|
|
180
|
-
fin_infra-0.1.
|
|
176
|
+
fin_infra-0.1.68.dist-info/LICENSE,sha256=wK-Ya7Ylxa38dSIZRhvNj1ZVLIrHC-BAI8v38PNADiA,1061
|
|
177
|
+
fin_infra-0.1.68.dist-info/METADATA,sha256=Vet5JZ-o-ltJjw6lXcPuvY2SDbOAa59BeTHE0Vrc-Kc,10183
|
|
178
|
+
fin_infra-0.1.68.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
179
|
+
fin_infra-0.1.68.dist-info/entry_points.txt,sha256=Sr1uikvALZMeKm-DIkeKG4L9c4SNqysXGO_IRF8_9eU,53
|
|
180
|
+
fin_infra-0.1.68.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|