fin-infra 0.1.71__py3-none-any.whl → 0.1.73__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/__init__.py +53 -3
- fin_infra/categorization/engine.py +11 -8
- fin_infra/crypto/insights.py +4 -3
- fin_infra/insights/__init__.py +4 -1
- fin_infra/investments/providers/plaid.py +39 -13
- fin_infra/net_worth/aggregator.py +4 -2
- fin_infra/providers/market/ccxt_crypto.py +17 -1
- fin_infra/providers/market/yahoo.py +17 -2
- {fin_infra-0.1.71.dist-info → fin_infra-0.1.73.dist-info}/METADATA +14 -8
- {fin_infra-0.1.71.dist-info → fin_infra-0.1.73.dist-info}/RECORD +13 -13
- {fin_infra-0.1.71.dist-info → fin_infra-0.1.73.dist-info}/LICENSE +0 -0
- {fin_infra-0.1.71.dist-info → fin_infra-0.1.73.dist-info}/WHEEL +0 -0
- {fin_infra-0.1.71.dist-info → fin_infra-0.1.73.dist-info}/entry_points.txt +0 -0
fin_infra/__init__.py
CHANGED
|
@@ -1,9 +1,45 @@
|
|
|
1
|
-
"""fin_infra: Financial
|
|
1
|
+
"""fin_infra: Financial Infrastructure Toolkit.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
A comprehensive financial infrastructure library providing:
|
|
4
|
+
- Banking integration (Plaid, Teller, MX)
|
|
5
|
+
- Brokerage integration (Alpaca, Interactive Brokers)
|
|
6
|
+
- Market data (stocks, crypto, forex)
|
|
7
|
+
- Credit scores (Experian, Equifax, TransUnion)
|
|
8
|
+
- Financial calculations (NPV, IRR, PMT, FV, PV)
|
|
9
|
+
- Portfolio analytics (returns, allocation, benchmarking)
|
|
10
|
+
- Transaction categorization (rule-based + ML)
|
|
11
|
+
- Budget management and cash flow analysis
|
|
12
|
+
- Net worth tracking and goal management
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
from fin_infra.banking import easy_banking
|
|
16
|
+
from fin_infra.markets import easy_market
|
|
17
|
+
|
|
18
|
+
banking = easy_banking()
|
|
19
|
+
market = easy_market()
|
|
20
|
+
quote = market.quote("AAPL")
|
|
5
21
|
"""
|
|
6
22
|
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
# Core modules - can be imported as `from fin_infra import banking`
|
|
26
|
+
from . import (
|
|
27
|
+
analytics,
|
|
28
|
+
banking,
|
|
29
|
+
brokerage,
|
|
30
|
+
budgets,
|
|
31
|
+
cashflows,
|
|
32
|
+
categorization,
|
|
33
|
+
credit,
|
|
34
|
+
crypto,
|
|
35
|
+
investments,
|
|
36
|
+
markets,
|
|
37
|
+
net_worth,
|
|
38
|
+
recurring,
|
|
39
|
+
tax,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Base exceptions
|
|
7
43
|
from .exceptions import (
|
|
8
44
|
FinInfraError,
|
|
9
45
|
ProviderError,
|
|
@@ -14,6 +50,20 @@ from .version import __version__
|
|
|
14
50
|
|
|
15
51
|
__all__ = [
|
|
16
52
|
"__version__",
|
|
53
|
+
# Core modules
|
|
54
|
+
"analytics",
|
|
55
|
+
"banking",
|
|
56
|
+
"brokerage",
|
|
57
|
+
"budgets",
|
|
58
|
+
"cashflows",
|
|
59
|
+
"categorization",
|
|
60
|
+
"credit",
|
|
61
|
+
"crypto",
|
|
62
|
+
"investments",
|
|
63
|
+
"markets",
|
|
64
|
+
"net_worth",
|
|
65
|
+
"recurring",
|
|
66
|
+
"tax",
|
|
17
67
|
# Base errors
|
|
18
68
|
"FinInfraError",
|
|
19
69
|
"ProviderError",
|
|
@@ -251,8 +251,7 @@ class CategorizationEngine:
|
|
|
251
251
|
)
|
|
252
252
|
|
|
253
253
|
except Exception as e:
|
|
254
|
-
|
|
255
|
-
print(f"ML prediction error: {e}")
|
|
254
|
+
logger.error("ML prediction error: %s", e)
|
|
256
255
|
return None
|
|
257
256
|
|
|
258
257
|
def _load_ml_model(self) -> None:
|
|
@@ -273,8 +272,10 @@ class CategorizationEngine:
|
|
|
273
272
|
vectorizer_file = self.model_path / "vectorizer.joblib"
|
|
274
273
|
|
|
275
274
|
if not model_file.exists() or not vectorizer_file.exists():
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
logger.warning(
|
|
276
|
+
"ML model not found at %s. Run training script to generate model files.",
|
|
277
|
+
self.model_path,
|
|
278
|
+
)
|
|
278
279
|
return
|
|
279
280
|
|
|
280
281
|
try:
|
|
@@ -282,12 +283,14 @@ class CategorizationEngine:
|
|
|
282
283
|
|
|
283
284
|
self._ml_model = joblib.load(model_file)
|
|
284
285
|
self._ml_vectorizer = joblib.load(vectorizer_file)
|
|
285
|
-
|
|
286
|
+
logger.info("Loaded ML model from %s", self.model_path)
|
|
286
287
|
except ImportError:
|
|
287
|
-
|
|
288
|
-
|
|
288
|
+
logger.warning(
|
|
289
|
+
"scikit-learn not installed. ML predictions disabled. "
|
|
290
|
+
"Install with: pip install scikit-learn"
|
|
291
|
+
)
|
|
289
292
|
except Exception as e:
|
|
290
|
-
|
|
293
|
+
logger.error("Error loading ML model: %s", e)
|
|
291
294
|
|
|
292
295
|
def add_rule(
|
|
293
296
|
self,
|
fin_infra/crypto/insights.py
CHANGED
|
@@ -8,6 +8,7 @@ CRITICAL: Uses ai-infra.llm.LLM (NEVER custom LLM clients).
|
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
+
import logging
|
|
11
12
|
from datetime import datetime
|
|
12
13
|
from decimal import Decimal
|
|
13
14
|
from typing import TYPE_CHECKING
|
|
@@ -17,6 +18,8 @@ from pydantic import BaseModel, Field
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from ai_infra.llm import LLM
|
|
19
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
class CryptoInsight(BaseModel):
|
|
22
25
|
"""Personalized cryptocurrency insight.
|
|
@@ -284,8 +287,6 @@ Provide your insight:"""
|
|
|
284
287
|
)
|
|
285
288
|
)
|
|
286
289
|
except Exception as e:
|
|
287
|
-
|
|
288
|
-
# In production, use svc-infra logging
|
|
289
|
-
print(f"Warning: LLM insight generation failed: {e}")
|
|
290
|
+
logger.warning("LLM insight generation failed: %s", e)
|
|
290
291
|
|
|
291
292
|
return insights
|
fin_infra/insights/__init__.py
CHANGED
|
@@ -10,6 +10,7 @@ Aggregates insights from multiple sources:
|
|
|
10
10
|
- Cash flow projections
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
import logging
|
|
13
14
|
from typing import TYPE_CHECKING
|
|
14
15
|
|
|
15
16
|
if TYPE_CHECKING:
|
|
@@ -18,6 +19,8 @@ if TYPE_CHECKING:
|
|
|
18
19
|
from .models import Insight, InsightFeed, InsightPriority, InsightCategory
|
|
19
20
|
from .aggregator import aggregate_insights, get_user_insights
|
|
20
21
|
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
21
24
|
__all__ = [
|
|
22
25
|
"Insight",
|
|
23
26
|
"InsightFeed",
|
|
@@ -125,4 +128,4 @@ def add_insights(
|
|
|
125
128
|
# Mount router
|
|
126
129
|
app.include_router(router, include_in_schema=True)
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
logger.info("Insights feed enabled")
|
|
@@ -12,19 +12,33 @@ from datetime import date
|
|
|
12
12
|
from decimal import Decimal
|
|
13
13
|
from typing import Any, Dict, List, Optional, cast
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
from plaid.
|
|
17
|
-
from plaid.model.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
from plaid.model.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
import
|
|
26
|
-
|
|
27
|
-
from plaid.
|
|
15
|
+
try:
|
|
16
|
+
from plaid.api import plaid_api
|
|
17
|
+
from plaid.model.investments_holdings_get_request import InvestmentsHoldingsGetRequest
|
|
18
|
+
from plaid.model.investments_transactions_get_request import (
|
|
19
|
+
InvestmentsTransactionsGetRequest,
|
|
20
|
+
)
|
|
21
|
+
from plaid.model.investments_holdings_get_response import InvestmentsHoldingsGetResponse
|
|
22
|
+
from plaid.model.investments_transactions_get_response import (
|
|
23
|
+
InvestmentsTransactionsGetResponse,
|
|
24
|
+
)
|
|
25
|
+
from plaid.exceptions import ApiException
|
|
26
|
+
import plaid
|
|
27
|
+
from plaid.api_client import ApiClient
|
|
28
|
+
from plaid.configuration import Configuration
|
|
29
|
+
|
|
30
|
+
HAS_PLAID = True
|
|
31
|
+
except ImportError: # pragma: no cover
|
|
32
|
+
HAS_PLAID = False
|
|
33
|
+
plaid_api = None
|
|
34
|
+
plaid = None
|
|
35
|
+
ApiClient = None
|
|
36
|
+
Configuration = None
|
|
37
|
+
ApiException = Exception
|
|
38
|
+
InvestmentsHoldingsGetRequest = Any
|
|
39
|
+
InvestmentsTransactionsGetRequest = Any
|
|
40
|
+
InvestmentsHoldingsGetResponse = Any
|
|
41
|
+
InvestmentsTransactionsGetResponse = Any
|
|
28
42
|
|
|
29
43
|
from ..models import (
|
|
30
44
|
Holding,
|
|
@@ -36,6 +50,15 @@ from ..models import (
|
|
|
36
50
|
from .base import InvestmentProvider
|
|
37
51
|
|
|
38
52
|
|
|
53
|
+
def _require_plaid() -> None:
|
|
54
|
+
"""Raise ImportError if plaid-python is not installed."""
|
|
55
|
+
if not HAS_PLAID:
|
|
56
|
+
raise ImportError(
|
|
57
|
+
"Plaid support requires the 'plaid-python' package. "
|
|
58
|
+
"Install with: pip install fin-infra[plaid] or pip install fin-infra[banking]"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
39
62
|
class PlaidInvestmentProvider(InvestmentProvider):
|
|
40
63
|
"""Plaid Investment API provider.
|
|
41
64
|
|
|
@@ -76,7 +99,10 @@ class PlaidInvestmentProvider(InvestmentProvider):
|
|
|
76
99
|
|
|
77
100
|
Raises:
|
|
78
101
|
ValueError: If client_id or secret is missing
|
|
102
|
+
ImportError: If plaid-python is not installed
|
|
79
103
|
"""
|
|
104
|
+
_require_plaid()
|
|
105
|
+
|
|
80
106
|
if not client_id or not secret:
|
|
81
107
|
raise ValueError("client_id and secret are required for Plaid provider")
|
|
82
108
|
|
|
@@ -30,6 +30,7 @@ print(f"Net Worth: ${snapshot.total_net_worth:,.2f}")
|
|
|
30
30
|
"""
|
|
31
31
|
|
|
32
32
|
import asyncio
|
|
33
|
+
import logging
|
|
33
34
|
import uuid
|
|
34
35
|
from datetime import datetime
|
|
35
36
|
from typing import Any
|
|
@@ -47,6 +48,8 @@ from fin_infra.net_worth.models import (
|
|
|
47
48
|
NetWorthSnapshot,
|
|
48
49
|
)
|
|
49
50
|
|
|
51
|
+
logger = logging.getLogger(__name__)
|
|
52
|
+
|
|
50
53
|
|
|
51
54
|
class NetWorthAggregator:
|
|
52
55
|
"""
|
|
@@ -219,8 +222,7 @@ class NetWorthAggregator:
|
|
|
219
222
|
|
|
220
223
|
for i, result in enumerate(results):
|
|
221
224
|
if isinstance(result, BaseException):
|
|
222
|
-
|
|
223
|
-
print(f"Provider {providers_used[i]} failed: {result}")
|
|
225
|
+
logger.warning("Provider %s failed: %s", providers_used[i], result)
|
|
224
226
|
continue
|
|
225
227
|
|
|
226
228
|
# result is now tuple[list[AssetDetail], list[LiabilityDetail]]
|
|
@@ -2,15 +2,31 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, cast
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
try:
|
|
6
|
+
import ccxt
|
|
7
|
+
|
|
8
|
+
HAS_CCXT = True
|
|
9
|
+
except ImportError: # pragma: no cover
|
|
10
|
+
HAS_CCXT = False
|
|
11
|
+
ccxt = None
|
|
6
12
|
|
|
7
13
|
from ..base import CryptoDataProvider
|
|
8
14
|
|
|
9
15
|
|
|
16
|
+
def _require_ccxt() -> None:
|
|
17
|
+
"""Raise ImportError if ccxt is not installed."""
|
|
18
|
+
if not HAS_CCXT:
|
|
19
|
+
raise ImportError(
|
|
20
|
+
"Crypto exchange support requires the 'ccxt' package. "
|
|
21
|
+
"Install with: pip install fin-infra[crypto] or pip install fin-infra[markets]"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
10
25
|
class CCXTCryptoData(CryptoDataProvider):
|
|
11
26
|
"""Exchange-agnostic crypto market data using CCXT."""
|
|
12
27
|
|
|
13
28
|
def __init__(self, exchange: str = "binance") -> None:
|
|
29
|
+
_require_ccxt()
|
|
14
30
|
if not hasattr(ccxt, exchange):
|
|
15
31
|
raise ValueError(f"Unknown exchange '{exchange}' in ccxt")
|
|
16
32
|
self.exchange = getattr(ccxt, exchange)()
|
|
@@ -14,12 +14,27 @@ from typing import Sequence
|
|
|
14
14
|
from decimal import Decimal
|
|
15
15
|
from datetime import datetime, timezone
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
try:
|
|
18
|
+
from yahooquery import Ticker
|
|
19
|
+
|
|
20
|
+
HAS_YAHOOQUERY = True
|
|
21
|
+
except ImportError: # pragma: no cover
|
|
22
|
+
HAS_YAHOOQUERY = False
|
|
23
|
+
Ticker = None
|
|
18
24
|
|
|
19
25
|
from .base import MarketDataProvider
|
|
20
26
|
from ...models import Quote, Candle
|
|
21
27
|
|
|
22
28
|
|
|
29
|
+
def _require_yahooquery() -> None:
|
|
30
|
+
"""Raise ImportError if yahooquery is not installed."""
|
|
31
|
+
if not HAS_YAHOOQUERY:
|
|
32
|
+
raise ImportError(
|
|
33
|
+
"Yahoo Finance support requires the 'yahooquery' package. "
|
|
34
|
+
"Install with: pip install fin-infra[yahoo] or pip install fin-infra[markets]"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
23
38
|
class YahooFinanceMarketData(MarketDataProvider):
|
|
24
39
|
"""Yahoo Finance provider (zero config, no API key needed).
|
|
25
40
|
|
|
@@ -42,7 +57,7 @@ class YahooFinanceMarketData(MarketDataProvider):
|
|
|
42
57
|
|
|
43
58
|
def __init__(self) -> None:
|
|
44
59
|
"""Initialize Yahoo Finance provider (no configuration needed)."""
|
|
45
|
-
|
|
60
|
+
_require_yahooquery()
|
|
46
61
|
|
|
47
62
|
def quote(self, symbol: str) -> Quote:
|
|
48
63
|
"""Get real-time quote for a symbol.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fin-infra
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.73
|
|
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
|
|
@@ -19,24 +19,30 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
19
19
|
Classifier: Topic :: Office/Business :: Financial
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
21
|
Classifier: Typing :: Typed
|
|
22
|
+
Provides-Extra: all
|
|
23
|
+
Provides-Extra: banking
|
|
24
|
+
Provides-Extra: crypto
|
|
25
|
+
Provides-Extra: markets
|
|
26
|
+
Provides-Extra: plaid
|
|
27
|
+
Provides-Extra: yahoo
|
|
22
28
|
Requires-Dist: ai-infra (>=0.1.142)
|
|
23
29
|
Requires-Dist: cashews[redis] (>=7.0)
|
|
24
|
-
Requires-Dist: ccxt (>=4.0.0)
|
|
30
|
+
Requires-Dist: ccxt (>=4.0.0) ; extra == "markets" or extra == "crypto" or extra == "all"
|
|
25
31
|
Requires-Dist: httpx (>=0.25.0)
|
|
26
32
|
Requires-Dist: loguru (>=0.7.0)
|
|
27
33
|
Requires-Dist: numpy (>=1.24.0)
|
|
28
34
|
Requires-Dist: numpy-financial (>=1.0.0)
|
|
29
|
-
Requires-Dist: plaid-python (>=25.0.0)
|
|
35
|
+
Requires-Dist: plaid-python (>=25.0.0) ; extra == "plaid" or extra == "banking" or extra == "all"
|
|
30
36
|
Requires-Dist: pydantic (>=2.0)
|
|
31
37
|
Requires-Dist: pydantic-settings (>=2.0)
|
|
32
38
|
Requires-Dist: python-dotenv (>=1.0.0)
|
|
33
39
|
Requires-Dist: tenacity (>=8.0.0)
|
|
34
40
|
Requires-Dist: typing-extensions (>=4.0)
|
|
35
|
-
Requires-Dist: yahooquery (>=2.3.0)
|
|
36
|
-
Project-URL: Documentation, https://
|
|
37
|
-
Project-URL: Homepage, https://github.com/
|
|
38
|
-
Project-URL: Issues, https://github.com/
|
|
39
|
-
Project-URL: Repository, https://github.com/
|
|
41
|
+
Requires-Dist: yahooquery (>=2.3.0) ; extra == "markets" or extra == "yahoo" or extra == "all"
|
|
42
|
+
Project-URL: Documentation, https://nfrax.com/fin-infra
|
|
43
|
+
Project-URL: Homepage, https://github.com/nfraxlab/fin-infra
|
|
44
|
+
Project-URL: Issues, https://github.com/nfraxlab/fin-infra/issues
|
|
45
|
+
Project-URL: Repository, https://github.com/nfraxlab/fin-infra
|
|
40
46
|
Description-Content-Type: text/markdown
|
|
41
47
|
|
|
42
48
|
<div align="center">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
fin_infra/__init__.py,sha256=
|
|
1
|
+
fin_infra/__init__.py,sha256=7oL-CCsALNifBODAn9LriicaIrzgJkmVPvE-9duP0mw,1574
|
|
2
2
|
fin_infra/__main__.py,sha256=1qNP7j0ffw0wFs1dBwDcJ9TNXlC6FcYuulzoV87pMi8,262
|
|
3
3
|
fin_infra/analytics/__init__.py,sha256=aiuNnii0vc34XlNzrSiMbz33lzgmR7W1nHkmAEXavCY,1870
|
|
4
4
|
fin_infra/analytics/add.py,sha256=YhNxFAH0m-GiLxgNzwZY09wt6kmy4n88Xa9DrYBLB6E,12709
|
|
@@ -32,7 +32,7 @@ fin_infra/cashflows/core.py,sha256=Or0hPqCvY_ypV0YiMXh-mle6xWK0tE8WuPPAqHGUp8E,5
|
|
|
32
32
|
fin_infra/categorization/__init__.py,sha256=efLje12AW-ec9Vs5ynb41r4XCIWx5a-Z9WoGb3kQdIE,2030
|
|
33
33
|
fin_infra/categorization/add.py,sha256=JDOvxngh-7oWHTddOyP4GAse9vLuxSTfoIhrDKUHOKg,6278
|
|
34
34
|
fin_infra/categorization/ease.py,sha256=bomEtJAgwk9uiemNt1rk-IsTjJIhyJn0GJ_c58YEmJs,5836
|
|
35
|
-
fin_infra/categorization/engine.py,sha256=
|
|
35
|
+
fin_infra/categorization/engine.py,sha256=vpwxtQGEbjCMyvzB5EQV2etjHHNOu1R05o99mHP_WZY,12132
|
|
36
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
|
|
@@ -56,7 +56,7 @@ fin_infra/credit/experian/parser.py,sha256=7ptdLyTWWqHWqCo1CXn6L7XaIn9ZRRuOaATbF
|
|
|
56
56
|
fin_infra/credit/experian/provider.py,sha256=QqnxFN0WIKyxV5y5jzIB_gv2djNpR-rTUiIhMtTWq8k,13701
|
|
57
57
|
fin_infra/credit/mock.py,sha256=xKWZk3fhuIYRfiZkNc9fbHUNViNKjmOLSj0MTI1f4ik,5356
|
|
58
58
|
fin_infra/crypto/__init__.py,sha256=p-gEoF59XzyV1RouubW4onl5mE62XvXSAw9isMc48qc,8314
|
|
59
|
-
fin_infra/crypto/insights.py,sha256=
|
|
59
|
+
fin_infra/crypto/insights.py,sha256=cgMsjdrR7vOTKvEDbFCXpS7O7I8dMs1oz6cIbtrJWZI,11393
|
|
60
60
|
fin_infra/documents/__init__.py,sha256=Ub1hbX3PTrBSsBdcbL8PFf6oq8jSH4pYxW45-qOYPqs,1909
|
|
61
61
|
fin_infra/documents/add.py,sha256=dxzhdCsDcVVyTYKrgM30j-Wr0BAG797p4xa4j9UXST8,8118
|
|
62
62
|
fin_infra/documents/analysis.py,sha256=zY5OQEIlq3JLNND_cg2KheFdryUmIecPOR2lR6oKhPw,13992
|
|
@@ -76,7 +76,7 @@ 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=ptVdG3_GJdpab8Ktn97sq6lk3ruReqeXjuLjB79e1Us,3984
|
|
80
80
|
fin_infra/insights/aggregator.py,sha256=XG32mN5w5Nc4AZllmfl1esL4q44mFAf0Fvj9mWev_zk,10249
|
|
81
81
|
fin_infra/insights/models.py,sha256=xov_YV8oBLJt3YdyVjbryRfcXqmGeGiPvZsZHSbvtl8,3202
|
|
82
82
|
fin_infra/investments/__init__.py,sha256=o4p_8slq-CzIK0ditVhNfcyoWsDdyFaxRl-IMBHtLNE,6732
|
|
@@ -85,7 +85,7 @@ fin_infra/investments/ease.py,sha256=d5ISfxpCius6JM2LZNReztW6-IizaqoxNU4aEbXWA74
|
|
|
85
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
87
|
fin_infra/investments/providers/base.py,sha256=MwwwVaijq-8SpM6oR_HYwFWkONCiTV6zyteVP3RMM_s,9850
|
|
88
|
-
fin_infra/investments/providers/plaid.py,sha256=
|
|
88
|
+
fin_infra/investments/providers/plaid.py,sha256=O98rTo7QVfBrn8ObPSrUiLMMAgtmRF3K0T6jx15qTnA,18777
|
|
89
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
|
|
@@ -104,7 +104,7 @@ fin_infra/models/tax.py,sha256=lhNVIW650CdtpfgmSyMMJdojV7QnpHOUFQKiwMLTT4A,15656
|
|
|
104
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
|
-
fin_infra/net_worth/aggregator.py,sha256=
|
|
107
|
+
fin_infra/net_worth/aggregator.py,sha256=9Kx2vUR71QwqYZdGaCfmYrJ1hNxzd1EEuAdWJoNjqTI,12780
|
|
108
108
|
fin_infra/net_worth/calculator.py,sha256=SQJGJDok5HgvoAhKBxeeqt8vhGMchABU3zPmNRpqNy4,13139
|
|
109
109
|
fin_infra/net_worth/ease.py,sha256=ERdFrUjjb5l5BRp_c2tEfE1obTpRc_-FA9LnV7BTiEw,15883
|
|
110
110
|
fin_infra/net_worth/goals.py,sha256=BJGxdsMjvgQDELFEJo-ai3DvsAzUNXvzMXkwovHr8yQ,1238
|
|
@@ -135,9 +135,9 @@ fin_infra/providers/credit/experian.py,sha256=r7lpFecgOdNEhb_Lxz2Z-BG8R3p2n0XlqD
|
|
|
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=AknYS3ZRBOtVxsr1MrI_ECL2vLlTR2hT60SeuAoECXE,1610
|
|
139
139
|
fin_infra/providers/market/coingecko.py,sha256=F1Bwdk28xSsIaFEuT7lhT3F6Vkd0Lp-CMp1rnYiLfaE,2702
|
|
140
|
-
fin_infra/providers/market/yahoo.py,sha256=
|
|
140
|
+
fin_infra/providers/market/yahoo.py,sha256=5MZv4Kb-eCPbZZxi7ZCJHR_3L8eMDXHNROVoyhgXgto,5416
|
|
141
141
|
fin_infra/providers/registry.py,sha256=yPFmHHaSQERXZTcGkdXAtMU7rL7VwAzW4FOr14o6KS8,8409
|
|
142
142
|
fin_infra/providers/tax/__init__.py,sha256=Tq2gLyTXL_U_ht6r7HXgaDMCAPylgcRD2ZN-COjSSQU,207
|
|
143
143
|
fin_infra/providers/tax/irs.py,sha256=f7l6w0byprBszTlCB4ef60K8GrYV-03Dicl1a1Q2oVk,4701
|
|
@@ -173,8 +173,8 @@ fin_infra/utils/__init__.py,sha256=gKacLSWMAis--pasd8AuVN7ap0e9Z1TjRGur0J23EDo,6
|
|
|
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.73.dist-info/LICENSE,sha256=wK-Ya7Ylxa38dSIZRhvNj1ZVLIrHC-BAI8v38PNADiA,1061
|
|
177
|
+
fin_infra-0.1.73.dist-info/METADATA,sha256=CQgU6BdLf8koGwkUJB_FiaMirv3_lqfQXehd45IjVOg,10479
|
|
178
|
+
fin_infra-0.1.73.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
179
|
+
fin_infra-0.1.73.dist-info/entry_points.txt,sha256=Sr1uikvALZMeKm-DIkeKG4L9c4SNqysXGO_IRF8_9eU,53
|
|
180
|
+
fin_infra-0.1.73.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|