mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-30 14:02:06 +00:00
Merge branch 'develop' of https://github.com/OpenBB-finance/OpenBBTerminal into develop
This commit is contained in:
@@ -371,6 +371,8 @@ class AccountController(BaseController):
|
||||
self.REMOTE_CHOICES.append(name)
|
||||
self.update_runtime_choices()
|
||||
|
||||
# store data in list with "personal/default" to identify data's routine type
|
||||
# and for save_routine
|
||||
@log_start_end(log=logger)
|
||||
def call_download(self, other_args: List[str]):
|
||||
"""Download"""
|
||||
@@ -398,37 +400,36 @@ class AccountController(BaseController):
|
||||
print_guest_block_msg()
|
||||
else:
|
||||
if ns_parser:
|
||||
data = None
|
||||
|
||||
# Default routine
|
||||
data = []
|
||||
name = " ".join(ns_parser.name)
|
||||
if name in self.DEFAULT_CHOICES:
|
||||
data = next(
|
||||
(r for r in self.DEFAULT_ROUTINES if r["name"] == name), None
|
||||
)
|
||||
else:
|
||||
# User routine
|
||||
response = Hub.download_routine(
|
||||
auth_header=get_current_user().profile.get_auth_header(),
|
||||
name=name,
|
||||
)
|
||||
data = (
|
||||
response.json()
|
||||
if response and response.status_code == 200
|
||||
else None
|
||||
)
|
||||
# Personal routines
|
||||
response = Hub.download_routine(
|
||||
auth_header=get_current_user().profile.get_auth_header(),
|
||||
name=name,
|
||||
)
|
||||
if response and response.status_code == 200:
|
||||
data = [response.json(), "personal"]
|
||||
# Default routine
|
||||
elif name in self.DEFAULT_CHOICES:
|
||||
data = [
|
||||
next(
|
||||
(r for r in self.DEFAULT_ROUTINES if r["name"] == name),
|
||||
None,
|
||||
),
|
||||
"default",
|
||||
]
|
||||
|
||||
# Save routine
|
||||
if data:
|
||||
name = data.get("name", "")
|
||||
if data[0]:
|
||||
name = data[0].get("name", "")
|
||||
if name:
|
||||
console.print(f"[info]Name:[/info] {name}")
|
||||
|
||||
description = data.get("description", "")
|
||||
description = data[0].get("description", "")
|
||||
if description:
|
||||
console.print(f"[info]Description:[/info] {description}")
|
||||
|
||||
script = data.get("script", "")
|
||||
script = [data[0].get("script", ""), data[1]]
|
||||
if script:
|
||||
file_name = f"{name}.openbb"
|
||||
file_path = save_routine(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
from os import walk
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
@@ -10,7 +11,10 @@ from openbb_terminal.core.session.current_user import get_current_user
|
||||
from openbb_terminal.rich_config import console
|
||||
|
||||
|
||||
def download_routines(auth_header: str, silent: bool = False) -> Dict[str, str]:
|
||||
# created dictionaries for personal and default routines with the structure
|
||||
# {"file_name" :["script","personal/default"]}
|
||||
# and stored dictionaries in list
|
||||
def download_routines(auth_header: str, silent: bool = False) -> list:
|
||||
"""Download default and personal routines.
|
||||
|
||||
Parameters
|
||||
@@ -25,7 +29,8 @@ def download_routines(auth_header: str, silent: bool = False) -> Dict[str, str]:
|
||||
Dict[str, str]
|
||||
The routines.
|
||||
"""
|
||||
routines_dict = {}
|
||||
personal_routines_dict = {}
|
||||
default_routines_dict = {}
|
||||
|
||||
try:
|
||||
response = Hub.get_default_routines(silent=silent)
|
||||
@@ -35,7 +40,7 @@ def download_routines(auth_header: str, silent: bool = False) -> Dict[str, str]:
|
||||
for routine in data:
|
||||
name = routine.get("name", "")
|
||||
if name:
|
||||
routines_dict[name] = routine.get("script", "")
|
||||
default_routines_dict[name] = [routine.get("script", ""), "default"]
|
||||
except Exception:
|
||||
console.print("[red]\nFailed to download default routines.[/red]")
|
||||
|
||||
@@ -54,13 +59,17 @@ def download_routines(auth_header: str, silent: bool = False) -> Dict[str, str]:
|
||||
for routine in items:
|
||||
name = routine.get("name", "")
|
||||
if name:
|
||||
routines_dict[name] = routine.get("script", "")
|
||||
personal_routines_dict[name] = [
|
||||
routine.get("script", ""),
|
||||
"personal",
|
||||
]
|
||||
except Exception:
|
||||
console.print("[red]\nFailed to download personal routines.[/red]")
|
||||
|
||||
return routines_dict
|
||||
return [personal_routines_dict, default_routines_dict]
|
||||
|
||||
|
||||
# use os.walk to search subdirectories and then construct file path
|
||||
def read_routine(file_name: str, folder: Optional[Path] = None) -> Optional[str]:
|
||||
"""Read the routine.
|
||||
|
||||
@@ -85,12 +94,12 @@ def read_routine(file_name: str, folder: Optional[Path] = None) -> Optional[str]
|
||||
|
||||
try:
|
||||
user_folder = folder / "hub"
|
||||
file_path = (
|
||||
user_folder / file_name
|
||||
if os.path.exists(user_folder / file_name)
|
||||
else folder / file_name
|
||||
)
|
||||
|
||||
for path, _, files in walk(user_folder):
|
||||
file_path = (
|
||||
folder / os.path.relpath(path, folder) / file_name
|
||||
if file_name in files
|
||||
else folder / file_name
|
||||
)
|
||||
with open(file_path) as f:
|
||||
routine = "".join(f.readlines())
|
||||
return routine
|
||||
@@ -99,9 +108,10 @@ def read_routine(file_name: str, folder: Optional[Path] = None) -> Optional[str]
|
||||
return None
|
||||
|
||||
|
||||
# created new directory structure to account for personal and default routines
|
||||
def save_routine(
|
||||
file_name: str,
|
||||
routine: str,
|
||||
routine: list,
|
||||
folder: Optional[Path] = None,
|
||||
force: bool = False,
|
||||
silent: bool = False,
|
||||
@@ -134,6 +144,11 @@ def save_routine(
|
||||
|
||||
try:
|
||||
user_folder = folder / "hub"
|
||||
if routine[1] == "default":
|
||||
user_folder = folder / "hub" / "default"
|
||||
elif routine[1] == "personal":
|
||||
user_folder = folder / "hub" / "personal"
|
||||
|
||||
if not os.path.exists(user_folder):
|
||||
os.makedirs(user_folder)
|
||||
|
||||
@@ -141,7 +156,7 @@ def save_routine(
|
||||
if os.path.exists(file_path) and not force:
|
||||
return "File already exists"
|
||||
with open(file_path, "w") as f:
|
||||
f.write(routine)
|
||||
f.write(routine[0])
|
||||
return user_folder / file_name
|
||||
except Exception:
|
||||
console_print("[red]\nFailed to save routine.[/red]")
|
||||
|
||||
@@ -133,8 +133,12 @@ def download_and_save_routines(auth_header: str):
|
||||
The authorization header, e.g. "Bearer <token>".
|
||||
"""
|
||||
routines = download_routines(auth_header=auth_header)
|
||||
personal_routines_dict = routines[0]
|
||||
default_routines_dict = routines[1]
|
||||
try:
|
||||
for name, content in routines.items():
|
||||
for name, content in personal_routines_dict.items():
|
||||
save_routine(file_name=f"{name}.openbb", routine=content, force=True)
|
||||
for name, content in default_routines_dict.items():
|
||||
save_routine(file_name=f"{name}.openbb", routine=content, force=True)
|
||||
except Exception:
|
||||
console.print("[red]\nFailed to save routines.[/red]")
|
||||
|
||||
@@ -13,7 +13,7 @@ import time
|
||||
import webbrowser
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import certifi
|
||||
import pandas as pd
|
||||
@@ -126,6 +126,11 @@ class TerminalController(BaseController):
|
||||
|
||||
def __init__(self, jobs_cmds: Optional[List[str]] = None):
|
||||
"""Construct terminal controller."""
|
||||
self.ROUTINE_FILES: Dict[str, str] = dict()
|
||||
self.ROUTINE_DEFAULT_FILES: Dict[str, str] = dict()
|
||||
self.ROUTINE_PERSONAL_FILES: Dict[str, str] = dict()
|
||||
self.ROUTINE_CHOICES: Dict[str, Any] = dict()
|
||||
|
||||
super().__init__(jobs_cmds)
|
||||
|
||||
self.queue: List[str] = list()
|
||||
@@ -147,8 +152,24 @@ class TerminalController(BaseController):
|
||||
"*.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 = {}
|
||||
self.ROUTINE_CHOICES["--file"] = {
|
||||
filename: None for filename in self.ROUTINE_FILES
|
||||
}
|
||||
@@ -564,19 +585,34 @@ class TerminalController(BaseController):
|
||||
|
||||
if ns_parser:
|
||||
if ns_parser.example:
|
||||
path = MISCELLANEOUS_DIRECTORY / "routines" / "routine_example.openbb"
|
||||
routine_path = (
|
||||
MISCELLANEOUS_DIRECTORY / "routines" / "routine_example.openbb"
|
||||
)
|
||||
console.print(
|
||||
"[info]Executing an example, please type `about exe` "
|
||||
"to learn how to create your own script.[/info]\n"
|
||||
)
|
||||
time.sleep(3)
|
||||
elif ns_parser.file:
|
||||
# if string is not in this format "default/file.openbb" then check for files in ROUTINE_FILES
|
||||
file_path = " ".join(ns_parser.file)
|
||||
path = self.ROUTINE_FILES.get(file_path, Path(file_path))
|
||||
full_path = file_path
|
||||
hub_routine = file_path.split("/")
|
||||
if hub_routine[0] == "default":
|
||||
routine_path = Path(
|
||||
self.ROUTINE_DEFAULT_FILES.get(hub_routine[1], full_path)
|
||||
)
|
||||
elif hub_routine[0] == "personal":
|
||||
routine_path = Path(
|
||||
self.ROUTINE_PERSONAL_FILES.get(hub_routine[1], full_path)
|
||||
)
|
||||
else:
|
||||
routine_path = Path(self.ROUTINE_FILES.get(file_path, full_path))
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
with open(path) as fp:
|
||||
with open(routine_path) as fp:
|
||||
raw_lines = [
|
||||
x for x in fp if (not is_reset(x)) and ("#" not in x) and x
|
||||
]
|
||||
@@ -955,7 +991,7 @@ def replace_dynamic(match: re.Match, special_arguments: Dict[str, str]) -> str:
|
||||
return default
|
||||
|
||||
|
||||
def run_routine(file: str, routines_args=List[str]):
|
||||
def run_routine(file: str, routines_args=Optional[str]):
|
||||
"""Execute command routine from .openbb file."""
|
||||
user_routine_path = (
|
||||
get_current_user().preferences.USER_DATA_DIRECTORY / "routines" / file
|
||||
|
||||
@@ -483,8 +483,7 @@ def test_call_download(mocker, test_user):
|
||||
name="script1",
|
||||
)
|
||||
mock_save_routine.assert_called_once_with(
|
||||
file_name="script1.openbb",
|
||||
routine="do something",
|
||||
file_name="script1.openbb", routine=["do something", "personal"]
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import json
|
||||
from unittest.mock import mock_open
|
||||
|
||||
import pytest
|
||||
from requests import Response
|
||||
|
||||
# IMPORTATION INTERNAL
|
||||
from openbb_terminal.core.models.user_model import (
|
||||
@@ -16,7 +17,11 @@ from openbb_terminal.core.models.user_model import (
|
||||
UserModel,
|
||||
)
|
||||
from openbb_terminal.core.session.current_user import get_current_user
|
||||
from openbb_terminal.core.session.routines_handler import read_routine, save_routine
|
||||
from openbb_terminal.core.session.routines_handler import (
|
||||
download_routines,
|
||||
read_routine,
|
||||
save_routine,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="test_user")
|
||||
@@ -29,14 +34,7 @@ def fixture_test_user():
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exists",
|
||||
[
|
||||
False,
|
||||
True,
|
||||
],
|
||||
)
|
||||
def test_read_routine(mocker, exists: bool, test_user):
|
||||
def test_read_routine(mocker, test_user):
|
||||
file_name = "test_routine.openbb"
|
||||
routine = "do something"
|
||||
current_user = get_current_user()
|
||||
@@ -46,50 +44,76 @@ def test_read_routine(mocker, exists: bool, test_user):
|
||||
target=path + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
|
||||
exists_mock = mocker.patch(path + ".os.path.exists", return_value=exists)
|
||||
open_mock = mocker.patch(
|
||||
path + ".open",
|
||||
mock_open(read_data=json.dumps(routine)),
|
||||
walk_mock = mocker.patch(
|
||||
path + ".walk",
|
||||
return_value=[
|
||||
(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub",
|
||||
["personal"],
|
||||
[],
|
||||
),
|
||||
(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / "personal",
|
||||
[],
|
||||
[file_name],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
relpath_mock = mocker.patch(path + ".os.path.relpath", return_value="hub/personal")
|
||||
open_mock = mocker.patch(path + ".open", mock_open(read_data=json.dumps(routine)))
|
||||
assert read_routine(file_name=file_name) == json.dumps(routine)
|
||||
|
||||
exists_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name
|
||||
walk_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub"
|
||||
)
|
||||
relpath_mock.assert_called_once_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / "personal",
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY,
|
||||
)
|
||||
open_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY
|
||||
/ "hub"
|
||||
/ "personal"
|
||||
/ file_name
|
||||
)
|
||||
if exists:
|
||||
open_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name
|
||||
)
|
||||
else:
|
||||
open_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / file_name
|
||||
)
|
||||
|
||||
|
||||
def test_read_routine_exception(mocker, test_user):
|
||||
file_name = "test_routine.openbb"
|
||||
current_user = get_current_user()
|
||||
path = "openbb_terminal.core.session.routines_handler"
|
||||
|
||||
mocker.patch(
|
||||
target=path + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
exists_mock = mocker.patch(path + ".os.path.exists")
|
||||
walk_mock = mocker.patch(
|
||||
path + ".walk",
|
||||
return_value=[
|
||||
(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub",
|
||||
["personal"],
|
||||
[],
|
||||
),
|
||||
(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / "personal",
|
||||
[],
|
||||
["do something"],
|
||||
),
|
||||
],
|
||||
)
|
||||
relpath_mock = mocker.patch(path + ".os.path.relpath")
|
||||
open_mock = mocker.patch(
|
||||
path + ".open",
|
||||
side_effect=Exception("test exception"),
|
||||
)
|
||||
|
||||
assert read_routine(file_name=file_name) is None
|
||||
|
||||
exists_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name
|
||||
walk_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub"
|
||||
)
|
||||
relpath_mock.assert_not_called()
|
||||
open_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / file_name
|
||||
)
|
||||
|
||||
|
||||
@@ -102,7 +126,7 @@ def test_read_routine_exception(mocker, test_user):
|
||||
)
|
||||
def test_save_routine(mocker, exists: bool, test_user):
|
||||
file_name = "test_routine.openbb"
|
||||
routine = "do something"
|
||||
routine = ["do something", "personal"]
|
||||
current_user = get_current_user()
|
||||
path = "openbb_terminal.core.session.routines_handler"
|
||||
|
||||
@@ -125,11 +149,18 @@ def test_save_routine(mocker, exists: bool, test_user):
|
||||
else:
|
||||
assert (
|
||||
result
|
||||
== current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name
|
||||
== current_user.preferences.USER_ROUTINES_DIRECTORY
|
||||
/ "hub"
|
||||
/ "personal"
|
||||
/ file_name
|
||||
)
|
||||
makedirs_mock.assert_called_once()
|
||||
open_mock.assert_called_with(
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY / "hub" / file_name, "w"
|
||||
current_user.preferences.USER_ROUTINES_DIRECTORY
|
||||
/ "hub"
|
||||
/ "personal"
|
||||
/ file_name,
|
||||
"w",
|
||||
)
|
||||
|
||||
assert exists_mock.call_count == 2
|
||||
@@ -137,7 +168,7 @@ def test_save_routine(mocker, exists: bool, test_user):
|
||||
|
||||
def test_save_routine_exception(mocker, test_user):
|
||||
file_name = "test_routine.openbb"
|
||||
routine = "do something"
|
||||
routine = ["do something", "personal"]
|
||||
path = "openbb_terminal.core.session.routines_handler"
|
||||
|
||||
mocker.patch(
|
||||
@@ -154,3 +185,159 @@ def test_save_routine_exception(mocker, test_user):
|
||||
|
||||
result = save_routine(file_name=file_name, routine=routine)
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_download_routine(mocker, test_user, silent=False):
|
||||
path_hub_model = "openbb_terminal.core.session.hub_model"
|
||||
path_routines_handler = "openbb_terminal.core.session.routines_handler"
|
||||
mocker.patch(
|
||||
target=path_routines_handler + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
response_default = Response()
|
||||
response_default.status_code = 200
|
||||
content = {
|
||||
"data": [{"name": "script1", "description": "abc", "script": "do something"}]
|
||||
}
|
||||
response_default._content = json.dumps(
|
||||
content
|
||||
).encode( # pylint: disable=protected-access
|
||||
"utf-8"
|
||||
)
|
||||
# print(response_default._content)
|
||||
|
||||
response_personal = Response()
|
||||
response_personal.status_code = 200
|
||||
content = {
|
||||
"items": [{"name": "script2", "description": "cde", "script": "do something"}]
|
||||
}
|
||||
|
||||
response_personal._content = json.dumps(
|
||||
content
|
||||
).encode( # pylint: disable=protected-access
|
||||
"utf-8"
|
||||
)
|
||||
get_default_routines_mock = mocker.patch(
|
||||
target=path_hub_model + ".get_default_routines", return_value=response_default
|
||||
)
|
||||
get_personal_routines_mock = mocker.patch(
|
||||
target=path_hub_model + ".list_routines", return_value=response_personal
|
||||
)
|
||||
assert download_routines(test_user.profile.get_auth_header()) == [
|
||||
{"script2": ["do something", "personal"]},
|
||||
{"script1": ["do something", "default"]},
|
||||
]
|
||||
|
||||
get_default_routines_mock.assert_called_once()
|
||||
get_personal_routines_mock.assert_called_once_with(
|
||||
auth_header=test_user.profile.get_auth_header(),
|
||||
fields=["name", "script"],
|
||||
page=1,
|
||||
size=100,
|
||||
silent=silent,
|
||||
)
|
||||
|
||||
|
||||
def test_download_default_routine_exception(mocker, test_user, silent=False):
|
||||
path_hub_model = "openbb_terminal.core.session.hub_model"
|
||||
path_routines_handler = "openbb_terminal.core.session.routines_handler"
|
||||
mocker.patch(
|
||||
target=path_routines_handler + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
response_personal = Response()
|
||||
response_personal.status_code = 200
|
||||
content = {
|
||||
"items": [{"name": "script2", "description": "cde", "script": "do something"}]
|
||||
}
|
||||
response_personal._content = json.dumps(
|
||||
content
|
||||
).encode( # pylint: disable=protected-access
|
||||
"utf-8"
|
||||
)
|
||||
get_personal_routines_mock = mocker.patch(
|
||||
target=path_hub_model + ".list_routines", return_value=response_personal
|
||||
)
|
||||
get_default_routines_mock = mocker.patch(
|
||||
path_hub_model + ".get_default_routines",
|
||||
side_effect=Exception("test exception"),
|
||||
)
|
||||
assert download_routines(test_user.profile.get_auth_header()) == [
|
||||
{"script2": ["do something", "personal"]},
|
||||
{},
|
||||
]
|
||||
get_default_routines_mock.assert_called_once()
|
||||
get_personal_routines_mock.assert_called_once_with(
|
||||
auth_header=test_user.profile.get_auth_header(),
|
||||
fields=["name", "script"],
|
||||
page=1,
|
||||
size=100,
|
||||
silent=silent,
|
||||
)
|
||||
|
||||
|
||||
def test_download_personal_routine_exception(mocker, test_user, silent=False):
|
||||
path_hub_model = "openbb_terminal.core.session.hub_model"
|
||||
path_routines_handler = "openbb_terminal.core.session.routines_handler"
|
||||
mocker.patch(
|
||||
target=path_routines_handler + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
response_default = Response()
|
||||
response_default.status_code = 200
|
||||
content = {
|
||||
"data": [{"name": "script1", "description": "abc", "script": "do something"}]
|
||||
}
|
||||
response_default._content = json.dumps(
|
||||
content
|
||||
).encode( # pylint: disable=protected-access
|
||||
"utf-8"
|
||||
)
|
||||
get_default_routines_mock = mocker.patch(
|
||||
target=path_hub_model + ".get_default_routines", return_value=response_default
|
||||
)
|
||||
get_personal_routines_mock = mocker.patch(
|
||||
path_hub_model + ".list_routines",
|
||||
side_effect=Exception("test exception"),
|
||||
)
|
||||
assert download_routines(test_user.profile.get_auth_header()) == [
|
||||
{},
|
||||
{"script1": ["do something", "default"]},
|
||||
]
|
||||
get_default_routines_mock.assert_called_once()
|
||||
get_personal_routines_mock.assert_called_once_with(
|
||||
auth_header=test_user.profile.get_auth_header(),
|
||||
fields=["name", "script"],
|
||||
page=1,
|
||||
size=100,
|
||||
silent=silent,
|
||||
)
|
||||
|
||||
|
||||
def test_download_default_and_personal_routine_exception(
|
||||
mocker, test_user, silent=False
|
||||
):
|
||||
path_hub_model = "openbb_terminal.core.session.hub_model"
|
||||
path_routines_handler = "openbb_terminal.core.session.routines_handler"
|
||||
mocker.patch(
|
||||
target=path_routines_handler + ".get_current_user",
|
||||
return_value=test_user,
|
||||
)
|
||||
get_default_routines_mock = mocker.patch(
|
||||
path_hub_model + ".get_default_routines",
|
||||
side_effect=Exception("test exception"),
|
||||
)
|
||||
|
||||
get_personal_routines_mock = mocker.patch(
|
||||
path_hub_model + ".list_routines",
|
||||
side_effect=Exception("test exception"),
|
||||
)
|
||||
assert download_routines(test_user.profile.get_auth_header()) == [{}, {}]
|
||||
get_default_routines_mock.assert_called_once()
|
||||
get_personal_routines_mock.assert_called_once_with(
|
||||
auth_header=test_user.profile.get_auth_header(),
|
||||
fields=["name", "script"],
|
||||
page=1,
|
||||
size=100,
|
||||
silent=silent,
|
||||
)
|
||||
|
||||
12
website/content/terminal/faqs/launching.md
vendored
12
website/content/terminal/faqs/launching.md
vendored
@@ -42,6 +42,18 @@ softwareupdate --install-rosetta
|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Incompatible library version: libtiff.6.dylib requires version 10.0.0 or later, but liblzma.5.dylib provides version 8.0.0</summary>
|
||||
|
||||
This issue can be resolved by following the steps below.
|
||||
|
||||
- Show hidden files
|
||||
- Command + Shift + . (period)
|
||||
- Then go to Applications folder > OpenBB Terminal > .OpenBB
|
||||
- Find the file "liblzma.5.dylib" and remove it.
|
||||
- Relaunch the terminal.
|
||||
|
||||
</details>
|
||||
|
||||
<details><summary>Terminal app does not launch: Failed to execute script 'terminal' due to unhandled exception!</summary>
|
||||
|
||||
When an installer-packaged version of the OpenBB Terminal fails to launch, because of this message, the machine may have an obsolete CPU-type or operating system. Please try installing via the source code, and if problems persist, reach out to us on [Discord](https://discord.gg/xPHTuHCmuV) or fill out a support request form on our [website](https://openbb.co/support).
|
||||
|
||||
Reference in New Issue
Block a user