sovai 0.2.67__tar.gz → 0.2.70__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 (106) hide show
  1. {sovai-0.2.67 → sovai-0.2.70}/PKG-INFO +4 -2
  2. {sovai-0.2.67 → sovai-0.2.70}/pyproject.toml +1 -1
  3. {sovai-0.2.67 → sovai-0.2.70}/sovai/__init__.py +7 -0
  4. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_data.py +9 -7
  5. sovai-0.2.70/sovai/utils/file_management.py +58 -0
  6. {sovai-0.2.67 → sovai-0.2.70}/LICENSE +0 -0
  7. {sovai-0.2.67 → sovai-0.2.70}/README.md +0 -0
  8. {sovai-0.2.67 → sovai-0.2.70}/data/codes.parq +0 -0
  9. {sovai-0.2.67 → sovai-0.2.70}/data/tickers.parq +0 -0
  10. {sovai-0.2.67 → sovai-0.2.70}/sovai/.DS_Store +0 -0
  11. {sovai-0.2.67 → sovai-0.2.70}/sovai/api_config.py +0 -0
  12. {sovai-0.2.67 → sovai-0.2.70}/sovai/assets/dropdown.css +0 -0
  13. {sovai-0.2.67 → sovai-0.2.70}/sovai/assets/features_mapping.parq +0 -0
  14. {sovai-0.2.67 → sovai-0.2.70}/sovai/assets/tickers.parq +0 -0
  15. {sovai-0.2.67 → sovai-0.2.70}/sovai/basic_auth.py +0 -0
  16. {sovai-0.2.67 → sovai-0.2.70}/sovai/computations/__init__.py +0 -0
  17. {sovai-0.2.67 → sovai-0.2.70}/sovai/computations/functions.py +0 -0
  18. {sovai-0.2.67 → sovai-0.2.70}/sovai/errors/__init__.py +0 -0
  19. {sovai-0.2.67 → sovai-0.2.70}/sovai/errors/sovai_errors.py +0 -0
  20. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/__init__.py +0 -0
  21. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/anomalies.py +0 -0
  22. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/ask_df_llm.py +0 -0
  23. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/change_point_generator copy.py +0 -0
  24. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/change_point_generator.py +0 -0
  25. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/clustering.py +0 -0
  26. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/core_kshape.py +0 -0
  27. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/cum_sum_torch.py +0 -0
  28. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/cusum.py +0 -0
  29. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/dimensionality_reduction.py +0 -0
  30. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/feature_extraction.py +0 -0
  31. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/feature_importance.py +0 -0
  32. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/feature_neutralizer.py +0 -0
  33. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/filter_df.py +0 -0
  34. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/fractional_differencing.py +0 -0
  35. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/nowcasting.py +0 -0
  36. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/pairwise.py +0 -0
  37. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/pandas_extensions.py +0 -0
  38. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/parallel_functions.py +0 -0
  39. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/pfa_feature_selector.py +0 -0
  40. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/regime_change.py +0 -0
  41. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/regime_change_pca.py +0 -0
  42. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/shapley_global_importance.py +0 -0
  43. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/shapley_importance.py +0 -0
  44. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/signal_evaluation.py +0 -0
  45. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/technical_indicators.py +0 -0
  46. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/time_decomposition.py +0 -0
  47. {sovai-0.2.67 → sovai-0.2.70}/sovai/extensions/weight_optimization.py +0 -0
  48. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_compute.py +0 -0
  49. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_data copy 2.py +0 -0
  50. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_data copy.py +0 -0
  51. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_plots.py +0 -0
  52. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_reports.py +0 -0
  53. {sovai-0.2.67 → sovai-0.2.70}/sovai/get_tools.py +0 -0
  54. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/__init__.py +0 -0
  55. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/accounting/__init__.py +0 -0
  56. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/accounting/accounting_plots.py +0 -0
  57. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/allocation/__init__.py +0 -0
  58. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/allocation/allocation_plots.py +0 -0
  59. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/bankruptcy/__init__.py +0 -0
  60. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/bankruptcy/bankruptcy_plots.py +0 -0
  61. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/breakout/__init__.py +0 -0
  62. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/breakout/breakout_plots.py +0 -0
  63. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/corp_risk/__init__.py +0 -0
  64. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/corp_risk/corp_risk_plots.py +0 -0
  65. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/earnings_surprise/__init__.py +0 -0
  66. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/earnings_surprise/earnings_surprise_plots.py +0 -0
  67. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/insider/__init__.py +0 -0
  68. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/insider/insider_plots.py +0 -0
  69. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/institutional/__init__.py +0 -0
  70. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/institutional/institutional_plots.py +0 -0
  71. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/news/__init__.py +0 -0
  72. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/news/news_plots.py +0 -0
  73. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/ratios/__init__.py +0 -0
  74. {sovai-0.2.67 → sovai-0.2.70}/sovai/plots/ratios/ratios_plots.py +0 -0
  75. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/accounting/__init__.py +0 -0
  76. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/accounting/accounting_balance_sheet.py +0 -0
  77. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/bankruptcy/__init__.py +0 -0
  78. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/bankruptcy/bankruptcy_monthly_top.py +0 -0
  79. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/general/__init__.py +0 -0
  80. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/general/general_plots.py +0 -0
  81. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/news/__inti__.py +0 -0
  82. {sovai-0.2.67 → sovai-0.2.70}/sovai/reports/news/news_econometric_analysis.py +0 -0
  83. {sovai-0.2.67 → sovai-0.2.70}/sovai/studies/nowcasting.py +0 -0
  84. {sovai-0.2.67 → sovai-0.2.70}/sovai/token_auth.py +0 -0
  85. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/authentication/__init__.py +0 -0
  86. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/authentication/authentication.py +0 -0
  87. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/sec/__init__.py +0 -0
  88. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/sec/graphs.py +0 -0
  89. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/sec/llm_code_generator.py +0 -0
  90. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/sec/sec_10_k_8_k_filings.py +0 -0
  91. {sovai-0.2.67 → sovai-0.2.70}/sovai/tools/sec/sec_edgar_search.py +0 -0
  92. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/__init__.py +0 -0
  93. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/client_side.py +0 -0
  94. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/client_side_s3.py +0 -0
  95. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/client_side_s3_part_high.py +0 -0
  96. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/converter.py +0 -0
  97. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/datetime_formats.py +0 -0
  98. /sovai-0.2.67/sovai/utils/file_management.py → /sovai-0.2.70/sovai/utils/file_management copy.py +0 -0
  99. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/get_tickers.py +0 -0
  100. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/helpers.py +0 -0
  101. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/pandas_extensions copy.py +0 -0
  102. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/plot.py +0 -0
  103. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/port_manager copy.py +0 -0
  104. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/port_manager.py +0 -0
  105. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/stream.py +0 -0
  106. {sovai-0.2.67 → sovai-0.2.70}/sovai/utils/verbose_utils.py +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: sovai
3
- Version: 0.2.67
3
+ Version: 0.2.70
4
4
  Summary: python for asset management
5
5
  License: Proprietary License
6
+ License-File: LICENSE
6
7
  Author: Derek Snow
7
8
  Author-email: d.snow@outlook.com
8
9
  Requires-Python: >=3.10
@@ -10,6 +11,7 @@ Classifier: License :: Other/Proprietary License
10
11
  Classifier: Programming Language :: Python :: 3
11
12
  Classifier: Programming Language :: Python :: 3.12
12
13
  Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
13
15
  Provides-Extra: full
14
16
  Requires-Dist: aiobotocore (==2.21.1)
15
17
  Requires-Dist: boto3 (==1.37.1)
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "sovai"
7
- version = "0.2.67"
7
+ version = "0.2.70"
8
8
  description = "python for asset management"
9
9
  authors = [
10
10
  {name = "Derek Snow", email = "d.snow@outlook.com"}
@@ -5,11 +5,18 @@ from .api_config import read_key, save_key, ApiConfig
5
5
  from .basic_auth import basic_auth
6
6
  from .token_auth import token_auth
7
7
  from .utils.file_management import update_data_files # Keep update_data_files import
8
+ from .api_config import read_key, ApiConfig
9
+
8
10
 
9
11
 
10
12
  import warnings
11
13
  warnings.filterwarnings("ignore")
14
+ update_data_files()
12
15
 
16
+ try:
17
+ read_key(".env")
18
+ except FileNotFoundError:
19
+ pass
13
20
 
14
21
  try:
15
22
  from importlib.metadata import version
@@ -379,15 +379,14 @@ ENDPOINT_TO_TICKER = {
379
379
  "/news/polarity_score": "",
380
380
  "/macro/features": "",
381
381
  "/congress": "",
382
+
382
383
  "/market/closeadj": "",
383
- "/lobbying/public": "",
384
+ "/market/prices": "",
385
+
386
+ "/lobbying": "",
384
387
  "/liquidity/price_improvement": "",
385
388
  "/liquidity/market_opportunity": "",
386
- "/trials/predict": "",
387
- "/trials/describe": "",
388
- "/trials/all/predict": "",
389
- "/trials/all/decribe": "",
390
- "/trials/all": "",
389
+
391
390
 
392
391
  "/patents/applications": "",
393
392
  "/patents/grants": "",
@@ -395,11 +394,13 @@ ENDPOINT_TO_TICKER = {
395
394
  "/clinical/trials": "",
396
395
 
397
396
 
398
-
399
397
  "/spending/awards": "",
400
398
  "/spending/compensation": "",
401
399
  "/spending/competition": "",
402
400
  "/spending/contracts": "",
401
+
402
+ # "/spending/contract": "", has changed to details.
403
+
403
404
  "/spending/entities": "",
404
405
  "/spending/location": "",
405
406
  "/spending/product": "",
@@ -993,6 +994,7 @@ def _get_ticker_codes_df():
993
994
  return pd.read_parquet("data/codes.parq")
994
995
  except Exception as e:
995
996
  logger.error(f"Failed to load ticker mapping data (data/codes.parq): {e}")
997
+
996
998
  # Consider if this should raise a more specific error or if ValueError is appropriate
997
999
  raise ValueError(f"Cannot perform ticker mapping due to data loading failure: {e}")
998
1000
 
@@ -0,0 +1,58 @@
1
+ import pandas as pd
2
+ import os
3
+ import time
4
+ from datetime import timedelta
5
+ from pathlib import Path
6
+
7
+ # Cache configuration
8
+ CACHE_DIR = Path("data")
9
+ CACHE_TTL_SECONDS = timedelta(days=7).total_seconds()
10
+
11
+ def _get_file_age_seconds(file_path: Path) -> float | None:
12
+ """Return file age in seconds, or None if it doesn't exist."""
13
+ try:
14
+ return time.time() - file_path.stat().st_mtime
15
+ except (FileNotFoundError, OSError):
16
+ return None
17
+
18
+
19
+ def _cached_parquet(url: str, filename: str) -> pd.DataFrame:
20
+ """
21
+ Fetch a Parquet file from a URL into a local cache directory if missing or expired,
22
+ then load and return it as a pandas DataFrame.
23
+ """
24
+ CACHE_DIR.mkdir(parents=True, exist_ok=True)
25
+ path = CACHE_DIR / filename
26
+ age = _get_file_age_seconds(path)
27
+ if age is None or age > CACHE_TTL_SECONDS:
28
+ print(f"Downloading {url} to {path}")
29
+ df = pd.read_parquet(url)
30
+ df.to_parquet(path)
31
+ else:
32
+ print(f"Loading from cache: {path}")
33
+ df = pd.read_parquet(path)
34
+ return df
35
+
36
+
37
+ def get_ticker_meta() -> pd.DataFrame:
38
+ """Return the tickers metadata, cached for 7 days."""
39
+ return _cached_parquet(
40
+ url="https://storage.googleapis.com/sovai-public/accounting/tickers_transformed.parq",
41
+ filename="tickers.parq"
42
+ )
43
+
44
+
45
+ def get_codes_meta() -> pd.DataFrame:
46
+ """Return the codes metadata, cached for 7 days."""
47
+ return _cached_parquet(
48
+ url="https://storage.googleapis.com/sovai-public/sovai-master/output/df_codes.parquet",
49
+ filename="codes.parq"
50
+ )
51
+
52
+
53
+ def update_data_files():
54
+ """
55
+ Manually pre-warm both ticker and code caches.
56
+ """
57
+ get_ticker_meta()
58
+ get_codes_meta()
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