diff --git a/openbb_terminal/dashboards/dashboards_controller.py b/openbb_terminal/dashboards/dashboards_controller.py index 936988c5b33..167cb772787 100644 --- a/openbb_terminal/dashboards/dashboards_controller.py +++ b/openbb_terminal/dashboards/dashboards_controller.py @@ -1,4 +1,4 @@ -"""Dashboards Module""" +"""Dashboards Module.""" __docformat__ = "numpy" import argparse @@ -11,7 +11,7 @@ import sys import threading import time from pathlib import Path -from subprocess import PIPE, STDOUT +from subprocess import PIPE, STDOUT # nosec from typing import List, Optional import dotenv @@ -37,7 +37,7 @@ JUPYTER_STARTED = False class DashboardsController(BaseController): - """Dashboards Controller class""" + """Dashboards Controller class.""" CHOICES_COMMANDS = [ "stocks", @@ -54,7 +54,7 @@ class DashboardsController(BaseController): PATH = "/dashboards/" def __init__(self, queue: Optional[List[str]] = None): - """Constructor""" + """Construct controller.""" super().__init__(queue) self.jupyter_token: Optional[str] = None self.streamlit_url: Optional[str] = None @@ -72,7 +72,7 @@ class DashboardsController(BaseController): self.completer = NestedCompleter.from_nested_dict(choices) def print_help(self): - """Print help""" + """Print help.""" mt = MenuText("dashboards/") mt.add_raw("\nVoila Apps:\n") mt.add_cmd("stocks") @@ -90,57 +90,70 @@ class DashboardsController(BaseController): @log_start_end(log=logger) def call_stocks(self, other_args: List[str]): - """Process stocks command""" + """Process stocks command.""" self.create_call_voila(other_args, "stocks", "stocks") @log_start_end(log=logger) def call_correlation(self, other_args: List[str]): - """Process correlation command""" + """Process correlation command.""" self.create_call_voila(other_args, "correlation", "correlation") @log_start_end(log=logger) def call_vsurf(self, other_args: List[str]): - """Process vsurf command""" + """Process vsurf command.""" self.create_call_voila(other_args, "vsurf", "") @log_start_end(log=logger) def call_chains(self, other_args: List[str]): - """Process chains command""" + """Process chains command.""" self.create_call_voila(other_args, "chains", "") @log_start_end(log=logger) def call_shortdata(self, other_args: List[str]): - """Process shortdata command""" + """Process shortdata command.""" self.create_call_voila(other_args, "shortdata", "") @log_start_end(log=logger) def call_crypto(self, other_args: List[str]): - """Process crypto command""" + """Process crypto command.""" self.create_call_voila(other_args, "crypto", "") @log_start_end(log=logger) def call_futures(self, other_args: List[str]): - """Process futures command""" + """Process futures command.""" self.create_call_voila(other_args, "futures", "") @log_start_end(log=logger) def call_forecast(self, other_args: List[str]): - """Process forecast command""" + """Process forecast command.""" self.create_call_voila(other_args, "forecast", "") @log_start_end(log=logger) def call_forecasting(self, other_args: List[str]): - """Process forecasting command""" + """Process forecasting command.""" self.create_call_streamlit(other_args, "Forecasting") @log_start_end(log=logger) def call_indicators(self, other_args: List[str]): - """Process indicators command""" + """Process indicators command.""" self.create_call_streamlit(other_args, "Indicators") def create_call_voila( self, other_args: List[str], name: str, filename: Optional[str] = None ) -> None: + """Create a voila call command. + + A metafunction that creates a call command for a voila dashboard. + + Parameters + ---------- + other_args : List[str] + Other arguments to pass to the voila command. + name : str + Name of the dashboard. + filename : Optional[str], optional + Filename of the dashboard, by default None + """ filename = filename if filename else name parser = argparse.ArgumentParser( @@ -231,7 +244,7 @@ class DashboardsController(BaseController): ) def get_jupyter_token(self, url: str) -> None: - """Gets the url and token for current jupyter-lab session.""" + """Get the url and token for current jupyter-lab session.""" process = psutil.Popen("jupyter-lab list", shell=True, stdout=PIPE) # nosec output = process.communicate()[0] @@ -253,7 +266,7 @@ class DashboardsController(BaseController): def check_processes( self, ns_parser: argparse.Namespace, filepath: Optional[Path] = None ) -> str: - """Checks if a process is already running, and returns the url.""" + """Check if a process is already running, and returns the url.""" if not filepath: filepath = Path(__file__).absolute() @@ -277,7 +290,7 @@ class DashboardsController(BaseController): @staticmethod def get_free_port() -> int: - """Searches for a random free port number.""" + """Search for a random free port number.""" not_free = True while not_free: port = np.random.randint(7000, 7999) @@ -290,6 +303,19 @@ class DashboardsController(BaseController): def create_call_streamlit( self, other_args: List[str], name: str, filename: Optional[str] = None ) -> None: + """Create a streamlit call command. + + A metafunction that creates a launch command for a streamlit dashboard. + + Parameters + ---------- + other_args : List[str] + Other arguments to pass to the streamlit command. + name : str + Name of the dashboard. + filename : Optional[str], optional + Filename of the dashboard, by default None + """ filename = filename if filename else name parser = argparse.ArgumentParser( @@ -368,6 +394,8 @@ class DashboardsController(BaseController): def is_streamlit_activated() -> bool: + """Check if streamlit is activated.""" + def _declined(): console.print( "\n[green]You will need to activate streamlit before running this command.[/]\n" @@ -401,7 +429,7 @@ def is_streamlit_activated() -> bool: try: console.print("\n[green]Activating streamlit. This may take a few seconds.[/]") - activate = os.system("streamlit activate") + activate = os.system("streamlit activate") # nosec: B605 B607 if activate == 0: _set_key() return True diff --git a/openbb_terminal/dashboards/widget_helpers.py b/openbb_terminal/dashboards/widget_helpers.py deleted file mode 100644 index 665b0acd852..00000000000 --- a/openbb_terminal/dashboards/widget_helpers.py +++ /dev/null @@ -1,43 +0,0 @@ -"""Widgets Helper Library. - -A library of `ipywidgets` wrappers for notebook based reports and voila dashboards. -The library includes both python code and html/css/js elements that can be found in the -`./widgets` folder. -""" -import os - -from jinja2 import Template - - -def stylesheet(): - """Load a default CSS stylesheet from file.""" - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "style.css") - ) as f: - style = f.read() - return style - - -def price_card(ticker: str, price: str, price_color: str = "neutral_color") -> str: - """Prepare a styled HTML element of a 128 by 128 price card. - - Parameters - ---------- - ticker : str - Instrument ticker for the price card - price : str - Instrument price as a string - price_color : str, optional - The color of the price. Accepts "up_color", "down_color" and default "neutral_color" - - Returns - ------- - str - HTML code as string - """ - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "card.j2") - ) as f: - template = Template(f.read()) - card = template.render(ticker=ticker, price=price, price_color=price_color) - return card diff --git a/openbb_terminal/dashboards/widgets/card.j2 b/openbb_terminal/dashboards/widgets/card.j2 deleted file mode 100644 index 09e630ad46b..00000000000 --- a/openbb_terminal/dashboards/widgets/card.j2 +++ /dev/null @@ -1,8 +0,0 @@ -
-
-
-

{{ ticker }}

-

{{ price }}

-
-
-
diff --git a/openbb_terminal/dashboards/widgets/currencies.json b/openbb_terminal/dashboards/widgets/currencies.json deleted file mode 100644 index d6bd4641251..00000000000 --- a/openbb_terminal/dashboards/widgets/currencies.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "global": { - "tabSetEnableClose": true, - "tabSetEnableTabStrip": false, - "tabSetTabLocation": "bottom" - }, - "borders": [], - "layout": { - "type": "row", - "id": "#1", - "children": [ - { - "type": "tabset", - "id": "#2", - "children": [ - { - "type": "tab", - "id": "#3", - "name": "New section ", - "component": "sub", - "config": { - "model": { - "global": { - "tabSetEnableClose": true - }, - "borders": [], - "layout": { - "type": "row", - "id": "#1", - "children": [ - { - "type": "row", - "id": "#930eb3e5-1999-46b8-afc6-01d731dcb211", - "children": [ - { - "type": "row", - "id": "#5debcdc6-eaaf-4224-83a7-17f9908a7a78", - "height": 145, - "children": [ - { - "type": "tabset", - "id": "#ca43de5d-5956-4fe3-8f55-94eb954a2886", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#ff22f410-6265-4a7b-b975-1dc8676fb138", - "name": "EUR/USD", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#6bf131b1-a6eb-4b8f-941a-14e0655acd79", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#8b10c77b-40f2-40e6-9673-13ddcc8238c1", - "name": "USD/JPY", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#6939401f-4c4d-41dd-9849-fd3178320122", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#7bd5f16d-d127-46f8-86a0-f413feff3b92", - "name": "GBP/USD", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#61c25933-b899-4d59-aad8-e1e98df13b7d", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#762d37fc-312e-4f16-8541-af486fe2ec4f", - "name": "AUD/USD", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#d44c4bf6-c879-46fc-bb57-80fd352ae872", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#fc1a8e88-160f-41d3-b5d8-d4d9abc5ac44", - "name": "USD/CAD", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#298c01a6-e058-4e2d-8ac6-ebb279716761", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#c2dfcb8c-9078-44f1-9118-3beebc3181d4", - "name": "USD/CNY", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#f544d439-5557-470f-ad2b-8f6168a40b77", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#d1f5dcf1-5643-49dd-aa28-725287f1b3f2", - "name": "USD/CHF", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#bcbbac20-d71f-4e6a-990e-b2a5d0a11255", - "width": 142, - "children": [ - { - "type": "tab", - "id": "#65907a81-d976-482a-b1df-45de9317cad2", - "name": "USD/HKD", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - } - ] - }, - { - "type": "row", - "id": "#410cd13c-0d14-4ada-8aad-5cfc522d1421", - "weight": 15, - "children": [ - { - "type": "tabset", - "id": "#d83b1943-b895-43bd-9f0f-d36672194a58", - "width": 256, - "children": [ - { - "type": "tab", - "id": "#044a38ed-6f61-4586-ae3f-8c76c494351b", - "name": "Select", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - }, - { - "type": "tabset", - "id": "#239aa076-2c4d-44da-a9ed-6f8ad9b27c30", - "weight": 75, - "children": [ - { - "type": "tab", - "id": "#3f45998e-34f5-42b0-9980-d07f9fff2eb5", - "name": "Historical", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - } - ] - }, - { - "type": "tabset", - "id": "#1fd33f67-3fdd-4f36-822a-ac0ee05ad8ab", - "weight": 85, - "children": [ - { - "type": "tab", - "id": "#4b4ab553-fc3a-4984-93ad-99b89def2dc4", - "name": "Candle", - "component": "Widget", - "config": { - "layoutID": "#3" - } - } - ] - } - ] - } - ] - } - } - } - } - ], - "active": true - } - ] - } -} diff --git a/openbb_terminal/dashboards/widgets/style.css b/openbb_terminal/dashboards/widgets/style.css deleted file mode 100644 index 9d503f9df68..00000000000 --- a/openbb_terminal/dashboards/widgets/style.css +++ /dev/null @@ -1,54 +0,0 @@ -.container { - position: relative; -} - -.container .card { - font-family: Consolas, sans-serif; - position: relative; - width: 128px; - height: 128px; - background: #000000; - border-radius: 5px; - border-color: rgb(142, 142, 142); - border-style: solid; - border-width: 0.5px; - overflow: hidden; -} - -.container .card .contentBx { - position: absolute; - top: 28; - bottom: 32; - width: 100%; - text-align: center; - z-index: 10; -} - -.container .card .contentBx h1 { - position: relative; - font-size: 28; - font-weight: 600; - letter-spacing: 1px; - color: #fff; - margin-top: 28px; - margin-bottom: 10px; -} - -.container .card .contentBx h2 { - position: relative; - font-size: 28px; - font-weight: 600; - letter-spacing: 1px; -} - -.up_color { - color: #00ACFF; -} - -.down_color { - color: #e4003a; -} - -.neutral_color { - color: #ffed00; -}