sovai 0.2.32__tar.gz → 0.2.34__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 (96) hide show
  1. {sovai-0.2.32 → sovai-0.2.34}/PKG-INFO +1 -1
  2. {sovai-0.2.32 → sovai-0.2.34}/pyproject.toml +1 -1
  3. sovai-0.2.34/sovai/.DS_Store +0 -0
  4. {sovai-0.2.32 → sovai-0.2.34}/sovai/api_config.py +1 -1
  5. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/filter_df.py +1 -209
  6. {sovai-0.2.32 → sovai-0.2.34}/sovai/get_compute.py +1 -1
  7. {sovai-0.2.32 → sovai-0.2.34}/sovai/get_data.py +70 -15
  8. {sovai-0.2.32 → sovai-0.2.34}/sovai/get_plots.py +3 -3
  9. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/earnings_surprise/earnings_surprise_plots.py +5 -1
  10. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/client_side_s3.py +50 -15
  11. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/plot.py +1 -0
  12. {sovai-0.2.32 → sovai-0.2.34}/LICENSE +0 -0
  13. {sovai-0.2.32 → sovai-0.2.34}/README.md +0 -0
  14. {sovai-0.2.32 → sovai-0.2.34}/sovai/__init__.py +0 -0
  15. {sovai-0.2.32 → sovai-0.2.34}/sovai/assets/dropdown.css +0 -0
  16. {sovai-0.2.32 → sovai-0.2.34}/sovai/assets/features_mapping.parq +0 -0
  17. {sovai-0.2.32 → sovai-0.2.34}/sovai/basic_auth.py +0 -0
  18. {sovai-0.2.32 → sovai-0.2.34}/sovai/computations/__init__.py +0 -0
  19. {sovai-0.2.32 → sovai-0.2.34}/sovai/computations/functions.py +0 -0
  20. {sovai-0.2.32 → sovai-0.2.34}/sovai/errors/__init__.py +0 -0
  21. {sovai-0.2.32 → sovai-0.2.34}/sovai/errors/sovai_errors.py +0 -0
  22. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/__init__.py +0 -0
  23. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/anomalies.py +0 -0
  24. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/ask_df_llm.py +0 -0
  25. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/change_point_generator.py +0 -0
  26. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/clustering.py +0 -0
  27. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/core_kshape.py +0 -0
  28. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/cum_sum_torch.py +0 -0
  29. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/cusum.py +0 -0
  30. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/dimensionality_reduction.py +0 -0
  31. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/feature_extraction.py +0 -0
  32. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/feature_importance.py +0 -0
  33. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/feature_neutralizer.py +0 -0
  34. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/fractional_differencing.py +0 -0
  35. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/nowcasting.py +0 -0
  36. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/pairwise.py +0 -0
  37. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/pandas_extensions.py +0 -0
  38. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/parallel_functions.py +0 -0
  39. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/pfa_feature_selector.py +0 -0
  40. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/regime_change.py +0 -0
  41. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/regime_change_pca.py +0 -0
  42. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/shapley_global_importance.py +0 -0
  43. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/shapley_importance.py +0 -0
  44. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/signal_evaluation.py +0 -0
  45. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/technical_indicators.py +0 -0
  46. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/time_decomposition.py +0 -0
  47. {sovai-0.2.32 → sovai-0.2.34}/sovai/extensions/weight_optimization.py +0 -0
  48. {sovai-0.2.32 → sovai-0.2.34}/sovai/get_reports.py +0 -0
  49. {sovai-0.2.32 → sovai-0.2.34}/sovai/get_tools.py +0 -0
  50. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/__init__.py +0 -0
  51. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/accounting/__init__.py +0 -0
  52. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/accounting/accounting_plots.py +0 -0
  53. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/allocation/__init__.py +0 -0
  54. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/allocation/allocation_plots.py +0 -0
  55. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/bankruptcy/__init__.py +0 -0
  56. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/bankruptcy/bankruptcy_plots.py +0 -0
  57. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/breakout/__init__.py +0 -0
  58. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/breakout/breakout_plots.py +0 -0
  59. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/corp_risk/__init__.py +0 -0
  60. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/corp_risk/corp_risk_plots.py +0 -0
  61. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/earnings_surprise/__init__.py +0 -0
  62. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/insider/__init__.py +0 -0
  63. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/insider/insider_plots.py +0 -0
  64. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/institutional/__init__.py +0 -0
  65. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/institutional/institutional_plots.py +0 -0
  66. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/news/__init__.py +0 -0
  67. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/news/news_plots.py +0 -0
  68. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/ratios/__init__.py +0 -0
  69. {sovai-0.2.32 → sovai-0.2.34}/sovai/plots/ratios/ratios_plots.py +0 -0
  70. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/accounting/__init__.py +0 -0
  71. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/accounting/accounting_balance_sheet.py +0 -0
  72. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/bankruptcy/__init__.py +0 -0
  73. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/bankruptcy/bankruptcy_monthly_top.py +0 -0
  74. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/general/__init__.py +0 -0
  75. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/general/general_plots.py +0 -0
  76. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/news/__inti__.py +0 -0
  77. {sovai-0.2.32 → sovai-0.2.34}/sovai/reports/news/news_econometric_analysis.py +0 -0
  78. {sovai-0.2.32 → sovai-0.2.34}/sovai/studies/nowcasting.py +0 -0
  79. {sovai-0.2.32 → sovai-0.2.34}/sovai/token_auth.py +0 -0
  80. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/authentication/__init__.py +0 -0
  81. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/authentication/authentication.py +0 -0
  82. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/sec/__init__.py +0 -0
  83. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/sec/graphs.py +0 -0
  84. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/sec/llm_code_generator.py +0 -0
  85. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/sec/sec_10_k_8_k_filings.py +0 -0
  86. {sovai-0.2.32 → sovai-0.2.34}/sovai/tools/sec/sec_edgar_search.py +0 -0
  87. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/__init__.py +0 -0
  88. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/client_side.py +0 -0
  89. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/converter.py +0 -0
  90. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/datetime_formats.py +0 -0
  91. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/file_management.py +0 -0
  92. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/get_tickers.py +0 -0
  93. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/helpers.py +0 -0
  94. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/pandas_extensions copy.py +0 -0
  95. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/port_manager.py +0 -0
  96. {sovai-0.2.32 → sovai-0.2.34}/sovai/utils/stream.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sovai
3
- Version: 0.2.32
3
+ Version: 0.2.34
4
4
  Summary: python for asset management
5
5
  License: Proprietary License
6
6
  Author: Derek Snow
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "sovai"
3
- version = "0.2.32"
3
+ version = "0.2.34"
4
4
  description = "python for asset management"
5
5
  authors = ["Derek Snow <d.snow@outlook.com>"]
6
6
  license = "Proprietary License"
Binary file
@@ -3,7 +3,7 @@ from typing import Optional, Union
3
3
 
4
4
  from dotenv import dotenv_values
5
5
 
6
- ### save
6
+ ### save le chose a faire.
7
7
 
8
8
  class ApiConfig:
9
9
  """
@@ -1,211 +1,3 @@
1
- import pandas as pd
2
- import re
3
- import time
4
- from typing import Union, List, Tuple
5
- from functools import wraps
6
- from rapidfuzz import process, fuzz
7
- from sovai.tools.sec.llm_code_generator import get_openai_key
8
- from collections import deque
9
- from datetime import datetime, timedelta
10
- import openai
11
- from textwrap import dedent
12
- from functools import lru_cache
13
-
14
- def with_openai_key(func):
15
- @wraps(func)
16
- def wrapper(*args, **kwargs):
17
- openai.api_key = get_openai_key()
18
- try:
19
- return func(*args, **kwargs)
20
- finally:
21
- openai.api_key = None
22
- return wrapper
23
-
24
- class Filter:
25
- _call_timestamps = deque()
26
- _max_calls_per_minute = 10
27
- _ask_cache = {}
28
- verbose = False
29
- mutable = False
30
- models = ['gpt-3.5-turbo', 'gpt-4']
31
- completion_config = {}
32
-
33
-
34
- @staticmethod
35
- @lru_cache(maxsize=1)
36
- def _load_combined_df():
37
- return pd.read_parquet("https://storage.googleapis.com/sovai-public/concats/filters/latest.parquet")
38
-
39
-
40
- @classmethod
41
- def _check_rate_limit(cls):
42
- now = datetime.now()
43
- while cls._call_timestamps and cls._call_timestamps[0] < now - timedelta(minutes=1):
44
- cls._call_timestamps.popleft()
45
-
46
- if len(cls._call_timestamps) >= cls._max_calls_per_minute:
47
- raise ValueError("Slow down mate! You've reached the maximum number of filtering attempts per minute.")
48
-
49
- cls._call_timestamps.append(now)
50
-
51
- @staticmethod
52
- def rate_limit_decorator(func):
53
- @wraps(func)
54
- def wrapper(*args, **kwargs):
55
- Filter._check_rate_limit()
56
- return func(*args, **kwargs)
57
- return wrapper
58
-
59
- @staticmethod
60
- def _find_best_match(query: str, choices: List[str], threshold: int = 80) -> Union[str, None]:
61
- best_match = process.extractOne(query, choices, scorer=fuzz.ratio, score_cutoff=threshold)
62
- return best_match[0] if best_match else None
63
-
64
- @staticmethod
65
- def _parse_value(value: str) -> Union[float, int]:
66
- multipliers = {'k': 1e3, 'm': 1e6, 'b': 1e9}
67
- if value.endswith('%'):
68
- return float(value.rstrip('%')) / 100
69
- for suffix, multiplier in multipliers.items():
70
- if value.lower().endswith(suffix):
71
- return float(value[:-1]) * multiplier
72
- return float(value)
73
-
74
- @classmethod
75
- def _create_standard_query(cls, condition: str, df: pd.DataFrame) -> Tuple[str, str]:
76
- pattern = r'(\w+)\s*([<>=]+|like|contains)\s*(.+)'
77
- match = re.match(pattern, condition, re.IGNORECASE)
78
- if not match:
79
- raise ValueError(f"Invalid condition format: {condition}")
80
-
81
- column, operator, value = match.groups()
82
- best_match = cls._find_best_match(column, df.columns.tolist())
83
- if not best_match:
84
- raise ValueError(f"No close match found for column: {column}")
85
-
86
- original_column = column
87
- column = best_match
88
-
89
- operator = operator.lower().strip()
90
- value = value.strip()
91
-
92
- is_string_type = df[column].dtype == 'object'
93
-
94
- if operator in ['like', 'contains'] or (operator == '=' and is_string_type):
95
- query = f"`{column}`.str.contains('{value}', case=False, na=False)"
96
- display_operator = 'like'
97
- else:
98
- parsed_value = cls._parse_value(value)
99
- query = f"`{column}` {operator} {parsed_value}"
100
- display_operator = operator
101
-
102
- display_condition = f"{column} ({original_column}) {display_operator} {value}" if column != original_column else condition
103
- return query, display_condition
104
-
105
- @staticmethod
106
- def _is_simple_condition(condition: str) -> bool:
107
- simple_pattern = r'\w+\s*([<>=]+|like|contains)\s*.+'
108
- return bool(re.match(simple_pattern, condition, re.IGNORECASE))
109
-
110
- @staticmethod
111
- def _split_conditions(condition: str) -> List[str]:
112
- pattern = r'\s+(?:and|or)\s+(?![^()]*\))'
113
- conditions = re.split(pattern, condition, flags=re.IGNORECASE)
114
- return [cond.strip() for cond in conditions if cond.strip()]
115
-
116
- @classmethod
117
- @rate_limit_decorator
118
- @with_openai_key
119
- def _apply_condition_with_retry(cls, df: pd.DataFrame, condition: str, max_retries: int = 3, verbose: bool = False) -> pd.DataFrame:
120
- original_len = len(df)
121
-
122
- sub_conditions = cls._split_conditions(condition)
123
- if len(sub_conditions) > 1:
124
- if verbose:
125
- print(f"Detected multiple conditions: {sub_conditions}")
126
- for sub_condition in sub_conditions:
127
- df = cls._apply_condition_with_retry(df, sub_condition, max_retries, verbose)
128
- return df
129
-
130
- if cls._is_simple_condition(condition):
131
- try:
132
- query, display_condition = cls._create_standard_query(condition, df)
133
- filtered_df = df.query(query)
134
- if len(filtered_df) < original_len:
135
- if verbose:
136
- print(f"Applied standard filter: {display_condition}")
137
- return filtered_df
138
- except Exception as e:
139
- if verbose:
140
- print(f"Standard filtering failed: {str(e)}. Falling back to GPT method.")
141
-
142
- for attempt in range(max_retries):
143
- try:
144
- filtered_df = df.ask(condition)
145
- if isinstance(filtered_df, pd.DataFrame) and len(filtered_df) < original_len:
146
- return filtered_df
147
- elif verbose:
148
- print(f"Attempt {attempt + 1}: GPT filtering didn't remove any rows. Retrying...")
149
-
150
- alternative_conditions = [f"filter {condition}", f"select {condition}", f"find {condition}"]
151
- for alt_condition in alternative_conditions:
152
- try:
153
- filtered_df = df.ask(alt_condition)
154
- if isinstance(filtered_df, pd.DataFrame) and len(filtered_df) < original_len:
155
- return filtered_df
156
- except Exception:
157
- pass
158
-
159
- columns_str = ", ".join(df.columns)
160
- general_condition = f"Based on the columns {columns_str}, {condition}"
161
- filtered_df = df.ask(general_condition)
162
- if isinstance(filtered_df, pd.DataFrame) and len(filtered_df) < original_len:
163
- return filtered_df
164
- except Exception as e:
165
- if verbose:
166
- print(f"Error on GPT attempt {attempt + 1}: {str(e)}")
167
- time.sleep(1)
168
-
169
- if verbose:
170
- print("All filtering attempts failed. Returning original DataFrame.")
171
- return df
172
-
173
-
174
- @staticmethod
175
- def create_table(data, headers):
176
- col_widths = [max(len(str(x)) for x in col) for col in zip(*data, headers)]
177
- col_widths = [max(15, width) for width in col_widths]
178
-
179
- row_format = '│ {:<{}} │ {:>{}} │ {:>{}} │ {:>{}} │'
180
- header = row_format.format(headers[0], col_widths[0],
181
- headers[1], col_widths[1],
182
- headers[2], col_widths[2],
183
- headers[3], col_widths[3])
184
-
185
- separator = '┼' + '─' * (col_widths[0] + 2) + '┼' + '─' * (col_widths[1] + 2) + '┼' + '─' * (col_widths[2] + 2) + '┼' + '─' * (col_widths[3] + 2) + '┼'
186
- top_border = '┌' + '─' * (col_widths[0] + 2) + '┬' + '─' * (col_widths[1] + 2) + '┬' + '─' * (col_widths[2] + 2) + '┬' + '─' * (col_widths[3] + 2) + '┐'
187
- bottom_border = '└' + '─' * (col_widths[0] + 2) + '┴' + '─' * (col_widths[1] + 2) + '┴' + '─' * (col_widths[2] + 2) + '┴' + '─' * (col_widths[3] + 2) + '┘'
188
-
189
- rows = []
190
- for i, row in enumerate(data):
191
- if i == 0: # Initial row
192
- formatted_row = row_format.format(row[0], col_widths[0],
193
- f"{row[1]:,}", col_widths[1],
194
- '-', col_widths[2],
195
- '-', col_widths[3])
196
- elif i == len(data) - 1: # Final row
197
- formatted_row = row_format.format(row[0], col_widths[0],
198
- f"{data[0][1]:,}", col_widths[1],
199
- f"{row[2]:,}", col_widths[2],
200
- f"{row[1]:,}", col_widths[3])
201
- else: # Other rows
202
- formatted_row = row_format.format(row[0], col_widths[0],
203
- f"{row[1]:,}", col_widths[1],
204
- f"{row[2]:,}", col_widths[2],
205
- f"{row[1]:,}", col_widths[3])
206
- rows.append(formatted_row)
207
-
208
- return '\n'.join([top_border, header, separator] + rows[:-1] + [separator, rows[-1], bottom_border])
209
1
 
210
2
  import pandas as pd
211
3
  import re
@@ -243,7 +35,7 @@ class Filter:
243
35
  @staticmethod
244
36
  @lru_cache(maxsize=1)
245
37
  def _load_combined_df():
246
- return pd.read_parquet("https://storage.googleapis.com/sovai-public/combined/latest_values.parquet")
38
+ return pd.read_parquet("https://storage.googleapis.com/sovai-public/concats/filters/latest.parquet")
247
39
 
248
40
 
249
41
  @classmethod
@@ -1,4 +1,4 @@
1
- # Inside plot/get_plot.py
1
+ # Inside plot/get_plot.py ##
2
2
  from .computations.functions import *
3
3
 
4
4
  COMPUTE_FUNCTION_MAPPER = {
@@ -10,7 +10,7 @@ import pyarrow.parquet as pq
10
10
  from io import BytesIO
11
11
  import boto3
12
12
  import polars as pl
13
-
13
+ import plotly.graph_objects as go
14
14
  # from fastapi import HTTPException ## Dee
15
15
 
16
16
  import pyarrow.parquet as pq
@@ -243,7 +243,7 @@ endpoint_to_ticker = {
243
243
  "/spending/competition": "",
244
244
  "/spending/entities": "",
245
245
  "/accounting/weekly": "",
246
- "/visa/h1b": "",
246
+ "/visas/h1b": "",
247
247
  "/factors/accounting": "",
248
248
  "/factors/alternative": "",
249
249
  "/factors/comprehensive": "",
@@ -257,6 +257,7 @@ endpoint_to_ticker = {
257
257
  "/complaints/private": "",
258
258
  "/complaints/public": "",
259
259
  "/short/over_shorted": "",
260
+ "/short/volume": "",
260
261
  "/earnings/surprise": "",
261
262
  "/news/sentiment_score": "",
262
263
  "/news/topic_probability": "",
@@ -264,8 +265,15 @@ endpoint_to_ticker = {
264
265
  "/macro/features": "",
265
266
  "/congress": "",
266
267
  "/market/closeadj": "",
268
+ "/lobbying/public": "",
267
269
 
268
270
 
271
+ ## remember to add leading "/"
272
+ "/trials/predict": "",
273
+ "/trials/describe": "",
274
+ "/trials/all/predict": "",
275
+ "/trials/all/decribe": "",
276
+ "/trials/all": ""
269
277
 
270
278
 
271
279
  }
@@ -282,6 +290,8 @@ def normalize_endpoint(endpoint):
282
290
  return endpoint.strip("/").strip()
283
291
 
284
292
 
293
+ ## If you also want access by full file, please also add to endpoint_to_ticker
294
+
285
295
  client_side_endpoints_gcs = {
286
296
  "ratios/relative",
287
297
  "market/prices",
@@ -292,10 +302,19 @@ client_side_endpoints_gcs = {
292
302
  "lobbying/public",
293
303
  }
294
304
 
305
+ ## If you also want access by full file, please also add to endpoint_to_ticker
295
306
  client_side_endpoints_s3 = {
296
- "sec/10k"
307
+ "sec/10k",
308
+ "trials/predict",
309
+ "trials/describe",
310
+ "trials/all/predict",
311
+ "trials/all/decribe",
312
+ "trials/all",
313
+
297
314
  }
298
315
 
316
+
317
+
299
318
  # In your main function or wherever this logic is implemented:
300
319
 
301
320
 
@@ -594,7 +613,7 @@ def data(
594
613
 
595
614
  elif (
596
615
  normalized_endpoint in client_side_endpoints_s3
597
- # and tickers is not None
616
+ and tickers is not None
598
617
  and frequency is None
599
618
  ):
600
619
  verbose_mode.vprint("Grabbing s3 client side")
@@ -605,6 +624,7 @@ def data(
605
624
  if tickers is not None and not is_all(tickers):
606
625
  params = ticker_mapper(params,verbose)
607
626
 
627
+
608
628
  res = requests.get(
609
629
  url=url,
610
630
  headers=headers,
@@ -613,7 +633,7 @@ def data(
613
633
  stream=True,
614
634
  verify=ApiConfig.verify_ssl,
615
635
  )
616
- res.raise_for_status()
636
+
617
637
  verbose_mode.vprint(f"Response Status: {res.status_code}")
618
638
  verbose_mode.vprint(f"Response Content-Type: {res.headers.get('content-type')}")
619
639
 
@@ -624,12 +644,20 @@ def data(
624
644
  tickers = get_ticker_from_endpoint(endpoint, tickers, endpoint_to_ticker)
625
645
 
626
646
  print_tickers_value(tickers)
647
+
648
+
649
+ res.raise_for_status()
627
650
 
628
651
  data_format = res.headers.get("X-Data-Format")
629
652
  content_type = res.headers["content-type"]
653
+
654
+ plot_header = res.headers.get("X-Plotly-Data")
655
+ # print(data_format)
656
+ # print(plot_header)
657
+
630
658
  # print(content_type)
631
659
 
632
- if content_type == "application/octet-stream":
660
+ if (content_type == "application/octet-stream") and not plot_header:
633
661
  if data_format == "pyarrow":
634
662
  verbose_mode.vprint(f"header: {data_format}")
635
663
  data = stream_data_pyarrow(res)
@@ -670,25 +698,54 @@ def data(
670
698
  data = CustomDataFrame(data)
671
699
 
672
700
  verbose_mode.vprint("It reached the DF")
673
- else:
701
+
702
+ _query_cache[cache_key] = data
703
+
704
+ verbose_mode.vprint("It passed the DF")
705
+
706
+ elif not plot_header:
674
707
  if HAS_FULL_INSTALL:
675
708
  data = CustomDataFrame(convert_data2df(res.json()))
676
709
  else:
677
710
  data = pd.DataFrame(convert_data2df(res.json()))
678
711
 
679
- _query_cache[cache_key] = data
712
+ _query_cache[cache_key] = data
713
+
714
+ verbose_mode.vprint("It passed the DF")
680
715
 
681
- verbose_mode.vprint("It passed the DF")
716
+ import pickle
717
+ from plotly.graph_objs import Figure
718
+ def set_dark_mode(fig: Figure):
719
+ return fig.update_layout(
720
+ template="plotly_dark",
721
+ plot_bgcolor="rgba(10, 10, 10, 1)",
722
+ paper_bgcolor="rgba(10, 10, 10, 1)",
723
+ )
682
724
 
725
+ if plot_header:
726
+ # print(res.content[:100])
727
+ if HAS_FULL_INSTALL:
728
+ # Decompress the data
729
+ pickle_bytes = res.content
730
+ # Unpickle the data
731
+ fig = pickle.loads(pickle_bytes)
732
+ fig = go.Figure(json.loads(fig))
733
+ fig = set_dark_mode(fig)
734
+
735
+ return fig
736
+ else:
737
+ print("Plotting is only available with the full installation. Please install 'sovai[full]' to use this feature.")
738
+ return None
739
+
683
740
  if plot:
684
741
  if HAS_FULL_INSTALL:
685
- _draw_graphs(data)
742
+ return _draw_graphs(data)
686
743
  else:
687
744
  print("Plotting is only available with the full installation. Please install 'sovai[full]' to use this feature.")
688
745
  return None
689
746
  return data
690
747
  except Exception as err:
691
- verbose_mode.vprint("An error occurred:", err)
748
+ verbose_mode.vprint("An error occurred, check dictaionries for 'data/name':'None':", err)
692
749
  return data
693
750
  if res.status_code == 404:
694
751
  msg = res.json()
@@ -747,9 +804,7 @@ def _draw_graphs(data: Union[Dict, List[Dict]]):
747
804
  if isinstance(data, list):
748
805
  for plot in data:
749
806
  for _, val in plot.items():
750
- plotting_data(val)
751
- break
807
+ return plotting_data(val)
752
808
  else:
753
809
  for _, val in data.items():
754
- plotting_data(val)
755
- break
810
+ return plotting_data(val)
@@ -44,12 +44,12 @@ def _draw_graphs(data: Union[Dict, List[Dict]]):
44
44
  if isinstance(data, list):
45
45
  for plot in data:
46
46
  for _, val in plot.items():
47
- plotting_data(val)
47
+ return plotting_data(val)
48
48
  break
49
49
  else:
50
50
  for _, val in data.items():
51
- plotting_data(val)
52
- break
51
+ return plotting_data(val)
52
+
53
53
 
54
54
 
55
55
  from typing import Optional, Union, Tuple, List, Dict
@@ -127,6 +127,7 @@ def earnings_tree():
127
127
  if 'ticker' not in df_earn.columns:
128
128
  df_earn = df_earn.reset_index()
129
129
 
130
+ df_earn['market_cap'] = df_earn['market_cap'].replace(0, 1e-6)
130
131
  # Calculate market cap deciles and handle NaN values
131
132
  df_earn['market_cap_decile'] = pd.qcut(df_earn['market_cap'].rank(method='first'), q=10, labels=range(1, 11))
132
133
  df_earn['market_cap_decile'] = df_earn['market_cap_decile'].astype(str).replace('nan', 'Unknown')
@@ -134,6 +135,7 @@ def earnings_tree():
134
135
  # Update decile labels
135
136
  df_earn['market_cap_decile'] = df_earn['market_cap_decile'].apply(lambda x: f"{x} Cap Decile" if x != 'Unknown' else x)
136
137
 
138
+
137
139
  # Create the main treemap
138
140
  fig = px.treemap(
139
141
  df_earn,
@@ -183,4 +185,6 @@ def earnings_tree():
183
185
  )
184
186
 
185
187
  # Show the plot
186
- fig.show()
188
+ fig
189
+
190
+ return fig
@@ -63,6 +63,9 @@ def process_partition(storage_provider, base_path, identifier_column, identifier
63
63
 
64
64
  if identifier:
65
65
  df[identifier_column] = identifier
66
+
67
+ df = df[[identifier_column] + [col for col in df.columns if col != identifier_column]]
68
+
66
69
 
67
70
  return df
68
71
 
@@ -165,6 +168,8 @@ def map_identifier(input_values, input_identifier='ticker', output_identifier='c
165
168
  else:
166
169
  return result.tolist()
167
170
 
171
+
172
+
168
173
  def load_frame_s3(endpoint, tickers=None, columns=None, start_date=None, end_date=None):
169
174
 
170
175
  endpoint_config = {
@@ -177,12 +182,44 @@ def load_frame_s3(endpoint, tickers=None, columns=None, start_date=None, end_dat
177
182
  "partitioned": True,
178
183
 
179
184
  },
180
- "future/enpdoint": {
185
+ "trials/predict": {
181
186
  "storage_provider": {
182
- "digitalocean": "sovai/sovai-filings/tenk",
183
- "wasabi": "sovai-filings/tenk"
187
+ "digitalocean": "sovai/sovai-clinical-trials-export/prediction_public",
188
+ "wasabi": "sovai-clinical-trials-export/prediction_public"
184
189
  },
185
- "identifier_column": "cik",
190
+ "identifier_column": "ticker",
191
+ "partitioned": True,
192
+ },
193
+ "trials/describe": {
194
+ "storage_provider": {
195
+ "digitalocean": "sovai/sovai-clinical-trials-export/describe_public",
196
+ "wasabi": "sovai-clinical-trials-export/describe_public"
197
+ },
198
+ "identifier_column": "ticker",
199
+ "partitioned": True,
200
+ },
201
+ "trials/all": {
202
+ "storage_provider": {
203
+ "digitalocean": "sovai/sovai-clinical-trials-export/describe_all",
204
+ "wasabi": "sovai-clinical-trials-export/describe_all"
205
+ },
206
+ "identifier_column": "ticker",
207
+ "partitioned": True,
208
+ },
209
+ "trials/all/predict": {
210
+ "storage_provider": {
211
+ "digitalocean": "sovai/sovai-clinical-trials-export/prediction_all",
212
+ "wasabi": "sovai-clinical-trials-export/prediction_all"
213
+ },
214
+ "identifier_column": "ticker",
215
+ "partitioned": True,
216
+ },
217
+ "trials/all/decribe": {
218
+ "storage_provider": {
219
+ "digitalocean": "sovai/sovai-clinical-trials-export/describe_all",
220
+ "wasabi": "sovai-clinical-trials-export/describe_all"
221
+ },
222
+ "identifier_column": "ticker",
186
223
  "partitioned": True,
187
224
  }
188
225
  }
@@ -193,17 +230,15 @@ def load_frame_s3(endpoint, tickers=None, columns=None, start_date=None, end_dat
193
230
  config = endpoint_config[endpoint]
194
231
 
195
232
 
196
- if endpoint == "sec/10k":
197
- df_frame = client_side_s3_frame(
198
- config,
199
- tickers,
200
- columns,
201
- start_date,
202
- end_date
203
- )
204
- else:
205
- # Implement logic for other endpoints if needed
206
- raise NotImplementedError(f"Endpoint {endpoint} is not yet implemented")
233
+
234
+ df_frame = client_side_s3_frame(
235
+ config,
236
+ tickers,
237
+ columns,
238
+ start_date,
239
+ end_date
240
+ )
241
+
207
242
 
208
243
  if HAS_CUSTOM_DATAFRAME:
209
244
  return CustomDataFrame(df_frame)
@@ -52,3 +52,4 @@ def plotting_data(
52
52
  elif chart_type == "scatter":
53
53
  fig = px.scatter(df, x=x, y=y, **kwargs)
54
54
  fig.show()
55
+ return fig
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