sovai 0.2.68__tar.gz → 0.2.71__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.68 → sovai-0.2.71}/PKG-INFO +4 -2
- {sovai-0.2.68 → sovai-0.2.71}/pyproject.toml +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/__init__.py +7 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/change_point_generator copy.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/change_point_generator.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/clustering.py +3 -3
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/nowcasting.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/regime_change.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/regime_change_pca.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/time_decomposition.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_data.py +9 -8
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/accounting/accounting_plots.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/breakout/breakout_plots.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/corp_risk/corp_risk_plots.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/earnings_surprise/earnings_surprise_plots.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/insider/insider_plots.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/institutional/institutional_plots.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/news/news_plots.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/ratios/ratios_plots.py +2 -2
- {sovai-0.2.68 → sovai-0.2.71}/sovai/studies/nowcasting.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/sec/sec_10_k_8_k_filings.py +1 -1
- {sovai-0.2.68 → sovai-0.2.71}/LICENSE +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/README.md +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/data/codes.parq +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/data/tickers.parq +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/.DS_Store +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/api_config.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/assets/dropdown.css +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/assets/features_mapping.parq +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/assets/tickers.parq +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/basic_auth.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/computations/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/computations/functions.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/errors/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/errors/sovai_errors.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/anomalies.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/ask_df_llm.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/core_kshape.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/cum_sum_torch.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/cusum.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/dimensionality_reduction.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/feature_extraction.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/feature_importance.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/feature_neutralizer.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/filter_df.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/fractional_differencing.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/pairwise.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/pandas_extensions.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/parallel_functions.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/pfa_feature_selector.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/shapley_global_importance.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/shapley_importance.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/signal_evaluation.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/technical_indicators.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/extensions/weight_optimization.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_compute.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_data copy 2.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_data copy.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_plots.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_reports.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/get_tools.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/accounting/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/allocation/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/allocation/allocation_plots.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/bankruptcy/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/bankruptcy/bankruptcy_plots.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/breakout/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/corp_risk/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/earnings_surprise/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/insider/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/institutional/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/news/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/plots/ratios/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/accounting/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/accounting/accounting_balance_sheet.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/bankruptcy/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/bankruptcy/bankruptcy_monthly_top.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/general/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/general/general_plots.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/news/__inti__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/reports/news/news_econometric_analysis.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/token_auth.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/authentication/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/authentication/authentication.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/sec/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/sec/graphs.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/sec/llm_code_generator.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/tools/sec/sec_edgar_search.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/__init__.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/client_side.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/client_side_s3.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/client_side_s3_part_high.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/converter.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/datetime_formats.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/file_management copy.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/file_management.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/get_tickers.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/helpers.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/pandas_extensions copy.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/plot.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/port_manager copy.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/port_manager.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/stream.py +0 -0
- {sovai-0.2.68 → sovai-0.2.71}/sovai/utils/verbose_utils.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sovai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.71
|
|
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)
|
|
@@ -5,12 +5,19 @@ 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")
|
|
12
14
|
update_data_files()
|
|
13
15
|
|
|
16
|
+
try:
|
|
17
|
+
read_key(".env")
|
|
18
|
+
except FileNotFoundError:
|
|
19
|
+
pass
|
|
20
|
+
|
|
14
21
|
try:
|
|
15
22
|
from importlib.metadata import version
|
|
16
23
|
__version__ = version("sovai")
|
|
@@ -363,7 +363,7 @@ def run_cusum_dashboard(df_accounting, ticker=None, feature=None):
|
|
|
363
363
|
return fig
|
|
364
364
|
|
|
365
365
|
app_name = "cumsum-app"
|
|
366
|
-
return app.
|
|
366
|
+
return app.run(debug=False, port=get_unique_port(app_name))
|
|
367
367
|
|
|
368
368
|
|
|
369
369
|
def perform_cusum_analysis(df_accounting, ticker=None, feature=None):
|
|
@@ -379,7 +379,7 @@ def run_cusum_dashboard(df_accounting, ticker=None, feature=None): # Modified fo
|
|
|
379
379
|
try:
|
|
380
380
|
print(f"Attempting to launch Dash app '{app_name}' on port {port} (Attempt {attempt + 1}/{max_retries})")
|
|
381
381
|
# Using host='0.0.0.0' to make it accessible on the network
|
|
382
|
-
app.
|
|
382
|
+
app.run(debug=False, port=port, host='0.0.0.0')
|
|
383
383
|
print(f"Dash app '{app_name}' running on http://127.0.0.1:{port}/ or http://<your-ip>:{port}/")
|
|
384
384
|
break # Success
|
|
385
385
|
except socket.error as e:
|
|
@@ -401,7 +401,7 @@ def run_cusum_dashboard(df_accounting, ticker=None, feature=None): # Modified fo
|
|
|
401
401
|
# To match original behavior of returning the server object, this structure would need adjustment
|
|
402
402
|
# However, run_server is blocking, so returning it means the rest of the script doesn't run until server stops.
|
|
403
403
|
# This current structure runs the server and blocks, or prints failure and continues if it can't.
|
|
404
|
-
# The original `return app.
|
|
404
|
+
# The original `return app.run(...)` would also block.
|
|
405
405
|
# If it fails to launch due to port, original would raise error immediately.
|
|
406
406
|
# This structure tries to recover or fails after retries.
|
|
407
407
|
# To make it fully equivalent on failure, we should re-raise here.
|
|
@@ -521,7 +521,7 @@ def vizualisation_cluster(df_mega):
|
|
|
521
521
|
return dash.no_update, dash.no_update, dash.no_update, dash.no_update
|
|
522
522
|
|
|
523
523
|
app_name = "clustering-app"
|
|
524
|
-
return app.
|
|
524
|
+
return app.run(
|
|
525
525
|
debug=False, port=get_unique_port(app_name)
|
|
526
526
|
) # Apply exponential moving average to smooth the data
|
|
527
527
|
|
|
@@ -739,7 +739,7 @@ def vizualisation_scatter(df_mega):
|
|
|
739
739
|
return fig
|
|
740
740
|
|
|
741
741
|
app_name = "scatter-app"
|
|
742
|
-
return app.
|
|
742
|
+
return app.run(
|
|
743
743
|
debug=False, port=get_unique_port(app_name)
|
|
744
744
|
) # Apply exponential moving average to smooth the data
|
|
745
745
|
|
|
@@ -906,4 +906,4 @@ def vizualisation_animation(df_mega):
|
|
|
906
906
|
return fig
|
|
907
907
|
|
|
908
908
|
app_name = "animation-app"
|
|
909
|
-
return app.
|
|
909
|
+
return app.run(debug=False, port=get_unique_port(app_name))
|
|
@@ -257,7 +257,7 @@ def run_pca_regime_change_dashboard(df_accounting, ticker=None):
|
|
|
257
257
|
return fig
|
|
258
258
|
|
|
259
259
|
app_name = "pca-regime-change-app"
|
|
260
|
-
return app.
|
|
260
|
+
return app.run(debug=False, port=get_unique_port(app_name))
|
|
261
261
|
|
|
262
262
|
|
|
263
263
|
# Example usage
|
|
@@ -327,7 +327,7 @@ def run_comprehensive_analysis_dashboard(df_accounting, ticker=None, feature=Non
|
|
|
327
327
|
)
|
|
328
328
|
|
|
329
329
|
app_name = "comprehensive-analysis-app"
|
|
330
|
-
return app.
|
|
330
|
+
return app.run(debug=False, port=get_unique_port(app_name))
|
|
331
331
|
|
|
332
332
|
|
|
333
333
|
# Example usage
|
|
@@ -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
|
-
"/
|
|
384
|
+
"/market/prices": "",
|
|
385
|
+
|
|
386
|
+
"/lobbying": "",
|
|
384
387
|
"/liquidity/price_improvement": "",
|
|
385
388
|
"/liquidity/market_opportunity": "",
|
|
386
|
-
|
|
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,7 +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}")
|
|
996
|
-
|
|
997
|
+
|
|
997
998
|
# Consider if this should raise a more specific error or if ValueError is appropriate
|
|
998
999
|
raise ValueError(f"Cannot perform ticker mapping due to data loading failure: {e}")
|
|
999
1000
|
|
|
@@ -391,7 +391,7 @@ def plot_cash_flows(df_accounting):
|
|
|
391
391
|
# Example usage
|
|
392
392
|
app_name = "cummulative_cash"
|
|
393
393
|
|
|
394
|
-
return app.
|
|
394
|
+
return app.run(
|
|
395
395
|
debug=False, port=get_unique_port(app_name)
|
|
396
396
|
) # Use a different port for each app
|
|
397
397
|
|
|
@@ -486,4 +486,4 @@ def plot_assets(df_accounting):
|
|
|
486
486
|
return graphs
|
|
487
487
|
|
|
488
488
|
app_name = "assets"
|
|
489
|
-
return app.
|
|
489
|
+
return app.run(debug=True, port=get_unique_port(app_name))
|
|
@@ -596,7 +596,7 @@ def interactive_plot_display_breakout_accuracy(df=None):
|
|
|
596
596
|
# Assuming you have your DataFrame 'df' ready
|
|
597
597
|
app = create_dash_app(df)
|
|
598
598
|
|
|
599
|
-
return app.
|
|
599
|
+
return app.run(debug=False)
|
|
600
600
|
|
|
601
601
|
|
|
602
602
|
# def interactive_plot_display_breakout_accuracy(df=None):
|
|
@@ -479,7 +479,7 @@ def insider_flows_plot():
|
|
|
479
479
|
# insider_factors_for_plot("pressure")
|
|
480
480
|
|
|
481
481
|
app_name = "insider_flows"
|
|
482
|
-
return app.
|
|
482
|
+
return app.run(
|
|
483
483
|
debug=False, port=get_unique_port(app_name)
|
|
484
484
|
) # Apply exponential moving average to smooth the data
|
|
485
485
|
|
|
@@ -659,6 +659,6 @@ def insider_flow_predictions_plot():
|
|
|
659
659
|
sys.stderr = open(os.devnull, "w")
|
|
660
660
|
|
|
661
661
|
app_name = "insider_predictions"
|
|
662
|
-
return app.
|
|
662
|
+
return app.run(
|
|
663
663
|
debug=False, port=get_unique_port(app_name)
|
|
664
664
|
) # Apply exponential moving average to smooth the data
|
|
@@ -363,7 +363,7 @@ def institutional_flows_plot():
|
|
|
363
363
|
# def run_long_task(start):
|
|
364
364
|
# factors_for_plot("pressure")
|
|
365
365
|
|
|
366
|
-
return app.
|
|
366
|
+
return app.run(
|
|
367
367
|
debug=False, port=get_unique_port( "institutional_flows")
|
|
368
368
|
) # Apply exponential moving average to smooth the data
|
|
369
369
|
|
|
@@ -540,6 +540,6 @@ def institutional_flow_predictions_plot():
|
|
|
540
540
|
stderr = sys.stderr
|
|
541
541
|
sys.stderr = open(os.devnull, "w")
|
|
542
542
|
|
|
543
|
-
return app.
|
|
543
|
+
return app.run(
|
|
544
544
|
debug=False, port=get_unique_port("institutional_predictions")
|
|
545
545
|
) # Apply exponential moving average to smooth the data
|
|
@@ -556,7 +556,7 @@ def plot_news_daily(ticker='NVDA'):
|
|
|
556
556
|
return fig, explanation, long_ma, short_ma, threshold, future_days
|
|
557
557
|
|
|
558
558
|
# Run the app
|
|
559
|
-
app.
|
|
559
|
+
app.run(debug=False, port=get_unique_port("news_daily_sentiment"), jupyter_mode="inline", jupyter_height=1100)
|
|
560
560
|
|
|
561
561
|
# Usage example:
|
|
562
562
|
# plot_news_daily(ticker='AAPL')
|
|
@@ -785,5 +785,5 @@ def run_dash_news_ts():
|
|
|
785
785
|
df_topic = data("news/topic_probability", full_history=True).reset_index()
|
|
786
786
|
|
|
787
787
|
app = dash_news_ts_analysis(df_sentiment, df_polarity, df_topic)
|
|
788
|
-
app.
|
|
788
|
+
app.run(debug=False, port=get_unique_port("news_topic_valuest"), jupyter_mode="inline", jupyter_height=1300)
|
|
789
789
|
|
|
@@ -576,7 +576,7 @@ def plot_ratios_benchmark():
|
|
|
576
576
|
|
|
577
577
|
# Example usage
|
|
578
578
|
app_name = "ratio_benchmark"
|
|
579
|
-
return app.
|
|
579
|
+
return app.run(
|
|
580
580
|
debug=False, port=get_unique_port(app_name)
|
|
581
581
|
) # Use a different port for each app
|
|
582
582
|
|
|
@@ -930,6 +930,6 @@ def plot_ratios_triple(ticker="TSLA"):
|
|
|
930
930
|
return None
|
|
931
931
|
|
|
932
932
|
app_name = "ratios"
|
|
933
|
-
return app.
|
|
933
|
+
return app.run(
|
|
934
934
|
debug=False, port=get_unique_port(app_name)
|
|
935
935
|
) # Use a different port for each app
|
|
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
|