sovai 0.2.76__tar.gz → 0.2.78__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.
- {sovai-0.2.76 → sovai-0.2.78}/PKG-INFO +1 -1
- {sovai-0.2.76 → sovai-0.2.78}/pyproject.toml +1 -1
- {sovai-0.2.76 → sovai-0.2.78}/sovai/api_config.py +4 -1
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/signal_evaluation.py +3 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_data.py +164 -10
- {sovai-0.2.76 → sovai-0.2.78}/sovai/token_auth.py +24 -3
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/client_side_s3_part_high.py +76 -1
- {sovai-0.2.76 → sovai-0.2.78}/LICENSE +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/README.md +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/.DS_Store +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/assets/dropdown.css +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/basic_auth.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/computations/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/computations/functions.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/errors/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/errors/sovai_errors.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/anomalies.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/ask_df_llm.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/change_point_generator copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/change_point_generator.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/chart_explainer.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/clustering.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/core_kshape.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/cum_sum_torch.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/cusum.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/dimensionality_reduction.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/feature_extraction.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/feature_importance.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/feature_neutralizer.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/filter_df.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/fractional_differencing.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/nowcasting.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/overall_explainers.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/pairwise.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/pandas_extensions.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/parallel_functions.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/pfa_feature_selector.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/regime_change.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/regime_change_pca.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/shapley_global_importance.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/shapley_importance.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/signal_evaluation copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/signal_evaluation_old.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/table_explainer.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/technical_indicators.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/time_decomposition.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/extensions/weight_optimization.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_compute.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_data copy 2.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_data copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_reports.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/get_tools.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/accounting/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/accounting/accounting_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/allocation/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/allocation/allocation_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/bankruptcy/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/bankruptcy/bankruptcy_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/breakout/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/breakout/breakout_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/corp_risk/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/corp_risk/corp_risk_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/earnings_surprise/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/earnings_surprise/earnings_surprise_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/insider/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/insider/insider_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/institutional/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/institutional/institutional_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/news/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/news/news_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/ratios/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/plots/ratios/ratios_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/accounting/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/accounting/accounting_balance_sheet.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/bankruptcy/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/bankruptcy/bankruptcy_monthly_top.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/general/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/general/general_plots.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/news/__inti__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/reports/news/news_econometric_analysis.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/studies/nowcasting.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/authentication/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/authentication/authentication.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/explainers.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/sec/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/sec/graphs.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/sec/llm_code_generator.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/sec/sec_10_k_8_k_filings.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/tools/sec/sec_edgar_search.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/__init__.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/client_side.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/client_side_s3.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/converter.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/datetime_formats.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/file_management copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/file_management.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/get_tickers.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/helpers.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/pandas_extensions copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/plot.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/port_manager copy.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/port_manager.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/stream.py +0 -0
- {sovai-0.2.76 → sovai-0.2.78}/sovai/utils/verbose_utils.py +0 -0
|
@@ -14,6 +14,7 @@ class ApiConfig:
|
|
|
14
14
|
base_url: str = "https://data.sov.ai"
|
|
15
15
|
token_type: str = "Bearer"
|
|
16
16
|
verify_ssl: bool = True
|
|
17
|
+
version: Optional[str] = None
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def read_key(envpath: Union[str, Path]) -> Optional[str]:
|
|
@@ -45,7 +46,9 @@ def save_key(envpath: Union[str, Path] = ".env") -> None:
|
|
|
45
46
|
envpath = Path(envpath)
|
|
46
47
|
|
|
47
48
|
with open(envpath, "w", encoding="utf8") as fh:
|
|
48
|
-
fh.write(f"API_TOKEN={ApiConfig.token}")
|
|
49
|
+
fh.write(f"API_TOKEN={ApiConfig.token}\n")
|
|
50
|
+
if ApiConfig.version:
|
|
51
|
+
fh.write(f"API_VERSION={ApiConfig.version}\n")
|
|
49
52
|
|
|
50
53
|
|
|
51
54
|
def _lookup_token(config: dict[str, Optional[str]]) -> Optional[str]:
|
|
@@ -1182,7 +1182,10 @@ def stress_plotting(portfolio_returns):
|
|
|
1182
1182
|
start_date, end_date = min(all_dates), max(all_dates)
|
|
1183
1183
|
|
|
1184
1184
|
# Add horizontal lines for average returns of selected events
|
|
1185
|
+
# Only process events that exist in event_avg_returns (handles shorter time series)
|
|
1185
1186
|
for i, event in enumerate(selected_events):
|
|
1187
|
+
if event not in event_avg_returns:
|
|
1188
|
+
continue # Skip events not present in the data
|
|
1186
1189
|
avg_return = event_avg_returns[event]
|
|
1187
1190
|
color = color_map[list(event_returns.keys()).index(event) % len(color_map)]
|
|
1188
1191
|
fig.add_trace(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Optional, Union, Tuple, List, Dict, Any, Callable, TypeVar
|
|
1
|
+
from typing import Optional, Union, Tuple, List, Dict, Any, Callable, TypeVar, TYPE_CHECKING
|
|
2
2
|
import re
|
|
3
3
|
import time
|
|
4
4
|
import functools
|
|
@@ -20,7 +20,6 @@ from requests.exceptions import RequestException, ConnectionError, Timeout, HTTP
|
|
|
20
20
|
import boto3
|
|
21
21
|
import polars as pl
|
|
22
22
|
import pyarrow.parquet as pq
|
|
23
|
-
import plotly.graph_objects as go
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
# Local imports
|
|
@@ -41,16 +40,52 @@ logger = logging.getLogger(__name__)
|
|
|
41
40
|
T = TypeVar('T')
|
|
42
41
|
DataFrameType = Union[pd.DataFrame, pl.DataFrame, 'CustomDataFrame']
|
|
43
42
|
|
|
43
|
+
# Version-based column exclusions configuration
|
|
44
|
+
VERSION_COLUMN_EXCLUSIONS = {
|
|
45
|
+
"p72": {
|
|
46
|
+
"lobbying": {
|
|
47
|
+
"always": [
|
|
48
|
+
"registrant_name",
|
|
49
|
+
"registrant_address",
|
|
50
|
+
"registrant_contact_phone",
|
|
51
|
+
"registrant_contact_name",
|
|
52
|
+
"lobbyist_full_names",
|
|
53
|
+
"previous_government_positions",
|
|
54
|
+
"registrant_contact_telephone",
|
|
55
|
+
"lobbyist_ids",
|
|
56
|
+
"previous_goverment_positions"
|
|
57
|
+
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"cfpb": {
|
|
61
|
+
"always": ["consumer_complaint_narrative"]
|
|
62
|
+
},
|
|
63
|
+
"clinical_trials": {
|
|
64
|
+
"always": ["responsible_party_investigator_name"]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"sovai": {
|
|
68
|
+
# Define sovai version exclusions here if needed
|
|
69
|
+
# For now, no exclusions for sovai version
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
44
73
|
# Check for full installation
|
|
45
74
|
try:
|
|
46
75
|
from sovai.extensions.pandas_extensions import CustomDataFrame
|
|
47
|
-
from sovai.utils.plot import plotting_data
|
|
76
|
+
from sovai.utils.plot import plotting_data
|
|
77
|
+
import plotly.graph_objects as go
|
|
78
|
+
|
|
48
79
|
HAS_FULL_INSTALL = True
|
|
49
80
|
except ImportError:
|
|
50
81
|
HAS_FULL_INSTALL = False
|
|
51
82
|
CustomDataFrame = pd.DataFrame # Fallback if not available
|
|
52
83
|
plotting_data = lambda x: None # Fallback
|
|
53
84
|
logger.warning("Running with limited installation. Some features unavailable.")
|
|
85
|
+
|
|
86
|
+
# Create a mock go module for type hints when full install is not available
|
|
87
|
+
if TYPE_CHECKING:
|
|
88
|
+
import plotly.graph_objects as go
|
|
54
89
|
|
|
55
90
|
|
|
56
91
|
def is_full_installation() -> bool:
|
|
@@ -337,6 +372,7 @@ ENDPOINT_TO_TICKER = {
|
|
|
337
372
|
"/breakout/median": "",
|
|
338
373
|
"/institutional/trading": "",
|
|
339
374
|
"/institutional/flow_prediction": "",
|
|
375
|
+
|
|
340
376
|
"/news/daily": "",
|
|
341
377
|
"/news/match_quality": "",
|
|
342
378
|
"/news/within_article": "",
|
|
@@ -353,6 +389,7 @@ ENDPOINT_TO_TICKER = {
|
|
|
353
389
|
"/news/activeness": "",
|
|
354
390
|
"/news/pronouns": "",
|
|
355
391
|
"/news/word_count": "",
|
|
392
|
+
|
|
356
393
|
"/news/sentiment_score": "", # was None before?
|
|
357
394
|
|
|
358
395
|
"/insider/trading": "",
|
|
@@ -480,7 +517,24 @@ CLIENT_SIDE_ENDPOINTS_S3_PART_HIGH = {
|
|
|
480
517
|
"short/maker",
|
|
481
518
|
"short/over_shorted",
|
|
482
519
|
|
|
483
|
-
"institutional/trading"
|
|
520
|
+
"institutional/trading",
|
|
521
|
+
|
|
522
|
+
"news/daily",
|
|
523
|
+
"news/match_quality",
|
|
524
|
+
"news/within_article",
|
|
525
|
+
"news/relevance",
|
|
526
|
+
"news/magnitude",
|
|
527
|
+
"news/sentiment",
|
|
528
|
+
"news/article_count",
|
|
529
|
+
"news/associated_people",
|
|
530
|
+
"news/associated_companies",
|
|
531
|
+
"news/tone",
|
|
532
|
+
"news/positive",
|
|
533
|
+
"news/negative",
|
|
534
|
+
"news/polarity",
|
|
535
|
+
"news/activeness",
|
|
536
|
+
"news/pronouns",
|
|
537
|
+
"news/word_count"
|
|
484
538
|
|
|
485
539
|
}
|
|
486
540
|
|
|
@@ -691,6 +745,93 @@ def read_parquet(url: str, use_polars: bool = False) -> DataFrameType:
|
|
|
691
745
|
|
|
692
746
|
DEFAULT_COLUMNS_TO_REMOVE = ['ticker_partitioned', 'date_partitioned', 'year_partitioned', 'month_partitioned', 'day_partitioned']
|
|
693
747
|
|
|
748
|
+
|
|
749
|
+
def detect_dataset_type(endpoint: str) -> Optional[str]:
|
|
750
|
+
"""
|
|
751
|
+
Detect dataset type from endpoint URL for version-based column exclusions.
|
|
752
|
+
|
|
753
|
+
Args:
|
|
754
|
+
endpoint: The API endpoint path
|
|
755
|
+
|
|
756
|
+
Returns:
|
|
757
|
+
Dataset type string ('lobbying', 'cfpb', 'clinical_trials') or None
|
|
758
|
+
"""
|
|
759
|
+
endpoint_lower = endpoint.lower().strip('/')
|
|
760
|
+
|
|
761
|
+
if 'lobbying' in endpoint_lower:
|
|
762
|
+
return 'lobbying'
|
|
763
|
+
elif 'complaint' in endpoint_lower or 'cfpb' in endpoint_lower:
|
|
764
|
+
return 'cfpb'
|
|
765
|
+
elif 'clinical' in endpoint_lower or 'trial' in endpoint_lower:
|
|
766
|
+
return 'clinical_trials'
|
|
767
|
+
|
|
768
|
+
return None
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
def apply_version_exclusions(
|
|
772
|
+
data: DataFrameType,
|
|
773
|
+
version: Optional[str],
|
|
774
|
+
endpoint: str,
|
|
775
|
+
use_polars: bool = False
|
|
776
|
+
) -> DataFrameType:
|
|
777
|
+
"""
|
|
778
|
+
Apply version-based column exclusions to a DataFrame.
|
|
779
|
+
|
|
780
|
+
Args:
|
|
781
|
+
data: Input DataFrame
|
|
782
|
+
version: Version parameter (e.g., 'p72', 'sovai')
|
|
783
|
+
endpoint: API endpoint to detect dataset type
|
|
784
|
+
use_polars: Whether using polars DataFrame
|
|
785
|
+
|
|
786
|
+
Returns:
|
|
787
|
+
DataFrame with excluded columns removed
|
|
788
|
+
"""
|
|
789
|
+
if data is None or (hasattr(data, 'empty') and data.empty):
|
|
790
|
+
return data
|
|
791
|
+
|
|
792
|
+
if not version or version not in VERSION_COLUMN_EXCLUSIONS:
|
|
793
|
+
return data
|
|
794
|
+
|
|
795
|
+
dataset_type = detect_dataset_type(endpoint)
|
|
796
|
+
if not dataset_type:
|
|
797
|
+
return data
|
|
798
|
+
|
|
799
|
+
version_config = VERSION_COLUMN_EXCLUSIONS.get(version, {})
|
|
800
|
+
dataset_config = version_config.get(dataset_type, {})
|
|
801
|
+
|
|
802
|
+
if not dataset_config:
|
|
803
|
+
return data
|
|
804
|
+
|
|
805
|
+
# Get columns to exclude
|
|
806
|
+
columns_to_exclude = dataset_config.get('always', [])
|
|
807
|
+
|
|
808
|
+
if not columns_to_exclude:
|
|
809
|
+
return data
|
|
810
|
+
|
|
811
|
+
# Case-insensitive matching - find columns that exist in the DataFrame
|
|
812
|
+
data_columns = list(data.columns)
|
|
813
|
+
data_columns_lower = {col.lower(): col for col in data_columns}
|
|
814
|
+
|
|
815
|
+
actual_columns_to_exclude = []
|
|
816
|
+
for exclude_col in columns_to_exclude:
|
|
817
|
+
exclude_col_lower = exclude_col.lower()
|
|
818
|
+
if exclude_col_lower in data_columns_lower:
|
|
819
|
+
actual_columns_to_exclude.append(data_columns_lower[exclude_col_lower])
|
|
820
|
+
|
|
821
|
+
if not actual_columns_to_exclude:
|
|
822
|
+
verbose_mode.log(f"Version {version}: No matching columns found to exclude for {dataset_type}")
|
|
823
|
+
return data
|
|
824
|
+
|
|
825
|
+
verbose_mode.log(f"Version {version}: Excluding columns {actual_columns_to_exclude} from {dataset_type}")
|
|
826
|
+
|
|
827
|
+
# Remove the columns
|
|
828
|
+
if use_polars:
|
|
829
|
+
columns_to_keep = [col for col in data.columns if col not in actual_columns_to_exclude]
|
|
830
|
+
return data.select(columns_to_keep)
|
|
831
|
+
else: # pandas
|
|
832
|
+
return data.drop(columns=actual_columns_to_exclude, errors='ignore')
|
|
833
|
+
|
|
834
|
+
|
|
694
835
|
def filter_data(
|
|
695
836
|
data: DataFrameType,
|
|
696
837
|
columns: Optional[Union[str, List[str]]] = None,
|
|
@@ -1156,7 +1297,7 @@ def _uniform_datetime_params(datetime_params: Dict[str, str]) -> None:
|
|
|
1156
1297
|
logger.debug(f"Date parameter '{key}' with value '{original_val}' did not match any known formats: {datetime_format}. Leaving as is.")
|
|
1157
1298
|
|
|
1158
1299
|
|
|
1159
|
-
def _draw_graphs(data: Union[Dict, List[Dict]]) -> Optional[go.Figure]:
|
|
1300
|
+
def _draw_graphs(data: Union[Dict, List[Dict]]) -> Optional['go.Figure']:
|
|
1160
1301
|
"""
|
|
1161
1302
|
Generate plots from data.
|
|
1162
1303
|
|
|
@@ -1206,7 +1347,7 @@ def _draw_graphs(data: Union[Dict, List[Dict]]) -> Optional[go.Figure]:
|
|
|
1206
1347
|
return None
|
|
1207
1348
|
|
|
1208
1349
|
|
|
1209
|
-
def set_dark_mode(fig: go.Figure) -> go.Figure:
|
|
1350
|
+
def set_dark_mode(fig: 'go.Figure') -> 'go.Figure':
|
|
1210
1351
|
"""
|
|
1211
1352
|
Apply dark mode styling to a Plotly figure.
|
|
1212
1353
|
|
|
@@ -1305,7 +1446,7 @@ def data(
|
|
|
1305
1446
|
verbose: bool = False,
|
|
1306
1447
|
full_history: bool = False,
|
|
1307
1448
|
source: Optional[str] = None,
|
|
1308
|
-
) -> Union[DataFrameType, go.Figure, None]:
|
|
1449
|
+
) -> Union[DataFrameType, 'go.Figure', None]:
|
|
1309
1450
|
"""
|
|
1310
1451
|
Main function to retrieve data from the API.
|
|
1311
1452
|
Caches results to disk in 'cache/' directory (Parquet for DataFrames, Pickle for Figures).
|
|
@@ -1594,7 +1735,20 @@ def data(
|
|
|
1594
1735
|
except Exception as err: verbose_mode.log(f"General API/processing error: {err}"); raise
|
|
1595
1736
|
|
|
1596
1737
|
if result_data is not None:
|
|
1597
|
-
result_data = process_dataframe(result_data)
|
|
1738
|
+
result_data = process_dataframe(result_data)
|
|
1739
|
+
|
|
1740
|
+
# Apply version-based column exclusions if a version is set
|
|
1741
|
+
# Use the version from function parameter, or fall back to ApiConfig.version
|
|
1742
|
+
effective_version = version if version is not None else ApiConfig.version
|
|
1743
|
+
|
|
1744
|
+
if effective_version and isinstance(result_data, (pd.DataFrame, pl.DataFrame)):
|
|
1745
|
+
verbose_mode.log(f"Applying version-based exclusions for version: {effective_version}")
|
|
1746
|
+
result_data = apply_version_exclusions(
|
|
1747
|
+
result_data,
|
|
1748
|
+
effective_version,
|
|
1749
|
+
final_endpoint_path,
|
|
1750
|
+
use_polars
|
|
1751
|
+
)
|
|
1598
1752
|
|
|
1599
1753
|
if forced_columns_list is not None and isinstance(result_data, (pd.DataFrame, pl.DataFrame)):
|
|
1600
1754
|
current_data_cols = list(result_data.columns)
|
|
@@ -1617,7 +1771,7 @@ async def fetch_multiple_tickers(
|
|
|
1617
1771
|
endpoint: str,
|
|
1618
1772
|
tickers: List[str],
|
|
1619
1773
|
**kwargs
|
|
1620
|
-
) -> Dict[str, Union[DataFrameType, go.Figure, None]]: # Updated return type hint
|
|
1774
|
+
) -> Dict[str, Union[DataFrameType, 'go.Figure', None]]: # Updated return type hint
|
|
1621
1775
|
"""
|
|
1622
1776
|
Fetch data for multiple tickers concurrently using asyncio.
|
|
1623
1777
|
|
|
@@ -1752,4 +1906,4 @@ ApiConfig.base_url = "your_api_base_url_here" # Ensure base_url is set
|
|
|
1752
1906
|
|
|
1753
1907
|
# if __name__ == "__main__":
|
|
1754
1908
|
# asyncio.run(main())
|
|
1755
|
-
"""
|
|
1909
|
+
"""
|
|
@@ -1,16 +1,37 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from sovai.api_config import ApiConfig, save_key
|
|
2
3
|
# Removed verify_token import from top level
|
|
3
4
|
from sovai.errors.sovai_errors import InvalidCredentialsError
|
|
4
5
|
|
|
6
|
+
# Valid version values
|
|
7
|
+
VALID_VERSIONS = ["p72", "sovai"]
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
def token_auth(token: str, version: Optional[str] = None):
|
|
11
|
+
"""
|
|
12
|
+
Authenticates using a token, saves it, and verifies it.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
token: API authentication token
|
|
16
|
+
version: Optional version parameter for column exclusions (e.g., 'p72', 'sovai')
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
InvalidCredentialsError: If token is invalid or expired
|
|
20
|
+
ValueError: If version is provided but not in the list of valid versions
|
|
21
|
+
"""
|
|
22
|
+
# Validate version if provided
|
|
23
|
+
if version is not None and version not in VALID_VERSIONS:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"Invalid version '{version}'. Must be one of: {', '.join(VALID_VERSIONS)}"
|
|
26
|
+
)
|
|
8
27
|
|
|
9
28
|
# Lazy load verify_token here, just before use
|
|
10
29
|
from sovai.utils.client_side import verify_token
|
|
11
30
|
|
|
12
31
|
ApiConfig.token = token
|
|
13
32
|
ApiConfig.token_type = "Bearer"
|
|
33
|
+
ApiConfig.version = version
|
|
34
|
+
|
|
14
35
|
save_key() # Assumes save_key doesn't trigger heavy imports
|
|
15
36
|
|
|
16
37
|
# Now call the imported function
|
|
@@ -22,4 +43,4 @@ def token_auth(token: str):
|
|
|
22
43
|
|
|
23
44
|
# Optionally, you could return something useful, like the validity or user_id
|
|
24
45
|
# print(f"Token verified successfully for user ID: {user_id}") # Or use logging
|
|
25
|
-
# return is_valid, user_id
|
|
46
|
+
# return is_valid, user_id
|
|
@@ -875,10 +875,85 @@ ENDPOINT_CONFIG = {
|
|
|
875
875
|
"date_path": "sovai/sovai-institutional/trading/partitioned/date",
|
|
876
876
|
"has_year": False
|
|
877
877
|
},
|
|
878
|
-
|
|
878
|
+
"news/match_quality": {
|
|
879
|
+
"ticker_path": "sovai/sovai-news/partitioned/match_quality/ticker",
|
|
880
|
+
"date_path": "sovai/sovai-news/partitioned/match_quality/date",
|
|
881
|
+
"has_year": False
|
|
882
|
+
},
|
|
883
|
+
"news/within_article": {
|
|
884
|
+
"ticker_path": "sovai/sovai-news/partitioned/within_article/ticker",
|
|
885
|
+
"date_path": "sovai/sovai-news/partitioned/within_article/date",
|
|
886
|
+
"has_year": False
|
|
887
|
+
},
|
|
888
|
+
"news/relevance": {
|
|
889
|
+
"ticker_path": "sovai/sovai-news/partitioned/relevance/ticker",
|
|
890
|
+
"date_path": "sovai/sovai-news/partitioned/relevance/date",
|
|
891
|
+
"has_year": False
|
|
892
|
+
},
|
|
893
|
+
"news/magnitude": {
|
|
894
|
+
"ticker_path": "sovai/sovai-news/partitioned/magnitude/ticker",
|
|
895
|
+
"date_path": "sovai/sovai-news/partitioned/magnitude/date",
|
|
896
|
+
"has_year": False
|
|
897
|
+
},
|
|
898
|
+
"news/sentiment": {
|
|
899
|
+
"ticker_path": "sovai/sovai-news/partitioned/sentiment/ticker",
|
|
900
|
+
"date_path": "sovai/sovai-news/partitioned/sentiment/date",
|
|
901
|
+
"has_year": False
|
|
902
|
+
},
|
|
903
|
+
"news/article_count": {
|
|
904
|
+
"ticker_path": "sovai/sovai-news/partitioned/article_count/ticker",
|
|
905
|
+
"date_path": "sovai/sovai-news/partitioned/article_count/date",
|
|
906
|
+
"has_year": False
|
|
907
|
+
},
|
|
908
|
+
"news/associated_people": {
|
|
909
|
+
"ticker_path": "sovai/sovai-news/partitioned/associated_people/ticker",
|
|
910
|
+
"date_path": "sovai/sovai-news/partitioned/associated_people/date",
|
|
911
|
+
"has_year": False
|
|
912
|
+
},
|
|
913
|
+
"news/associated_companies": {
|
|
914
|
+
"ticker_path": "sovai/sovai-news/partitioned/associated_companies/ticker",
|
|
915
|
+
"date_path": "sovai/sovai-news/partitioned/associated_companies/date",
|
|
916
|
+
"has_year": False
|
|
917
|
+
},
|
|
918
|
+
"news/tone": {
|
|
919
|
+
"ticker_path": "sovai/sovai-news/partitioned/tone/ticker",
|
|
920
|
+
"date_path": "sovai/sovai-news/partitioned/tone/date",
|
|
921
|
+
"has_year": False
|
|
922
|
+
},
|
|
923
|
+
"news/positive": {
|
|
924
|
+
"ticker_path": "sovai/sovai-news/partitioned/positive/ticker",
|
|
925
|
+
"date_path": "sovai/sovai-news/partitioned/positive/date",
|
|
926
|
+
"has_year": False
|
|
927
|
+
},
|
|
928
|
+
"news/negative": {
|
|
929
|
+
"ticker_path": "sovai/sovai-news/partitioned/negative/ticker",
|
|
930
|
+
"date_path": "sovai/sovai-news/partitioned/negative/date",
|
|
931
|
+
"has_year": False
|
|
932
|
+
},
|
|
933
|
+
"news/polarity": {
|
|
934
|
+
"ticker_path": "sovai/sovai-news/partitioned/polarity/ticker",
|
|
935
|
+
"date_path": "sovai/sovai-news/partitioned/polarity/date",
|
|
936
|
+
"has_year": False
|
|
937
|
+
},
|
|
938
|
+
"news/activeness": {
|
|
939
|
+
"ticker_path": "sovai/sovai-news/partitioned/activeness/ticker",
|
|
940
|
+
"date_path": "sovai/sovai-news/partitioned/activeness/date",
|
|
941
|
+
"has_year": False
|
|
942
|
+
},
|
|
943
|
+
"news/pronouns": {
|
|
944
|
+
"ticker_path": "sovai/sovai-news/partitioned/pronouns/ticker",
|
|
945
|
+
"date_path": "sovai/sovai-news/partitioned/pronouns/date",
|
|
946
|
+
"has_year": False
|
|
947
|
+
},
|
|
948
|
+
"news/word_count": {
|
|
949
|
+
"ticker_path": "sovai/sovai-news/partitioned/word_count/ticker",
|
|
950
|
+
"date_path": "sovai/sovai-news/partitioned/word_count/date",
|
|
951
|
+
"has_year": False
|
|
952
|
+
}
|
|
879
953
|
}
|
|
880
954
|
|
|
881
955
|
|
|
956
|
+
|
|
882
957
|
# =========================================================================
|
|
883
958
|
# Public Interface
|
|
884
959
|
# =========================================================================
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|