From 3d579ca2e3d1f8745627dc7bdf1691f091ab895d Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 10:12:25 -0400 Subject: [PATCH 01/28] 3.2 -> 3.2.1 --- build/docker/compose.env | 2 +- build/nsis/setup.nsi | 6 +++--- build/pyinstaller/version.rc | 4 ++-- openbb_terminal/core/models/system_model.py | 2 +- pyproject.toml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/docker/compose.env b/build/docker/compose.env index d1c6141e53c..943d85414f3 100644 --- a/build/docker/compose.env +++ b/build/docker/compose.env @@ -1,2 +1,2 @@ OPENBBTERMINAL_DOCKER_REGISTRY="ghcr.io" -OPENBBTERMINAL_DOCKER_RELEASE_VERSION="3.2.0" +OPENBBTERMINAL_DOCKER_RELEASE_VERSION="3.2.1" diff --git a/build/nsis/setup.nsi b/build/nsis/setup.nsi index d80b4ffaf05..8bb8de9696f 100644 --- a/build/nsis/setup.nsi +++ b/build/nsis/setup.nsi @@ -10,7 +10,7 @@ !define NAME "OpenBB Terminal" !define COMPANY "OpenBB" !define APPFILE "OpenBBTerminal.exe" - !define VERSION "3.2.0" + !define VERSION "3.2.1" !define SLUG "${NAME} v${VERSION}" ;-------------------------------- @@ -20,8 +20,8 @@ VIAddVersionKey Comments "An installer for OpenBB Terminal. For additional details, visit OpenBB.co" VIAddVersionKey CompanyName OpenBB.co VIAddVersionKey FileDescription "OpenBB Terminal Program" - VIAddVersionKey FileVersion 3.2.0.0 - VIAddVersionKey ProductVersion 3.2.0.0 + VIAddVersionKey FileVersion 3.2.1.0 + VIAddVersionKey ProductVersion 3.2.1.0 VIAddVersionKey InternalName "OpenBB Terminal" ;-------------------------------- diff --git a/build/pyinstaller/version.rc b/build/pyinstaller/version.rc index 444f270896b..76cb484c2c8 100644 --- a/build/pyinstaller/version.rc +++ b/build/pyinstaller/version.rc @@ -32,10 +32,10 @@ VSVersionInfo( [StringStruct('Comments', 'The OpenBB Terminal. For additional details, visit OpenBB.co'), StringStruct('CompanyName', 'OpenBB'), StringStruct('FileDescription', 'OpenBB Terminal Program'), - StringStruct('FileVersion', '3.2.0.0'), + StringStruct('FileVersion', '3.2.1.0'), StringStruct('InternalName', 'OpenBB Terminal'), StringStruct('ProductName', 'OpenBB Terminal'), - StringStruct('ProductVersion', '3.2.0.0')]) + StringStruct('ProductVersion', '3.2.1.0')]) ]), VarFileInfo([VarStruct('Translation', [1033, 1200])]) ] diff --git a/openbb_terminal/core/models/system_model.py b/openbb_terminal/core/models/system_model.py index 85d61e7b1bf..e8a1b6c181d 100644 --- a/openbb_terminal/core/models/system_model.py +++ b/openbb_terminal/core/models/system_model.py @@ -28,7 +28,7 @@ class SystemModel(BaseModel): PLATFORM: str = str(platform.platform()) # OpenBB section - VERSION: str = "3.2.0" + VERSION: str = "3.2.1" # Logging section LOGGING_APP_ID: str = "REPLACE_ME" diff --git a/pyproject.toml b/pyproject.toml index e99652e0ee5..a7d46128a19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "openbb" -version = "3.2.0" +version = "3.2.1" description = "Investment Research for Everyone, Anywhere." license = "MIT" authors = ["Didier Rodrigues Lopes"] From d3b399069968537a5ff50c4eeb18a75b54aea178 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 10:17:10 -0400 Subject: [PATCH 02/28] Update changelogs --- website/content/terminal/changelog/version2_0_0.mdx | 2 +- website/content/terminal/changelog/version2_1_0.mdx | 2 +- website/content/terminal/changelog/version2_2_0.mdx | 2 +- website/content/terminal/changelog/version2_3_0.mdx | 2 +- website/content/terminal/changelog/version2_3_1.mdx | 2 +- website/content/terminal/changelog/version2_4_0.mdx | 2 +- website/content/terminal/changelog/version2_4_1.mdx | 2 +- website/content/terminal/changelog/version2_5_0.mdx | 2 +- website/content/terminal/changelog/version2_5_1.mdx | 2 +- website/content/terminal/changelog/version3_0_0.mdx | 2 +- website/content/terminal/changelog/version3_0_1.mdx | 2 +- website/content/terminal/changelog/version3_1_0.mdx | 2 +- website/content/terminal/changelog/version3_2_0.mdx | 4 ++-- website/content/terminal/changelog/version3_2_1.mdx | 7 +++++++ website/content/terminal/installation/macos.md | 2 +- website/content/terminal/installation/windows.md | 2 +- 16 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 website/content/terminal/changelog/version3_2_1.mdx diff --git a/website/content/terminal/changelog/version2_0_0.mdx b/website/content/terminal/changelog/version2_0_0.mdx index c401bd29c86..0841d51f334 100644 --- a/website/content/terminal/changelog/version2_0_0.mdx +++ b/website/content/terminal/changelog/version2_0_0.mdx @@ -3,7 +3,7 @@ title: v2.0.0 version: "2.0.0" date: 2022-11-29 description: v2.0.0 -sidebar_position: 104 +sidebar_position: 105 --- ## Major Release Notes diff --git a/website/content/terminal/changelog/version2_1_0.mdx b/website/content/terminal/changelog/version2_1_0.mdx index e1cdd8e5f44..321425a6955 100644 --- a/website/content/terminal/changelog/version2_1_0.mdx +++ b/website/content/terminal/changelog/version2_1_0.mdx @@ -3,7 +3,7 @@ title: v2.1.0 version: "2.1.0" date: 2022-12-21 description: v2.1.0 -sidebar_position: 103 +sidebar_position: 104 --- ## What's new diff --git a/website/content/terminal/changelog/version2_2_0.mdx b/website/content/terminal/changelog/version2_2_0.mdx index 5bedd316e98..51bc24934de 100644 --- a/website/content/terminal/changelog/version2_2_0.mdx +++ b/website/content/terminal/changelog/version2_2_0.mdx @@ -3,7 +3,7 @@ title: v2.2.0 version: "2.2.0" date: 2022-01-19 description: v2.2.0 -sidebar_position: 102 +sidebar_position: 103 --- ## What's new diff --git a/website/content/terminal/changelog/version2_3_0.mdx b/website/content/terminal/changelog/version2_3_0.mdx index 11a082997df..c6b65de6aa3 100644 --- a/website/content/terminal/changelog/version2_3_0.mdx +++ b/website/content/terminal/changelog/version2_3_0.mdx @@ -3,7 +3,7 @@ title: v2.3.0 version: "2.3.0" date: 2023-01-31 description: v2.3.0 -sidebar_position: 101 +sidebar_position: 102 --- diff --git a/website/content/terminal/changelog/version2_3_1.mdx b/website/content/terminal/changelog/version2_3_1.mdx index 1b553ad84ad..7f811c4a3fc 100644 --- a/website/content/terminal/changelog/version2_3_1.mdx +++ b/website/content/terminal/changelog/version2_3_1.mdx @@ -3,7 +3,7 @@ title: v2.3.1 version: "2.3.1" date: 2023-02-01 description: v2.3.1 -sidebar_position: 100 +sidebar_position: 101 --- ## Fixed diff --git a/website/content/terminal/changelog/version2_4_0.mdx b/website/content/terminal/changelog/version2_4_0.mdx index bea3f19a099..2296a060a3b 100644 --- a/website/content/terminal/changelog/version2_4_0.mdx +++ b/website/content/terminal/changelog/version2_4_0.mdx @@ -3,7 +3,7 @@ title: v2.4.0 version: "2.4.0" date: 2023-02-14 description: v2.4.0 -sidebar_position: 99 +sidebar_position: 100 --- ## What's new diff --git a/website/content/terminal/changelog/version2_4_1.mdx b/website/content/terminal/changelog/version2_4_1.mdx index 1cba750d632..dfa0696ac39 100644 --- a/website/content/terminal/changelog/version2_4_1.mdx +++ b/website/content/terminal/changelog/version2_4_1.mdx @@ -3,7 +3,7 @@ title: v2.4.1 version: "2.4.1" date: 2023-02-17 description: v2.4.1 -sidebar_position: 98 +sidebar_position: 99 --- ## What's new diff --git a/website/content/terminal/changelog/version2_5_0.mdx b/website/content/terminal/changelog/version2_5_0.mdx index 35aaf918ba5..adf11b02a15 100644 --- a/website/content/terminal/changelog/version2_5_0.mdx +++ b/website/content/terminal/changelog/version2_5_0.mdx @@ -3,7 +3,7 @@ title: v2.5.0 version: "2.5.0" date: 2023-03-01 description: v2.5.0 -sidebar_position: 97 +sidebar_position: 98 --- diff --git a/website/content/terminal/changelog/version2_5_1.mdx b/website/content/terminal/changelog/version2_5_1.mdx index ef55df63440..2a52912bda0 100644 --- a/website/content/terminal/changelog/version2_5_1.mdx +++ b/website/content/terminal/changelog/version2_5_1.mdx @@ -3,7 +3,7 @@ title: 2.5.1 version: "2.5.1" date: 2023-03-01 description: Current - v2.5.1 -sidebar_position: 96 +sidebar_position: 97 --- ## Fixed diff --git a/website/content/terminal/changelog/version3_0_0.mdx b/website/content/terminal/changelog/version3_0_0.mdx index 8c44fefb86c..a9bdddeafaf 100644 --- a/website/content/terminal/changelog/version3_0_0.mdx +++ b/website/content/terminal/changelog/version3_0_0.mdx @@ -3,7 +3,7 @@ title: v3.0.0 version: "3.0.0" date: 2023-04-25 description: v3.0.0 -sidebar_position: 95 +sidebar_position: 96 --- ## What's new diff --git a/website/content/terminal/changelog/version3_0_1.mdx b/website/content/terminal/changelog/version3_0_1.mdx index a63a568308c..c800ffe2d9f 100644 --- a/website/content/terminal/changelog/version3_0_1.mdx +++ b/website/content/terminal/changelog/version3_0_1.mdx @@ -3,7 +3,7 @@ title: v3.0.1 version: "3.0.1" date: 2023-05-15 description: v3.0.1 -sidebar_position: 94 +sidebar_position: 95 --- ## Thank you and welcome to our new contributors 🔥 diff --git a/website/content/terminal/changelog/version3_1_0.mdx b/website/content/terminal/changelog/version3_1_0.mdx index 64a7333629d..8c7583c9495 100644 --- a/website/content/terminal/changelog/version3_1_0.mdx +++ b/website/content/terminal/changelog/version3_1_0.mdx @@ -3,7 +3,7 @@ title: v3.1.0 version: "3.1.0" date: 2023-06-21 description: v3.1.0 -sidebar_position: 93 +sidebar_position: 94 --- ## Thank you and welcome to our new contributors 🔥 diff --git a/website/content/terminal/changelog/version3_2_0.mdx b/website/content/terminal/changelog/version3_2_0.mdx index f6394b67ed6..17acdec8042 100644 --- a/website/content/terminal/changelog/version3_2_0.mdx +++ b/website/content/terminal/changelog/version3_2_0.mdx @@ -1,9 +1,9 @@ --- -title: Current - v3.2.0 +title: v3.2.0 version: "3.2.0" date: 2023-07-21 description: Current - v3.2.0 -sidebar_position: 92 +sidebar_position: 93 --- ## Thank you and welcome to our new contributors 🔥 diff --git a/website/content/terminal/changelog/version3_2_1.mdx b/website/content/terminal/changelog/version3_2_1.mdx new file mode 100644 index 00000000000..fc668a0aa27 --- /dev/null +++ b/website/content/terminal/changelog/version3_2_1.mdx @@ -0,0 +1,7 @@ +--- +title: Current - v3.2.1 +version: "3.2.1" +date: 2023-08-07 +description: Current - v3.2.1 +sidebar_position: 92 +--- diff --git a/website/content/terminal/installation/macos.md b/website/content/terminal/installation/macos.md index 5cb04f61679..5e5511dca76 100644 --- a/website/content/terminal/installation/macos.md +++ b/website/content/terminal/installation/macos.md @@ -37,7 +37,7 @@ Install the OpenBB Terminal on MacOS (Big Sur or later). There are two versions
- +
Minimum Requirements diff --git a/website/content/terminal/installation/windows.md b/website/content/terminal/installation/windows.md index 2eaa9e62242..c9c1727bcb4 100644 --- a/website/content/terminal/installation/windows.md +++ b/website/content/terminal/installation/windows.md @@ -30,7 +30,7 @@ import InstallerButton from "@site/src/components/General/InstallerButton"; This section provides you with the installation file as well as the guide to install the OpenBB Terminal via Windows (10 or greater). - +
Minimum Requirements From 71122ee4e75135532471bcb5d644c50628c06e8a Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 10:31:43 -0400 Subject: [PATCH 03/28] fix vsurf labels --- openbb_terminal/stocks/options/yfinance_view.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbb_terminal/stocks/options/yfinance_view.py b/openbb_terminal/stocks/options/yfinance_view.py index 27e6236ca0d..1359a79523c 100644 --- a/openbb_terminal/stocks/options/yfinance_view.py +++ b/openbb_terminal/stocks/options/yfinance_view.py @@ -320,8 +320,8 @@ def display_vol_surface( tick_kwargs = dict(tickfont=dict(size=13), titlefont=dict(size=16)) fig.update_layout( scene=dict( - xaxis=dict(title="Strike", **tick_kwargs), - yaxis=dict(title="DTE", **tick_kwargs), + xaxis=dict(title="DTE", **tick_kwargs), + yaxis=dict(title="Strike", **tick_kwargs), zaxis=dict(title=z, **tick_kwargs), ) ) From 32c3a5d5db0c932d8f323e0956369c590cee4b28 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 10:41:07 -0400 Subject: [PATCH 04/28] Remove deprecated argument from yfinance dl --- openbb_terminal/economy/yfinance_model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openbb_terminal/economy/yfinance_model.py b/openbb_terminal/economy/yfinance_model.py index df410b4e26c..c8c92fbe61c 100644 --- a/openbb_terminal/economy/yfinance_model.py +++ b/openbb_terminal/economy/yfinance_model.py @@ -646,7 +646,6 @@ def get_index( end=end_date, interval=interval, progress=False, - show_errors=False, ignore_tz=True, ) From 7978cef54184808889859ed41c1171599916cced Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 10:49:22 -0400 Subject: [PATCH 05/28] Fix #5272 --- openbb_terminal/stocks/comparison_analysis/ca_controller.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openbb_terminal/stocks/comparison_analysis/ca_controller.py b/openbb_terminal/stocks/comparison_analysis/ca_controller.py index 464bf83b8fa..8e1225ae1c1 100644 --- a/openbb_terminal/stocks/comparison_analysis/ca_controller.py +++ b/openbb_terminal/stocks/comparison_analysis/ca_controller.py @@ -442,7 +442,10 @@ class ComparisonAnalysisController(BaseController): other_args.insert(0, "-s") ns_parser = self.parse_known_args_and_warn(parser, other_args) if ns_parser: - self.similar = list(set(ns_parser.l_similar + [self.ticker.upper()])) + if self.ticker: + self.similar = list(set(ns_parser.l_similar + [self.ticker.upper()])) + else: + self.similar = list(set(ns_parser.l_similar)) self.user = "Custom" console.print( f"[{self.user}] Similar Companies: {', '.join(self.similar)}", "\n" From ee76e95b4aa130edebbc665cd47fc57deee3c415 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 11:22:56 -0400 Subject: [PATCH 06/28] deprecate econometrics/season --- .../econometrics/econometrics_controller.py | 77 ------------------- .../econometrics/econometrics_view.py | 57 -------------- 2 files changed, 134 deletions(-) diff --git a/openbb_terminal/econometrics/econometrics_controller.py b/openbb_terminal/econometrics/econometrics_controller.py index 03b1a9a538d..9d1bf49a9f1 100644 --- a/openbb_terminal/econometrics/econometrics_controller.py +++ b/openbb_terminal/econometrics/econometrics_controller.py @@ -56,7 +56,6 @@ class EconometricsController(BaseController): "type", "desc", "corr", - "season", "index", "clean", "add", @@ -188,7 +187,6 @@ class EconometricsController(BaseController): "granger", "coint", "corr", - "season", "lag", "vif", ]: @@ -216,7 +214,6 @@ class EconometricsController(BaseController): "norm", "root", "coint", - "season", "lag", "regressions", "ols", @@ -279,7 +276,6 @@ class EconometricsController(BaseController): mt.add_cmd("type", self.files) mt.add_cmd("desc", self.files) mt.add_cmd("corr", self.files) - mt.add_cmd("season", self.files) mt.add_cmd("index", self.files) mt.add_cmd("clean", self.files) mt.add_cmd("add", self.files) @@ -752,79 +748,6 @@ class EconometricsController(BaseController): ns_parser.export, ) - @log_start_end(log=logger) - def call_season(self, other_args: List[str]): - """Process season command""" - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="season", - description="The seasonality for a given column", - ) - parser.add_argument( - "-v", - "--values", - help="Dataset.column values to be displayed in a plot", - dest="values", - choices={ - f"{dataset}.{column}": {column: None, dataset: None} - for dataset, dataframe in self.datasets.items() - for column in dataframe.columns - }, - type=str, - ) - parser.add_argument( - "-m", - help="A time lag to highlight on the plot", - dest="m", - type=int, - default=None, - ) - parser.add_argument( - "--max_lag", - help="The maximal lag order to consider", - dest="max_lag", - type=int, - default=24, - ) - parser.add_argument( - "-a", - "--alpha", - help="The confidence interval to display", - dest="alpha", - type=float, - default=0.05, - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-v") - ns_parser = self.parse_known_args_and_warn( - parser, other_args, export_allowed=EXPORT_ONLY_FIGURES_ALLOWED - ) - - if not ns_parser: - return - - if not ns_parser.values: - console.print("[red]Please enter valid dataset.\n[/red]") - return - - try: - dataset, col = ns_parser.values.split(".") - data = self.datasets[dataset] - data.name = dataset - except ValueError: - console.print("[red]Please enter 'dataset'.'column'.[/red]\n") - return - - econometrics_view.display_seasonality( - data=data, - column=col, - export=ns_parser.export, - m=ns_parser.m, - max_lag=ns_parser.max_lag, - alpha=ns_parser.alpha, - ) - @log_start_end(log=logger) def call_type(self, other_args: List[str]): """Process type command""" diff --git a/openbb_terminal/econometrics/econometrics_view.py b/openbb_terminal/econometrics/econometrics_view.py index 6bebc81065a..6a34ffc126c 100644 --- a/openbb_terminal/econometrics/econometrics_view.py +++ b/openbb_terminal/econometrics/econometrics_view.py @@ -200,63 +200,6 @@ def display_corr( return fig.show(external=external_axes) -@log_start_end(log=logger) -def display_seasonality( - data: pd.DataFrame, - column: str = "close", - export: str = "", - sheet_name: Optional[str] = None, - m: Optional[int] = None, - max_lag: int = 24, - alpha: float = 0.05, - external_axes: bool = False, -) -> Union[OpenBBFigure, None]: - """Plot seasonality from a dataset - - Parameters - ---------- - data: pd.DataFrame - The dataframe to plot - column: str - The column of the dataframe to analyze - sheet_name: str - Optionally specify the name of the sheet the data is exported to. - export: str - Format to export image - m: Optional[int] - Optionally, a time lag to highlight on the plot. Default is none. - max_lag: int - The maximal lag order to consider. Default is 24. - alpha: float - The confidence interval to display. Default is 0.05. - external_axes : bool, optional - Whether to return the figure object or not, by default False - """ - - if data.empty: - return console.print("No data to plot") - - series = data[column] - - ending = get_ending(data.name, column) - - fig = OpenBBFigure() - fig.set_title(f"Seasonality{ending}", wrap=True, wrap_width=55) - fig.add_corr_plot(series, m=m, max_lag=max_lag, alpha=alpha) - fig.update_xaxes(autorange=False, range=[-1, max_lag + 1]) - fig.add_legend_label() - - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "plot", - sheet_name=sheet_name, - figure=fig, - ) - - return fig.show(external=external_axes) - - @log_start_end(log=logger) def display_norm( data: pd.Series, From 5759ebad24fb67677816650024267c07923f706a Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 14:49:10 -0400 Subject: [PATCH 07/28] Fix #5258 --- openbb_terminal/stocks/government/quiverquant_model.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openbb_terminal/stocks/government/quiverquant_model.py b/openbb_terminal/stocks/government/quiverquant_model.py index e0428525f86..81f28d42cd8 100644 --- a/openbb_terminal/stocks/government/quiverquant_model.py +++ b/openbb_terminal/stocks/government/quiverquant_model.py @@ -275,8 +275,8 @@ def get_government_buys( else -float(x["min"]), axis=1, ) - - df_gov = df_gov.sort_values("TransactionDate", ascending=True) + df_gov = df_gov[df_gov.Transaction == "Purchase"] + df_gov = df_gov.sort_values(by="Amount", ascending=False).reset_index(drop=True) return df_gov @@ -348,7 +348,11 @@ def get_government_sells( ) df_gov = df_gov.sort_values("TransactionDate", ascending=True) - + df_gov = ( + df_gov[df_gov.Transaction == "Sale"] + .sort_values(by="Amount", key=lambda x: abs(x), ascending=False) + .reset_index(drop=True) + ) return df_gov From fcde988335f38b58582e9272786743c98ca22f5d Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 14:55:39 -0400 Subject: [PATCH 08/28] Update finvizfinance version to fix #5158 --- poetry.lock | 487 ++---------------------------------------- pyproject.toml | 2 +- requirements-full.txt | 8 +- requirements.txt | 8 +- 4 files changed, 26 insertions(+), 479 deletions(-) diff --git a/poetry.lock b/poetry.lock index 943196d1e9b..26737938fd5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "absl-py" version = "1.4.0" description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -16,7 +15,6 @@ files = [ name = "adagio" version = "0.2.4" description = "The Dag IO Framework for Fugue projects" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -31,7 +29,6 @@ triad = ">=0.6.1" name = "aiodns" version = "3.0.0" description = "Simple DNS resolver for asyncio" -category = "main" optional = false python-versions = "*" files = [ @@ -46,7 +43,6 @@ pycares = ">=4.0.0" name = "aiofiles" version = "22.1.0" description = "File support for asyncio." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -58,7 +54,6 @@ files = [ name = "aiohttp" version = "3.8.5" description = "Async http client/server framework (asyncio)" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -167,7 +162,6 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -182,7 +176,6 @@ frozenlist = ">=1.1.0" name = "aiosqlite" version = "0.19.0" description = "asyncio bridge to the standard sqlite3 module" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -198,7 +191,6 @@ docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"] name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -210,7 +202,6 @@ files = [ name = "alpha-vantage" version = "2.3.1" description = "Python module to get stock data from the Alpha Vantage Api" -category = "main" optional = false python-versions = "*" files = [ @@ -226,7 +217,6 @@ requests = "*" name = "altair" version = "5.0.1" description = "Vega-Altair: A declarative statistical visualization library for Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -250,7 +240,6 @@ doc = ["docutils", "geopandas", "jinja2", "myst-parser", "numpydoc", "pillow", " name = "altgraph" version = "0.17.3" description = "Python graph (network) package" -category = "main" optional = true python-versions = "*" files = [ @@ -262,7 +251,6 @@ files = [ name = "ansi2html" version = "1.8.0" description = "" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -278,7 +266,6 @@ test = ["pytest", "pytest-cov"] name = "ansiwrap" version = "0.8.4" description = "textwrap, but savvy to ANSI colors and styles" -category = "main" optional = false python-versions = "*" files = [ @@ -293,7 +280,6 @@ textwrap3 = ">=0.9.2" name = "antlr4-python3-runtime" version = "4.11.1" description = "ANTLR 4.11.1 runtime for Python 3" -category = "main" optional = true python-versions = "*" files = [ @@ -305,7 +291,6 @@ files = [ name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -327,7 +312,6 @@ trio = ["trio (<0.22)"] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = "*" files = [ @@ -339,7 +323,6 @@ files = [ name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "main" optional = false python-versions = "*" files = [ @@ -351,7 +334,6 @@ files = [ name = "arch" version = "5.6.0" description = "ARCH for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -391,7 +373,6 @@ statsmodels = ">=0.11" name = "argon2-cffi" version = "21.3.0" description = "The secure Argon2 password hashing algorithm." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -411,7 +392,6 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -449,7 +429,6 @@ tests = ["pytest"] name = "arrow" version = "1.2.3" description = "Better dates & times for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -464,7 +443,6 @@ python-dateutil = ">=2.7.0" name = "ascii-magic" version = "1.6" description = "Converts pictures into ASCII art" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -480,7 +458,6 @@ Pillow = "*" name = "astor" version = "0.8.1" description = "Read/rewrite/write Python ASTs" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ @@ -492,7 +469,6 @@ files = [ name = "astroid" version = "2.15.6" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -509,7 +485,6 @@ wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""} name = "astropy" version = "5.2.2" description = "Astronomy and astrophysics core library" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -563,7 +538,6 @@ test-all = ["coverage[toml]", "ipython (>=4.2)", "objgraph", "pytest (>=7.0)", " name = "asttokens" version = "2.2.1" description = "Annotate AST trees with source code positions" -category = "main" optional = false python-versions = "*" files = [ @@ -581,7 +555,6 @@ test = ["astroid", "pytest"] name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -593,7 +566,6 @@ files = [ name = "atomicwrites" version = "1.4.1" description = "Atomic file writes." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -604,7 +576,6 @@ files = [ name = "attrs" version = "21.4.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -622,7 +593,6 @@ tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy" name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -637,7 +607,6 @@ pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "main" optional = false python-versions = "*" files = [ @@ -649,7 +618,6 @@ files = [ name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -661,7 +629,6 @@ files = [ name = "backports-zoneinfo" version = "0.2.1" description = "Backport of the standard library zoneinfo module" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -690,7 +657,6 @@ tzdata = ["tzdata"] name = "bandit" version = "1.7.5" description = "Security oriented static analyser for python code." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -714,7 +680,6 @@ yaml = ["PyYAML"] name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -729,7 +694,6 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -748,7 +712,6 @@ lxml = ["lxml"] name = "black" version = "23.7.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -795,7 +758,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -814,7 +776,6 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "blinker" version = "1.6.2" description = "Fast, simple object-to-object and broadcast signaling" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -826,7 +787,6 @@ files = [ name = "brotli" version = "1.0.9" description = "Python bindings for the Brotli compression library" -category = "main" optional = true python-versions = "*" files = [ @@ -918,7 +878,6 @@ files = [ name = "brotlicffi" version = "1.0.9.2" description = "Python CFFI bindings to the Brotli library" -category = "main" optional = true python-versions = "*" files = [ @@ -961,7 +920,6 @@ cffi = ">=1.0.0" name = "bs4" version = "0.0.1" description = "Dummy package for Beautiful Soup" -category = "main" optional = false python-versions = "*" files = [ @@ -975,7 +933,6 @@ beautifulsoup4 = "*" name = "bt" version = "0.2.9" description = "A flexible backtesting framework for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -1001,7 +958,6 @@ dev = ["black (>=20.8b1)", "codecov", "coverage", "cython (>=0.25)", "ffn (>=0.3 name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1013,7 +969,6 @@ files = [ name = "catboost" version = "1.2" description = "CatBoost Python Package" -category = "main" optional = true python-versions = "*" files = [ @@ -1056,7 +1011,6 @@ widget = ["ipython", "ipywidgets (>=7.0,<9.0)", "traitlets"] name = "cattrs" version = "23.1.2" description = "Composable complex class support for attrs and dataclasses." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1082,7 +1036,6 @@ ujson = ["ujson (>=5.4.0,<6.0.0)"] name = "ccxt" version = "4.0.33" description = "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges" -category = "main" optional = false python-versions = "*" files = [ @@ -1106,7 +1059,6 @@ qa = ["flake8 (==3.7.9)"] name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1118,7 +1070,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -1195,7 +1146,6 @@ pycparser = "*" name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -1207,7 +1157,6 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -1292,7 +1241,6 @@ files = [ name = "click" version = "8.1.6" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1307,7 +1255,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "cloudpickle" version = "2.2.1" description = "Extended pickling support for Python objects" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -1319,7 +1266,6 @@ files = [ name = "cmdstanpy" version = "1.1.0" description = "Python interface to CmdStan" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1341,7 +1287,6 @@ tests = ["flake8", "mypy", "pylint", "pytest", "pytest-cov", "pytest-order", "tq name = "codespell" version = "2.2.5" description = "Codespell" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1359,7 +1304,6 @@ types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -1371,7 +1315,6 @@ files = [ name = "comm" version = "0.1.3" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1391,7 +1334,6 @@ typing = ["mypy (>=0.990)"] name = "commonmark" version = "0.9.1" description = "Python parser for the CommonMark Markdown spec" -category = "main" optional = false python-versions = "*" files = [ @@ -1406,7 +1348,6 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1465,7 +1406,6 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "convertdate" version = "2.4.0" description = "Converts between Gregorian dates and other calendar systems" -category = "main" optional = false python-versions = "<4,>=3.7" files = [ @@ -1485,7 +1425,6 @@ tests = ["coverage"] name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1561,7 +1500,6 @@ toml = ["tomli"] name = "cryptography" version = "41.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1607,7 +1545,6 @@ test-randomorder = ["pytest-randomly"] name = "cssselect" version = "1.2.0" description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1619,7 +1556,6 @@ files = [ name = "cssselect2" version = "0.7.0" description = "CSS selectors for Python ElementTree" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1639,7 +1575,6 @@ test = ["flake8", "isort", "pytest"] name = "cvxpy" version = "1.2.2" description = "A domain-specific language for modeling convex optimization problems in Python." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1672,7 +1607,6 @@ scs = ">=1.1.6" name = "cycler" version = "0.11.0" description = "Composable style cycles" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1684,7 +1618,6 @@ files = [ name = "cython" version = "3.0.0" description = "The Cython compiler for writing C extensions in the Python language." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1752,7 +1685,6 @@ files = [ name = "dash" version = "2.9.3" description = "A Python framework for building reactive web-apps. Developed by Plotly." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -1779,7 +1711,6 @@ testing = ["beautifulsoup4 (>=4.8.2)", "cryptography (<3.4)", "dash-testing-stub name = "dash-core-components" version = "2.0.0" description = "Core component suite for Dash" -category = "main" optional = true python-versions = "*" files = [ @@ -1791,7 +1722,6 @@ files = [ name = "dash-html-components" version = "2.0.0" description = "Vanilla HTML components for Dash" -category = "main" optional = true python-versions = "*" files = [ @@ -1803,7 +1733,6 @@ files = [ name = "dash-table" version = "5.0.0" description = "Dash table" -category = "main" optional = true python-versions = "*" files = [ @@ -1815,7 +1744,6 @@ files = [ name = "dataclasses-json" version = "0.5.12" description = "Easily serialize dataclasses to and from JSON." -category = "main" optional = false python-versions = ">=3.7,<3.12" files = [ @@ -1831,7 +1759,6 @@ typing-inspect = ">=0.4.0,<1" name = "dateparser" version = "1.1.8" description = "Date parsing library designed to parse dates from HTML pages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1854,7 +1781,6 @@ langdetect = ["langdetect"] name = "datetime" version = "5.2" description = "This package provides a DateTime data type, as known from Zope. Unless you need to communicate with Zope APIs, you're probably better off using Python's built-in datetime module." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1870,7 +1796,6 @@ pytz = "*" name = "debugpy" version = "1.6.7" description = "An implementation of the Debug Adapter Protocol for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1898,7 +1823,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1910,7 +1834,6 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1922,7 +1845,6 @@ files = [ name = "degiro-connector" version = "2.0.21" description = "This is yet another library to access Degiro's API." -category = "main" optional = false python-versions = ">=3.7.1,<4.0.0" files = [ @@ -1942,7 +1864,6 @@ wrapt = ">=1.12.1,<2.0.0" name = "detecta" version = "0.0.5" description = "Detect events in data" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1954,7 +1875,6 @@ files = [ name = "dill" version = "0.3.6" description = "serialize all of python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1969,7 +1889,6 @@ graph = ["objgraph (>=1.7.2)"] name = "distlib" version = "0.3.7" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -1981,7 +1900,6 @@ files = [ name = "dnspython" version = "2.4.0" description = "DNS toolkit" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -2005,7 +1923,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"] name = "docstring-parser" version = "0.15" description = "Parse Python docstrings in reST, Google and Numpydoc format" -category = "main" optional = true python-versions = ">=3.6,<4.0" files = [ @@ -2017,7 +1934,6 @@ files = [ name = "docstring-to-markdown" version = "0.12" description = "On the fly conversion of Python docstrings to markdown" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2029,7 +1945,6 @@ files = [ name = "docutils" version = "0.17.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -2041,7 +1956,6 @@ files = [ name = "ecdsa" version = "0.18.0" description = "ECDSA cryptographic signature library (pure python)" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2060,7 +1974,6 @@ gmpy2 = ["gmpy2"] name = "ecos" version = "2.0.12" description = "This is the Python package for ECOS: Embedded Cone Solver. See Github page for more information." -category = "main" optional = true python-versions = "*" files = [ @@ -2090,7 +2003,6 @@ scipy = ">=0.9" name = "entrypoints" version = "0.4" description = "Discover and load entry points from installed packages." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2102,7 +2014,6 @@ files = [ name = "ephem" version = "4.1.4" description = "Compute positions of the planets and stars" -category = "main" optional = true python-versions = "*" files = [ @@ -2179,7 +2090,6 @@ files = [ name = "et-xmlfile" version = "1.1.0" description = "An implementation of lxml.xmlfile for the standard library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2191,7 +2101,6 @@ files = [ name = "exceptiongroup" version = "1.1.2" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2206,7 +2115,6 @@ test = ["pytest (>=6)"] name = "exchange-calendars" version = "4.2.8" description = "Calendars for securities exchanges" -category = "main" optional = false python-versions = "~=3.8" files = [ @@ -2230,7 +2138,6 @@ dev = ["flake8", "hypothesis", "pip-tools", "pytest", "pytest-benchmark", "pytes name = "execnet" version = "2.0.2" description = "execnet: rapid multi-Python deployment" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2245,7 +2152,6 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" -category = "main" optional = false python-versions = "*" files = [ @@ -2260,7 +2166,6 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "fastjsonschema" version = "2.17.1" description = "Fastest Python implementation of JSON schema" -category = "main" optional = false python-versions = "*" files = [ @@ -2275,7 +2180,6 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "feedparser" version = "6.0.10" description = "Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2290,7 +2194,6 @@ sgmllib3k = "*" name = "ffmpeg-python" version = "0.2.0" description = "Python bindings for FFmpeg - with complex filtering support" -category = "main" optional = true python-versions = "*" files = [ @@ -2308,7 +2211,6 @@ dev = ["Sphinx (==2.1.0)", "future (==0.17.1)", "numpy (==1.16.4)", "pytest (==4 name = "ffn" version = "0.3.6" description = "Financial functions for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -2334,7 +2236,6 @@ dev = ["black (>=20.8b1)", "codecov", "coverage", "flake8", "flake8-black", "fut name = "filelock" version = "3.12.2" description = "A platform independent file lock." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2350,7 +2251,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "financedatabase" version = "2.1.0" description = "This is a database of 300.000+ symbols containing Equities, ETFs, Funds, Indices, Currencies, Cryptocurrencies and Money Markets." -category = "main" optional = false python-versions = "*" files = [ @@ -2365,7 +2265,6 @@ pandas = "*" name = "finnhub-python" version = "2.4.18" description = "Finnhub API" -category = "main" optional = false python-versions = "*" files = [ @@ -2380,7 +2279,6 @@ requests = ">=2.22.0" name = "finviz" version = "1.4.6" description = "Unofficial API for FinViz.com" -category = "main" optional = false python-versions = "*" files = [ @@ -2400,14 +2298,13 @@ user_agent = "*" [[package]] name = "finvizfinance" -version = "0.14.5" +version = "0.14.6rc2" description = "Finviz Finance. Information downloader." -category = "main" optional = false python-versions = ">=3.5" files = [ - {file = "finvizfinance-0.14.5-py3-none-any.whl", hash = "sha256:1b22bfd7af36f01a08c6032e19f64e810ae3f42bfba681e9a2132226a5a90924"}, - {file = "finvizfinance-0.14.5.tar.gz", hash = "sha256:c97fe0e69d681d9108113aed943988561665d0d4dbd64ffa0b666a2899c25899"}, + {file = "finvizfinance-0.14.6rc2-py3-none-any.whl", hash = "sha256:70742b5054e84fbe5a1ffcc7cad97ca9225292e07ce0349dcb78462d5e5e51a0"}, + {file = "finvizfinance-0.14.6rc2.tar.gz", hash = "sha256:736f3064faac1f8ba6d06fdd7c77f79a3e831c2048fc6442759861fce4c4a6e8"}, ] [package.dependencies] @@ -2421,7 +2318,6 @@ requests = "*" name = "flake8" version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" -category = "main" optional = false python-versions = ">=3.8.1" files = [ @@ -2438,7 +2334,6 @@ pyflakes = ">=3.0.0,<3.1.0" name = "flask" version = "2.3.2" description = "A simple framework for building complex web applications." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -2462,7 +2357,6 @@ dotenv = ["python-dotenv"] name = "fonttools" version = "4.41.0" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2520,7 +2414,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "formulaic" version = "0.6.4" description = "An implementation of Wilkinson formulas." -category = "main" optional = false python-versions = ">=3.7.2" files = [ @@ -2546,7 +2439,6 @@ calculus = ["sympy (>=1.3,!=1.10)"] name = "fqdn" version = "1.5.1" description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -category = "main" optional = false python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" files = [ @@ -2558,7 +2450,6 @@ files = [ name = "fred" version = "3.1" description = "St. Louis Federal Reserve FRED API" -category = "main" optional = false python-versions = "*" files = [ @@ -2572,7 +2463,6 @@ requests = "*" name = "fredapi" version = "0.4.3" description = "Python API for Federal Reserve Economic Data (FRED) from St. Louis Fed" -category = "main" optional = false python-versions = "*" files = [ @@ -2587,7 +2477,6 @@ pandas = "*" name = "freezegun" version = "1.2.2" description = "Let your Python tests travel through time" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2602,7 +2491,6 @@ python-dateutil = ">=2.7" name = "frozendict" version = "2.3.8" description = "A simple immutable dictionary" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2649,7 +2537,6 @@ files = [ name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2720,7 +2607,6 @@ files = [ name = "fs" version = "2.4.16" description = "Python's filesystem abstraction layer" -category = "main" optional = true python-versions = "*" files = [ @@ -2740,7 +2626,6 @@ scandir = ["scandir (>=1.5,<2.0)"] name = "fsspec" version = "2023.6.0" description = "File-system specification" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2780,7 +2665,6 @@ tqdm = ["tqdm"] name = "fugue" version = "0.8.5" description = "An abstraction layer for distributed computation" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2814,7 +2698,6 @@ sql = ["fugue-sql-antlr (>=0.1.6)", "jinja2", "qpd (>=0.4.3)", "sqlglot"] name = "fugue-sql-antlr" version = "0.1.6" description = "Fugue SQL Antlr Parser" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2834,7 +2717,6 @@ test = ["speedy_antlr_tool"] name = "fundamentalanalysis" version = "0.2.14" description = "Fully-fledged Fundamental Analysis package capable of collecting 20 years of Company Profiles, Financial Statements, Ratios and Stock Data of 20.000+ companies." -category = "main" optional = false python-versions = "*" files = [ @@ -2846,7 +2728,6 @@ files = [ name = "future" version = "0.18.3" description = "Clean single-source support for Python 3 and 2" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2857,7 +2738,6 @@ files = [ name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2872,7 +2752,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.32" description = "GitPython is a Python library used to interact with Git repositories" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2887,7 +2766,6 @@ gitdb = ">=4.0.1,<5" name = "google-auth" version = "2.22.0" description = "Google Authentication Library" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2913,7 +2791,6 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] name = "google-auth-oauthlib" version = "1.0.0" description = "Google Authentication Library" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2932,7 +2809,6 @@ tool = ["click (>=6.0.0)"] name = "graphlib-backport" version = "1.0.3" description = "Backport of the Python 3.9 graphlib module for Python 3.6+" -category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -2944,7 +2820,6 @@ files = [ name = "graphviz" version = "0.20.1" description = "Simple Python interface for Graphviz" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2961,7 +2836,6 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -3035,7 +2909,6 @@ test = ["objgraph", "psutil"] name = "grpcio" version = "1.56.2" description = "HTTP/2-based RPC framework" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3093,7 +2966,6 @@ protobuf = ["grpcio-tools (>=1.56.2)"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3105,7 +2977,6 @@ files = [ name = "hijri-converter" version = "2.3.1" description = "Accurate Hijri-Gregorian dates converter based on the Umm al-Qura calendar" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3117,7 +2988,6 @@ files = [ name = "holidays" version = "0.14.2" description = "Generate and work with holidays in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3135,7 +3005,6 @@ python-dateutil = "*" name = "html5lib" version = "1.1" description = "HTML parser based on the WHATWG HTML specification" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -3157,7 +3026,6 @@ lxml = ["lxml"] name = "httpcore" version = "0.17.3" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3169,17 +3037,16 @@ files = [ anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = ">=1.0.0,<2.0.0" +sniffio = "==1.*" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "huggingface-hub" version = "0.16.4" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -category = "main" optional = true python-versions = ">=3.7.0" files = [ @@ -3212,7 +3079,6 @@ typing = ["pydantic", "types-PyYAML", "types-requests", "types-simplejson", "typ name = "identify" version = "2.5.25" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3227,7 +3093,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3239,7 +3104,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3251,7 +3115,6 @@ files = [ name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3271,7 +3134,6 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "importlib-resources" version = "6.0.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3290,7 +3152,6 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3302,7 +3163,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3314,7 +3174,6 @@ files = [ name = "interface-meta" version = "1.3.0" description = "`interface_meta` provides a convenient way to expose an extensible API with enforced method signatures and consistent documentation." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -3326,7 +3185,6 @@ files = [ name = "intrinio-sdk" version = "6.24.1" description = "Intrinio API" -category = "main" optional = false python-versions = "*" files = [ @@ -3345,7 +3203,6 @@ urllib3 = ">=1.15" name = "ipykernel" version = "6.24.0" description = "IPython Kernel for Jupyter" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3359,7 +3216,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -3379,7 +3236,6 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" name = "ipympl" version = "0.8.4" description = "Matplotlib Jupyter Extension" -category = "main" optional = false python-versions = "*" files = [ @@ -3396,7 +3252,6 @@ matplotlib = ">=2.0.0" name = "ipython" version = "8.11.0" description = "IPython: Productive Interactive Computing" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3435,7 +3290,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "ipython-genutils" version = "0.2.0" description = "Vestigial utilities from IPython" -category = "main" optional = false python-versions = "*" files = [ @@ -3447,7 +3301,6 @@ files = [ name = "ipywidgets" version = "8.0.7" description = "Jupyter interactive widgets" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3469,7 +3322,6 @@ test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] name = "iso8601" version = "0.1.16" description = "Simple module to parse ISO 8601 dates" -category = "main" optional = false python-versions = "*" files = [ @@ -3481,7 +3333,6 @@ files = [ name = "isodate" version = "0.6.1" description = "An ISO 8601 date/time/duration parser and formatter" -category = "main" optional = false python-versions = "*" files = [ @@ -3496,7 +3347,6 @@ six = "*" name = "isoduration" version = "20.11.0" description = "Operations with ISO 8601 durations" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3511,7 +3361,6 @@ arrow = ">=0.15.0" name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -3529,7 +3378,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -3541,7 +3389,6 @@ files = [ name = "jedi" version = "0.18.2" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3561,7 +3408,6 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jedi-language-server" version = "0.40.0" description = "A language server for Jedi!" -category = "main" optional = true python-versions = ">=3.7,<3.12" files = [ @@ -3580,7 +3426,6 @@ pygls = ">=1.0.0,<2.0.0" name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3598,7 +3443,6 @@ i18n = ["Babel (>=2.7)"] name = "joblib" version = "1.3.1" description = "Lightweight pipelining with Python functions" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3610,7 +3454,6 @@ files = [ name = "json5" version = "0.9.14" description = "A Python implementation of the JSON5 data format." -category = "main" optional = false python-versions = "*" files = [ @@ -3625,7 +3468,6 @@ dev = ["hypothesis"] name = "jsonpointer" version = "2.4" description = "Identify specific nodes in a JSON document (RFC 6901)" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" files = [ @@ -3637,7 +3479,6 @@ files = [ name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3667,7 +3508,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jupyter-client" version = "7.4.1" description = "Jupyter protocol implementation and client libraries" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3692,7 +3532,6 @@ test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-comm name = "jupyter-core" version = "5.3.1" description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3713,7 +3552,6 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyter-dash" version = "0.4.2" description = "Dash support for the Jupyter notebook interface" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -3738,7 +3576,6 @@ dev = ["jupyter-server-proxy", "jupyterlab (>=2.0)", "notebook (>=6.0)"] name = "jupyter-events" version = "0.6.3" description = "Jupyter Event System library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3763,7 +3600,6 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= name = "jupyter-lsp" version = "2.2.0" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -3779,7 +3615,6 @@ jupyter-server = ">=1.1.2" name = "jupyter-server" version = "1.23.6" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3792,7 +3627,7 @@ anyio = ">=3.1.0,<4" argon2-cffi = "*" jinja2 = "*" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" nbconvert = ">=6.4.4" nbformat = ">=5.2.0" packaging = "*" @@ -3812,7 +3647,6 @@ test = ["coverage", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console name = "jupyter-server-fileid" version = "0.9.0" description = "" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3832,7 +3666,6 @@ test = ["jupyter-server[test] (>=1.15,<3)", "pytest", "pytest-cov"] name = "jupyter-server-ydoc" version = "0.8.0" description = "A Jupyter Server Extension Providing Y Documents." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3852,7 +3685,6 @@ test = ["coverage", "jupyter-server[test] (>=2.0.0a0)", "pytest (>=7.0)", "pytes name = "jupyter-ydoc" version = "0.2.5" description = "Document structures for collaborative editing using Ypy" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3872,7 +3704,6 @@ test = ["pre-commit", "pytest", "pytest-asyncio", "websockets (>=10.0)", "ypy-we name = "jupyterlab" version = "3.6.5" description = "JupyterLab computational environment" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3901,7 +3732,6 @@ test = ["check-manifest", "coverage", "jupyterlab-server[test]", "pre-commit", " name = "jupyterlab-code-formatter" version = "1.6.1" description = "Code formatter for JupyterLab" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -3916,7 +3746,6 @@ jupyterlab = ">=3.0,<4.0" name = "jupyterlab-lsp" version = "3.10.2" description = "Coding assistance for JupyterLab with Language Server Protocol" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -3932,7 +3761,6 @@ jupyterlab = ">=3.1.0,<4.0.0a0" name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3944,7 +3772,6 @@ files = [ name = "jupyterlab-server" version = "2.23.0" description = "A set of server components for JupyterLab and JupyterLab like applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3971,7 +3798,6 @@ test = ["hatch", "ipykernel", "jupyterlab-server[openapi]", "openapi-spec-valida name = "jupyterlab-widgets" version = "3.0.8" description = "Jupyter interactive widgets for JupyterLab" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3983,7 +3809,6 @@ files = [ name = "kiwisolver" version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4061,7 +3886,6 @@ files = [ name = "korean-lunar-calendar" version = "0.3.1" description = "Korean Lunar Calendar" -category = "main" optional = false python-versions = "*" files = [ @@ -4073,7 +3897,6 @@ files = [ name = "langchain" version = "0.0.237" description = "Building applications with LLMs through composability" -category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ @@ -4113,7 +3936,6 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"] name = "langsmith" version = "0.0.10" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ @@ -4129,7 +3951,6 @@ requests = ">=2,<3" name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4175,7 +3996,6 @@ files = [ name = "lightgbm" version = "3.3.5" description = "LightGBM Python Package" -category = "main" optional = true python-versions = "*" files = [ @@ -4199,7 +4019,6 @@ dask = ["dask[array] (>=2.0.0)", "dask[dataframe] (>=2.0.0)", "dask[distributed] name = "lightning-utilities" version = "0.9.0" description = "PyTorch Lightning Sample project." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4220,7 +4039,6 @@ typing = ["mypy (>=1.0.0)"] name = "linearmodels" version = "4.31" description = "Linear Panel, Instrumental Variable, Asset Pricing, and System Regression models for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4265,7 +4083,6 @@ statsmodels = ">=0.11" name = "llama-index" version = "0.7.11" description = "Interface between LLMs and your data" -category = "main" optional = false python-versions = "*" files = [ @@ -4293,7 +4110,6 @@ urllib3 = "<2" name = "llvmlite" version = "0.40.1" description = "lightweight wrapper around basic LLVM functionality" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -4327,7 +4143,6 @@ files = [ name = "loguru" version = "0.7.0" description = "Python logging made (stupidly) simple" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4346,7 +4161,6 @@ dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegu name = "lsprotocol" version = "2023.0.0a2" description = "Python implementation of the Language Server Protocol." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4362,7 +4176,6 @@ cattrs = "*" name = "lunarcalendar" version = "0.0.9" description = "A lunar calendar converter, including a number of lunar and solar holidays, mainly from China." -category = "main" optional = true python-versions = ">=2.7, <4" files = [ @@ -4379,7 +4192,6 @@ pytz = "*" name = "lxml" version = "4.9.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -4487,7 +4299,6 @@ source = ["Cython (>=0.29.35)"] name = "macholib" version = "1.16.2" description = "Mach-O header analysis and editing" -category = "main" optional = true python-versions = "*" files = [ @@ -4502,7 +4313,6 @@ altgraph = ">=0.17" name = "markdown" version = "3.4.3" description = "Python implementation of John Gruber's Markdown." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4520,7 +4330,6 @@ testing = ["coverage", "pyyaml"] name = "markdown-it-py" version = "1.1.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = "~=3.6" files = [ @@ -4543,7 +4352,6 @@ testing = ["coverage", "psutil", "pytest (>=3.6,<4)", "pytest-benchmark (>=3.2,< name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4603,7 +4411,6 @@ files = [ name = "marshmallow" version = "3.19.0" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4624,7 +4431,6 @@ tests = ["pytest", "pytz", "simplejson"] name = "matplotlib" version = "3.7.2" description = "Python plotting package" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4687,7 +4493,6 @@ python-dateutil = ">=2.7" name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4702,7 +4507,6 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4714,7 +4518,6 @@ files = [ name = "mdit-py-plugins" version = "0.2.8" description = "Collection of plugins for markdown-it-py" -category = "dev" optional = false python-versions = "~=3.6" files = [ @@ -4734,7 +4537,6 @@ testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] name = "mistune" version = "3.0.1" description = "A sane and fast Markdown parser with useful plugins and renderers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4746,7 +4548,6 @@ files = [ name = "mock" version = "4.0.3" description = "Rolling backport of unittest.mock for all Pythons" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -4763,7 +4564,6 @@ test = ["pytest (<5.4)", "pytest-cov"] name = "monotonic" version = "1.6" description = "An implementation of time.monotonic() for Python 2 & < 3.3" -category = "main" optional = false python-versions = "*" files = [ @@ -4775,7 +4575,6 @@ files = [ name = "more-itertools" version = "9.1.0" description = "More routines for operating on iterables, beyond itertools" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4787,7 +4586,6 @@ files = [ name = "mplfinance" version = "0.12.9b7" description = "Utilities for the visualization, and visual analysis, of financial data" -category = "main" optional = false python-versions = "*" files = [ @@ -4803,7 +4601,6 @@ pandas = "*" name = "mstarpy" version = "0.0.4" description = "Mutual funds data extraction from MorningStar with Python" -category = "main" optional = false python-versions = "*" files = [ @@ -4820,7 +4617,6 @@ requests = ">=2.28.1" name = "multidict" version = "6.0.4" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4904,7 +4700,6 @@ files = [ name = "multitasking" version = "0.0.11" description = "Non-blocking Python methods using decorators" -category = "main" optional = false python-versions = "*" files = [ @@ -4916,7 +4711,6 @@ files = [ name = "mutagen" version = "1.46.0" description = "read and write audio tags for many formats" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -4928,7 +4722,6 @@ files = [ name = "mypy" version = "1.4.1" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4975,7 +4768,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4987,7 +4779,6 @@ files = [ name = "myst-parser" version = "0.15.2" description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -5013,7 +4804,6 @@ testing = ["beautifulsoup4", "coverage", "docutils (>=0.17.0,<0.18.0)", "pytest name = "nbclassic" version = "1.0.0" description = "Jupyter Notebook as a Jupyter Server extension." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5049,7 +4839,6 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p name = "nbclient" version = "0.6.8" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -5071,7 +4860,6 @@ test = ["black", "check-manifest", "flake8", "ipykernel", "ipython", "ipywidgets name = "nbconvert" version = "7.7.2" description = "Converting Jupyter Notebooks" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5110,7 +4898,6 @@ webpdf = ["playwright"] name = "nbformat" version = "5.9.1" description = "The Jupyter Notebook format" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5132,7 +4919,6 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "nbmake" version = "1.4.1" description = "Pytest plugin for testing notebooks" -category = "dev" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -5152,7 +4938,6 @@ pytest = ">=6.1.0" name = "nest-asyncio" version = "1.5.6" description = "Patch asyncio to allow nested event loops" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -5164,7 +4949,6 @@ files = [ name = "networkx" version = "3.1" description = "Python package for creating and manipulating graphs and networks" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -5183,7 +4967,6 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "nfoursid" version = "1.0.1" description = "Implementation of N4SID, Kalman filtering and state-space models" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -5200,7 +4983,6 @@ pandas = ">=1.1" name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -5215,7 +4997,6 @@ setuptools = "*" name = "notebook" version = "6.5.4" description = "A web-based notebook environment for interactive computing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5250,7 +5031,6 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixs name = "notebook-shim" version = "0.2.3" description = "A shim layer for notebook traits and config" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5268,7 +5048,6 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" name = "numba" version = "0.57.1" description = "compiling Python code using LLVM" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -5300,14 +5079,13 @@ files = [ [package.dependencies] importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} -llvmlite = ">=0.40.0dev0,<0.41" +llvmlite = "==0.40.*" numpy = ">=1.21,<1.25" [[package]] name = "numexpr" version = "2.8.4" description = "Fast numerical expression evaluator for NumPy" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5350,7 +5128,6 @@ numpy = ">=1.13.3" name = "numpy" version = "1.23.4" description = "NumPy is the fundamental package for array computing with Python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5388,7 +5165,6 @@ files = [ name = "oandapyv20" version = "0.6.3" description = "Python wrapper for the OANDA REST-V20 API" -category = "main" optional = false python-versions = "*" files = [ @@ -5399,7 +5175,6 @@ files = [ name = "oauthlib" version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -5416,7 +5191,6 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] name = "onetimepass" version = "1.0.1" description = "Module for generating and validating HOTP and TOTP tokens" -category = "main" optional = false python-versions = "*" files = [ @@ -5430,7 +5204,6 @@ six = "*" name = "openai" version = "0.27.8" description = "Python client library for the OpenAI API" -category = "main" optional = false python-versions = ">=3.7.1" files = [ @@ -5445,7 +5218,7 @@ tqdm = "*" [package.extras] datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"] +dev = ["black (>=21.6b0,<22.0)", "pytest (==6.*)", "pytest-asyncio", "pytest-mock"] embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] @@ -5453,7 +5226,6 @@ wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1 name = "openai-whisper" version = "20230124" description = "Robust Speech Recognition via Large-Scale Weak Supervision" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -5475,7 +5247,6 @@ dev = ["pytest"] name = "openapi-schema-pydantic" version = "1.2.4" description = "OpenAPI (v3) specification schema as pydantic class" -category = "main" optional = false python-versions = ">=3.6.1" files = [ @@ -5490,7 +5261,6 @@ pydantic = ">=1.8.2" name = "openpyxl" version = "3.1.2" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5505,7 +5275,6 @@ et-xmlfile = "*" name = "orjson" version = "3.9.2" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -5561,7 +5330,6 @@ files = [ name = "osqp" version = "0.6.3" description = "OSQP: The Operator Splitting QP Solver" -category = "main" optional = true python-versions = "*" files = [ @@ -5601,7 +5369,6 @@ scipy = ">=0.13.2" name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5613,7 +5380,6 @@ files = [ name = "pandas" version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5661,7 +5427,6 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] name = "pandas-datareader" version = "0.10.0" description = "Data readers extracted from the pandas codebase,should be compatible with recent pandas versions" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5678,7 +5443,6 @@ requests = ">=2.19.0" name = "pandas-market-calendars" version = "3.2" description = "Market and exchange trading calendars for pandas" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -5696,7 +5460,6 @@ pytz = "*" name = "pandas-ta" version = "0.3.14b" description = "An easy to use Python 3 Pandas Extension with 130+ Technical Analysis Indicators. Can be called from a Pandas DataFrame or standalone like TA-Lib. Correlation tested with TA-Lib." -category = "main" optional = false python-versions = "*" files = [ @@ -5714,7 +5477,6 @@ test = ["ta-lib"] name = "pandocfilters" version = "1.5.0" description = "Utilities for writing pandoc filters in python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5726,7 +5488,6 @@ files = [ name = "papermill" version = "2.4.0" description = "Parametrize and run Jupyter and nteract Notebooks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5760,7 +5521,6 @@ test = ["attrs (>=17.4.0)", "azure-datalake-store (>=0.0.30)", "azure-storage-bl name = "parso" version = "0.8.3" description = "A Python Parser" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5776,7 +5536,6 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5788,7 +5547,6 @@ files = [ name = "patsy" version = "0.5.3" description = "A Python package for describing statistical models and for building design matrices." -category = "main" optional = false python-versions = "*" files = [ @@ -5807,7 +5565,6 @@ test = ["pytest", "pytest-cov", "scipy"] name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" files = [ @@ -5819,7 +5576,6 @@ files = [ name = "pefile" version = "2023.2.7" description = "Python PE parsing module" -category = "main" optional = true python-versions = ">=3.6.0" files = [ @@ -5831,7 +5587,6 @@ files = [ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -5846,7 +5601,6 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" -category = "main" optional = false python-versions = "*" files = [ @@ -5858,7 +5612,6 @@ files = [ name = "pillow" version = "9.5.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5938,7 +5691,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5950,7 +5702,6 @@ files = [ name = "platformdirs" version = "3.9.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5966,7 +5717,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- name = "plotly" version = "5.15.0" description = "An open-source, interactive data visualization library for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5982,7 +5732,6 @@ tenacity = ">=6.2.0" name = "plotly-resampler" version = "0.8.3.2" description = "Visualizing large time series with plotly" -category = "main" optional = true python-versions = ">=3.7.1,<4.0.0" files = [ @@ -6006,7 +5755,6 @@ inline-persistent = ["Flask-Cors (>=3.0.10,<4.0.0)", "kaleido (==0.2.1)"] name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -6022,7 +5770,6 @@ testing = ["pytest", "pytest-benchmark"] name = "pmaw" version = "3.0.0" description = "A multithread Pushshift.io API Wrapper for reddit.com comment and submission searches." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6038,7 +5785,6 @@ requests = "*" name = "pmdarima" version = "2.0.3" description = "Python's forecast::auto.arima equivalent" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -6084,7 +5830,6 @@ urllib3 = "*" name = "posthog" version = "3.0.1" description = "Integrate PostHog into any python application." -category = "main" optional = false python-versions = "*" files = [ @@ -6108,7 +5853,6 @@ test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint" name = "praw" version = "7.7.1" description = "PRAW, an acronym for \"Python Reddit API Wrapper\", is a Python package that allows for simple access to Reddit's API." -category = "main" optional = false python-versions = "~=3.7" files = [ @@ -6123,16 +5867,15 @@ websocket-client = ">=0.54.0" [package.extras] ci = ["coveralls"] -dev = ["betamax (>=0.8,<0.9)", "betamax-matchers (>=0.3.0,<0.5)", "furo", "packaging", "pre-commit", "pytest (>=2.7.3)", "requests (>=2.20.1,<3)", "sphinx", "urllib3 (>=1.26.0,<1.27.0)"] +dev = ["betamax (>=0.8,<0.9)", "betamax-matchers (>=0.3.0,<0.5)", "furo", "packaging", "pre-commit", "pytest (>=2.7.3)", "requests (>=2.20.1,<3)", "sphinx", "urllib3 (==1.26.*)"] lint = ["furo", "pre-commit", "sphinx"] readthedocs = ["furo", "sphinx"] -test = ["betamax (>=0.8,<0.9)", "betamax-matchers (>=0.3.0,<0.5)", "pytest (>=2.7.3)", "requests (>=2.20.1,<3)", "urllib3 (>=1.26.0,<1.27.0)"] +test = ["betamax (>=0.8,<0.9)", "betamax-matchers (>=0.3.0,<0.5)", "pytest (>=2.7.3)", "requests (>=2.20.1,<3)", "urllib3 (==1.26.*)"] [[package]] name = "prawcore" version = "2.3.0" description = "Low-level communication layer for PRAW 4+." -category = "main" optional = false python-versions = "~=3.6" files = [ @@ -6153,7 +5896,6 @@ test = ["betamax (>=0.8,<0.9)", "betamax-matchers (>=0.4.0,<0.5)", "betamax-seri name = "pre-commit" version = "2.21.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -6172,7 +5914,6 @@ virtualenv = ">=20.10.0" name = "prometheus-client" version = "0.17.1" description = "Python client for the Prometheus monitoring system." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6187,7 +5928,6 @@ twisted = ["twisted"] name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -6202,7 +5942,6 @@ wcwidth = "*" name = "property-cached" version = "1.6.4" description = "A decorator for caching properties in classes (forked from cached-property)." -category = "main" optional = false python-versions = ">= 3.5" files = [ @@ -6214,7 +5953,6 @@ files = [ name = "prophet" version = "1.1.3" description = "Automatic Forecasting Procedure" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -6245,7 +5983,6 @@ parallel = ["dask[dataframe]", "distributed"] name = "protobuf" version = "3.20.1" description = "Protocol Buffers" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6279,7 +6016,6 @@ files = [ name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -6306,7 +6042,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -6318,7 +6053,6 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "main" optional = false python-versions = "*" files = [ @@ -6333,7 +6067,6 @@ tests = ["pytest"] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -6345,7 +6078,6 @@ files = [ name = "pyarrow" version = "12.0.1" description = "Python library for Apache Arrow" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6383,7 +6115,6 @@ numpy = ">=1.16.6" name = "pyasn1" version = "0.5.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -6395,7 +6126,6 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" -category = "main" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -6410,7 +6140,6 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pycares" version = "4.3.0" description = "Python interface for c-ares" -category = "main" optional = false python-versions = "*" files = [ @@ -6478,7 +6207,6 @@ idna = ["idna (>=2.1)"] name = "pycodestyle" version = "2.10.0" description = "Python style guide checker" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6490,7 +6218,6 @@ files = [ name = "pycoingecko" version = "3.1.0" description = "Python wrapper around the CoinGecko API" -category = "main" optional = false python-versions = "*" files = [ @@ -6505,7 +6232,6 @@ requests = "*" name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -6517,7 +6243,6 @@ files = [ name = "pycryptodome" version = "3.18.0" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -6559,7 +6284,6 @@ files = [ name = "pycryptodomex" version = "3.18.0" description = "Cryptographic library for Python" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -6601,7 +6325,6 @@ files = [ name = "pydantic" version = "1.10.11" description = "Data validation and settings management using python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6654,7 +6377,6 @@ email = ["email-validator (>=1.0.3)"] name = "pydeck" version = "0.8.0" description = "Widget for deck.gl maps" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6674,7 +6396,6 @@ jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "t name = "pydeprecate" version = "0.3.2" description = "Deprecation tooling" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -6686,7 +6407,6 @@ files = [ name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -6704,7 +6424,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyerfa" version = "2.0.0.3" description = "Python bindings for ERFA" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -6761,7 +6480,6 @@ test = ["pytest", "pytest-doctestplus (>=0.7)"] name = "pyflakes" version = "3.0.1" description = "passive checker of Python programs" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6773,7 +6491,6 @@ files = [ name = "pygls" version = "1.0.2" description = "a pythonic generic language server (pronounced like \"pie glass\")." -category = "main" optional = true python-versions = "<4,>=3.7" files = [ @@ -6789,13 +6506,12 @@ typeguard = ">=3,<4" dev = ["bandit (==1.7.4)", "flake8 (==4.0.1)", "mypy (==0.961)"] docs = ["sphinx (==5.0.1)", "sphinx-rtd-theme (==1.0.0)"] test = ["pytest (==7.1.2)", "pytest-asyncio (==0.18.3)"] -ws = ["websockets (>=10.0.0,<11.0.0)"] +ws = ["websockets (==10.*)"] [[package]] name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6810,7 +6526,6 @@ plugins = ["importlib-metadata"] name = "pyhdfe" version = "0.1.2" description = "High dimensional fixed effect absorption with Python 3" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6830,7 +6545,6 @@ tests = ["pytest", "pytest-xdist"] name = "pyinstaller" version = "4.10" description = "PyInstaller bundles a Python application and all its dependencies into a single package." -category = "main" optional = true python-versions = "<3.11,>=3.6" files = [ @@ -6863,7 +6577,6 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] name = "pyinstaller-hooks-contrib" version = "2023.6" description = "Community maintained hooks for PyInstaller" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -6875,7 +6588,6 @@ files = [ name = "pylint" version = "2.17.0" description = "python code static checker" -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -6902,7 +6614,6 @@ testutils = ["gitpython (>3)"] name = "pyluach" version = "2.2.0" description = "A Python package for dealing with Hebrew (Jewish) calendar dates." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6918,7 +6629,6 @@ test = ["beautifulsoup4", "flake8", "pytest", "pytest-cov"] name = "pymeeus" version = "0.5.12" description = "Python implementation of Jean Meeus astronomical routines" -category = "main" optional = false python-versions = "*" files = [ @@ -6929,7 +6639,6 @@ files = [ name = "pympler" version = "1.0.1" description = "A development tool to measure, monitor and analyze the memory behavior of Python objects." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6941,7 +6650,6 @@ files = [ name = "pyobjc-core" version = "9.2" description = "Python<->ObjC Interoperability Module" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6959,7 +6667,6 @@ files = [ name = "pyobjc-framework-cocoa" version = "9.2" description = "Wrappers for the Cocoa frameworks on macOS" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6980,7 +6687,6 @@ pyobjc-core = ">=9.2" name = "pyod" version = "1.1.0" description = "A Comprehensive and Scalable Python Library for Outlier Detection (Anomaly Detection)" -category = "main" optional = true python-versions = "*" files = [ @@ -7000,7 +6706,6 @@ six = "*" name = "pyotp" version = "2.8.0" description = "Python One Time Password Library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7012,7 +6717,6 @@ files = [ name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" optional = false python-versions = ">=3.6.8" files = [ @@ -7027,7 +6731,6 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyprind" version = "2.11.3" description = "Python Progress Bar and Percent Indicator Utility" -category = "main" optional = false python-versions = "*" files = [ @@ -7039,7 +6742,6 @@ files = [ name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7076,7 +6778,6 @@ files = [ name = "pytest" version = "6.2.5" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -7101,7 +6802,6 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xm name = "pytest-cov" version = "3.0.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -7120,7 +6820,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.11.1" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -7138,7 +6837,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "pytest-recorder" version = "0.2.3" description = "Pytest plugin, meant to facilitate unit tests writing for tools consumming Web APIs." -category = "dev" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -7154,7 +6852,6 @@ vcrpy = ">=4.2.1,<5.0.0" name = "pytest-recording" version = "0.12.2" description = "A pytest plugin that allows you recording of network interactions via VCR.py" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -7171,7 +6868,6 @@ vcrpy = ">=2.0.1" name = "pytest-timeout" version = "2.1.0" description = "pytest plugin to abort hanging tests" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -7186,7 +6882,6 @@ pytest = ">=5.0.0" name = "pytest-xdist" version = "3.3.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -7207,7 +6902,6 @@ testing = ["filelock"] name = "pythclient" version = "0.1.6" description = "A library to retrieve Pyth account structures off the Solana blockchain." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -7233,7 +6927,6 @@ testing = ["aiodns", "aiohttp (>=3.7.4)", "backoff", "base58", "dnspython", "fla name = "python-binance" version = "1.0.17" description = "Binance REST API python implementation" -category = "main" optional = false python-versions = "*" files = [ @@ -7254,7 +6947,6 @@ websockets = "*" name = "python-coinmarketcap" version = "0.2" description = "CoinMarketCap Python API Wrapper" -category = "main" optional = false python-versions = "*" files = [ @@ -7267,7 +6959,6 @@ files = [ name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -7282,7 +6973,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7297,7 +6987,6 @@ cli = ["click (>=5.0)"] name = "python-i18n" version = "0.3.9" description = "Translation library for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -7312,7 +7001,6 @@ yaml = ["pyyaml (>=3.10)"] name = "python-jose" version = "3.3.0" description = "JOSE implementation in Python" -category = "main" optional = false python-versions = "*" files = [ @@ -7334,7 +7022,6 @@ pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"] name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7346,7 +7033,6 @@ files = [ name = "pytorch-lightning" version = "1.6.5" description = "PyTorch Lightning is the lightweight PyTorch wrapper for ML researchers. Scale your models. Write less boilerplate." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -7384,7 +7070,6 @@ test = ["cloudpickle (>=1.3)", "codecov (>=2.1)", "coverage (>=6.4)", "flake8 (> name = "pytrends" version = "4.9.2" description = "Pseudo API for Google Trends" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7401,7 +7086,6 @@ requests = ">=2.0" name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -7413,7 +7097,6 @@ files = [ name = "pytz-deprecation-shim" version = "0.1.0.post0" description = "Shims to make deprecation of pytz easier" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -7429,7 +7112,6 @@ tzdata = {version = "*", markers = "python_version >= \"3.6\""} name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" files = [ @@ -7453,7 +7135,6 @@ files = [ name = "pywin32-ctypes" version = "0.2.2" description = "A (partial) reimplementation of pywin32 using ctypes/cffi" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -7465,7 +7146,6 @@ files = [ name = "pywinpty" version = "2.0.11" description = "Pseudo terminal support for Windows from Python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7480,7 +7160,6 @@ files = [ name = "pywry" version = "0.5.13" description = "" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7509,7 +7188,6 @@ dev = ["auditwheel", "wheel"] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7559,7 +7237,6 @@ files = [ name = "pyzmq" version = "25.1.0" description = "Python bindings for 0MQ" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7649,7 +7326,6 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "qdldl" version = "0.1.7.post0" description = "QDLDL, a free LDL factorization routine." -category = "main" optional = true python-versions = "*" files = [ @@ -7682,7 +7358,6 @@ scipy = ">=0.13.2" name = "qpd" version = "0.4.4" description = "Query Pandas Using SQL" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -7704,7 +7379,6 @@ dask = ["cloudpickle (>=1.4.0)", "dask[dataframe,distributed]"] name = "quandl" version = "3.7.0" description = "Package for quandl API access" -category = "main" optional = false python-versions = ">= 3.6" files = [ @@ -7725,7 +7399,6 @@ six = "*" name = "rdflib" version = "6.3.2" description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -7747,7 +7420,6 @@ networkx = ["networkx (>=2.0.0,<3.0.0)"] name = "regex" version = "2023.6.3" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7845,7 +7517,6 @@ files = [ name = "reportlab" version = "3.6.13" description = "The Reportlab Toolkit" -category = "main" optional = false python-versions = ">=3.7,<4" files = [ @@ -7907,7 +7578,6 @@ rlpycairo = ["rlPyCairo (>=0.1.0)"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7929,7 +7599,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-futures" version = "1.0.1" description = "Asynchronous Python HTTP for Humans." -category = "main" optional = false python-versions = "*" files = [ @@ -7947,7 +7616,6 @@ dev = ["black (>=22.3.0)", "build (>=0.7.0)", "isort (>=5.11.4)", "pyflakes (>=2 name = "requests-oauthlib" version = "1.3.1" description = "OAuthlib authentication support for Requests." -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -7966,7 +7634,6 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] name = "retrying" version = "1.3.4" description = "Retrying" -category = "main" optional = false python-versions = "*" files = [ @@ -7981,7 +7648,6 @@ six = ">=1.7.0" name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -7996,7 +7662,6 @@ six = "*" name = "rfc3986-validator" version = "0.1.1" description = "Pure python rfc3986 validator" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -8008,7 +7673,6 @@ files = [ name = "rich" version = "12.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" optional = false python-versions = ">=3.6.3,<4.0.0" files = [ @@ -8028,7 +7692,6 @@ jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] name = "riskfolio-lib" version = "3.3.0" description = "Portfolio Optimization and Quantitative Strategic Asset Allocation in Python" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -8053,7 +7716,6 @@ xlsxwriter = ">=1.3.7" name = "robin-stocks" version = "2.1.0" description = "A Python wrapper around the Robinhood API" -category = "main" optional = false python-versions = ">=3" files = [ @@ -8071,7 +7733,6 @@ requests = "*" name = "rsa" version = "4.9" description = "Pure-Python RSA implementation" -category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -8086,7 +7747,6 @@ pyasn1 = ">=0.1.3" name = "ruamel-yaml" version = "0.17.32" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" -category = "main" optional = false python-versions = ">=3" files = [ @@ -8105,7 +7765,6 @@ jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] name = "ruamel-yaml-clib" version = "0.2.7" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -8152,7 +7811,6 @@ files = [ name = "ruff" version = "0.0.256" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -8179,7 +7837,6 @@ files = [ name = "scikit-learn" version = "1.3.0" description = "A set of python modules for machine learning and data mining" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -8222,7 +7879,6 @@ tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc ( name = "scipy" version = "1.10.1" description = "Fundamental algorithms for scientific computing in Python" -category = "main" optional = false python-versions = "<3.12,>=3.8" files = [ @@ -8261,7 +7917,6 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo name = "screeninfo" version = "0.6.7" description = "Fetch location and size of physical screens." -category = "main" optional = false python-versions = "*" files = [ @@ -8276,7 +7931,6 @@ pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""} name = "scs" version = "3.2.3" description = "scs: splitting conic solver" -category = "main" optional = true python-versions = "*" files = [ @@ -8306,7 +7960,6 @@ scipy = ">=0.13.2" name = "seaborn" version = "0.11.2" description = "seaborn: statistical data visualization" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -8324,7 +7977,6 @@ scipy = ">=1.0" name = "semantic-version" version = "2.10.0" description = "A library implementing the 'SemVer' scheme." -category = "main" optional = true python-versions = ">=2.7" files = [ @@ -8340,7 +7992,6 @@ doc = ["Sphinx", "sphinx-rtd-theme"] name = "send2trash" version = "1.8.2" description = "Send file to trash natively under Mac OS X, Windows and Linux" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -8357,7 +8008,6 @@ win32 = ["pywin32"] name = "setproctitle" version = "1.3.2" description = "A Python module to customize the process title" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8442,7 +8092,6 @@ test = ["pytest"] name = "setuptools" version = "65.4.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8459,7 +8108,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "setuptools-rust" version = "1.6.0" description = "Setuptools Rust extension plugin" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -8476,7 +8124,6 @@ typing-extensions = ">=3.7.4.3" name = "setuptools-scm" version = "7.1.0" description = "the blessed package to manage your versions by scm tags" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8501,7 +8148,6 @@ toml = ["setuptools (>=42)"] name = "sgmllib3k" version = "1.0.0" description = "Py3k port of sgmllib." -category = "main" optional = false python-versions = "*" files = [ @@ -8512,7 +8158,6 @@ files = [ name = "shap" version = "0.42.1" description = "A unified approach to explain the output of any machine learning model." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -8565,7 +8210,6 @@ test-core = ["pytest", "pytest-cov", "pytest-mpl"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -8577,7 +8221,6 @@ files = [ name = "slicer" version = "0.0.7" description = "A small package for big slicing." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -8589,7 +8232,6 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -8601,7 +8243,6 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8613,7 +8254,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -8625,7 +8265,6 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8637,7 +8276,6 @@ files = [ name = "sparqlwrapper" version = "2.0.0" description = "SPARQL Endpoint interface to Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8658,7 +8296,6 @@ pandas = ["pandas (>=1.3.5)"] name = "sphinx" version = "4.5.0" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -8694,7 +8331,6 @@ test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] name = "sphinxcontrib-applehelp" version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -8710,7 +8346,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -8726,7 +8361,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -8742,7 +8376,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -8757,7 +8390,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -8773,7 +8405,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -8789,7 +8420,6 @@ test = ["pytest"] name = "sqlalchemy" version = "2.0.19" description = "Database Abstraction Library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8837,7 +8467,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} typing-extensions = ">=4.2.0" [package.extras] @@ -8868,7 +8498,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "sqlglot" version = "17.6.0" description = "An easily customizable SQL parser and transpiler" -category = "main" optional = true python-versions = "*" files = [ @@ -8883,7 +8512,6 @@ dev = ["autoflake", "black", "duckdb (>=0.6)", "isort", "mypy (>=0.990)", "panda name = "squarify" version = "0.4.3" description = "Pure Python implementation of the squarify treemap layout algorithm" -category = "main" optional = false python-versions = "*" files = [ @@ -8895,7 +8523,6 @@ files = [ name = "stack-data" version = "0.6.2" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "main" optional = false python-versions = "*" files = [ @@ -8915,7 +8542,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "statsforecast" version = "1.5.0" description = "Time series forecasting suite using statistical models" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -8943,7 +8569,6 @@ ray = ["fugue[ray] (>=0.8.1)", "protobuf (>=3.15.3,<4.0.0)"] name = "statsmodels" version = "0.13.2" description = "Statistical computations and models for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8988,7 +8613,6 @@ docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "n name = "statsmodels" version = "0.13.3" description = "Statistical computations and models for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9024,7 +8648,7 @@ numpy = {version = ">=1.17", markers = "python_version != \"3.10\" or platform_s packaging = ">=21.3" pandas = ">=0.25" patsy = ">=0.5.2" -scipy = {version = ">=1.3", markers = "python_version > \"3.7\" and python_version < \"3.12\" or platform_system != \"Windows\" and python_version < \"3.12\" or platform_machine != \"x86\" and python_version < \"3.12\""} +scipy = {version = ">=1.3", markers = "(python_version > \"3.7\" or platform_system != \"Windows\" or platform_machine != \"x86\") and python_version < \"3.12\""} [package.extras] build = ["cython (>=0.29.32)"] @@ -9035,7 +8659,6 @@ docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "n name = "statsmodels" version = "0.13.5" description = "Statistical computations and models for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9074,7 +8697,7 @@ numpy = [ packaging = ">=21.3" pandas = ">=0.25" patsy = ">=0.5.2" -scipy = {version = ">=1.3", markers = "python_version > \"3.9\" and python_version < \"3.12\" or platform_system != \"Windows\" and python_version < \"3.12\" or platform_machine != \"x86\" and python_version < \"3.12\""} +scipy = {version = ">=1.3", markers = "(python_version > \"3.9\" or platform_system != \"Windows\" or platform_machine != \"x86\") and python_version < \"3.12\""} [package.extras] build = ["cython (>=0.29.32)"] @@ -9085,7 +8708,6 @@ docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "n name = "stevedore" version = "5.1.0" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -9100,7 +8722,6 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" name = "stocksera" version = "0.1.21" description = "Official Stocksera API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -9116,7 +8737,6 @@ requests = "*" name = "streamlit" version = "1.24.1" description = "A faster way to build and share data apps" -category = "main" optional = false python-versions = ">=3.8, !=3.9.7" files = [ @@ -9157,7 +8777,6 @@ snowflake = ["snowflake-snowpark-python"] name = "svglib" version = "1.5.1" description = "A pure-Python library for reading and converting SVG" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9174,7 +8793,6 @@ tinycss2 = ">=0.6.0" name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9189,7 +8807,6 @@ widechars = ["wcwidth"] name = "tbats" version = "1.1.3" description = "BATS and TBATS for time series forecasting" -category = "main" optional = true python-versions = "*" files = [ @@ -9210,7 +8827,6 @@ dev = ["pip-tools", "pytest", "rpy2"] name = "tenacity" version = "8.2.2" description = "Retry code until it succeeds" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -9225,7 +8841,6 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] name = "tensorboard" version = "2.13.0" description = "TensorBoard lets you watch Tensors Flow" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -9250,7 +8865,6 @@ wheel = ">=0.26" name = "tensorboard-data-server" version = "0.7.1" description = "Fast data loading for TensorBoard" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -9263,7 +8877,6 @@ files = [ name = "terminado" version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9284,7 +8897,6 @@ test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] name = "textwrap3" version = "0.9.2" description = "textwrap from Python 3.6 backport (plus a few tweaks)" -category = "main" optional = false python-versions = "*" files = [ @@ -9296,7 +8908,6 @@ files = [ name = "thepassiveinvestor" version = "1.2.1" description = "Passive Investing for the Average Joe." -category = "main" optional = false python-versions = "*" files = [ @@ -9313,7 +8924,6 @@ yahooquery = "*" name = "threadpoolctl" version = "3.2.0" description = "threadpoolctl" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -9325,7 +8935,6 @@ files = [ name = "tiktoken" version = "0.4.0" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -9371,7 +8980,6 @@ blobfile = ["blobfile (>=2)"] name = "time-machine" version = "2.11.0" description = "Travel through time in your tests." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -9429,7 +9037,6 @@ python-dateutil = "*" name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9448,7 +9055,6 @@ test = ["flake8", "isort", "pytest"] name = "tokenizers" version = "0.13.3" description = "Fast and Customizable Tokenizers" -category = "main" optional = true python-versions = "*" files = [ @@ -9503,7 +9109,6 @@ testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] name = "tokenterminal" version = "1.0.1" description = "Unofficial Token Terminal API client." -category = "main" optional = false python-versions = "*" files = [ @@ -9518,7 +9123,6 @@ requests = ">=2.18.4" name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -9530,7 +9134,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9542,7 +9145,6 @@ files = [ name = "tomlkit" version = "0.11.8" description = "Style preserving TOML library" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -9554,7 +9156,6 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -9566,7 +9167,6 @@ files = [ name = "torch" version = "1.11.0" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -category = "main" optional = true python-versions = ">=3.7.0" files = [ @@ -9598,7 +9198,6 @@ typing-extensions = "*" name = "torchmetrics" version = "1.0.1" description = "PyTorch native Metrics" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -9628,7 +9227,6 @@ visual = ["SciencePlots (>=2.0.0)", "matplotlib (>=3.2.0)"] name = "tornado" version = "6.3.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = false python-versions = ">= 3.8" files = [ @@ -9649,7 +9247,6 @@ files = [ name = "tqdm" version = "4.65.0" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9670,7 +9267,6 @@ telegram = ["requests"] name = "trace-updater" version = "0.0.9.1" description = "Dash component which allows to update a dcc.Graph its traces. This component is data efficient as it (1) only sends the to-be-updated traces (and not the whole) from the back-end to the client-side and (2) only updates the traces that have changed (and does not redraw the whole figure)." -category = "main" optional = true python-versions = "*" files = [ @@ -9682,7 +9278,6 @@ files = [ name = "tradingview-ta" version = "3.3.0" description = "Unofficial TradingView technical analysis API wrapper." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -9697,7 +9292,6 @@ requests = "*" name = "traitlets" version = "5.9.0" description = "Traitlets Python configuration system" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9713,7 +9307,6 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] name = "transformers" version = "4.27.1" description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" -category = "main" optional = true python-versions = ">=3.7.0" files = [ @@ -9781,7 +9374,6 @@ vision = ["Pillow"] name = "triad" version = "0.9.1" description = "A collection of python utils for Fugue projects" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -9804,7 +9396,6 @@ ciso8601 = ["ciso8601"] name = "typeguard" version = "3.0.2" description = "Run-time type checker for Python" -category = "main" optional = true python-versions = ">=3.7.4" files = [ @@ -9824,7 +9415,6 @@ test = ["mypy (>=0.991)", "pytest (>=7)"] name = "types-python-dateutil" version = "2.8.19.14" description = "Typing stubs for python-dateutil" -category = "dev" optional = false python-versions = "*" files = [ @@ -9836,7 +9426,6 @@ files = [ name = "types-pytz" version = "2021.3.8" description = "Typing stubs for pytz" -category = "dev" optional = false python-versions = "*" files = [ @@ -9848,7 +9437,6 @@ files = [ name = "types-pyyaml" version = "6.0.12.11" description = "Typing stubs for PyYAML" -category = "dev" optional = false python-versions = "*" files = [ @@ -9860,7 +9448,6 @@ files = [ name = "types-requests" version = "2.31.0.2" description = "Typing stubs for requests" -category = "dev" optional = false python-versions = "*" files = [ @@ -9875,7 +9462,6 @@ types-urllib3 = "*" name = "types-setuptools" version = "57.4.18" description = "Typing stubs for setuptools" -category = "dev" optional = false python-versions = "*" files = [ @@ -9887,7 +9473,6 @@ files = [ name = "types-six" version = "1.16.21.9" description = "Typing stubs for six" -category = "dev" optional = false python-versions = "*" files = [ @@ -9899,7 +9484,6 @@ files = [ name = "types-urllib3" version = "1.26.25.14" description = "Typing stubs for urllib3" -category = "dev" optional = false python-versions = "*" files = [ @@ -9911,7 +9495,6 @@ files = [ name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9923,7 +9506,6 @@ files = [ name = "typing-inspect" version = "0.9.0" description = "Runtime inspection utilities for typing module." -category = "main" optional = false python-versions = "*" files = [ @@ -9939,7 +9521,6 @@ typing-extensions = ">=3.7.4" name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -9951,7 +9532,6 @@ files = [ name = "tzlocal" version = "4.3.1" description = "tzinfo object for the local timezone" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -9971,7 +9551,6 @@ devenv = ["black", "check-manifest", "flake8", "pyroma", "pytest (>=4.3)", "pyte name = "u8darts" version = "0.23.0" description = "A python library for easy manipulation and forecasting of time series." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -10012,7 +9591,6 @@ torch = ["pytorch-lightning (>=1.5.0)", "torch (>=1.8.0)"] name = "ujson" version = "5.8.0" description = "Ultra fast JSON encoder and decoder for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -10083,7 +9661,6 @@ files = [ name = "update-checker" version = "0.18.0" description = "A python module that will check for package updates." -category = "main" optional = false python-versions = "*" files = [ @@ -10103,7 +9680,6 @@ test = ["pytest (>=2.7.3)"] name = "uri-template" version = "1.3.0" description = "RFC 6570 URI Template Processor" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10118,7 +9694,6 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake name = "urllib3" version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -10135,7 +9710,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "user-agent" version = "0.1.10" description = "User-Agent generator" -category = "main" optional = false python-versions = "*" files = [ @@ -10149,7 +9723,6 @@ six = "*" name = "vadersentiment" version = "3.3.2" description = "VADER Sentiment Analysis. VADER (Valence Aware Dictionary and sEntiment Reasoner) is a lexicon and rule-based sentiment analysis tool that is specifically attuned to sentiments expressed in social media, and works well on texts from other domains." -category = "main" optional = false python-versions = "*" files = [ @@ -10164,7 +9737,6 @@ requests = "*" name = "validators" version = "0.20.0" description = "Python Data Validation for Humans™." -category = "main" optional = false python-versions = ">=3.4" files = [ @@ -10181,7 +9753,6 @@ test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] name = "valinvest" version = "0.0.2" description = "A value investing tool based on Warren Buffett, Joseph Piotroski and Benjamin Graham thoughts" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -10193,7 +9764,6 @@ files = [ name = "vcrpy" version = "4.4.0" description = "Automatically mock your HTTP interactions to simplify and speed up testing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -10212,7 +9782,6 @@ yarl = "*" name = "virtualenv" version = "20.24.1" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -10233,7 +9802,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "watchdog" version = "2.3.1" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -10274,7 +9842,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -10286,7 +9853,6 @@ files = [ name = "webcolors" version = "1.13" description = "A library for working with the color formats defined by HTML and CSS." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10302,7 +9868,6 @@ tests = ["pytest", "pytest-cov"] name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "main" optional = false python-versions = "*" files = [ @@ -10314,7 +9879,6 @@ files = [ name = "websocket-client" version = "1.6.1" description = "WebSocket client for Python with low level API options" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10331,7 +9895,6 @@ test = ["websockets"] name = "websockets" version = "11.0.3" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10411,7 +9974,6 @@ files = [ name = "werkzeug" version = "2.3.6" description = "The comprehensive WSGI web application library." -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -10429,7 +9991,6 @@ watchdog = ["watchdog (>=2.3)"] name = "wheel" version = "0.40.0" description = "A built-package format for Python" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -10444,7 +10005,6 @@ test = ["pytest (>=6.0.0)"] name = "widgetsnbextension" version = "4.0.8" description = "Jupyter interactive widgets for Jupyter Notebook" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10456,7 +10016,6 @@ files = [ name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -10471,7 +10030,6 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -10556,7 +10114,6 @@ files = [ name = "xarray" version = "2023.1.0" description = "N-D labeled arrays and datasets in Python" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -10581,7 +10138,6 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] name = "xgboost" version = "1.7.6" description = "XGBoost Python Package" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -10609,7 +10165,6 @@ scikit-learn = ["scikit-learn"] name = "xlsxwriter" version = "3.1.2" description = "A Python module for creating Excel XLSX files." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -10621,7 +10176,6 @@ files = [ name = "y-py" version = "0.6.0" description = "Python bindings for the Y-CRDT built from yrs (Rust)" -category = "main" optional = false python-versions = "*" files = [ @@ -10697,7 +10251,6 @@ files = [ name = "yahooquery" version = "2.3.2" description = "Python interface to unofficial Yahoo Finance API endpoints" -category = "main" optional = false python-versions = "*" files = [ @@ -10720,7 +10273,6 @@ test = ["coverage (==5.2.1)", "pytest (==6.0.2)", "pytest-cov (==2.10.1)", "sele name = "yarl" version = "1.9.2" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10808,7 +10360,6 @@ multidict = ">=4.0" name = "yfinance" version = "0.2.25" description = "Download market data from Yahoo! Finance API" -category = "main" optional = false python-versions = "*" files = [ @@ -10832,7 +10383,6 @@ requests = ">=2.26" name = "ypy-websocket" version = "0.8.4" description = "WebSocket connector for Ypy" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10852,7 +10402,6 @@ test = ["mypy", "pre-commit", "pytest", "pytest-asyncio", "websockets (>=10.0)"] name = "yt-dlp" version = "2023.7.6" description = "A youtube-dl fork with additional features and patches" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -10872,7 +10421,6 @@ websockets = "*" name = "zipp" version = "3.16.2" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -10888,7 +10436,6 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p name = "zope-interface" version = "6.0" description = "Interfaces for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -10943,4 +10490,4 @@ optimization = ["Riskfolio-Lib"] [metadata] lock-version = "2.0" python-versions = "^3.8.1,<3.11, !=3.9.7" -content-hash = "10cccda4c8b51c57241490d53d46268092e6ffe9054c8ef22b7e58477ad3b98c" +content-hash = "cf28c86b1360b436443a486b5ed8b33101e35d3a6c02f81c7dc85515e520c634" diff --git a/pyproject.toml b/pyproject.toml index a7d46128a19..504d83c49a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ robin-stocks = "^2.0.3" pycoingecko = "^3.1.0" detecta = "^0.0.5" tradingview-ta = "^3.2.3" -finvizfinance = "^0.14.0" +finvizfinance = "0.14.6rc2" statsmodels = "^0.13" python-coinmarketcap = "^0.2" oandapyV20 = "^0.6.3" diff --git a/requirements-full.txt b/requirements-full.txt index 19987f21814..7fea20f1211 100644 --- a/requirements-full.txt +++ b/requirements-full.txt @@ -14,7 +14,7 @@ ansiwrap==0.8.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9 antlr4-python3-runtime==4.11.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" anyio==3.7.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" appdirs==1.4.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -appnope==0.1.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "darwin" or python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and platform_system == "Darwin" +appnope==0.1.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (sys_platform == "darwin" or platform_system == "Darwin") arch==5.6.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" argon2-cffi-bindings==21.2.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" argon2-cffi==21.3.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -98,7 +98,7 @@ filelock==3.12.2 ; python_full_version >= "3.8.1" and python_full_version != "3. financedatabase==2.1.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" finnhub-python==2.4.18 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" finviz==1.4.6 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -finvizfinance==0.14.5 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" +finvizfinance==0.14.6rc2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" flake8==6.0.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" flask==2.3.2 ; python_full_version >= "3.8.1" and python_version < "3.11" and python_full_version != "3.9.7" fonttools==4.41.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -122,7 +122,7 @@ google-auth-oauthlib==1.0.0 ; python_full_version >= "3.8.1" and python_full_ver google-auth==2.22.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" graphlib-backport==1.0.3 ; python_full_version >= "3.8.1" and python_version < "3.9" graphviz==0.20.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -greenlet==2.0.2 ; python_full_version >= "3.8.1" and platform_machine == "aarch64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "ppc64le" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "x86_64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "amd64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "AMD64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "win32" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "WIN32" and python_full_version != "3.9.7" and python_version < "3.11" +greenlet==2.0.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (platform_machine == "win32" or platform_machine == "WIN32" or platform_machine == "AMD64" or platform_machine == "amd64" or platform_machine == "x86_64" or platform_machine == "ppc64le" or platform_machine == "aarch64") grpcio==1.56.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" h11==0.14.0 ; python_full_version >= "3.8.1" and python_version < "3.11" and python_full_version != "3.9.7" hijri-converter==2.3.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -257,7 +257,7 @@ property-cached==1.6.4 ; python_full_version >= "3.8.1" and python_full_version prophet==1.1.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" protobuf==3.20.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" psutil==5.9.5 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -ptyprocess==0.7.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform != "win32" or python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and os_name != "nt" +ptyprocess==0.7.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (sys_platform != "win32" or os_name != "nt") pure-eval==0.2.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" py==1.11.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" pyarrow==12.0.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" diff --git a/requirements.txt b/requirements.txt index 115a934a9a7..507bae43bea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ altair==5.0.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7 ansiwrap==0.8.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" anyio==3.7.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" appdirs==1.4.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -appnope==0.1.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "darwin" or python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and platform_system == "Darwin" +appnope==0.1.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (sys_platform == "darwin" or platform_system == "Darwin") arch==5.6.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" argon2-cffi-bindings==21.2.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" argon2-cffi==21.3.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -65,7 +65,7 @@ ffn==0.3.6 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" a financedatabase==2.1.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" finnhub-python==2.4.18 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" finviz==1.4.6 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -finvizfinance==0.14.5 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" +finvizfinance==0.14.6rc2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" flake8==6.0.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" fonttools==4.41.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" formulaic==0.6.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -80,7 +80,7 @@ future==0.18.3 ; python_full_version >= "3.8.1" and python_full_version != "3.9. gitdb==4.0.10 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" gitpython==3.1.32 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" graphlib-backport==1.0.3 ; python_full_version >= "3.8.1" and python_version < "3.9" -greenlet==2.0.2 ; python_full_version >= "3.8.1" and platform_machine == "aarch64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "ppc64le" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "x86_64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "amd64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "AMD64" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "win32" and python_full_version != "3.9.7" and python_version < "3.11" or python_full_version >= "3.8.1" and platform_machine == "WIN32" and python_full_version != "3.9.7" and python_version < "3.11" +greenlet==2.0.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (platform_machine == "win32" or platform_machine == "WIN32" or platform_machine == "AMD64" or platform_machine == "amd64" or platform_machine == "x86_64" or platform_machine == "ppc64le" or platform_machine == "aarch64") grpcio==1.56.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" h11==0.14.0 ; python_full_version >= "3.8.1" and python_version < "3.11" and python_full_version != "3.9.7" hijri-converter==2.3.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" @@ -178,7 +178,7 @@ prompt-toolkit==3.0.39 ; python_full_version >= "3.8.1" and python_full_version property-cached==1.6.4 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" protobuf==3.20.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" psutil==5.9.5 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" -ptyprocess==0.7.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform != "win32" or python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and os_name != "nt" +ptyprocess==0.7.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and (sys_platform != "win32" or os_name != "nt") pure-eval==0.2.2 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" pyarrow==12.0.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" pyasn1==0.5.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" From be96f3bba7c45ed67fa36729e0cc70ff3b439c6c Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 15:37:08 -0400 Subject: [PATCH 09/28] Add historical futures docstring --- openbb_terminal/futures/sdk_helper.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/openbb_terminal/futures/sdk_helper.py b/openbb_terminal/futures/sdk_helper.py index 7115b782be1..d8d43937d36 100644 --- a/openbb_terminal/futures/sdk_helper.py +++ b/openbb_terminal/futures/sdk_helper.py @@ -16,7 +16,29 @@ def get_historical( source: Optional[str] = "YahooFinance", expiry: Optional[str] = "", ) -> pd.DataFrame: - """Get historical futures data""" + """Get historical futures data + + Parameters + ---------- + symbols : Union[str, List[str]] + The futures symbols you want to retrieve historical data for. + It can be either a single symbol as a string or a list of symbols. + start_date : str + The start date of the historical data you want to retrieve. The date should be in the format "YYYY-MM-DD". + end_date : str + The end date of the historical data you want to retrieve. The date should be in the format "YYYY-MM-DD". + source : Optional[str], default "YahooFinance" + The source from which you want to retrieve the historical data. This parameter is optional and defaults to "YahooFinance". + Valid values for the source are "YahooFinance" and "DataBento". + expiry : Optional[str], default "" + The expiry date for futures contracts. This parameter is optional and defaults to an empty string. + It is applicable only when the source is "YahooFinance" and the symbols are futures contracts. + + Returns + ------- + pd.DataFrame + A pandas DataFrame containing the historical data for the given symbols and date range. + """ if source == "YahooFinance": if isinstance(symbols, str): symbols = [symbols] From 32f1b79f1a585acfcb387f8b4c9a87d26e0cd839 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 7 Aug 2023 16:56:11 -0400 Subject: [PATCH 10/28] fix lint --- openbb_terminal/futures/sdk_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbb_terminal/futures/sdk_helper.py b/openbb_terminal/futures/sdk_helper.py index d8d43937d36..94688eac5d8 100644 --- a/openbb_terminal/futures/sdk_helper.py +++ b/openbb_terminal/futures/sdk_helper.py @@ -28,7 +28,7 @@ def get_historical( end_date : str The end date of the historical data you want to retrieve. The date should be in the format "YYYY-MM-DD". source : Optional[str], default "YahooFinance" - The source from which you want to retrieve the historical data. This parameter is optional and defaults to "YahooFinance". + The source from which you want to retrieve the historical data. Valid values for the source are "YahooFinance" and "DataBento". expiry : Optional[str], default "" The expiry date for futures contracts. This parameter is optional and defaults to an empty string. From e122a0bb55c6f2d628a8aec89d35bfd15f30c7f7 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Tue, 8 Aug 2023 14:41:40 -0400 Subject: [PATCH 11/28] fix wsb/deprecate spacc --- .../behavioural_analysis/reddit_view.py | 7 ++-- .../behavioural_analysis/ba_controller.py | 36 ------------------- .../test_ba_controller.py | 11 ------ .../test_ba_controller/test_print_help.txt | 1 - 4 files changed, 4 insertions(+), 51 deletions(-) diff --git a/openbb_terminal/common/behavioural_analysis/reddit_view.py b/openbb_terminal/common/behavioural_analysis/reddit_view.py index 2855c5349cc..0c0f87c46f9 100644 --- a/openbb_terminal/common/behavioural_analysis/reddit_view.py +++ b/openbb_terminal/common/behavioural_analysis/reddit_view.py @@ -1,6 +1,7 @@ """Reddit View.""" __docformat__ = "numpy" +import io import logging import os import textwrap @@ -212,10 +213,10 @@ def display_wsb_community(limit: int = 10, new: bool = False): Flag to sort by new instead of hot, by default False """ subs = reddit_model.get_wsb_community(limit, new) + # I am not proud of this, but it works to eliminate the max recursion bug + subs = pd.read_csv(io.StringIO(subs.to_csv()), index_col=0).fillna("-") if not subs.empty: - # for sub in subs.iterrows(): - # print_reddit_post(sub) - print(print_rich_table(subs)) + print_rich_table(subs) @log_start_end(log=logger) diff --git a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py index 30cf872117e..00953436ee6 100644 --- a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py +++ b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py @@ -47,7 +47,6 @@ class BehaviouralAnalysisController(StockBaseController): "load", "wsb", "popular", - "spacc", "getdd", "redditsent", "bullbear", @@ -97,7 +96,6 @@ class BehaviouralAnalysisController(StockBaseController): mt.add_cmd("snews", self.ticker) mt.add_cmd("wsb") mt.add_cmd("popular") - mt.add_cmd("spacc") mt.add_cmd("getdd") mt.add_cmd("redditsent", self.ticker) mt.add_cmd("trending") @@ -137,40 +135,6 @@ class BehaviouralAnalysisController(StockBaseController): symbol=self.ticker, export=ns_parser.export ) - @log_start_end(log=logger) - def call_spacc(self, other_args: List[str]): - """Process spacc command.""" - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="spacc", - description="""Print other users SPACs announcement under subreddit 'SPACs'. [Source: Reddit]""", - ) - parser.add_argument( - "-l", - "--limit", - action="store", - dest="n_limit", - type=check_positive, - default=10, - help="limit of posts with SPACs retrieved", - ) - parser.add_argument( - "-p", - "--popular", - action="store_true", - default=False, - dest="b_popular", - help="popular flag, if true the posts retrieved are based on score rather than time", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-l") - ns_parser = self.parse_known_args_and_warn(parser, other_args) - if ns_parser: - reddit_view.display_spac_community( - limit=ns_parser.n_limit, popular=ns_parser.b_popular - ) - @log_start_end(log=logger) def call_wsb(self, other_args: List[str]): """Process wsb command.""" diff --git a/tests/openbb_terminal/stocks/behavioural_analysis/test_ba_controller.py b/tests/openbb_terminal/stocks/behavioural_analysis/test_ba_controller.py index b3e4d94c635..888a0ac6936 100644 --- a/tests/openbb_terminal/stocks/behavioural_analysis/test_ba_controller.py +++ b/tests/openbb_terminal/stocks/behavioural_analysis/test_ba_controller.py @@ -238,16 +238,6 @@ def test_call_func_expect_queue(expected_queue, queue, func): @pytest.mark.parametrize( "tested_func, other_args, mocked_func, called_args, called_kwargs", [ - ( - "call_spacc", - ["--limit=5", "--popular"], - "reddit_view.display_spac_community", - [], - dict( - limit=5, - popular=True, - ), - ), ( "call_wsb", ["--limit=5", "--new"], @@ -426,7 +416,6 @@ def test_call_func( @pytest.mark.parametrize( "func", [ - "call_spacc", "call_wsb", "call_popular", "call_bullbear", diff --git a/tests/openbb_terminal/stocks/behavioural_analysis/txt/test_ba_controller/test_print_help.txt b/tests/openbb_terminal/stocks/behavioural_analysis/txt/test_ba_controller/test_print_help.txt index b8c9ecfe68a..e2a9a232e0b 100644 --- a/tests/openbb_terminal/stocks/behavioural_analysis/txt/test_ba_controller/test_print_help.txt +++ b/tests/openbb_terminal/stocks/behavioural_analysis/txt/test_ba_controller/test_print_help.txt @@ -6,7 +6,6 @@ Ticker: TSLA snews stock price displayed over sentiment of news headlines [Finnhub] wsb show what WSB gang is up to in subreddit wallstreetbets [Reddit] popular show popular tickers [Reddit] - spacc show other users spacs announcements from subreddit SPACs [Reddit] getdd gets due diligence from another user's post [Reddit] redditsent searches reddit for ticker and finds reddit sentiment [Reddit] trending trending stocks [Stocktwits] From 673b22f4ef264c3004fe9fbba671db8bce72b6d8 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Tue, 8 Aug 2023 14:45:01 -0400 Subject: [PATCH 12/28] fix sdk --- openbb_terminal/core/sdk/controllers/stocks_sdk_controller.py | 1 - openbb_terminal/core/sdk/models/stocks_sdk_model.py | 2 -- openbb_terminal/core/sdk/trail_map.csv | 1 - 3 files changed, 4 deletions(-) diff --git a/openbb_terminal/core/sdk/controllers/stocks_sdk_controller.py b/openbb_terminal/core/sdk/controllers/stocks_sdk_controller.py index 7918c33d017..676362d2e6e 100644 --- a/openbb_terminal/core/sdk/controllers/stocks_sdk_controller.py +++ b/openbb_terminal/core/sdk/controllers/stocks_sdk_controller.py @@ -59,7 +59,6 @@ class StocksController(model.StocksRoot): `sentiment_chart`: Plots sentiments from symbol\n `snews`: Get headlines sentiment using VADER model over time. [Source: Finnhub]\n `snews_chart`: Display stock price and headlines sentiment using VADER model over time. [Source: Finnhub]\n - `spacc`: Get top tickers from r/SPACs [Source: reddit].\n `stalker`: Gets messages from given user [Source: stocktwits].\n `text_sent`: Find the sentiment of a post and related comments.\n `trending`: Get trending tickers from stocktwits [Source: stocktwits].\n diff --git a/openbb_terminal/core/sdk/models/stocks_sdk_model.py b/openbb_terminal/core/sdk/models/stocks_sdk_model.py index 0a2ba28f2f8..f0e4c74c4ac 100644 --- a/openbb_terminal/core/sdk/models/stocks_sdk_model.py +++ b/openbb_terminal/core/sdk/models/stocks_sdk_model.py @@ -59,7 +59,6 @@ class StocksBehavioralAnalysis(Category): `sentiment_chart`: Plots sentiments from symbol\n `snews`: Get headlines sentiment using VADER model over time. [Source: Finnhub]\n `snews_chart`: Display stock price and headlines sentiment using VADER model over time. [Source: Finnhub]\n - `spacc`: Get top tickers from r/SPACs [Source: reddit].\n `stalker`: Gets messages from given user [Source: stocktwits].\n `text_sent`: Find the sentiment of a post and related comments.\n `trending`: Get trending tickers from stocktwits [Source: stocktwits].\n @@ -94,7 +93,6 @@ class StocksBehavioralAnalysis(Category): self.snews_chart = ( lib.stocks_ba_finnhub_view.display_stock_price_headlines_sentiment ) - self.spacc = lib.stocks_ba_reddit_model.get_spac_community self.stalker = lib.stocks_ba_stocktwits_model.get_stalker self.text_sent = lib.stocks_ba_reddit_model.get_sentiment self.trending = lib.stocks_ba_stocktwits_model.get_trending diff --git a/openbb_terminal/core/sdk/trail_map.csv b/openbb_terminal/core/sdk/trail_map.csv index 63682195424..a7e369182cd 100644 --- a/openbb_terminal/core/sdk/trail_map.csv +++ b/openbb_terminal/core/sdk/trail_map.csv @@ -400,7 +400,6 @@ stocks.ba.regions,stocks_ba_google_model.get_regions,stocks_ba_google_view.displ stocks.ba.rise,stocks_ba_google_model.get_rise, stocks.ba.sentiment,stocks_ba_twitter_model.get_sentiment,stocks_ba_twitter_view.display_sentiment stocks.ba.snews,stocks_ba_finnhub_model.get_headlines_sentiment,stocks_ba_finnhub_view.display_stock_price_headlines_sentiment -stocks.ba.spacc,stocks_ba_reddit_model.get_spac_community, stocks.ba.stalker,stocks_ba_stocktwits_model.get_stalker, stocks.ba.text_sent,stocks_ba_reddit_model.get_sentiment, stocks.ba.trending,stocks_ba_stocktwits_model.get_trending, From 47092a2c44bf2be4268ecc5edd104b3102d2441a Mon Sep 17 00:00:00 2001 From: James Maslek Date: Wed, 9 Aug 2023 17:49:13 -0400 Subject: [PATCH 13/28] autocomplete --- openbb_terminal/terminal_controller.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openbb_terminal/terminal_controller.py b/openbb_terminal/terminal_controller.py index 7e3df6be9f3..649efdb55df 100644 --- a/openbb_terminal/terminal_controller.py +++ b/openbb_terminal/terminal_controller.py @@ -175,6 +175,7 @@ class TerminalController(BaseController): self.ROUTINE_CHOICES["-i"] = None self.ROUTINE_CHOICES["--help"] = None self.ROUTINE_CHOICES["--h"] = None + self.ROUTINE_CHOICES["--url"] = None if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: choices: dict = {c: {} for c in self.controller_choices} # type: ignore From 02732e99b3183d9376d6ae5cbc8353a82e182325 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Thu, 10 Aug 2023 10:04:08 -0400 Subject: [PATCH 14/28] rename -v -> -d in forecast/season --- openbb_terminal/forecast/forecast_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbb_terminal/forecast/forecast_controller.py b/openbb_terminal/forecast/forecast_controller.py index b4386fa6e75..218fcd66d40 100644 --- a/openbb_terminal/forecast/forecast_controller.py +++ b/openbb_terminal/forecast/forecast_controller.py @@ -1115,8 +1115,8 @@ class ForecastController(BaseController): description="The seasonality for a given column", ) parser.add_argument( - "-v", - "--values", + "-d", + "--dataset", help="Dataset.column values to be displayed in a plot", dest="values", choices=self.get_dataset_columns(), From f822b0afa3e192fba052f73134f2e8b127a68a7e Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sat, 12 Aug 2023 17:48:36 -0700 Subject: [PATCH 15/28] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 221332fb10d..8c9170ac86c 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,9 @@ Any of our social media platforms: [openbb.co/links](https://openbb.co/links) ## 6. Star History -This is a proxy of our growth and that we are just getting started. But for more metrics important to us check [openbb.co/open](https://openbb.co/open). +This is a proxy of our growth and that we are just getting started. + +But for more metrics important to us check [openbb.co/open](https://openbb.co/open). [![Star History Chart](https://api.star-history.com/svg?repos=openbb-finance/OpenBBTerminal&type=Date)](https://star-history.com/#openbb-finance/OpenBBTerminal&Date) From db746aa1a9a6850634ef1cedea2f9a46805f0e7e Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 13 Aug 2023 02:27:26 -0500 Subject: [PATCH 16/28] Silly (#5313) * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic --- openbb_terminal/core/session/hub_model.py | 6 + .../econometrics/econometrics_controller.py | 2 +- .../quantitative_analysis/qa_controller.py | 2 +- openbb_terminal/featflags_controller.py | 2 +- openbb_terminal/parent_classes.py | 210 +++++++++++++----- .../brokers/degiro/degiro_controller.py | 2 +- .../parameters/params_controller.py | 2 +- openbb_terminal/terminal_controller.py | 88 +++++--- 8 files changed, 216 insertions(+), 98 deletions(-) diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index f47412a46b0..5dea92f109b 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -14,6 +14,7 @@ from openbb_terminal.core.session.constants import ( TIMEOUT, ) from openbb_terminal.core.session.current_system import get_current_system +from openbb_terminal.core.session.current_user import get_current_user from openbb_terminal.rich_config import console @@ -476,7 +477,12 @@ def upload_routine( timeout=timeout, ) if response.status_code == 200: + username = get_current_user().profile.username console.print("[green]Successfully uploaded your routine.[/green]") + if public: + console.print(f"\n[yellow]Share or edit it at https://my.openbb.co/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + else: + console.print(f"\n[yellow]Edit it at https://my.openbb.co/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") elif response.status_code != 409: # 409: routine already exists console.print( "[red]" + response.json().get("detail", "Unknown error.") + "[/red]" diff --git a/openbb_terminal/econometrics/econometrics_controller.py b/openbb_terminal/econometrics/econometrics_controller.py index 03b1a9a538d..db42dcfa3a6 100644 --- a/openbb_terminal/econometrics/econometrics_controller.py +++ b/openbb_terminal/econometrics/econometrics_controller.py @@ -165,7 +165,7 @@ class EconometricsController(BaseController): } if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: - choices: dict = {c: {} for c in self.controller_choices} + choices: dict = self.choices_default choices["load"] = { "--file": {c: {} for c in self.DATA_FILES}, "-f": "--file", diff --git a/openbb_terminal/economy/quantitative_analysis/qa_controller.py b/openbb_terminal/economy/quantitative_analysis/qa_controller.py index a188b9b8e22..f35048f26e1 100644 --- a/openbb_terminal/economy/quantitative_analysis/qa_controller.py +++ b/openbb_terminal/economy/quantitative_analysis/qa_controller.py @@ -83,7 +83,7 @@ class QaController(StockBaseController): self.resolution = "" # For the views if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: - choices: dict = {c: {} for c in self.controller_choices} + choices: dict = self.choices_default choices["pick"] = {c: {} for c in self.options} choices["unitroot"] = { "--fuller_reg": {c: {} for c in self.FULLER_REG}, diff --git a/openbb_terminal/featflags_controller.py b/openbb_terminal/featflags_controller.py index 43ef32893e6..b3d3374819d 100644 --- a/openbb_terminal/featflags_controller.py +++ b/openbb_terminal/featflags_controller.py @@ -66,7 +66,7 @@ class FeatureFlagsController(BaseController): super().__init__(queue) if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: - choices: dict = {c: {} for c in self.controller_choices} + choices: dict = self.choices_default self.completer = NestedCompleter.from_nested_dict(choices) def print_help(self): diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index f3600597df5..b7427ec9f32 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -5,6 +5,7 @@ __docformat__ = "numpy" # IMPORTS STANDARD import argparse +import itertools import difflib import json import logging @@ -26,6 +27,7 @@ from rich.markdown import Markdown import openbb_terminal.core.session.local_model as Local from openbb_terminal import config_terminal from openbb_terminal.account.show_prompt import get_show_prompt +from openbb_terminal.core.session.constants import SCRIPT_TAGS from openbb_terminal.core.completer.choices import build_controller_choice_map from openbb_terminal.core.config.paths import HIST_FILE_PATH from openbb_terminal.core.session import hub_model as Hub @@ -85,6 +87,7 @@ SUPPORT_TYPE = ["bug", "suggestion", "question", "generic"] # TODO: We should try to avoid these global variables RECORD_SESSION = False +RECORD_SESSION_LOCAL_ONLY = False SESSION_RECORDED = list() SESSION_RECORDED_NAME = "" SESSION_RECORDED_DESCRIPTION = "" @@ -111,7 +114,6 @@ class BaseController(metaclass=ABCMeta): "reset", "support", "wiki", - "record", "stop", "screenshot", "askobb", @@ -892,8 +894,9 @@ class BaseController(metaclass=ABCMeta): action="store", dest="name", type=str, - default=datetime.now().strftime("%Y%m%d_%H%M%S_routine.openbb"), - help="Routine file name to be saved.", + default="", + help="Routine title name to be saved - only use characters, digits and whitespaces.", + nargs="+", ) parser.add_argument( "-d", @@ -901,15 +904,30 @@ class BaseController(metaclass=ABCMeta): type=str, dest="description", help="The description of the routine", + default=f"Routine recorded at {datetime.now().strftime('%H:%M')} from the OpenBB Terminal", + nargs="+", + ) + parser.add_argument( + "--tag1", + type=str, + dest="tag1", + help=f"The tag associated with the routine. Select from: {', '.join(SCRIPT_TAGS)}", default="", nargs="+", ) parser.add_argument( - "-t", - "--tags", + "--tag2", type=str, - dest="tags", - help="The tags of the routine", + dest="tag2", + help=f"The tag associated with the routine. Select from: {', '.join(SCRIPT_TAGS)}", + default="", + nargs="+", + ) + parser.add_argument( + "--tag3", + type=str, + dest="tag3", + help=f"The tag associated with the routine. Select from: {', '.join(SCRIPT_TAGS)}", default="", nargs="+", ) @@ -921,32 +939,72 @@ class BaseController(metaclass=ABCMeta): help="Whether the routine should be public or not", default=False, ) + parser.add_argument( + "-l", + "--local", + dest="local", + action="store_true", + help="Only save the routine locally - this is necessary if you are running terminal in guest mode.", + default=False, + ) if other_args and "-" not in other_args[0][0]: other_args.insert(0, "-n") + ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: + + if not ns_parser.name: + console.print("[red]Set a routine title by using the '-n' flag. E.g. 'record -n Morning routine'[/red]") + return + + tag1 = " ".join(ns_parser.tag1) if isinstance(ns_parser.tag1, list) else ns_parser.tag1 + if tag1 and tag1 not in SCRIPT_TAGS: + console.print(f"[red]The parameter 'tag1' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + return + + tag2 = " ".join(ns_parser.tag2) if isinstance(ns_parser.tag2, list) else ns_parser.tag2 + if tag2 and tag2 not in SCRIPT_TAGS: + console.print(f"[red]The parameter 'tag2' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + return + + tag3 = " ".join(ns_parser.tag3) if isinstance(ns_parser.tag3, list) else ns_parser.tag3 + if tag3 and tag3 not in SCRIPT_TAGS: + console.print(f"[red]The parameter 'tag3' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + return + + if is_local() and not ns_parser.local: + console.print("[red]Recording session to the OpenBB Hub is not supported in guest mode.[/red]") + console.print("\n[yellow]Sign to OpenBB Hub to register: http://openbb.co[/yellow]") + console.print("\n[yellow]Otherwise set the flag '-l' to save the file locally.[/yellow]") + return + + # Check if title has a valid format + title = " ".join(ns_parser.name) if ns_parser.name else "" + pattern = re.compile(r"^[a-zA-Z0-9\s]+(?:[-a-zA-Z0-9\s]+)*$") + if not pattern.match(title): + console.print(f"[red]The title '{title}' has invalid format. Please use only digits, characters and whitespaces.[/red]") + return + global RECORD_SESSION + global RECORD_SESSION_LOCAL_ONLY global SESSION_RECORDED_NAME global SESSION_RECORDED_DESCRIPTION global SESSION_RECORDED_TAGS global SESSION_RECORDED_PUBLIC - SESSION_RECORDED_NAME = ( - ns_parser.name - if ".openbb" in ns_parser.name - else ns_parser.name + ".openbb" - ) + RECORD_SESSION = True + RECORD_SESSION_LOCAL_ONLY = ns_parser.local + SESSION_RECORDED_NAME = title + SESSION_RECORDED_DESCRIPTION = " ".join(ns_parser.description) if isinstance(ns_parser.description, list) else ns_parser.description + SESSION_RECORDED_TAGS = tag1 if tag1 else "" + SESSION_RECORDED_TAGS += ',' + tag2 if tag2 else "" + SESSION_RECORDED_TAGS += ',' + tag3 if tag3 else "" - SESSION_RECORDED_DESCRIPTION = " ".join(ns_parser.description) - SESSION_RECORDED_TAGS = " ".join(ns_parser.tags) if ns_parser.tags else "" SESSION_RECORDED_PUBLIC = ns_parser.public - console.print( - "[green]The session is successfully being recorded." - + " Remember to 'stop' before exiting terminal!\n[/green]" - ) - RECORD_SESSION = True + console.print(f"[green]The routine '{title}' is successfully being recorded.[/green]") + console.print("\n[yellow]Remember to run 'stop' command when you are done!\n[/yellow]") @log_start_end(log=logger) def call_stop(self, _) -> None: @@ -956,57 +1014,95 @@ class BaseController(metaclass=ABCMeta): if not RECORD_SESSION: console.print( - "[red]There is no session being recorded. Start one using 'record'[/red]\n" + "[red]There is no session being recorded. Start one using the command 'record'[/red]\n" ) - elif not SESSION_RECORDED: + elif len(SESSION_RECORDED) < 5: console.print( - "[red]There is no session to be saved. Run at least 1 command after starting 'record'[/red]\n" + "[red]Run at least 4 commands before stopping recording a session.[/red]\n" ) else: current_user = get_current_user() - routine_file = os.path.join( - current_user.preferences.USER_ROUTINES_DIRECTORY, SESSION_RECORDED_NAME - ) - if os.path.isfile(routine_file): + # Check if the user just wants to store routine locally + # This works regardless of whether they are logged in or not + if RECORD_SESSION_LOCAL_ONLY: + # Whitespaces are replaced by underscores and an .openbb extension is added + title_for_local_storage = SESSION_RECORDED_NAME.replace(" ", "_") + ".openbb" + routine_file = os.path.join( current_user.preferences.USER_ROUTINES_DIRECTORY, - datetime.now().strftime("%Y%m%d_%H%M%S_") + SESSION_RECORDED_NAME, + title_for_local_storage ) - # Writing to file - with open(routine_file, "w") as file1: - # Writing data to a file - file1.writelines([c + "\n\n" for c in SESSION_RECORDED[:-1]]) - - console.print( - f"[green]Your routine has been recorded and saved here: {routine_file}[/green]\n" - ) - - if not is_local(): - routine = read_routine(file_name=routine_file) - if routine is not None: - name = SESSION_RECORDED_NAME.split(sep=".openbb", maxsplit=-1)[0] - kwargs = { - "auth_header": current_user.profile.get_auth_header(), - "name": name, - "description": SESSION_RECORDED_DESCRIPTION, - "routine": routine, - "tags": SESSION_RECORDED_TAGS, - "public": SESSION_RECORDED_PUBLIC, - } - response = Hub.upload_routine(**kwargs) # type: ignore - if response is not None and response.status_code == 409: + # If file already exists, add a timestamp to the name + if os.path.isfile(routine_file): + i = console.input( + "A local routine with the same name already exists, " + "do you want to override it? (y/n): " + ) + console.print("") + while i.lower() not in ["y", "yes", "n", "no"]: i = console.input( - "A routine with the same name already exists, " - "do you want to replace it? (y/n): " + "Select 'y' or 'n' to proceed: " ) console.print("") - if i.lower() in ["y", "yes"]: - kwargs["override"] = True # type: ignore - response = Hub.upload_routine(**kwargs) # type: ignore - else: - console.print("[info]Aborted.[/info]") + + if i.lower() in ["n", "no"]: + new_name = datetime.now().strftime("%Y%m%d_%H%M%S_") + title_for_local_storage + routine_file = os.path.join( + current_user.preferences.USER_ROUTINES_DIRECTORY, + new_name, + ) + console.print(f"[yellow]The routine name has been updated to '{new_name}'[/yellow]\n") + + # Writing to file + with open(routine_file, "w") as file1: + lines = ["# OpenBB Terminal - Routine", "\n"] + username = get_current_user().profile.username + lines += [f"# Author: {username}", "\n\n"] if username else ["\n"] + lines += [ + f"# Title: {SESSION_RECORDED_NAME}", + "\n", + f"# Tags: {SESSION_RECORDED_TAGS}", + "\n\n", + f"# Description: {SESSION_RECORDED_DESCRIPTION}", + "\n\n", + ] + lines += [c + "\n\n" for c in SESSION_RECORDED[:-1]] + # Writing data to a file + file1.writelines(lines) + + console.print( + f"[green]Your routine has been recorded and saved here: {routine_file}[/green]\n" + ) + + # If user doesn't specify they want to store routine locally + else: + # Confirm that the user is logged in + if not is_local(): + # routine = read_routine(file_name=routine_file) + routine = "\n\n".join(SESSION_RECORDED[:-1]) + if routine is not None: + kwargs = { + "auth_header": current_user.profile.get_auth_header(), + "name": SESSION_RECORDED_NAME, + "description": SESSION_RECORDED_DESCRIPTION, + "routine": routine, + "tags": SESSION_RECORDED_TAGS, + "public": SESSION_RECORDED_PUBLIC, + } + response = Hub.upload_routine(**kwargs) # type: ignore + if response is not None and response.status_code == 409: + i = console.input( + "A routine with the same name already exists, " + "do you want to replace it? (y/n): " + ) + console.print("") + if i.lower() in ["y", "yes"]: + kwargs["override"] = True # type: ignore + response = Hub.upload_routine(**kwargs) # type: ignore + else: + console.print("[info]Aborted.[/info]") # Clear session to be recorded again RECORD_SESSION = False diff --git a/openbb_terminal/portfolio/brokers/degiro/degiro_controller.py b/openbb_terminal/portfolio/brokers/degiro/degiro_controller.py index fdae00fab59..bae880cd568 100644 --- a/openbb_terminal/portfolio/brokers/degiro/degiro_controller.py +++ b/openbb_terminal/portfolio/brokers/degiro/degiro_controller.py @@ -43,7 +43,7 @@ class DegiroController(BaseController): self.__degiro_view = DegiroView() if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: - choices: dict = {c: {} for c in self.controller_choices} + choices: dict = self.choices_default zero_to_hundred: dict = {str(c): {} for c in range(0, 100)} diff --git a/openbb_terminal/portfolio/portfolio_optimization/parameters/params_controller.py b/openbb_terminal/portfolio/portfolio_optimization/parameters/params_controller.py index 472f0d24bd4..8d92c0188ab 100644 --- a/openbb_terminal/portfolio/portfolio_optimization/parameters/params_controller.py +++ b/openbb_terminal/portfolio/portfolio_optimization/parameters/params_controller.py @@ -78,7 +78,7 @@ class ParametersController(BaseController): self.DATA_FILES = params_helpers.load_data_files() if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: - choices: dict = {c: {} for c in self.controller_choices} + choices: dict = self.choices_default choices["set"] = {c: None for c in self.models} choices["set"]["--model"] = {c: None for c in self.models} choices["set"]["-m"] = "--model" diff --git a/openbb_terminal/terminal_controller.py b/openbb_terminal/terminal_controller.py index 7e3df6be9f3..fd791f55612 100644 --- a/openbb_terminal/terminal_controller.py +++ b/openbb_terminal/terminal_controller.py @@ -20,7 +20,7 @@ import certifi import pandas as pd import requests from prompt_toolkit import PromptSession -from prompt_toolkit.completion import NestedCompleter +from openbb_terminal.custom_prompt_toolkit import NestedCompleter from prompt_toolkit.formatted_text import HTML from prompt_toolkit.styles import Style @@ -33,6 +33,7 @@ from openbb_terminal.core.config.paths import ( REPOSITORY_DIRECTORY, SETTINGS_ENV_FILE, ) +from openbb_terminal.core.session.constants import SCRIPT_TAGS from openbb_terminal.core.log.generation.custom_logger import log_terminal from openbb_terminal.core.session import session_controller from openbb_terminal.core.session.current_system import set_system_variable @@ -90,6 +91,7 @@ class TerminalController(BaseController): "news", "intro", "askobb", + "record", ] CHOICES_MENUS = [ "stocks", @@ -142,44 +144,10 @@ class TerminalController(BaseController): def update_runtime_choices(self): """Update runtime choices.""" - self.ROUTINE_FILES = { - filepath.name: filepath - for filepath in get_current_user().preferences.USER_ROUTINES_DIRECTORY.rglob( - "*.openbb" - ) - } - if get_current_user().profile.get_token(): - self.ROUTINE_DEFAULT_FILES = { - filepath.name: filepath - for filepath in Path( - get_current_user().preferences.USER_ROUTINES_DIRECTORY - / "hub" - / "default" - ).rglob("*.openbb") - } - self.ROUTINE_PERSONAL_FILES = { - filepath.name: filepath - for filepath in Path( - get_current_user().preferences.USER_ROUTINES_DIRECTORY - / "hub" - / "personal" - ).rglob("*.openbb") - } - - self.ROUTINE_CHOICES["--file"] = { - filename: None for filename in self.ROUTINE_FILES - } - self.ROUTINE_CHOICES["--example"] = None - self.ROUTINE_CHOICES["-e"] = None - self.ROUTINE_CHOICES["--input"] = None - self.ROUTINE_CHOICES["-i"] = None - self.ROUTINE_CHOICES["--help"] = None - self.ROUTINE_CHOICES["--h"] = None - if session and get_current_user().preferences.USE_PROMPT_TOOLKIT: + # choices: dict = self.choices_default choices: dict = {c: {} for c in self.controller_choices} # type: ignore choices["support"] = self.SUPPORT_CHOICES - choices["exe"] = self.ROUTINE_CHOICES choices["news"] = self.NEWS_CHOICES choices["news"]["--source"] = {c: {} for c in ["Biztoc", "Feedparser"]} choices["hold"] = {c: None for c in ["on", "off", "-s", "--sameaxis"]} @@ -187,6 +155,53 @@ class TerminalController(BaseController): if biztoc_model.BIZTOC_TAGS: choices["news"]["--tag"] = {c: {} for c in biztoc_model.BIZTOC_TAGS} + self.ROUTINE_FILES = { + filepath.name: filepath + for filepath in get_current_user().preferences.USER_ROUTINES_DIRECTORY.rglob( + "*.openbb" + ) + } + if get_current_user().profile.get_token(): + self.ROUTINE_DEFAULT_FILES = { + filepath.name: filepath + for filepath in Path( + get_current_user().preferences.USER_ROUTINES_DIRECTORY + / "hub" + / "default" + ).rglob("*.openbb") + } + self.ROUTINE_PERSONAL_FILES = { + filepath.name: filepath + for filepath in Path( + get_current_user().preferences.USER_ROUTINES_DIRECTORY + / "hub" + / "personal" + ).rglob("*.openbb") + } + + choices["exe"] = { + "--file": {filename: {} for filename in list(self.ROUTINE_FILES.keys())}, + "-f": "--file", + "--example": None, + "-e": "--example", + "--input": None, + "-i": "--input", + } + + choices["record"] = { + "--name": None, + "-n": "--name", + "--description": None, + "-d": "--description", + "--public": None, + "-p": "--public", + "--local": None, + "-l": "--local", + "--tag1": {c: None for c in SCRIPT_TAGS}, + "--tag2": {c: None for c in SCRIPT_TAGS}, + "--tag3": {c: None for c in SCRIPT_TAGS}, + } + self.completer = NestedCompleter.from_nested_dict(choices) def print_help(self): @@ -761,6 +776,7 @@ class TerminalController(BaseController): self.queue = self.queue[1:] + # pylint: disable=global-statement def terminal(jobs_cmds: Optional[List[str]] = None, test_mode=False): """Terminal Menu.""" From 01210120d8c9806d4e738ddfd6bd1bed48e13037 Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 13 Aug 2023 19:18:14 -0500 Subject: [PATCH 17/28] --debug points to dev env (#5316) * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic * --debug runs .dev --- openbb_terminal/core/plots/backend.py | 7 ++++++- openbb_terminal/core/session/constants.py | 11 +++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/openbb_terminal/core/plots/backend.py b/openbb_terminal/core/plots/backend.py index ba82753ab6d..8955796855c 100644 --- a/openbb_terminal/core/plots/backend.py +++ b/openbb_terminal/core/plots/backend.py @@ -441,8 +441,13 @@ class Backend(PyWry): self.check_backend() endpoint = {True: "login", False: "logout"}[login] + if str(os.environ.get("DEBUG_MODE", "false")).lower() != "true": + json_url = f"https://my.openbb.dev/{endpoint}?pywry=true" + else: + json_url = f"https://my.openbb.co/{endpoint}?pywry=true" + outgoing = dict( - json_data=dict(url=f"https://my.openbb.co/{endpoint}?pywry=true"), + json_data=dict(url=json_url), **self.get_kwargs(endpoint.title()), width=900, height=800, diff --git a/openbb_terminal/core/session/constants.py b/openbb_terminal/core/session/constants.py index 252b362d165..21fdee6bee7 100644 --- a/openbb_terminal/core/session/constants.py +++ b/openbb_terminal/core/session/constants.py @@ -1,7 +1,14 @@ -BASE_URL = "https://payments.openbb.co/" +from os import environ + +if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + BASE_URL = "https://payments.openbb.dev/" + HUB_URL = "https://my.openbb.dev/" +else: + BASE_URL = "https://payments.openbb.co/" + HUB_URL = "https://my.openbb.co/" + # BASE_URL = "http://127.0.0.1:8000/" -HUB_URL = "https://my.openbb.co/" REGISTER_URL = HUB_URL + "register" SUPPORT_URL = HUB_URL + "app/terminal/support" SOURCES_URL = HUB_URL + "app/terminal/data-sources" From 3d6ad59643a01debaff91c7dd9d8b67f29f41e48 Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 13 Aug 2023 19:43:10 -0500 Subject: [PATCH 18/28] few more updates (#5317) * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic * --debug runs .dev * few more updates --- openbb_terminal/core/session/hub_model.py | 12 ++++++++---- openbb_terminal/parent_classes.py | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index 5dea92f109b..4fc99c5c582 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -2,7 +2,7 @@ import datetime import json from typing import Any, Dict, List, Literal, Optional from uuid import UUID - +from os import environ import requests from jose import jwt @@ -479,10 +479,14 @@ def upload_routine( if response.status_code == 200: username = get_current_user().profile.username console.print("[green]Successfully uploaded your routine.[/green]") - if public: - console.print(f"\n[yellow]Share or edit it at https://my.openbb.co/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + run_env = "dev" else: - console.print(f"\n[yellow]Edit it at https://my.openbb.co/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + run_env = "co" + if public: + console.print(f"\n[yellow]Share or edit it at https://my.openbb.{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + else: + console.print(f"\n[yellow]Edit it at https://my.openbb.{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") elif response.status_code != 409: # 409: routine already exists console.print( "[red]" + response.json().get("detail", "Unknown error.") + "[/red]" diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index b7427ec9f32..e5849a019f6 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -1068,7 +1068,7 @@ class BaseController(metaclass=ABCMeta): f"# Description: {SESSION_RECORDED_DESCRIPTION}", "\n\n", ] - lines += [c + "\n\n" for c in SESSION_RECORDED[:-1]] + lines += [c + "\n" for c in SESSION_RECORDED[:-1]] # Writing data to a file file1.writelines(lines) @@ -1081,7 +1081,8 @@ class BaseController(metaclass=ABCMeta): # Confirm that the user is logged in if not is_local(): # routine = read_routine(file_name=routine_file) - routine = "\n\n".join(SESSION_RECORDED[:-1]) + routine = "\n".join(SESSION_RECORDED[:-1]) + if routine is not None: kwargs = { "auth_header": current_user.profile.get_auth_header(), From 3e48648487b1b072b3b434f80f0b4b744ea666eb Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 13 Aug 2023 20:16:35 -0500 Subject: [PATCH 19/28] small fixy (#5318) * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic * --debug runs .dev * few more updates * small fix --- openbb_terminal/core/plots/backend.py | 2 +- openbb_terminal/core/session/constants.py | 2 +- openbb_terminal/core/session/hub_model.py | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openbb_terminal/core/plots/backend.py b/openbb_terminal/core/plots/backend.py index 8955796855c..e8433e98f2e 100644 --- a/openbb_terminal/core/plots/backend.py +++ b/openbb_terminal/core/plots/backend.py @@ -441,7 +441,7 @@ class Backend(PyWry): self.check_backend() endpoint = {True: "login", False: "logout"}[login] - if str(os.environ.get("DEBUG_MODE", "false")).lower() != "true": + if str(os.environ.get("DEBUG_MODE", "false")).lower() == "true": json_url = f"https://my.openbb.dev/{endpoint}?pywry=true" else: json_url = f"https://my.openbb.co/{endpoint}?pywry=true" diff --git a/openbb_terminal/core/session/constants.py b/openbb_terminal/core/session/constants.py index 21fdee6bee7..2d2fb992e0f 100644 --- a/openbb_terminal/core/session/constants.py +++ b/openbb_terminal/core/session/constants.py @@ -1,6 +1,6 @@ from os import environ -if str(environ.get("DEBUG_MODE", "false")).lower() != "true": +if str(environ.get("DEBUG_MODE", "false")).lower() == "true": BASE_URL = "https://payments.openbb.dev/" HUB_URL = "https://my.openbb.dev/" else: diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index 4fc99c5c582..1c112ed7ec2 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -479,10 +479,12 @@ def upload_routine( if response.status_code == 200: username = get_current_user().profile.username console.print("[green]Successfully uploaded your routine.[/green]") - if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + + if str(environ.get("DEBUG_MODE", "false")).lower() == "true": run_env = "dev" else: run_env = "co" + if public: console.print(f"\n[yellow]Share or edit it at https://my.openbb.{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") else: From c40c3f7529a1ee9b577288db2aaa3be4e461363b Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Mon, 14 Aug 2023 01:20:07 -0500 Subject: [PATCH 20/28] Creates a "--dev" flag that points to dev backend for testing with hub (#5319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic * --debug runs .dev * few more updates * small fix * rename BASE_URL from ultima to ULTIMA_BASE_URL * use debug from dataclasses instead of env since env doesn't get updated * create --dev flag that can point to .dev backend * merge conflits * few changes, made it actually work 🤣 --------- Co-authored-by: tehcoderer --- openbb_terminal/account/account_controller.py | 5 ++ .../common/ultima_newsmonitor_model.py | 14 ++-- openbb_terminal/core/completer/choices.py | 7 +- openbb_terminal/core/models/system_model.py | 1 + openbb_terminal/core/plots/backend.py | 7 +- openbb_terminal/core/session/constants.py | 22 +++--- openbb_terminal/core/session/hub_model.py | 72 ++++++++++++------- .../core/session/routines_handler.py | 1 + .../core/session/session_controller.py | 27 ++++--- openbb_terminal/core/session/session_model.py | 5 +- openbb_terminal/keys_controller.py | 4 +- openbb_terminal/parent_classes.py | 1 + openbb_terminal/portfolio/portfolio_engine.py | 3 +- openbb_terminal/settings_controller.py | 11 +-- openbb_terminal/sources_controller.py | 5 +- openbb_terminal/terminal_controller.py | 24 +++++-- openbb_terminal/terminal_helper.py | 8 ++- terminal.py | 3 +- .../openbb_terminal/session/test_hub_model.py | 36 +++++----- 19 files changed, 157 insertions(+), 99 deletions(-) diff --git a/openbb_terminal/account/account_controller.py b/openbb_terminal/account/account_controller.py index 12b26bb8869..c9f233b0600 100644 --- a/openbb_terminal/account/account_controller.py +++ b/openbb_terminal/account/account_controller.py @@ -255,6 +255,7 @@ class AccountController(BaseController): auth_header=get_current_user().profile.get_auth_header(), page=ns_parser.page, size=ns_parser.size, + base_url=Hub.BackendEnvironment.BASE_URL, ) df, page, pages = get_personal_routines_info(response) if not df.empty: @@ -356,6 +357,7 @@ class AccountController(BaseController): "routine": routine, "tags": tags, "public": ns_parser.public, + "base_url": Hub.BackendEnvironment.BASE_URL, } response = Hub.upload_routine(**kwargs) # type: ignore @@ -412,6 +414,7 @@ class AccountController(BaseController): response = Hub.download_routine( auth_header=get_current_user().profile.get_auth_header(), uuid=self.REMOTE_CHOICES[name], + base_url=Hub.BackendEnvironment.BASE_URL ) if response and response.status_code == 200: data = [response.json(), "personal"] @@ -499,6 +502,7 @@ class AccountController(BaseController): response = Hub.delete_routine( auth_header=get_current_user().profile.get_auth_header(), uuid=self.REMOTE_CHOICES[name], + base_url=Hub.BackendEnvironment.BASE_URL ) if ( response @@ -551,6 +555,7 @@ class AccountController(BaseController): response = Hub.generate_personal_access_token( auth_header=get_current_user().profile.get_auth_header(), + base_url=Hub.BackendEnvironment.BASE_URL, days=ns_parser.days, ) if response and response.status_code == 200: diff --git a/openbb_terminal/common/ultima_newsmonitor_model.py b/openbb_terminal/common/ultima_newsmonitor_model.py index b4e3782ac0d..e06226b7b10 100644 --- a/openbb_terminal/common/ultima_newsmonitor_model.py +++ b/openbb_terminal/common/ultima_newsmonitor_model.py @@ -18,7 +18,7 @@ from openbb_terminal.rich_config import console logger = logging.getLogger(__name__) -BASE_URL = "https://api.ultimainsights.ai/v1" +ULTIMA_BASE_URL = "https://api.ultimainsights.ai/v1" NO_API_KEY = "REPLACE_ME" @@ -69,10 +69,10 @@ def get_news(term: str = "", sort: str = "articlePublishedDate") -> pd.DataFrame if term in supported_terms(): if auth_header: data = request( - f"{BASE_URL}/getNewsArticles/{term}", headers=auth_header + f"{ULTIMA_BASE_URL}/getNewsArticles/{term}", headers=auth_header ) else: - data = request(f"{BASE_URL}/getNewsArticles/{term}") + data = request(f"{ULTIMA_BASE_URL}/getNewsArticles/{term}") else: console.print( "[red]Ticker not supported. Unable to retrieve data\n[/red]" @@ -150,7 +150,7 @@ def supported_terms() -> list: # https://stackoverflow.com/questions/27835619/urllib-and-ssl-certificate-verify-failed-error/73270162#73270162 os.environ["REQUESTS_CA_BUNDLE"] = certifi.where() os.environ["SSL_CERT_FILE"] = certifi.where() - data = request(f"{BASE_URL}/supportedTickers") + data = request(f"{ULTIMA_BASE_URL}/supportedTickers") return list(data.json()) @@ -176,7 +176,7 @@ def get_company_info(ticker: str) -> dict: os.environ["SSL_CERT_FILE"] = certifi.where() if ticker in supported_terms(): - data = request(f"{BASE_URL}/getCompanyInfo/{ticker}") + data = request(f"{ULTIMA_BASE_URL}/getCompanyInfo/{ticker}") return data.json() console.print("[red]Ticker not supported. Unable to retrieve data\n[/red]") return {} @@ -213,9 +213,9 @@ def get_top_headlines(ticker: str) -> dict: if ticker in supported_terms(): if auth_header: - data = request(f"{BASE_URL}/getTopHeadlines/{ticker}", headers=auth_header) + data = request(f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}", headers=auth_header) else: - data = request(f"{BASE_URL}/getTopHeadlines/{ticker}") + data = request(f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}") if ( hasattr(data, "status") and data.status_code == 429 ): # If data request failed diff --git a/openbb_terminal/core/completer/choices.py b/openbb_terminal/core/completer/choices.py index eff17a6f1fd..178006cdca4 100644 --- a/openbb_terminal/core/completer/choices.py +++ b/openbb_terminal/core/completer/choices.py @@ -8,6 +8,7 @@ from unittest.mock import patch from openbb_terminal.helper_funcs import check_file_type_saved, check_positive from openbb_terminal.rich_config import get_ordered_list_sources +from openbb_terminal.core.session.current_system import get_current_system def __mock_parse_known_args_and_warn( @@ -211,7 +212,7 @@ def __patch_controller_functions(controller): ), ] - if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + if not get_current_system().DEBUG_MODE: rich.start() patched_function_list = [] for patcher in patcher_list: @@ -219,7 +220,7 @@ def __patch_controller_functions(controller): yield patched_function_list - if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + if not get_current_system().DEBUG_MODE: rich.stop() for patcher in patcher_list: patcher.stop() @@ -317,7 +318,7 @@ def build_controller_choice_map(controller) -> dict: argument_parser=argument_parser ) except Exception as exception: - if str(environ.get("DEBUG_MODE", "false")).lower() == "true": + if get_current_system().DEBUG_MODE: raise Exception( f"On command : `{command}`.\n{str(exception)}" ) from exception diff --git a/openbb_terminal/core/models/system_model.py b/openbb_terminal/core/models/system_model.py index 85d61e7b1bf..55ba1868877 100644 --- a/openbb_terminal/core/models/system_model.py +++ b/openbb_terminal/core/models/system_model.py @@ -54,6 +54,7 @@ class SystemModel(BaseModel): # Others TEST_MODE: bool = False DEBUG_MODE: bool = False + DEV_BACKEND: bool = False ENABLE_AUTHENTICATION: bool = True HEADLESS: bool = False diff --git a/openbb_terminal/core/plots/backend.py b/openbb_terminal/core/plots/backend.py index e8433e98f2e..f32828bdeaa 100644 --- a/openbb_terminal/core/plots/backend.py +++ b/openbb_terminal/core/plots/backend.py @@ -17,6 +17,8 @@ import plotly.graph_objects as go from packaging import version from reportlab.graphics import renderPDF +from openbb_terminal.core.session.constants import BackendEnvironment + # pylint: disable=C0415 try: from pywry import PyWry @@ -441,10 +443,7 @@ class Backend(PyWry): self.check_backend() endpoint = {True: "login", False: "logout"}[login] - if str(os.environ.get("DEBUG_MODE", "false")).lower() == "true": - json_url = f"https://my.openbb.dev/{endpoint}?pywry=true" - else: - json_url = f"https://my.openbb.co/{endpoint}?pywry=true" + json_url = f"{BackendEnvironment.HUB_URL}{endpoint}?pywry=true" outgoing = dict( json_data=dict(url=json_url), diff --git a/openbb_terminal/core/session/constants.py b/openbb_terminal/core/session/constants.py index 2d2fb992e0f..83b9b854aac 100644 --- a/openbb_terminal/core/session/constants.py +++ b/openbb_terminal/core/session/constants.py @@ -1,20 +1,16 @@ -from os import environ - -if str(environ.get("DEBUG_MODE", "false")).lower() == "true": - BASE_URL = "https://payments.openbb.dev/" - HUB_URL = "https://my.openbb.dev/" -else: +class HubEnvironment: + # BASE_URL = "http://127.0.0.1:8000/" BASE_URL = "https://payments.openbb.co/" HUB_URL = "https://my.openbb.co/" -# BASE_URL = "http://127.0.0.1:8000/" + def __new__(cls, *args, **kwargs): # pylint: disable=W0613 + """Create a singleton instance of the backend.""" + if not hasattr(cls, "instance"): + cls.instance = super().__new__(cls) # pylint: disable=E1120 + return cls.instance -REGISTER_URL = HUB_URL + "register" -SUPPORT_URL = HUB_URL + "app/terminal/support" -SOURCES_URL = HUB_URL + "app/terminal/data-sources" -KEYS_URL = HUB_URL + "app/terminal/api-keys" -COLORS_URL = HUB_URL + "app/terminal/theme" -CHARTS_TABLES_URL = HUB_URL + "app/terminal/theme/charts-tables" + +BackendEnvironment = HubEnvironment() DEFAULT_ROUTINES_URL = "https://openbb-cms.directus.app/items/Routines" diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index 1c112ed7ec2..52f0005c645 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -2,16 +2,16 @@ import datetime import json from typing import Any, Dict, List, Literal, Optional from uuid import UUID -from os import environ + import requests from jose import jwt from openbb_terminal.core.session.constants import ( - BASE_URL, CONNECTION_ERROR_MSG, CONNECTION_TIMEOUT_MSG, DEFAULT_ROUTINES_URL, TIMEOUT, + BackendEnvironment, ) from openbb_terminal.core.session.current_system import get_current_system from openbb_terminal.core.session.current_user import get_current_user @@ -19,7 +19,10 @@ from openbb_terminal.rich_config import console def create_session( - email: str, password: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + email: str, + password: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Create a session. @@ -72,7 +75,7 @@ def check_token_expiration(token: str): def create_session_from_token( - token: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + token: str, base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT ): """Create a session from token. @@ -109,7 +112,10 @@ def create_session_from_token( def delete_session( - auth_header: str, token: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + auth_header: str, + token: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Delete the session. @@ -191,7 +197,7 @@ def get_session(email: str, password: str) -> dict: dict The session info. """ - response = create_session(email, password) + response = create_session(email, password, base_url=BackendEnvironment.BASE_URL) if response is None: return {} return process_session_response(response) @@ -210,14 +216,14 @@ def get_session_from_token(token: str) -> dict: dict The session info. """ - response = create_session_from_token(token) + response = create_session_from_token(token, base_url=BackendEnvironment.BASE_URL) if response is None: return {} return process_session_response(response) def fetch_user_configs( - session: dict, base_url: str = BASE_URL, timeout: int = TIMEOUT + session: dict, base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT ) -> Optional[requests.Response]: """Fetch user configurations. @@ -259,7 +265,10 @@ def fetch_user_configs( def clear_user_configs( - config: str, auth_header: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + config: str, + auth_header: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Clear user configurations to the server. @@ -308,7 +317,7 @@ def upload_user_field( key: str, value: Any, auth_header: str, - base_url: str = BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, silent: bool = False, ) -> Optional[requests.Response]: @@ -366,7 +375,7 @@ def upload_config( value: str, type_: Literal["settings", "terminal_style"], auth_header: str, - base_url: str = BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Patch user configurations to the server. @@ -430,7 +439,7 @@ def upload_routine( override: bool = False, tags: str = "", public: bool = False, - base_url: str = BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Send a routine to the server. @@ -468,7 +477,6 @@ def upload_routine( "version": get_current_system().VERSION, "public": public, } - try: response = requests.post( headers={"Authorization": auth_header}, @@ -478,17 +486,20 @@ def upload_routine( ) if response.status_code == 200: username = get_current_user().profile.username - console.print("[green]Successfully uploaded your routine.[/green]") + console.print("[green]Successfully uploaded your routine.[/]") + + run_env = BackendEnvironment.HUB_URL.rstrip("/") - if str(environ.get("DEBUG_MODE", "false")).lower() == "true": - run_env = "dev" - else: - run_env = "co" - if public: - console.print(f"\n[yellow]Share or edit it at https://my.openbb.{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + console.print( + f"\n[yellow]Share or edit it at {run_env}/u/{username}/routine/{name.replace(' ', '-')}[/]" + ) else: - console.print(f"\n[yellow]Edit it at https://my.openbb.{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/yellow]") + console.print(f"\n[yellow]Go to {run_env} to edit this script,[/]") + console.print( + f"[yellow]or even make it public so you can access it at " + f"{run_env}/u/{username}/routine/{name.replace(' ', '-')}[/]" + ) elif response.status_code != 409: # 409: routine already exists console.print( "[red]" + response.json().get("detail", "Unknown error.") + "[/red]" @@ -508,7 +519,7 @@ def upload_routine( def download_routine( auth_header: str, uuid: UUID, - base_url=BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Download a routine from the server. @@ -554,7 +565,7 @@ def download_routine( def delete_routine( auth_header: str, uuid: UUID, - base_url=BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Delete a routine from the server. @@ -604,7 +615,7 @@ def list_routines( fields: Optional[List[str]] = None, page: int = 1, size: int = 10, - base_url=BASE_URL, + base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, silent: bool = False, ) -> Optional[requests.Response]: @@ -695,7 +706,10 @@ def get_default_routines( def generate_personal_access_token( - auth_header: str, base_url: str = BASE_URL, timeout: int = TIMEOUT, days: int = 30 + auth_header: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, + days: int = 30, ) -> Optional[requests.Response]: """ Generate an OpenBB Personal Access Token. @@ -744,7 +758,9 @@ def generate_personal_access_token( def get_personal_access_token( - auth_header: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + auth_header: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """ Show the user's OpenBB Personal Access Token. @@ -789,7 +805,9 @@ def get_personal_access_token( def revoke_personal_access_token( - auth_header: str, base_url: str = BASE_URL, timeout: int = TIMEOUT + auth_header: str, + base_url: str = BackendEnvironment.BASE_URL, + timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """ Delete the user's OpenBB Personal Access Token. diff --git a/openbb_terminal/core/session/routines_handler.py b/openbb_terminal/core/session/routines_handler.py index bef93b1e747..56f185aaf2d 100644 --- a/openbb_terminal/core/session/routines_handler.py +++ b/openbb_terminal/core/session/routines_handler.py @@ -51,6 +51,7 @@ def download_routines(auth_header: str, silent: bool = False) -> list: fields=["name", "script"], page=1, size=100, + base_url=Hub.BackendEnvironment.BASE_URL, silent=silent, ) if response and response.status_code == 200: diff --git a/openbb_terminal/core/session/session_controller.py b/openbb_terminal/core/session/session_controller.py index 4069106a971..6d26fb29784 100644 --- a/openbb_terminal/core/session/session_controller.py +++ b/openbb_terminal/core/session/session_controller.py @@ -5,11 +5,11 @@ from prompt_toolkit import PromptSession import openbb_terminal.core.session.local_model as Local from openbb_terminal.core.config.paths import PACKAGE_DIRECTORY from openbb_terminal.core.plots.backend import plots_backend -from openbb_terminal.core.session.constants import ( - REGISTER_URL, - SUPPORT_URL, +from openbb_terminal.core.session.constants import BackendEnvironment +from openbb_terminal.core.session.current_system import ( + get_current_system, + set_system_variable, ) -from openbb_terminal.core.session.current_system import get_current_system from openbb_terminal.core.session.session_model import ( LoginStatus, create_session, @@ -24,8 +24,12 @@ def display_welcome_message(links: bool = True) -> None: with open(PACKAGE_DIRECTORY / "core" / "session" / "banner.txt") as f: console.print(f"[menu]{f.read()}[/menu]\n") if links: - console.print(f"Register : [cmds]{REGISTER_URL}[/cmds]") - console.print(f"Support : [cmds]{SUPPORT_URL}[/cmds]") + console.print( + f"Register : [cmds]{BackendEnvironment.HUB_URL + 'register'}[/cmds]" + ) + console.print( + f"Support : [cmds]{BackendEnvironment.HUB_URL + 'app/terminal/support'}[/cmds]" + ) def get_user_input() -> Tuple[str, str, bool]: @@ -135,13 +139,15 @@ def prompt_cli(welcome: bool = True): # pylint: disable=inconsistent-return-statements -def launch_terminal(debug: bool = False, queue: Optional[List[str]] = None): +def launch_terminal( + debug: bool = False, dev: bool = False, queue: Optional[List[str]] = None +): """Launch terminal""" # pylint: disable=import-outside-toplevel from openbb_terminal import terminal_controller if queue: - return terminal_controller.main(debug, queue, module="") + return terminal_controller.main(debug, dev, queue, module="") terminal_controller.parse_args_and_run() @@ -170,8 +176,13 @@ def main( welcome: bool = True, prompt: bool = True, queue: Optional[List[str]] = None, + dev: bool = False, ): """Main function""" + if dev: + set_system_variable("DEV_BACKEND", True) + BackendEnvironment.BASE_URL = "https://payments.openbb.dev/" + BackendEnvironment.HUB_URL = "https://my.openbb.dev/" local_session = Local.get_session() if session is None else session diff --git a/openbb_terminal/core/session/session_model.py b/openbb_terminal/core/session/session_model.py index a0e9732e499..5140932fe8e 100644 --- a/openbb_terminal/core/session/session_model.py +++ b/openbb_terminal/core/session/session_model.py @@ -93,7 +93,7 @@ def login(session: Dict, remember: bool = False) -> LoginStatus: preferences=get_current_user().preferences, sources=SourcesModel(), ) - response = Hub.fetch_user_configs(session) + response = Hub.fetch_user_configs(session, Hub.BackendEnvironment.BASE_URL) if response is not None: if response.status_code == 200: configs = json.loads(response.content) @@ -159,6 +159,7 @@ def update_backend_sources(auth_header, configs, silent: bool = True): key="features_sources", value=updated_sources, auth_header=auth_header, + base_url=Hub.BackendEnvironment.BASE_URL, silent=silent, ) except Exception: @@ -190,7 +191,7 @@ def logout( success = True - r = Hub.delete_session(auth_header, token) + r = Hub.delete_session(auth_header, token, base_url=Hub.BackendEnvironment.BASE_URL) if not r or r.status_code != 200: success = False diff --git a/openbb_terminal/keys_controller.py b/openbb_terminal/keys_controller.py index 3a522f68b64..6c2ccd5f398 100644 --- a/openbb_terminal/keys_controller.py +++ b/openbb_terminal/keys_controller.py @@ -8,7 +8,7 @@ import logging from typing import Callable, Dict, List, Optional from openbb_terminal import keys_model, keys_view -from openbb_terminal.core.session.constants import KEYS_URL +from openbb_terminal.core.session.constants import BackendEnvironment from openbb_terminal.core.session.current_user import get_current_user, is_local from openbb_terminal.core.session.env_handler import get_reading_order from openbb_terminal.custom_prompt_toolkit import NestedCompleter @@ -75,7 +75,7 @@ class KeysController(BaseController): # pylint: disable=too-many-public-methods """ reading_order = get_reading_order() hierarchy = "\n ".join(list(map(str, reversed(reading_order)))) - return hierarchy if is_local() else f"{KEYS_URL}\n {hierarchy}" + return hierarchy if is_local() else f"{BackendEnvironment.HUB_URL + 'app/terminal/api-keys'}\n {hierarchy}" def print_help(self, update_status: bool = True, reevaluate: bool = True): """Print help""" diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index e5849a019f6..69c1710e32b 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -1091,6 +1091,7 @@ class BaseController(metaclass=ABCMeta): "routine": routine, "tags": SESSION_RECORDED_TAGS, "public": SESSION_RECORDED_PUBLIC, + "base_url": Hub.BackendEnvironment.BASE_URL, } response = Hub.upload_routine(**kwargs) # type: ignore if response is not None and response.status_code == 409: diff --git a/openbb_terminal/portfolio/portfolio_engine.py b/openbb_terminal/portfolio/portfolio_engine.py index 22adcd191e9..ce931d77d07 100644 --- a/openbb_terminal/portfolio/portfolio_engine.py +++ b/openbb_terminal/portfolio/portfolio_engine.py @@ -21,6 +21,7 @@ from openbb_terminal.portfolio.portfolio_helper import ( from openbb_terminal.rich_config import console from openbb_terminal.stocks.fundamental_analysis.yahoo_finance_model import get_splits from openbb_terminal.terminal_helper import suppress_stdout +from openbb_terminal.core.session.current_system import get_current_system # pylint: disable=E1136,W0201,R0902,C0302 # pylint: disable=unsupported-assignment-operation,redefined-outer-name @@ -196,7 +197,7 @@ class PortfolioEngine: # Load transactions from file if path.endswith(".xlsx"): - if str(environ.get("DEBUG_MODE", "false")).lower() != "true": + if not get_current_system().DEBUG_MODE: warnings.filterwarnings( "ignore", category=UserWarning, module="openpyxl" ) diff --git a/openbb_terminal/settings_controller.py b/openbb_terminal/settings_controller.py index 4d0b31e6007..4ba909c0021 100644 --- a/openbb_terminal/settings_controller.py +++ b/openbb_terminal/settings_controller.py @@ -21,7 +21,7 @@ from openbb_terminal.core.config.paths import ( SETTINGS_ENV_FILE, STYLES_DIRECTORY_REPO, ) -from openbb_terminal.core.session.constants import CHARTS_TABLES_URL, COLORS_URL +from openbb_terminal.core.session.constants import BackendEnvironment from openbb_terminal.core.session.current_user import ( get_current_user, is_local, @@ -231,7 +231,7 @@ class SettingsController(BaseController): " Then, place the downloaded file 'openbb_config.richstyle.json'" f" inside {get_current_user().preferences.USER_STYLES_DIRECTORY} or " f"{STYLES_DIRECTORY_REPO}. If you have a hub account you can change colors " - f"here {COLORS_URL}.", + f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme'}.", ) if other_args and "-" not in other_args[0][0]: other_args.insert(0, "-s") @@ -246,6 +246,7 @@ class SettingsController(BaseController): value=ns_parser.style, type_="settings", auth_header=get_current_user().profile.get_auth_header(), + base_url=BackendEnvironment.HUB_URL, ) console.print("") console.print("Colors updated.") @@ -266,7 +267,7 @@ class SettingsController(BaseController): dest="style", choices=["dark", "light"], help="Choose chart style. If you have a hub account you can change theme " - f"here {CHARTS_TABLES_URL}.", + f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme/charts-tables'}.", required="-h" not in other_args and "--help" not in other_args, ) if other_args and "-" not in other_args[0][0]: @@ -282,6 +283,7 @@ class SettingsController(BaseController): value=ns_parser.style, type_="terminal_style", auth_header=get_current_user().profile.get_auth_header(), + base_url=BackendEnvironment.HUB_URL, ) console.print("") theme.apply_style(ns_parser.style) @@ -303,7 +305,7 @@ class SettingsController(BaseController): dest="style", choices=["dark", "light"], help="Choose table style. If you have a hub account you can change theme " - f"here {CHARTS_TABLES_URL}.", + f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme/charts-tables'}.", required="-h" not in other_args and "--help" not in other_args, ) if other_args and "-" not in other_args[0][0]: @@ -319,6 +321,7 @@ class SettingsController(BaseController): value=ns_parser.style, type_="terminal_style", auth_header=get_current_user().profile.get_auth_header(), + base_url=BackendEnvironment.HUB_URL, ) console.print("") console.print("Table theme updated.\n") diff --git a/openbb_terminal/sources_controller.py b/openbb_terminal/sources_controller.py index eebedbe7904..d6483057bbf 100644 --- a/openbb_terminal/sources_controller.py +++ b/openbb_terminal/sources_controller.py @@ -8,7 +8,7 @@ import os from pathlib import Path from typing import List, Optional -from openbb_terminal.core.session.constants import SOURCES_URL +from openbb_terminal.core.session.constants import BackendEnvironment # IMPORTATION THIRDPARTY # IMPORTATION INTERNAL @@ -54,7 +54,7 @@ class SourcesController(BaseController): if Path(sources_file).exists() and os.stat(sources_file).st_size > 0: self.source = sources_file else: - self.source = SOURCES_URL + self.source = BackendEnvironment.HUB_URL + "app/terminal/data-sources" def parse_input(self, an_input: str) -> List: """Parse controller input @@ -176,6 +176,7 @@ class SourcesController(BaseController): key="features_sources", value=choices, auth_header=get_current_user().profile.get_auth_header(), + base_url=BackendEnvironment.BASE_URL, ) console.print("") console.print( diff --git a/openbb_terminal/terminal_controller.py b/openbb_terminal/terminal_controller.py index fd791f55612..4afab50b1f3 100644 --- a/openbb_terminal/terminal_controller.py +++ b/openbb_terminal/terminal_controller.py @@ -33,7 +33,7 @@ from openbb_terminal.core.config.paths import ( REPOSITORY_DIRECTORY, SETTINGS_ENV_FILE, ) -from openbb_terminal.core.session.constants import SCRIPT_TAGS +from openbb_terminal.core.session import constants from openbb_terminal.core.log.generation.custom_logger import log_terminal from openbb_terminal.core.session import session_controller from openbb_terminal.core.session.current_system import set_system_variable @@ -197,9 +197,9 @@ class TerminalController(BaseController): "-p": "--public", "--local": None, "-l": "--local", - "--tag1": {c: None for c in SCRIPT_TAGS}, - "--tag2": {c: None for c in SCRIPT_TAGS}, - "--tag3": {c: None for c in SCRIPT_TAGS}, + "--tag1": {c: None for c in constants.SCRIPT_TAGS}, + "--tag2": {c: None for c in constants.SCRIPT_TAGS}, + "--tag3": {c: None for c in constants.SCRIPT_TAGS}, } self.completer = NestedCompleter.from_nested_dict(choices) @@ -1100,6 +1100,7 @@ def run_routine(file: str, routines_args=Optional[str]): def main( debug: bool, + dev: bool, path_list: List[str], routines_args: Optional[List[str]] = None, **kwargs, @@ -1110,6 +1111,8 @@ def main( ---------- debug : bool Whether to run the terminal in debug mode + dev: + Points backend towards development environment instead of production test : bool Whether to run the terminal in integrated test mode filtert : str @@ -1129,6 +1132,11 @@ def main( if debug: set_system_variable("DEBUG_MODE", True) + if dev: + set_system_variable("DEV_BACKEND", True) + constants.BackendEnvironment.BASE_URL = "https://payments.openbb.dev/" + constants.BackendEnvironment.HUB_URL = "https://my.openbb.dev/" + cfg.start_plot_backend() if isinstance(path_list, list) and path_list[0].endswith(".openbb"): @@ -1156,6 +1164,13 @@ def parse_args_and_run(): default=False, help="Runs the terminal in debug mode.", ) + parser.add_argument( + "--dev", + dest="dev", + action="store_true", + default=False, + help="Points backend towards development environment instead of production", + ) parser.add_argument( "--file", help="The path or .openbb file to run.", @@ -1227,6 +1242,7 @@ def parse_args_and_run(): main( ns_parser.debug, + ns_parser.dev, ns_parser.path, ns_parser.routine_args, module=ns_parser.module, diff --git a/openbb_terminal/terminal_helper.py b/openbb_terminal/terminal_helper.py index 81f3ff7e33e..63458b34186 100644 --- a/openbb_terminal/terminal_helper.py +++ b/openbb_terminal/terminal_helper.py @@ -23,7 +23,7 @@ from openbb_terminal import thought_of_the_day as thought from openbb_terminal.base_helpers import load_env_files from openbb_terminal.core.config.paths import HIST_FILE_PATH, SETTINGS_ENV_FILE from openbb_terminal.core.plots.backend import plots_backend -from openbb_terminal.core.session.constants import REGISTER_URL +from openbb_terminal.core.session.constants import BackendEnvironment from openbb_terminal.core.session.current_system import get_current_system from openbb_terminal.core.session.current_user import ( get_current_user, @@ -257,7 +257,8 @@ def print_guest_block_msg(): console.print( "[info]You are currently logged as a guest.[/info]\n" "[info]Login to use this feature.[/info]\n\n" - f"[info]If you don't have an account, you can create one here: [/info][cmds]{REGISTER_URL}\n[/cmds]" + "[info]If you don't have an account, you can create one here: [/info]" + f"[cmds]{BackendEnvironment.HUB_URL + 'register'}\n[/cmds]" ) @@ -369,6 +370,7 @@ def reset(queue: Optional[List[str]] = None): plots_backend().close(reset=True) load_env_files() debug = get_current_system().DEBUG_MODE + dev = get_current_system().DEV_BACKEND try: # save the current user @@ -399,7 +401,7 @@ def reset(queue: Optional[List[str]] = None): if is_local(): from openbb_terminal.terminal_controller import main - main(debug, queue_list, module="") # type: ignore + main(debug, dev, queue_list, module="") # type: ignore else: from openbb_terminal.core.session import session_controller diff --git a/terminal.py b/terminal.py index dd0977a5f62..f9d8d8e5248 100644 --- a/terminal.py +++ b/terminal.py @@ -34,8 +34,9 @@ def main(): and ("--login" in sys.argv[1:] or is_installer()) and sys.stdin.isatty() ) + dev = "--dev" in sys.argv[1:] - session_controller.main(prompt=prompt_login) + session_controller.main(prompt=prompt_login, dev=dev) if __name__ == "__main__": diff --git a/tests/openbb_terminal/session/test_hub_model.py b/tests/openbb_terminal/session/test_hub_model.py index 25f620deef9..489ccae660f 100644 --- a/tests/openbb_terminal/session/test_hub_model.py +++ b/tests/openbb_terminal/session/test_hub_model.py @@ -46,7 +46,7 @@ def test_create_session_success(email, password): assert response.json() == TEST_RESPONSE mock_post.assert_called_once_with( - url=hub_model.BASE_URL + "login", + url=hub_model.BackendEnvironment.BASE_URL + "login", json={"email": email, "password": password, "remember": True}, timeout=hub_model.TIMEOUT, ) @@ -113,7 +113,7 @@ def test_create_session_from_token_success(mocker, token): assert response.json() == TEST_RESPONSE mock_post.assert_called_once_with( - url=hub_model.BASE_URL + "sdk/login", + url=hub_model.BackendEnvironment.BASE_URL + "sdk/login", json={"token": token}, timeout=hub_model.TIMEOUT, ) @@ -151,7 +151,7 @@ def test_delete_session_success(auth_header, token): assert response.status_code == 200 mock_post.assert_called_once_with( - url=hub_model.BASE_URL + "logout", + url=hub_model.BackendEnvironment.BASE_URL + "logout", headers={"Authorization": "Bearer test_token"}, json={"token": "test_token"}, timeout=hub_model.TIMEOUT, @@ -336,7 +336,7 @@ def test_fetch_user_configs_success(token_type, access_token): assert result == mock_response requests_get_mock.assert_called_once() _, kwargs = requests_get_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == { "Authorization": f"{token_type.title()} {access_token}" } @@ -352,7 +352,7 @@ def test_fetch_user_configs_failure(): result = hub_model.fetch_user_configs(session) assert isinstance(result, requests.Response) get_mock.assert_called_once_with( - url=hub_model.BASE_URL + "terminal/user", + url=hub_model.BackendEnvironment.BASE_URL + "terminal/user", headers={"Authorization": "Bearer abc123"}, timeout=hub_model.TIMEOUT, ) @@ -366,7 +366,7 @@ def test_fetch_user_configs_connection_error(): result = hub_model.fetch_user_configs(session) assert result is None get_mock.assert_called_once_with( - url=hub_model.BASE_URL + "terminal/user", + url=hub_model.BackendEnvironment.BASE_URL + "terminal/user", headers={"Authorization": "Bearer abc123"}, timeout=hub_model.TIMEOUT, ) @@ -378,7 +378,7 @@ def test_fetch_user_configs_timeout(): result = hub_model.fetch_user_configs(session) assert result is None get_mock.assert_called_once_with( - url=hub_model.BASE_URL + "terminal/user", + url=hub_model.BackendEnvironment.BASE_URL + "terminal/user", headers={"Authorization": "Bearer abc123"}, timeout=hub_model.TIMEOUT, ) @@ -390,7 +390,7 @@ def test_fetch_user_configs_exception(): result = hub_model.fetch_user_configs(session) assert result is None get_mock.assert_called_once_with( - url=hub_model.BASE_URL + "terminal/user", + url=hub_model.BackendEnvironment.BASE_URL + "terminal/user", headers={"Authorization": "Bearer abc123"}, timeout=hub_model.TIMEOUT, ) @@ -415,7 +415,7 @@ def test_upload_config_success(key, value, type_, auth_header): assert result.status_code == mock_response.status_code requests_patch_mock.assert_called_once() _, kwargs = requests_patch_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == {"Authorization": f"{auth_header}"} assert kwargs["json"] == {"key": f"features_{type_}.{key}", "value": value} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -434,7 +434,7 @@ def test_upload_config_failure(): assert result.status_code == mock_response.status_code requests_patch_mock.assert_called_once() _, kwargs = requests_patch_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"key": "features_settings.key", "value": "value"} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -451,7 +451,7 @@ def test_upload_config_connection_error(): assert result is None requests_patch_mock.assert_called_once() _, kwargs = requests_patch_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"key": "features_settings.key", "value": "value"} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -468,7 +468,7 @@ def test_upload_config_timeout(): assert result is None requests_patch_mock.assert_called_once() _, kwargs = requests_patch_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"key": "features_settings.key", "value": "value"} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -485,7 +485,7 @@ def test_upload_config_exception(): assert result is None requests_patch_mock.assert_called_once() _, kwargs = requests_patch_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "terminal/user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "terminal/user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"key": "features_settings.key", "value": "value"} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -504,7 +504,7 @@ def test_clear_user_configs_success(): assert result.status_code == mock_response.status_code requests_put_mock.assert_called_once() _, kwargs = requests_put_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"config": {}} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -523,7 +523,7 @@ def test_clear_user_configs_failure(): assert result.status_code == mock_response.status_code requests_put_mock.assert_called_once() _, kwargs = requests_put_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"config": {}} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -539,7 +539,7 @@ def test_clear_user_configs_timeout(): assert result is None requests_put_mock.assert_called_once() _, kwargs = requests_put_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"config": {}} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -555,7 +555,7 @@ def test_clear_user_configs_connection_error(): assert result is None requests_put_mock.assert_called_once() _, kwargs = requests_put_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"config": {}} assert kwargs["timeout"] == hub_model.TIMEOUT @@ -570,7 +570,7 @@ def test_clear_user_configs_exception(): assert result is None requests_put_mock.assert_called_once() _, kwargs = requests_put_mock.call_args - assert kwargs["url"] == hub_model.BASE_URL + "user" + assert kwargs["url"] == hub_model.BackendEnvironment.BASE_URL + "user" assert kwargs["headers"] == {"Authorization": "auth_header"} assert kwargs["json"] == {"config": {}} assert kwargs["timeout"] == hub_model.TIMEOUT From 5ddeb8f35e01fdb90ace17299975111a850082bc Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Mon, 14 Aug 2023 05:20:25 -0500 Subject: [PATCH 21/28] Fix regex (#5320) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * check that routine title is valid * more updates * small fixes * override local routine * more improvements to routine logic * --debug runs .dev * few more updates * small fix * rename BASE_URL from ultima to ULTIMA_BASE_URL * use debug from dataclasses instead of env since env doesn't get updated * create --dev flag that can point to .dev backend * merge conflits * few changes, made it actually work 🤣 * fix regex --------- Co-authored-by: tehcoderer --- openbb_terminal/parent_classes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index 69c1710e32b..d0bb293902b 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -981,7 +981,8 @@ class BaseController(metaclass=ABCMeta): # Check if title has a valid format title = " ".join(ns_parser.name) if ns_parser.name else "" - pattern = re.compile(r"^[a-zA-Z0-9\s]+(?:[-a-zA-Z0-9\s]+)*$") + # To this day, the reason why /^[a-zA-Z0-9\s]+$/ does not work is unknown + pattern = re.compile(r"^[a-zA-Z0-9\s]+(?:[a-zA-Z0-9\s]+)*$") if not pattern.match(title): console.print(f"[red]The title '{title}' has invalid format. Please use only digits, characters and whitespaces.[/red]") return From 2c44cae0e9bf002377fd1d9bf987da5b3dc006b8 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 14 Aug 2023 09:57:41 -0400 Subject: [PATCH 22/28] add back --url auto complete --- openbb_terminal/account/account_controller.py | 4 +- .../common/ultima_newsmonitor_model.py | 4 +- openbb_terminal/core/completer/choices.py | 3 +- openbb_terminal/keys_controller.py | 6 +- openbb_terminal/parent_classes.py | 92 +++++++++++++------ openbb_terminal/portfolio/portfolio_engine.py | 3 +- openbb_terminal/terminal_controller.py | 11 ++- 7 files changed, 83 insertions(+), 40 deletions(-) diff --git a/openbb_terminal/account/account_controller.py b/openbb_terminal/account/account_controller.py index c9f233b0600..8db4d421c25 100644 --- a/openbb_terminal/account/account_controller.py +++ b/openbb_terminal/account/account_controller.py @@ -414,7 +414,7 @@ class AccountController(BaseController): response = Hub.download_routine( auth_header=get_current_user().profile.get_auth_header(), uuid=self.REMOTE_CHOICES[name], - base_url=Hub.BackendEnvironment.BASE_URL + base_url=Hub.BackendEnvironment.BASE_URL, ) if response and response.status_code == 200: data = [response.json(), "personal"] @@ -502,7 +502,7 @@ class AccountController(BaseController): response = Hub.delete_routine( auth_header=get_current_user().profile.get_auth_header(), uuid=self.REMOTE_CHOICES[name], - base_url=Hub.BackendEnvironment.BASE_URL + base_url=Hub.BackendEnvironment.BASE_URL, ) if ( response diff --git a/openbb_terminal/common/ultima_newsmonitor_model.py b/openbb_terminal/common/ultima_newsmonitor_model.py index e06226b7b10..656ba75c53f 100644 --- a/openbb_terminal/common/ultima_newsmonitor_model.py +++ b/openbb_terminal/common/ultima_newsmonitor_model.py @@ -213,7 +213,9 @@ def get_top_headlines(ticker: str) -> dict: if ticker in supported_terms(): if auth_header: - data = request(f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}", headers=auth_header) + data = request( + f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}", headers=auth_header + ) else: data = request(f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}") if ( diff --git a/openbb_terminal/core/completer/choices.py b/openbb_terminal/core/completer/choices.py index 178006cdca4..fabfb46c384 100644 --- a/openbb_terminal/core/completer/choices.py +++ b/openbb_terminal/core/completer/choices.py @@ -1,14 +1,13 @@ from argparse import ArgumentParser from contextlib import contextmanager from inspect import isfunction, unwrap -from os import environ from types import MethodType from typing import Callable, List from unittest.mock import patch +from openbb_terminal.core.session.current_system import get_current_system from openbb_terminal.helper_funcs import check_file_type_saved, check_positive from openbb_terminal.rich_config import get_ordered_list_sources -from openbb_terminal.core.session.current_system import get_current_system def __mock_parse_known_args_and_warn( diff --git a/openbb_terminal/keys_controller.py b/openbb_terminal/keys_controller.py index 6c2ccd5f398..69c94595a53 100644 --- a/openbb_terminal/keys_controller.py +++ b/openbb_terminal/keys_controller.py @@ -75,7 +75,11 @@ class KeysController(BaseController): # pylint: disable=too-many-public-methods """ reading_order = get_reading_order() hierarchy = "\n ".join(list(map(str, reversed(reading_order)))) - return hierarchy if is_local() else f"{BackendEnvironment.HUB_URL + 'app/terminal/api-keys'}\n {hierarchy}" + return ( + hierarchy + if is_local() + else f"{BackendEnvironment.HUB_URL + 'app/terminal/api-keys'}\n {hierarchy}" + ) def print_help(self, update_status: bool = True, reevaluate: bool = True): """Print help""" diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index d0bb293902b..e5ec6945bc9 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -5,7 +5,6 @@ __docformat__ = "numpy" # IMPORTS STANDARD import argparse -import itertools import difflib import json import logging @@ -27,12 +26,11 @@ from rich.markdown import Markdown import openbb_terminal.core.session.local_model as Local from openbb_terminal import config_terminal from openbb_terminal.account.show_prompt import get_show_prompt -from openbb_terminal.core.session.constants import SCRIPT_TAGS from openbb_terminal.core.completer.choices import build_controller_choice_map from openbb_terminal.core.config.paths import HIST_FILE_PATH from openbb_terminal.core.session import hub_model as Hub +from openbb_terminal.core.session.constants import SCRIPT_TAGS from openbb_terminal.core.session.current_user import get_current_user, is_local -from openbb_terminal.core.session.routines_handler import read_routine from openbb_terminal.cryptocurrency import cryptocurrency_helpers from openbb_terminal.custom_prompt_toolkit import NestedCompleter from openbb_terminal.decorators import log_start_end @@ -953,30 +951,55 @@ class BaseController(metaclass=ABCMeta): ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - if not ns_parser.name: - console.print("[red]Set a routine title by using the '-n' flag. E.g. 'record -n Morning routine'[/red]") + console.print( + "[red]Set a routine title by using the '-n' flag. E.g. 'record -n Morning routine'[/red]" + ) return - tag1 = " ".join(ns_parser.tag1) if isinstance(ns_parser.tag1, list) else ns_parser.tag1 + tag1 = ( + " ".join(ns_parser.tag1) + if isinstance(ns_parser.tag1, list) + else ns_parser.tag1 + ) if tag1 and tag1 not in SCRIPT_TAGS: - console.print(f"[red]The parameter 'tag1' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + console.print( + f"[red]The parameter 'tag1' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]" + ) return - tag2 = " ".join(ns_parser.tag2) if isinstance(ns_parser.tag2, list) else ns_parser.tag2 + tag2 = ( + " ".join(ns_parser.tag2) + if isinstance(ns_parser.tag2, list) + else ns_parser.tag2 + ) if tag2 and tag2 not in SCRIPT_TAGS: - console.print(f"[red]The parameter 'tag2' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + console.print( + f"[red]The parameter 'tag2' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]" + ) return - tag3 = " ".join(ns_parser.tag3) if isinstance(ns_parser.tag3, list) else ns_parser.tag3 + tag3 = ( + " ".join(ns_parser.tag3) + if isinstance(ns_parser.tag3, list) + else ns_parser.tag3 + ) if tag3 and tag3 not in SCRIPT_TAGS: - console.print(f"[red]The parameter 'tag3' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]") + console.print( + f"[red]The parameter 'tag3' needs to be one of the following {', '.join(SCRIPT_TAGS)}[/red]" + ) return if is_local() and not ns_parser.local: - console.print("[red]Recording session to the OpenBB Hub is not supported in guest mode.[/red]") - console.print("\n[yellow]Sign to OpenBB Hub to register: http://openbb.co[/yellow]") - console.print("\n[yellow]Otherwise set the flag '-l' to save the file locally.[/yellow]") + console.print( + "[red]Recording session to the OpenBB Hub is not supported in guest mode.[/red]" + ) + console.print( + "\n[yellow]Sign to OpenBB Hub to register: http://openbb.co[/yellow]" + ) + console.print( + "\n[yellow]Otherwise set the flag '-l' to save the file locally.[/yellow]" + ) return # Check if title has a valid format @@ -984,7 +1007,9 @@ class BaseController(metaclass=ABCMeta): # To this day, the reason why /^[a-zA-Z0-9\s]+$/ does not work is unknown pattern = re.compile(r"^[a-zA-Z0-9\s]+(?:[a-zA-Z0-9\s]+)*$") if not pattern.match(title): - console.print(f"[red]The title '{title}' has invalid format. Please use only digits, characters and whitespaces.[/red]") + console.print( + f"[red]Title '{title}' has invalid format. Please use only digits, characters and whitespaces.[/]" + ) return global RECORD_SESSION @@ -997,15 +1022,23 @@ class BaseController(metaclass=ABCMeta): RECORD_SESSION = True RECORD_SESSION_LOCAL_ONLY = ns_parser.local SESSION_RECORDED_NAME = title - SESSION_RECORDED_DESCRIPTION = " ".join(ns_parser.description) if isinstance(ns_parser.description, list) else ns_parser.description + SESSION_RECORDED_DESCRIPTION = ( + " ".join(ns_parser.description) + if isinstance(ns_parser.description, list) + else ns_parser.description + ) SESSION_RECORDED_TAGS = tag1 if tag1 else "" - SESSION_RECORDED_TAGS += ',' + tag2 if tag2 else "" - SESSION_RECORDED_TAGS += ',' + tag3 if tag3 else "" + SESSION_RECORDED_TAGS += "," + tag2 if tag2 else "" + SESSION_RECORDED_TAGS += "," + tag3 if tag3 else "" SESSION_RECORDED_PUBLIC = ns_parser.public - console.print(f"[green]The routine '{title}' is successfully being recorded.[/green]") - console.print("\n[yellow]Remember to run 'stop' command when you are done!\n[/yellow]") + console.print( + f"[green]The routine '{title}' is successfully being recorded.[/green]" + ) + console.print( + "\n[yellow]Remember to run 'stop' command when you are done!\n[/yellow]" + ) @log_start_end(log=logger) def call_stop(self, _) -> None: @@ -1028,11 +1061,13 @@ class BaseController(metaclass=ABCMeta): # This works regardless of whether they are logged in or not if RECORD_SESSION_LOCAL_ONLY: # Whitespaces are replaced by underscores and an .openbb extension is added - title_for_local_storage = SESSION_RECORDED_NAME.replace(" ", "_") + ".openbb" + title_for_local_storage = ( + SESSION_RECORDED_NAME.replace(" ", "_") + ".openbb" + ) routine_file = os.path.join( current_user.preferences.USER_ROUTINES_DIRECTORY, - title_for_local_storage + title_for_local_storage, ) # If file already exists, add a timestamp to the name @@ -1043,18 +1078,21 @@ class BaseController(metaclass=ABCMeta): ) console.print("") while i.lower() not in ["y", "yes", "n", "no"]: - i = console.input( - "Select 'y' or 'n' to proceed: " - ) + i = console.input("Select 'y' or 'n' to proceed: ") console.print("") if i.lower() in ["n", "no"]: - new_name = datetime.now().strftime("%Y%m%d_%H%M%S_") + title_for_local_storage + new_name = ( + datetime.now().strftime("%Y%m%d_%H%M%S_") + + title_for_local_storage + ) routine_file = os.path.join( current_user.preferences.USER_ROUTINES_DIRECTORY, new_name, ) - console.print(f"[yellow]The routine name has been updated to '{new_name}'[/yellow]\n") + console.print( + f"[yellow]The routine name has been updated to '{new_name}'[/yellow]\n" + ) # Writing to file with open(routine_file, "w") as file1: diff --git a/openbb_terminal/portfolio/portfolio_engine.py b/openbb_terminal/portfolio/portfolio_engine.py index ce931d77d07..2c945b661d5 100644 --- a/openbb_terminal/portfolio/portfolio_engine.py +++ b/openbb_terminal/portfolio/portfolio_engine.py @@ -4,7 +4,6 @@ __docformat__ = "numpy" import datetime import logging import warnings -from os import environ from typing import Any, Dict import numpy as np @@ -12,6 +11,7 @@ import pandas as pd import yfinance as yf from tqdm import tqdm +from openbb_terminal.core.session.current_system import get_current_system from openbb_terminal.decorators import log_start_end from openbb_terminal.portfolio.allocation_model import get_allocation from openbb_terminal.portfolio.portfolio_helper import ( @@ -21,7 +21,6 @@ from openbb_terminal.portfolio.portfolio_helper import ( from openbb_terminal.rich_config import console from openbb_terminal.stocks.fundamental_analysis.yahoo_finance_model import get_splits from openbb_terminal.terminal_helper import suppress_stdout -from openbb_terminal.core.session.current_system import get_current_system # pylint: disable=E1136,W0201,R0902,C0302 # pylint: disable=unsupported-assignment-operation,redefined-outer-name diff --git a/openbb_terminal/terminal_controller.py b/openbb_terminal/terminal_controller.py index 4afab50b1f3..84453250a20 100644 --- a/openbb_terminal/terminal_controller.py +++ b/openbb_terminal/terminal_controller.py @@ -20,7 +20,6 @@ import certifi import pandas as pd import requests from prompt_toolkit import PromptSession -from openbb_terminal.custom_prompt_toolkit import NestedCompleter from prompt_toolkit.formatted_text import HTML from prompt_toolkit.styles import Style @@ -33,11 +32,11 @@ from openbb_terminal.core.config.paths import ( REPOSITORY_DIRECTORY, SETTINGS_ENV_FILE, ) -from openbb_terminal.core.session import constants from openbb_terminal.core.log.generation.custom_logger import log_terminal -from openbb_terminal.core.session import session_controller +from openbb_terminal.core.session import constants, session_controller from openbb_terminal.core.session.current_system import set_system_variable from openbb_terminal.core.session.current_user import get_current_user, set_preference +from openbb_terminal.custom_prompt_toolkit import NestedCompleter from openbb_terminal.helper_funcs import ( EXPORT_ONLY_RAW_DATA_ALLOWED, check_positive, @@ -180,12 +179,15 @@ class TerminalController(BaseController): } choices["exe"] = { - "--file": {filename: {} for filename in list(self.ROUTINE_FILES.keys())}, + "--file": { + filename: {} for filename in list(self.ROUTINE_FILES.keys()) + }, "-f": "--file", "--example": None, "-e": "--example", "--input": None, "-i": "--input", + "--url": None, } choices["record"] = { @@ -776,7 +778,6 @@ class TerminalController(BaseController): self.queue = self.queue[1:] - # pylint: disable=global-statement def terminal(jobs_cmds: Optional[List[str]] = None, test_mode=False): """Terminal Menu.""" From 99a5459dc0cd4c81b836d64a6a1573d899a45403 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 14 Aug 2023 10:03:41 -0400 Subject: [PATCH 23/28] mypy --- openbb_terminal/core/session/hub_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index 52f0005c645..8c711b10d07 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -543,7 +543,7 @@ def download_routine( try: response = requests.get( headers={"Authorization": auth_header}, - url=base_url + "terminal/script/" + uuid, + url=base_url + "terminal/script/" + uuid, # type: ignore timeout=timeout, ) if response.status_code == 404: @@ -589,7 +589,7 @@ def delete_routine( try: response = requests.delete( headers={"Authorization": auth_header}, - url=base_url + "terminal/script/" + uuid, + url=base_url + "terminal/script/" + uuid, # type: ignore timeout=timeout, ) if response.status_code == 200: From 889a986b072938231a8511d8f3c04932fefd003e Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 14 Aug 2023 10:47:29 -0400 Subject: [PATCH 24/28] pylint + test --- openbb_terminal/core/plots/backend.py | 2 +- tests/openbb_terminal/test_terminal_controller.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openbb_terminal/core/plots/backend.py b/openbb_terminal/core/plots/backend.py index f32828bdeaa..af6a29e2947 100644 --- a/openbb_terminal/core/plots/backend.py +++ b/openbb_terminal/core/plots/backend.py @@ -19,7 +19,7 @@ from reportlab.graphics import renderPDF from openbb_terminal.core.session.constants import BackendEnvironment -# pylint: disable=C0415 +# pylint: disable=C0411,C0412,C0415 try: from pywry import PyWry except ImportError as e: diff --git a/tests/openbb_terminal/test_terminal_controller.py b/tests/openbb_terminal/test_terminal_controller.py index 7abdbadde20..5ff5f757236 100644 --- a/tests/openbb_terminal/test_terminal_controller.py +++ b/tests/openbb_terminal/test_terminal_controller.py @@ -68,10 +68,10 @@ def no_suppress(): @pytest.mark.vcr(record_mode="none") @pytest.mark.record_stdout @pytest.mark.parametrize( - "debug, path", - [(True, None), (False, ["scripts/test_alt_covid.openbb"])], + "debug, dev, path", + [(True, False, None), (False, False, ["scripts/test_alt_covid.openbb"])], ) -def test_menu(mocker, debug, path): +def test_menu(mocker, debug, dev, path): mocker.patch(target="terminal_controller.terminal") mocker.patch(target="terminal_controller.suppress_stdout", side_effect=no_suppress) - terminal_controller.main(debug, path) + terminal_controller.main(debug, dev, path) From f4460fbf18eb369fa1b3ce083a3a41239f01e284 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 14 Aug 2023 11:40:39 -0400 Subject: [PATCH 25/28] tests --- .../econometrics/econometrics_controller.py | 1 + .../openbb_terminal/session/test_hub_model.py | 32 ++++++++++++++----- .../session/test_routines_handler.py | 4 +++ .../session/test_session_model.py | 17 +++++++--- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/openbb_terminal/econometrics/econometrics_controller.py b/openbb_terminal/econometrics/econometrics_controller.py index a429a7230ff..5229e030e5a 100644 --- a/openbb_terminal/econometrics/econometrics_controller.py +++ b/openbb_terminal/econometrics/econometrics_controller.py @@ -189,6 +189,7 @@ class EconometricsController(BaseController): "corr", "lag", "vif", + "panel", ]: choices[feature] = dict() diff --git a/tests/openbb_terminal/session/test_hub_model.py b/tests/openbb_terminal/session/test_hub_model.py index 489ccae660f..008325c9300 100644 --- a/tests/openbb_terminal/session/test_hub_model.py +++ b/tests/openbb_terminal/session/test_hub_model.py @@ -233,7 +233,9 @@ def test_get_session_success(): ) as create_session_mock: result = hub_model.get_session("email", "password") assert result == {"session": "info"} - create_session_mock.assert_called_once_with("email", "password") + create_session_mock.assert_called_once_with( + "email", "password", base_url="https://payments.openbb.co/" + ) def test_get_session_401(): @@ -246,7 +248,9 @@ def test_get_session_401(): ) as create_session_mock: result = hub_model.get_session("email", "password") assert result == {} - create_session_mock.assert_called_once_with("email", "password") + create_session_mock.assert_called_once_with( + "email", "password", base_url="https://payments.openbb.co/" + ) def test_get_session_403(): @@ -259,7 +263,9 @@ def test_get_session_403(): ) as create_session_mock: result = hub_model.get_session("email", "password") assert result == {} - create_session_mock.assert_called_once_with("email", "password") + create_session_mock.assert_called_once_with( + "email", "password", base_url="https://payments.openbb.co/" + ) def test_get_session_failed_to_request(): @@ -268,7 +274,9 @@ def test_get_session_failed_to_request(): ) as create_session_mock: result = hub_model.get_session("email", "password") assert result == {} - create_session_mock.assert_called_once_with("email", "password") + create_session_mock.assert_called_once_with( + "email", "password", base_url="https://payments.openbb.co/" + ) def test_get_session_from_token(): @@ -282,7 +290,9 @@ def test_get_session_from_token(): ) as create_session_mock: result = hub_model.get_session_from_token("token") assert result == {"session": "info"} - create_session_mock.assert_called_once_with("token") + create_session_mock.assert_called_once_with( + "token", base_url="https://payments.openbb.co/" + ) def test_get_session_from_token_401(): @@ -295,7 +305,9 @@ def test_get_session_from_token_401(): ) as create_session_mock: result = hub_model.get_session_from_token("token") assert result == {} - create_session_mock.assert_called_once_with("token") + create_session_mock.assert_called_once_with( + "token", base_url="https://payments.openbb.co/" + ) def test_get_session_from_token_403(): @@ -308,7 +320,9 @@ def test_get_session_from_token_403(): ) as create_session_mock: result = hub_model.get_session_from_token("token") assert result == {} - create_session_mock.assert_called_once_with("token") + create_session_mock.assert_called_once_with( + "token", base_url="https://payments.openbb.co/" + ) def test_get_session_from_token_failed_to_request(): @@ -318,7 +332,9 @@ def test_get_session_from_token_failed_to_request(): ) as create_session_mock: result = hub_model.get_session_from_token("token") assert result == {} - create_session_mock.assert_called_once_with("token") + create_session_mock.assert_called_once_with( + "token", base_url="https://payments.openbb.co/" + ) @pytest.mark.parametrize("token_type, access_token", [("TokenType", "AccessToken")]) diff --git a/tests/openbb_terminal/session/test_routines_handler.py b/tests/openbb_terminal/session/test_routines_handler.py index 566c275fd10..e62c0fc1b0e 100644 --- a/tests/openbb_terminal/session/test_routines_handler.py +++ b/tests/openbb_terminal/session/test_routines_handler.py @@ -234,6 +234,7 @@ def test_download_routine(mocker, test_user, silent=False): fields=["name", "script"], page=1, size=100, + base_url="https://payments.openbb.co/", silent=silent, ) @@ -272,6 +273,7 @@ def test_download_default_routine_exception(mocker, test_user, silent=False): fields=["name", "script"], page=1, size=100, + base_url="https://payments.openbb.co/", silent=silent, ) @@ -310,6 +312,7 @@ def test_download_personal_routine_exception(mocker, test_user, silent=False): fields=["name", "script"], page=1, size=100, + base_url="https://payments.openbb.co/", silent=silent, ) @@ -339,5 +342,6 @@ def test_download_default_and_personal_routine_exception( fields=["name", "script"], page=1, size=100, + base_url="https://payments.openbb.co/", silent=silent, ) diff --git a/tests/openbb_terminal/session/test_session_model.py b/tests/openbb_terminal/session/test_session_model.py index 25861d3c6bf..138c9af8a6f 100644 --- a/tests/openbb_terminal/session/test_session_model.py +++ b/tests/openbb_terminal/session/test_session_model.py @@ -75,7 +75,9 @@ def test_login_no_response(mocker): assert session_model.login(TEST_SESSION) == session_model.LoginStatus.NO_RESPONSE - mock_fetch_user_configs.assert_called_once_with(TEST_SESSION) + mock_fetch_user_configs.assert_called_once_with( + TEST_SESSION, "https://payments.openbb.co/" + ) mock_apply_configs.assert_not_called() mock_update_flair.assert_not_called() mock_get_updated_hub_sources.assert_not_called() @@ -96,7 +98,9 @@ def test_login_fail_response(mocker): assert session_model.login(TEST_SESSION) == session_model.LoginStatus.FAILED - mock_fetch_user_configs.assert_called_once_with(TEST_SESSION) + mock_fetch_user_configs.assert_called_once_with( + TEST_SESSION, "https://payments.openbb.co/" + ) mock_apply_configs.assert_not_called() mock_update_flair.assert_not_called() mock_get_updated_hub_sources.assert_not_called() @@ -119,7 +123,9 @@ def test_login_success_response(mocker): assert session_model.login(TEST_SESSION) == session_model.LoginStatus.SUCCESS - mock_fetch_user_configs.assert_called_once_with(TEST_SESSION) + mock_fetch_user_configs.assert_called_once_with( + TEST_SESSION, "https://payments.openbb.co/" + ) mock_apply_configs.assert_called_once() mock_update_flair.assert_called_once() @@ -142,10 +148,13 @@ def test_logout_user(mocker, guest): auth_header = "Bearer test_token" token = "test_token" + base_url = "https://payments.openbb.co/" session_model.logout(auth_header, token) if not guest: - mock_delete_session.assert_called_once_with(auth_header, token) + mock_delete_session.assert_called_once_with( + auth_header, token, base_url=base_url + ) assert mock_remove.call_args_list[0] == mocker.call(SESSION_FILE_PATH) assert mock_remove.call_args_list[1] == mocker.call(HIST_FILE_PATH) assert mock_remove.call_args_list[2] == mocker.call( From 2b2ccacbbe40cfba5f0373c622d67f23e65d0427 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 14 Aug 2023 11:52:14 -0400 Subject: [PATCH 26/28] more tests --- tests/openbb_terminal/account/test_account_controller.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/openbb_terminal/account/test_account_controller.py b/tests/openbb_terminal/account/test_account_controller.py index 6cbfb4edb3d..5dbbaa7ba5c 100644 --- a/tests/openbb_terminal/account/test_account_controller.py +++ b/tests/openbb_terminal/account/test_account_controller.py @@ -404,7 +404,10 @@ def test_call_list(mocker, test_user): controller.call_list(other_args=["--page", "1", "--size", "10"]) mock_list_routines.assert_called_once_with( - auth_header="Bearer 123", page=1, size=10 + auth_header="Bearer 123", + page=1, + size=10, + base_url="https://payments.openbb.co/", ) @@ -446,6 +449,7 @@ def test_call_upload(mocker, test_user): routine="do something", tags="stocks", public=False, + base_url="https://payments.openbb.co/", ) @@ -484,6 +488,7 @@ def test_call_download(mocker, test_user): mock_download_routine.assert_called_once_with( auth_header="Bearer 123", uuid="script1", + base_url="https://payments.openbb.co/", ) mock_save_routine.assert_called_once_with( file_name="script1.openbb", routine=["do something", "personal"] @@ -555,6 +560,7 @@ def test_call_generate(mocker, monkeypatch, test_user): mock_generate.assert_called_once_with( auth_header="Bearer 123", + base_url="https://payments.openbb.co/", days=30, ) From c6b0bfe6f2bc8aa94c9436a35a4d0244e3beed38 Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Tue, 15 Aug 2023 00:39:10 -0500 Subject: [PATCH 27/28] hotfix/simplify-regex (#5324) --- openbb_terminal/parent_classes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openbb_terminal/parent_classes.py b/openbb_terminal/parent_classes.py index e5ec6945bc9..11d31d2a52f 100644 --- a/openbb_terminal/parent_classes.py +++ b/openbb_terminal/parent_classes.py @@ -1004,8 +1004,7 @@ class BaseController(metaclass=ABCMeta): # Check if title has a valid format title = " ".join(ns_parser.name) if ns_parser.name else "" - # To this day, the reason why /^[a-zA-Z0-9\s]+$/ does not work is unknown - pattern = re.compile(r"^[a-zA-Z0-9\s]+(?:[a-zA-Z0-9\s]+)*$") + pattern = re.compile(r"^[a-zA-Z0-9\s]+$") if not pattern.match(title): console.print( f"[red]Title '{title}' has invalid format. Please use only digits, characters and whitespaces.[/]" From a2d0c571cd6a8cac36435a0dc275920a6a1de71b Mon Sep 17 00:00:00 2001 From: James Maslek Date: Tue, 15 Aug 2023 13:49:39 -0400 Subject: [PATCH 28/28] update changelog --- .../terminal/changelog/version3_2_1.mdx | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/website/content/terminal/changelog/version3_2_1.mdx b/website/content/terminal/changelog/version3_2_1.mdx index fc668a0aa27..bb270b77b77 100644 --- a/website/content/terminal/changelog/version3_2_1.mdx +++ b/website/content/terminal/changelog/version3_2_1.mdx @@ -1,7 +1,54 @@ --- title: Current - v3.2.1 version: "3.2.1" -date: 2023-08-07 +date: 2023-08-16 description: Current - v3.2.1 sidebar_position: 92 --- + +## What's new 🎉 + +We are super excited to launch community routines in the terminal! + +This is accompanied by our usual bug fix and general enhancements. + +## What's changed 🚀 +* hotfix/simplify-regex (#5324) @DidierRLopes +* Fix routines creation from the Terminal to Hub (#5312) @DidierRLopes +* Fix regex (#5320) @DidierRLopes +* Creates a "--dev" flag that points to dev backend for testing with hub (#5319) @DidierRLopes +* small fixy (#5318) @DidierRLopes +* few more updates (#5317) @DidierRLopes +* --debug points to dev env (#5316) @DidierRLopes +* Silly (#5313) @DidierRLopes +* hotfix/ `/stocks/fa/pt` show all price targets on hover (#5305) @tehcoderer +* hotfix/options-hist: Fixes `options/hist` to display date column when raw is True (#5304) @deeleeramone +* Allow the exe command to run URLs (#5295) @colin99d +* Feature/news sentiment (#5274) @Sai-132 +* hotfix/ conflict docstrings (#5293) @tehcoderer +* hotfix / forecast, qa/hist (#5290) @tehcoderer +* Fixed the get routines to meet the new backend standard (#5271) @colin99d +* Actually fix databento this time (#5287) @jmaslek +* add `--india` flag to `stocks/load` (#5281) @the-praxs +* Feature/options_views: Add a Variety of Views/Charts to Extend the OptionsChains Class (#5222) @deeleeramone +* hotfix/economy-controller-sort-filter: Fwd P/E regex fix (#5273) @deeleeramone +* Update all_api_keys.json (#5277) @DidierRLopes +* Move hub api keys ts (#5267) @montezdesousa +* Hotfix `economy/overview` rates displaying as dates (#5269) @tehcoderer +* Adds details/image for installing C++ Build Tools (#5268) @deeleeramone +* hotfix/gdp-units - better GDP units (#5262) @deeleeramone +* Hotfix/ locking when deploying streamlit app (#5261) @tehcoderer +* Fix issue where incorrect key for biztoc prints exception (#5257) @jmaslek +* Check token expiration before request (#5255) @montezdesousa +* hotfix/economy-report-duplicate-table: fixes duplicate tables. (#5252) @deeleeramone +* hotfix/docs-sdk-basics-headTitle: fix headTitle (#5253) @deeleeramone +* Fix/reports (#5251) @jmaslek +* Fix/reports (#5250) @jmaslek +* Release/3.2.0 (#5243) @jmaslek + +We are proud of our community contributors and staunch supporters of open-source ecosystems. +Help us promote our community by tagging `@openbb_finance` on Twitter with a link to your pull request, +and join our Discord server to chat about your contribution! We want to hear about your experience! + +### Links 🦋 +[Website](https://openbb.co/), [Twitter](https://twitter.com/openbb_finance), [Linkedin](https://www.linkedin.com/company/openbb-finance), [Instagram](https://www.instagram.com/openbb.finance/), [Reddit](https://www.reddit.com/r/openbb/), [Discord](https://discord.com/invite/xPHTuHCmuV)