diff --git a/openbb_sdk/extensions/charting/openbb_charting/__init__.py b/openbb_sdk/extensions/charting/openbb_charting/__init__.py index 3a3b1edbbd0..9d60f0e2e6f 100644 --- a/openbb_sdk/extensions/charting/openbb_charting/__init__.py +++ b/openbb_sdk/extensions/charting/openbb_charting/__init__.py @@ -3,3 +3,4 @@ from openbb_charting.core.backend import ( create_backend, get_backend, ) +from openbb_charting.core.to_plotly_json import to_plotly_json diff --git a/openbb_sdk/extensions/charting/openbb_charting/core/plotly_ta/ta_class.py b/openbb_sdk/extensions/charting/openbb_charting/core/plotly_ta/ta_class.py index 02a199cdd75..b4bcd0c8777 100644 --- a/openbb_sdk/extensions/charting/openbb_charting/core/plotly_ta/ta_class.py +++ b/openbb_sdk/extensions/charting/openbb_charting/core/plotly_ta/ta_class.py @@ -171,7 +171,7 @@ class PlotlyTA(PltTA): self.indicators = indicators self.intraday = df_stock.index[-2].time() != df_stock.index[-1].time() - self.df_stock = df_stock + self.df_stock = df_stock.sort_index(ascending=True) self.close_column = check_columns(self.df_stock) self.params = self.indicators.get_params() @@ -434,7 +434,6 @@ class PlotlyTA(PltTA): fig : OpenBBFigure Plotly figure with candlestick/line chart and volume bar chart (if enabled) """ - self.df_ta = self.calculate_indicators() symbol = ( diff --git a/openbb_sdk/extensions/charting/openbb_charting/core/to_plotly_json.py b/openbb_sdk/extensions/charting/openbb_charting/core/to_plotly_json.py new file mode 100644 index 00000000000..2a5745ae08b --- /dev/null +++ b/openbb_sdk/extensions/charting/openbb_charting/core/to_plotly_json.py @@ -0,0 +1,61 @@ +from typing import Any, Dict, Optional, Union + +import pandas as pd +from openbb_charting.core.plotly_ta.data_classes import ChartIndicators +from openbb_charting.core.plotly_ta.ta_class import PlotlyTA +from openbb_core.app.model.charts.charting_settings import ChartingSettings + + +def to_plotly_json( + charting_settings: ChartingSettings, + data: Union[pd.DataFrame, pd.Series], + indicators: Optional[Union[ChartIndicators, Dict[str, Dict[str, Any]]]] = None, + symbol: str = "", + candles: bool = True, + volume: bool = True, + prepost: bool = False, + volume_ticks_x: int = 7, +) -> str: + """ + Returns the plotly json representation of the chart. + This function is used so it can be called at the module level and used out of the box, + which allows some more flexibility, ease of use and doesn't require the user to know + about the PlotlyTA class. + + Parameters + ---------- + charting_settings : ChartingSettings + Charting settings. + data : Union[pd.DataFrame, pd.Series] + Data to be plotted. + indicators : Optional[Union[ChartIndicators, Dict[str, Dict[str, Any]]]], optional + Indicators to be plotted, by default None + symbol : str, optional + Symbol to be plotted, by default "" + candles : bool, optional + If True, candles will be plotted, by default True + volume : bool, optional + If True, volume will be plotted, by default True + prepost : bool, optional + If True, prepost will be plotted, by default False + volume_ticks_x : int, optional + Volume ticks, by default 7 + + Returns + ------- + str + Plotly json representation of the chart. + """ + + ta = PlotlyTA(charting_settings=charting_settings) + fig = ta.plot( + df_stock=data, + indicators=indicators, + symbol=symbol, + candles=candles, + volume=volume, + prepost=prepost, + volume_ticks_x=volume_ticks_x, + ) + + return fig.show(external=True).to_plotly_json() diff --git a/openbb_sdk/sdk/core/openbb_core/app/charting_manager.py b/openbb_sdk/sdk/core/openbb_core/app/charting_manager.py index 336a784ec11..5f6fc25289f 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/charting_manager.py +++ b/openbb_sdk/sdk/core/openbb_core/app/charting_manager.py @@ -1,12 +1,14 @@ from importlib import import_module -from typing import Callable, Generic, Optional, TypeVar +from typing import Callable, Generic, Optional, Tuple, TypeVar import pkg_resources +from openbb_core.app.model.abstract.singleton import SingletonMeta from openbb_core.app.model.charts.chart import Chart, ChartFormat from openbb_core.app.model.charts.charting_settings import ChartingSettings from openbb_core.app.model.system_settings import SystemSettings from openbb_core.app.model.user_settings import UserSettings +from openbb_core.app.service.system_service import SystemService from openbb_core.app.service.user_service import UserService T = TypeVar("T") @@ -18,7 +20,7 @@ class ChartingManagerError(Exception): pass -class ChartingManager: +class ChartingManager(metaclass=SingletonMeta): """ Charting manager class. It is responsible for retrieving and executing the charting function, corresponding @@ -42,14 +44,31 @@ class ChartingManager: def __init__( self, user_settings: Optional[UserSettings] = None, + system_settings: Optional[SystemSettings] = None, ) -> None: user_settings = user_settings or UserService().read_default_user_settings() + self._system_settings = ( + system_settings or SystemService().read_default_system_settings() + ) + self._charting_settings = ChartingSettings(user_settings, system_settings) self._charting_extension = user_settings.preferences.charting_extension self._charting_extension_installed = self.check_charting_extension_installed( self._charting_extension ) + @property + def charting_settings(self) -> ChartingSettings: + return self._charting_settings + + @charting_settings.setter + def charting_settings(self, value: Tuple[SystemSettings, UserSettings]): + system_settings, user_settings = value + self._charting_settings = ChartingSettings( + user_settings=user_settings, + system_settings=system_settings, + ) + @staticmethod def check_charting_extension_installed( charting_extension: str, plugin: str = POETRY_PLUGIN @@ -116,7 +135,6 @@ class ChartingManager: charting_settings : ChartingSettings Charting settings. """ - # Dynamically import the backend module backend_module = import_module(charting_extension) @@ -126,6 +144,25 @@ class ChartingManager: create_backend_func(charting_settings=charting_settings) get_backend_func().start(debug=charting_settings.debug_mode) + def to_plotly_json(self, **kwargs) -> str: + """ + Returns the plotly json representation of the chart. + """ + if not self._charting_extension_installed: + raise ChartingManagerError( + f"Charting extension `{self._charting_extension}` is not installed" + ) + self.handle_backend(self._charting_extension, self._charting_settings) + + # Dynamically import the charting module + backend_module = import_module(self._charting_extension) + # Get the plotly json function from the charting module + to_plotly_json_func = getattr(backend_module, "to_plotly_json") + # Add the charting settings to the kwargs + kwargs["charting_settings"] = self._charting_settings + + return to_plotly_json_func(**kwargs) + def chart( self, user_settings: UserSettings, @@ -158,8 +195,7 @@ class ChartingManager: Chart Chart object. """ - charting_settings = ChartingSettings(user_settings, system_settings) - + self._charting_settings = ChartingSettings(user_settings, system_settings) self._charting_extension = user_settings.preferences.charting_extension self._charting_extension_installed = self.check_charting_extension_installed( self._charting_extension @@ -170,10 +206,10 @@ class ChartingManager: f"Charting extension `{self._charting_extension}` is not installed" ) - self.handle_backend(self._charting_extension, charting_settings) + self.handle_backend(self._charting_extension, self._charting_settings) kwargs["command_output_item"] = command_output_item - kwargs["charting_settings"] = charting_settings + kwargs["charting_settings"] = self._charting_settings return Chart( content=self.get_chart_function(self._charting_extension, route)(**kwargs), diff --git a/openbb_sdk/sdk/core/openbb_core/app/command_runner.py b/openbb_sdk/sdk/core/openbb_core/app/command_runner.py index 2971b92d720..8f7db8c6eff 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/command_runner.py +++ b/openbb_sdk/sdk/core/openbb_core/app/command_runner.py @@ -355,6 +355,13 @@ class StaticCommandRunner: return command_output + @classmethod + def __update_managers_settings( + cls, system_settings: SystemSettings, user_settings: UserSettings + ): + cls.logging_manager.logging_settings = (system_settings, user_settings) + cls.charting_manager.charting_settings = (system_settings, user_settings) + @classmethod def run( cls, @@ -371,6 +378,10 @@ class StaticCommandRunner: route = execution_context.route journal_service = execution_context.journal_service + cls.__update_managers_settings( + execution_context.system_settings, execution_context.user_settings + ) + func = command_map.get_command(route=route) if func: diff --git a/openbb_sdk/sdk/core/openbb_core/app/logs/logging_manager.py b/openbb_sdk/sdk/core/openbb_core/app/logs/logging_manager.py index 1c8c35804b1..697c488d0d5 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/logs/logging_manager.py +++ b/openbb_sdk/sdk/core/openbb_core/app/logs/logging_manager.py @@ -2,13 +2,14 @@ import json import logging from enum import Enum -from typing import Any, Callable, Dict, Optional +from typing import Any, Callable, Dict, Optional, Tuple from openbb_core.app.logs.formatters.formatter_with_exceptions import ( FormatterWithExceptions, ) from openbb_core.app.logs.handlers_manager import HandlersManager from openbb_core.app.logs.models.logging_settings import LoggingSettings +from openbb_core.app.model.abstract.singleton import SingletonMeta from openbb_core.app.model.command_output import CommandOutput from openbb_core.app.model.system_settings import SystemSettings from openbb_core.app.model.user_settings import UserSettings @@ -21,12 +22,58 @@ from openbb_core.app.service.user_service import UserService from pydantic.json import pydantic_encoder -class LoggingManager: +class LoggingManager(metaclass=SingletonMeta): + """ + Logging Manager class responsible for managing logging settings and handling logs. + + Attributes + ---------- + _user_settings : Optional[UserSettings] + User Settings object. + _system_settings : Optional[SystemSettings] + System Settings object. + _logging_settings : LoggingSettings + LoggingSettings object containing the current logging settings. + _handlers_manager : HandlersManager + HandlersManager object managing logging handlers. + + Methods + ------- + __init__(system_settings, user_settings) + Logging Manager Constructor. + + log(user_settings, system_settings, command_output, route, func, kwargs) + Log command output and relevant information. + + logging_settings + Property to access the current logging settings. + + logging_settings.setter + Setter method to update the logging settings. + + _setup_handlers() + Setup Logging Handlers. + + _log_startup() + Log startup information. + """ + def __init__( self, system_settings: Optional[SystemSettings] = None, user_settings: Optional[UserSettings] = None, ) -> None: + """ + Logging Manager Constructor + Sets up the logging settings and handlers and then logs the startup information. + + Parameters + ---------- + system_settings : Optional[SystemSettings], optional + System Settings, by default None + user_settings : Optional[UserSettings], optional + User Settings, by default None + """ self._user_settings = ( user_settings or UserService().read_default_user_settings() ) @@ -40,8 +87,43 @@ class LoggingManager: self._handlers_manager = self._setup_handlers() self._log_startup() + @property + def logging_settings(self) -> LoggingSettings: + """ + Current logging settings. + + Returns + ------- + LoggingSettings + LoggingSettings object containing the current logging settings. + """ + return self._logging_settings + + @logging_settings.setter + def logging_settings(self, value: Tuple[SystemSettings, UserSettings]): + """ + Setter for updating the logging settings. + + Parameters + ---------- + value : Tuple[SystemSettings, UserSettings] + Tuple containing updated SystemSettings and UserSettings. + """ + system_settings, user_settings = value + self._logging_settings = LoggingSettings( + user_settings=user_settings, + system_settings=system_settings, + ) + def _setup_handlers(self) -> HandlersManager: - """Setup Logging""" + """ + Setup Logging Handlers. + + Returns + ------- + HandlersManager + Handlers Manager object. + """ logger = logging.getLogger(__name__) logging.basicConfig( level=self._logging_settings.verbosity, @@ -63,6 +145,10 @@ class LoggingManager: return handlers_manager def _log_startup(self) -> None: + """ + Log startup information. + """ + def check_credentials_defined(credentials: Dict[str, Any]): class CredentialsDefinition(Enum): defined = "defined" @@ -101,6 +187,24 @@ class LoggingManager: func: Callable, kwargs: Dict[str, Any], ): + """ + Log command output and relevant information. + + Parameters + ---------- + user_settings : UserSettings + User Settings object. + system_settings : SystemSettings + System Settings object. + command_output : CommandOutput + CommandOutput object containing command output and error information. + route : str + Route for the command. + func : Callable + Callable representing the executed function. + kwargs : Dict[str, Any] + Keyword arguments passed to the function. + """ self._user_settings = user_settings self._system_settings = system_settings self._logging_settings = LoggingSettings( diff --git a/openbb_sdk/sdk/core/openbb_core/app/model/abstract/singleton.py b/openbb_sdk/sdk/core/openbb_core/app/model/abstract/singleton.py new file mode 100644 index 00000000000..39270925bac --- /dev/null +++ b/openbb_sdk/sdk/core/openbb_core/app/model/abstract/singleton.py @@ -0,0 +1,9 @@ +class SingletonMeta(type): + # TODO : check if we want to update this to be thread safe + _instances = {} + + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + instance = super().__call__(*args, **kwargs) + cls._instances[cls] = instance + return cls._instances[cls] diff --git a/openbb_sdk/sdk/core/openbb_core/app/model/command_output.py b/openbb_sdk/sdk/core/openbb_core/app/model/command_output.py index 7c56b287ff2..987ae9028b5 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/model/command_output.py +++ b/openbb_sdk/sdk/core/openbb_core/app/model/command_output.py @@ -4,10 +4,11 @@ import pandas as pd from pydantic import Field from pydantic.generics import GenericModel +from openbb_core.app.charting_manager import ChartingManager from openbb_core.app.model.abstract.error import Error from openbb_core.app.model.abstract.tagged import Tagged from openbb_core.app.model.abstract.warning import Warning_ -from openbb_core.app.model.charts.chart import Chart +from openbb_core.app.model.charts.chart import Chart, ChartFormat from openbb_core.app.provider_interface import get_provider_interface T = TypeVar("T") @@ -85,20 +86,38 @@ class CommandOutput(GenericModel, Generic[T], Tagged): return results - def to_plotly_json(self) -> Optional[Dict[str, Any]]: + def to_plotly_json( + self, create_chart: bool = True, **kwargs + ) -> Optional[Dict[str, Any]]: """ - Outputs the plotly json. - It is a proxy to the `chart.content` attribute that contains it already. - Returns - ------- - Optional[Dict[str, Any]] - Plotly json. + Returns the plotly json representation of the chart. + If the chart was already computed it return the plotly json representation of the chart. + Otherwise it computes the chart based on the available data and provided kwargs. + + Parameters + ---------- + create_chart : bool, optional + If True, it creates the chart object and populates the respective field on the object, by default True. + **kwargs + Keyword arguments to be passed to the charting extension. + This implies that the user has to know the charting extension API; this is the case + because the charting extension may vary on user settings. """ - if not self.chart: - raise OpenBBError("Chart not found.") - if not self.chart.format == "plotly": - raise OpenBBError("Chart is not in plotly format.") - return self.chart.content + + if self.chart and not kwargs: + plotly_json = self.chart.content + else: + cm = ChartingManager() + kwargs["data"] = self.to_dataframe() + plotly_json = cm.to_plotly_json(**kwargs) + + if create_chart: + try: + self.chart = Chart(content=plotly_json, format=ChartFormat.plotly) + except Exception as e: + self.chart = Chart(error=Error(message=str(e))) + + return plotly_json def show(self): """Displays chart.""" diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/economy.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/economy.py index 11df89bf756..50d4fe172c8 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/economy.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/economy.py @@ -19,7 +19,7 @@ class CLASS_economy(Container): def corecpi( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """CORECPI.""" inputs = filter_inputs( @@ -248,7 +248,7 @@ class CLASS_economy(Container): def cpi_options( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """Get the options for v3 cpi(options=True)""" inputs = filter_inputs( @@ -448,7 +448,7 @@ class CLASS_economy(Container): def macro( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """Query EconDB for macro data.""" inputs = filter_inputs( @@ -470,7 +470,7 @@ class CLASS_economy(Container): def macro_countries( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """MACRO_COUNTRIES.""" inputs = filter_inputs( @@ -492,7 +492,7 @@ class CLASS_economy(Container): def macro_parameters( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """MACRO_PARAMETERS.""" inputs = filter_inputs( @@ -514,7 +514,7 @@ class CLASS_economy(Container): def balance( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """BALANCE.""" inputs = filter_inputs( @@ -536,7 +536,7 @@ class CLASS_economy(Container): def bigmac( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """BIGMAC.""" inputs = filter_inputs( @@ -558,7 +558,7 @@ class CLASS_economy(Container): def country_codes( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """COUNTRY_CODES.""" inputs = filter_inputs( @@ -580,7 +580,7 @@ class CLASS_economy(Container): def currencies( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """CURRENCIES.""" inputs = filter_inputs( @@ -602,7 +602,7 @@ class CLASS_economy(Container): def debt( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """DEBT.""" inputs = filter_inputs( @@ -624,7 +624,7 @@ class CLASS_economy(Container): def events( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """EVENTS.""" inputs = filter_inputs( @@ -646,7 +646,7 @@ class CLASS_economy(Container): def fgdp( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """FGDP.""" inputs = filter_inputs( @@ -668,7 +668,7 @@ class CLASS_economy(Container): def fred( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """FRED.""" inputs = filter_inputs( @@ -690,7 +690,7 @@ class CLASS_economy(Container): def fred_search( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """FRED Search (was fred_notes).""" inputs = filter_inputs( @@ -712,7 +712,7 @@ class CLASS_economy(Container): def futures( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """FUTURES. 2 sources""" inputs = filter_inputs( @@ -734,7 +734,7 @@ class CLASS_economy(Container): def gdp( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """GDP.""" inputs = filter_inputs( @@ -756,7 +756,7 @@ class CLASS_economy(Container): def glbonds( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """GLBONDS.""" inputs = filter_inputs( @@ -778,7 +778,7 @@ class CLASS_economy(Container): def indices( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """INDICES.""" inputs = filter_inputs( @@ -800,7 +800,7 @@ class CLASS_economy(Container): def overview( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """OVERVIEW.""" inputs = filter_inputs( @@ -822,7 +822,7 @@ class CLASS_economy(Container): def perfmap( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """PERFMAP.""" inputs = filter_inputs( @@ -844,7 +844,7 @@ class CLASS_economy(Container): def performance( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """PERFORMANCE.""" inputs = filter_inputs( @@ -866,7 +866,7 @@ class CLASS_economy(Container): def revenue( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """REVENUE.""" inputs = filter_inputs( @@ -888,7 +888,7 @@ class CLASS_economy(Container): def rgdp( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """RGDP.""" inputs = filter_inputs( @@ -910,7 +910,7 @@ class CLASS_economy(Container): def rtps( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """RTPS.""" inputs = filter_inputs( @@ -932,7 +932,7 @@ class CLASS_economy(Container): def search_index( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """SEARCH_INDEX.""" inputs = filter_inputs( @@ -954,7 +954,7 @@ class CLASS_economy(Container): def spending( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """SPENDING.""" inputs = filter_inputs( @@ -976,7 +976,7 @@ class CLASS_economy(Container): def trust( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """TRUST.""" inputs = filter_inputs( @@ -998,7 +998,7 @@ class CLASS_economy(Container): def usbonds( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """USBONDS.""" inputs = filter_inputs( @@ -1020,7 +1020,7 @@ class CLASS_economy(Container): def valuation( self, chart: bool = False, - provider: Optional[Literal["fmp", "fred", "benzinga", "polygon"]] = None, + provider: Optional[Literal["fmp", "fred", "polygon", "benzinga"]] = None, ) -> CommandOutput[openbb_core.app.model.results.empty.Empty]: """VALUATION.""" inputs = filter_inputs(