mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Feature/ Pywry login (#5115)
* Update .gitignore * init * Update backend.py * Update main.tsx * Update no_import.py * Update session_controller.py * indents * adjust window size * update keys * re-add save session for pywry login * pop response keys on rename * walrus remember * use session username for profile * implement logout clearing of cookies * don't display welcome when logging in from `account` menu * Update session_model.py * Update session_model.py * customdata handler for charts * fix remember key * only slice data if chandlestick trace in data * Update profile_model.py * Update streamlit_run.py * Update plotly.html * test * Update loggers.py * updates * Update session_controller.py * Update session_controller.py * no longer need to call_hub for logout * tests * Update test_session_controller.py * Update profile_model.py * bump pywry, fix numbers passed as strings tables * update plotly frontend packages * formatting * Update backend.py * Update backend.py * change to prod * return on image export --------- Co-authored-by: James Maslek <jmaslek11@gmail.com>
This commit is contained in:
1017
frontend-components/plotly/package-lock.json
generated
vendored
1017
frontend-components/plotly/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load Diff
18
frontend-components/plotly/package.json
vendored
18
frontend-components/plotly/package.json
vendored
@@ -10,22 +10,13 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-checkbox": "^1.0.3",
|
||||
"@radix-ui/react-context-menu": "^2.1.3",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||
"@radix-ui/react-icons": "^1.2.0",
|
||||
"@radix-ui/react-radio-group": "^1.1.2",
|
||||
"@radix-ui/react-select": "^1.2.1",
|
||||
"@radix-ui/react-toast": "^1.1.3",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"plotly.js-dist-min": "^2.21.0",
|
||||
"posthog-js": "^1.55.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0",
|
||||
"react-plotly.js": "^2.6.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"xss": "^1.0.14"
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-plotly.js": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/dom-to-image": "^2.6.4",
|
||||
@@ -34,13 +25,12 @@
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/react-plotly.js": "^2.6.0",
|
||||
"@types/react-table": "^7.7.14",
|
||||
"@types/wicg-file-system-access": "^2020.9.6",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"clsx": "^1.2.1",
|
||||
"posthog-js": "^1.55.0",
|
||||
"postcss": "^8.4.21",
|
||||
"posthog-js": "^1.55.0",
|
||||
"react-hotkeys-hook": "^4.4.0",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"typescript": "^4.9.3",
|
||||
|
||||
@@ -3,4 +3,4 @@ module.exports = {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,10 +140,10 @@ export default async function autoScaling(
|
||||
}
|
||||
});
|
||||
|
||||
return {to_update, yaxis_fixedrange};
|
||||
return { to_update, yaxis_fixedrange };
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`Error in AutoScaling: ${e}`);
|
||||
}
|
||||
return {to_update: {}, yaxis_fixedrange: []};
|
||||
return { to_update: {}, yaxis_fixedrange: [] };
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ export default function Chart({
|
||||
const extension = filename.split(".").pop().replace("jpg", "jpeg");
|
||||
|
||||
if (["jpeg", "png", "svg", "pdf"].includes(extension))
|
||||
non_blocking(async function () {
|
||||
return non_blocking(async function () {
|
||||
await hideModebar();
|
||||
await saveImage("MainChart", filename.split(".")[0], extension);
|
||||
}, 2)();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ICONS } from "./Config";
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { downloadCSV, downloadImage } from "../utils/utils";
|
||||
|
||||
export function hideModebar(hide: boolean = true) {
|
||||
export function hideModebar(hide = true) {
|
||||
return new Promise((resolve) => {
|
||||
if (!window.MODEBAR) {
|
||||
window.MODEBAR = window.document.getElementsByClassName(
|
||||
|
||||
2
frontend-components/plotly/src/index.css
vendored
2
frontend-components/plotly/src/index.css
vendored
@@ -1,6 +1,6 @@
|
||||
@font-face {
|
||||
font-family: "Fira Code";
|
||||
src: url("./fonts/FiraCode-VF.ttf") format("truetype");
|
||||
src: url("../../fonts/FiraCode-VF.ttf") format("truetype");
|
||||
/* fix Fire Code font width issue that makes Text get cut off in Plotly.js */
|
||||
font-weight: 400 700;
|
||||
font-stretch: 50%;
|
||||
|
||||
12
frontend-components/plotly/src/main.tsx
vendored
12
frontend-components/plotly/src/main.tsx
vendored
@@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import * as ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import "./index.css";
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById("root") as HTMLElement
|
||||
const rootElement = document.getElementById("root") as HTMLElement;
|
||||
ReactDOM.createRoot(rootElement).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: "class",
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}", "../fonts"],
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
|
||||
2
frontend-components/plotly/tsconfig.json
vendored
2
frontend-components/plotly/tsconfig.json
vendored
@@ -17,6 +17,6 @@
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["src", "../fonts"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
||||
2
frontend-components/plotly/vite.config.ts
vendored
2
frontend-components/plotly/vite.config.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vite";
|
||||
import { viteSingleFile } from "vite-plugin-singlefile";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
|
||||
@@ -34,7 +34,7 @@ class ProfileModel(BaseModel):
|
||||
self.token = session.get("access_token", "")
|
||||
self.uuid = session.get("uuid", "")
|
||||
self.email = email
|
||||
self.username = self.email[: self.email.find("@")]
|
||||
self.username = session.get("username", None) or email.split("@").pop(0)
|
||||
self.primary_usage = session.get("primary_usage", "")
|
||||
self.remember = remember
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ class Backend(PyWry):
|
||||
export_image : str, optional
|
||||
Path to export image to, by default ""
|
||||
"""
|
||||
self.ensure_backend()
|
||||
self.check_backend()
|
||||
# pylint: disable=C0415
|
||||
from openbb_terminal.helper_funcs import command_location
|
||||
|
||||
@@ -261,7 +261,7 @@ class Backend(PyWry):
|
||||
theme : light or dark, optional
|
||||
Theme of the table, by default "light"
|
||||
"""
|
||||
self.ensure_backend()
|
||||
self.check_backend()
|
||||
|
||||
if title:
|
||||
# We remove any html tags and markdown from the title
|
||||
@@ -328,7 +328,7 @@ class Backend(PyWry):
|
||||
height : int, optional
|
||||
Height of the window, by default 800
|
||||
"""
|
||||
self.ensure_backend()
|
||||
self.check_backend()
|
||||
script = f"""
|
||||
<script>
|
||||
window.location.replace("{url}");
|
||||
@@ -355,37 +355,37 @@ class Backend(PyWry):
|
||||
if self.isatty:
|
||||
super().start(debug)
|
||||
|
||||
def ensure_backend(self):
|
||||
"""Ensure the backend is running. Ignores was never awaited errors."""
|
||||
try:
|
||||
self.loop.run_until_complete(self.check_backend())
|
||||
except Exception: # pylint: disable=W0703
|
||||
pass
|
||||
|
||||
async def check_backend(self):
|
||||
def check_backend(self):
|
||||
"""Override to check if isatty."""
|
||||
if self.isatty:
|
||||
message = (
|
||||
"[bold red]PyWry version 0.5.12 or higher is required to use the "
|
||||
"OpenBB Plots backend.[/]\n"
|
||||
"[yellow]Please update pywry with 'pip install pywry --upgrade'[/]"
|
||||
)
|
||||
if not hasattr(PyWry, "__version__"):
|
||||
try:
|
||||
# pylint: disable=C0415
|
||||
from pywry import __version__ as pywry_version
|
||||
except ImportError:
|
||||
console.print(message)
|
||||
self.max_retries = 0
|
||||
return
|
||||
if not self.isatty:
|
||||
return None
|
||||
|
||||
PyWry.__version__ = pywry_version # pylint: disable=W0201
|
||||
message = (
|
||||
"[bold red]PyWry version 0.5.12 or higher is required to use the "
|
||||
"OpenBB Plots backend.[/]\n"
|
||||
"[yellow]Please update pywry with 'pip install pywry --upgrade'[/]"
|
||||
)
|
||||
if not hasattr(PyWry, "__version__"):
|
||||
try:
|
||||
# pylint: disable=C0415
|
||||
from pywry import __version__ as pywry_version
|
||||
except ImportError:
|
||||
self.max_retries = 0
|
||||
return console.print(message)
|
||||
|
||||
if version.parse(PyWry.__version__) < version.parse("0.5.12"):
|
||||
console.print(message)
|
||||
self.max_retries = 0 # pylint: disable=W0201
|
||||
return
|
||||
await super().check_backend()
|
||||
PyWry.__version__ = pywry_version # pylint: disable=W0201
|
||||
|
||||
if version.parse(PyWry.__version__) < version.parse("0.5.12"):
|
||||
self.max_retries = 0 # pylint: disable=W0201
|
||||
return console.print(message)
|
||||
|
||||
if version.parse(PyWry.__version__) > version.parse("0.5.12"):
|
||||
return super().check_backend()
|
||||
|
||||
try:
|
||||
return self.loop.run_until_complete(super().check_backend())
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def close(self, reset: bool = False):
|
||||
"""Close the backend."""
|
||||
@@ -394,6 +394,75 @@ class Backend(PyWry):
|
||||
|
||||
super().close()
|
||||
|
||||
async def get_results(self, description: str) -> dict:
|
||||
"""Wait for completion of interactive task and return the data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
description : str
|
||||
Description of the task to console print while waiting.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
The data returned from pywry backend.
|
||||
"""
|
||||
console.print(
|
||||
f"[green]{description}[/]\n\n"
|
||||
"[yellow]If the window is closed you can continue by pressing Ctrl+C.[/]"
|
||||
)
|
||||
while True:
|
||||
try:
|
||||
data: dict = self.recv.get(block=False) or {}
|
||||
if data.get("result", False):
|
||||
return json.loads(data["result"])
|
||||
except Exception: # pylint: disable=W0703
|
||||
pass
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
def call_hub(self, login: bool = True) -> Optional[dict]:
|
||||
"""Call the hub to login or logout.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
login : bool, optional
|
||||
Whether to login or logout, by default True
|
||||
|
||||
Returns
|
||||
-------
|
||||
Optional[dict]
|
||||
The user data if login was successful, None otherwise.
|
||||
"""
|
||||
self.check_backend()
|
||||
endpoint = {True: "login", False: "logout"}[login]
|
||||
|
||||
outgoing = dict(
|
||||
json_data=dict(url=f"https://my.openbb.co/{endpoint}?pywry=true"),
|
||||
**self.get_kwargs(endpoint.title()),
|
||||
width=900,
|
||||
height=800,
|
||||
)
|
||||
self.send_outgoing(outgoing)
|
||||
|
||||
messages_dict = dict(
|
||||
login=dict(
|
||||
message="Welcome to OpenBB Terminal! Please login to continue.",
|
||||
interrupt="Login cancelled. Continuing as guest.",
|
||||
),
|
||||
logout=dict(
|
||||
message="Sending logout request", interrupt="Continuing as guest."
|
||||
),
|
||||
)
|
||||
|
||||
try:
|
||||
return self.loop.run_until_complete(
|
||||
self.get_results(messages_dict[endpoint]["message"])
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
console.print(f"\n[red]{messages_dict[endpoint]['interrupt']}[/red]")
|
||||
return None
|
||||
|
||||
|
||||
async def download_plotly_js():
|
||||
"""Download or updates plotly.js to the assets folder."""
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
from queue import Queue
|
||||
from typing import List
|
||||
|
||||
import dotenv
|
||||
@@ -42,6 +43,7 @@ class DummyBackend:
|
||||
debug = False
|
||||
shell = False
|
||||
base = None
|
||||
recv: Queue = Queue()
|
||||
|
||||
def __new__(cls, *args, **kwargs): # pylint: disable=W0613
|
||||
"""Create a singleton instance of the backend."""
|
||||
|
||||
54
openbb_terminal/core/plots/plotly.html
vendored
54
openbb_terminal/core/plots/plotly.html
vendored
File diff suppressed because one or more lines are too long
@@ -4,7 +4,12 @@ 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.session.constants import REGISTER_URL, SUPPORT_URL
|
||||
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.current_system import get_current_system
|
||||
from openbb_terminal.core.session.session_model import (
|
||||
LoginStatus,
|
||||
create_session,
|
||||
@@ -14,12 +19,13 @@ from openbb_terminal.rich_config import console
|
||||
from openbb_terminal.terminal_helper import bootup, is_installer
|
||||
|
||||
|
||||
def display_welcome_message():
|
||||
def display_welcome_message(links: bool = True) -> None:
|
||||
"""Display welcome message"""
|
||||
with open(PACKAGE_DIRECTORY / "core" / "session" / "banner.txt") as f:
|
||||
console.print(f"[menu]{f.read()}[/menu]\n")
|
||||
console.print(f"Register : [cmds]{REGISTER_URL}[/cmds]")
|
||||
console.print(f"Support : [cmds]{SUPPORT_URL}[/cmds]")
|
||||
if links:
|
||||
console.print(f"Register : [cmds]{REGISTER_URL}[/cmds]")
|
||||
console.print(f"Support : [cmds]{SUPPORT_URL}[/cmds]")
|
||||
|
||||
|
||||
def get_user_input() -> Tuple[str, str, bool]:
|
||||
@@ -43,7 +49,7 @@ def get_user_input() -> Tuple[str, str, bool]:
|
||||
s: PromptSession = PromptSession()
|
||||
|
||||
email = s.prompt(
|
||||
message="> Email: ",
|
||||
message="> Email/Username: ",
|
||||
)
|
||||
if not email:
|
||||
return "", "", False
|
||||
@@ -59,7 +65,48 @@ def get_user_input() -> Tuple[str, str, bool]:
|
||||
return email, password, remember
|
||||
|
||||
|
||||
def prompt(welcome: bool = True):
|
||||
def pywry_login(welcome: bool = True):
|
||||
"""Login using PyWry window and launch terminal if login is successful.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
welcome : bool, optional
|
||||
Display welcome message, by default True
|
||||
"""
|
||||
bootup()
|
||||
|
||||
plots_backend().start(get_current_system().DEBUG_MODE)
|
||||
if plots_backend().isatty:
|
||||
if welcome:
|
||||
display_welcome_message(False)
|
||||
response = plots_backend().call_hub() or None
|
||||
else:
|
||||
return prompt_cli(welcome)
|
||||
|
||||
if response is None:
|
||||
if is_installer():
|
||||
return prompt_cli(welcome=False)
|
||||
return launch_terminal()
|
||||
|
||||
if isinstance(response, dict) and response:
|
||||
console.print("\n[info]Logging in... Please wait.[/info]\n")
|
||||
response["token_type"] = "bearer"
|
||||
|
||||
for r_key, new_key in zip(
|
||||
["status", "accessToken", "primaryUsage"],
|
||||
["information_complete", "access_token", "primary_usage"],
|
||||
):
|
||||
response[new_key] = response.pop(r_key, None)
|
||||
|
||||
if remember := response.get("remember", False):
|
||||
Local.save_session(response)
|
||||
|
||||
return login_and_launch(response, remember)
|
||||
|
||||
return pywry_login(welcome=False)
|
||||
|
||||
|
||||
def prompt_cli(welcome: bool = True):
|
||||
"""Prompt and launch terminal if login is successful.
|
||||
|
||||
Parameters
|
||||
@@ -75,7 +122,7 @@ def prompt(welcome: bool = True):
|
||||
while True:
|
||||
email, password, remember = get_user_input()
|
||||
if not email:
|
||||
return prompt(welcome=False) if is_installer() else launch_terminal()
|
||||
return prompt_cli(welcome=False) if is_installer() else launch_terminal()
|
||||
|
||||
session = create_session(email, password, remember)
|
||||
if isinstance(session, dict) and session:
|
||||
@@ -104,18 +151,22 @@ def login_and_launch(session: dict, remember: bool = False):
|
||||
if status in [LoginStatus.SUCCESS, LoginStatus.NO_RESPONSE]:
|
||||
launch_terminal()
|
||||
elif status == LoginStatus.FAILED:
|
||||
prompt(welcome=False)
|
||||
pywry_login(welcome=False)
|
||||
else:
|
||||
prompt(welcome=True)
|
||||
pywry_login(welcome=True)
|
||||
|
||||
|
||||
def main(session: Optional[Dict] = None):
|
||||
def main(session: Optional[Dict] = None, welcome: bool = True, prompt: bool = True):
|
||||
"""Main function"""
|
||||
|
||||
local_session = Local.get_session() if session is None else session
|
||||
if not local_session:
|
||||
prompt()
|
||||
else:
|
||||
|
||||
if not local_session and not prompt:
|
||||
launch_terminal()
|
||||
elif local_session:
|
||||
login_and_launch(session=local_session, remember=True)
|
||||
else:
|
||||
pywry_login(welcome)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -7,15 +7,9 @@ import matplotlib.pyplot as plt
|
||||
|
||||
import openbb_terminal.core.session.hub_model as Hub
|
||||
import openbb_terminal.core.session.local_model as Local
|
||||
from openbb_terminal.base_helpers import (
|
||||
remove_log_handlers,
|
||||
)
|
||||
from openbb_terminal.base_helpers import remove_log_handlers
|
||||
from openbb_terminal.core.config.paths import HIST_FILE_PATH, SESSION_FILE_PATH
|
||||
from openbb_terminal.core.models.user_model import (
|
||||
ProfileModel,
|
||||
SourcesModel,
|
||||
UserModel,
|
||||
)
|
||||
from openbb_terminal.core.models.user_model import ProfileModel, SourcesModel, UserModel
|
||||
from openbb_terminal.core.session.current_user import (
|
||||
get_current_user,
|
||||
set_current_user,
|
||||
@@ -195,6 +189,7 @@ def logout(
|
||||
return
|
||||
|
||||
success = True
|
||||
|
||||
r = Hub.delete_session(auth_header, token)
|
||||
if not r or r.status_code != 200:
|
||||
success = False
|
||||
|
||||
@@ -332,7 +332,7 @@ def print_rich_table(
|
||||
isinstance(df[col].iloc[x], pd.Timestamp)
|
||||
for x in range(min(10, len(df)))
|
||||
):
|
||||
df[col] = pd.to_numeric(df[col])
|
||||
df[col] = pd.to_numeric(df[col], errors="ignore")
|
||||
except (ValueError, TypeError):
|
||||
df[col] = df[col].astype(str)
|
||||
|
||||
|
||||
@@ -135,9 +135,14 @@ class PosthogHandler(logging.Handler):
|
||||
self.settings = settings
|
||||
self.app_settings = settings.app_settings
|
||||
self.logged_in = False
|
||||
self.disabled = openbb_posthog.feature_enabled(
|
||||
"disable_analytics",
|
||||
self.app_settings.identifier,
|
||||
send_feature_flag_events=False,
|
||||
)
|
||||
|
||||
def emit(self, record: logging.LogRecord):
|
||||
if "llama_index" in record.pathname:
|
||||
if self.disabled or "llama_index" in record.pathname:
|
||||
return
|
||||
try:
|
||||
self.send(record=record)
|
||||
|
||||
@@ -319,7 +319,7 @@ def get_quote(symbols: List[str]) -> pd.DataFrame:
|
||||
try:
|
||||
df_fa = fa.quote(
|
||||
symbol, get_current_user().credentials.API_KEY_FINANCIALMODELINGPREP
|
||||
)
|
||||
).rename({"yearLow": "52 Week Low", "yearHigh": "52 Week High"})
|
||||
# Invalid API Keys
|
||||
except ValueError:
|
||||
console.print("[red]Invalid API Key[/red]\n")
|
||||
|
||||
@@ -908,7 +908,7 @@ def terminal(jobs_cmds: Optional[List[str]] = None, test_mode=False):
|
||||
|
||||
if an_input in ("login", "logout") and get_show_prompt() and is_auth_enabled():
|
||||
set_show_prompt(False)
|
||||
return session_controller.main()
|
||||
return session_controller.main(welcome=False)
|
||||
|
||||
|
||||
def insert_start_slash(cmds: List[str]) -> List[str]:
|
||||
|
||||
30
poetry.lock
generated
vendored
30
poetry.lock
generated
vendored
@@ -6501,24 +6501,24 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pywry"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pywry-0.5.12-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:742e63522c324f4a313d83f6cc9470703b92ac3668be5e2c3221dd735f99241a"},
|
||||
{file = "pywry-0.5.12-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:4aaa2cfd161a694c1ad4f0d1abbc1650fd776e6d6f49077734077dff9e7541db"},
|
||||
{file = "pywry-0.5.12-cp310-none-win_amd64.whl", hash = "sha256:fde04222de82a697211385c0031ddd5cca3d609bf15c9edb74459c878013c45b"},
|
||||
{file = "pywry-0.5.12-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:c471a010782ee87c8b0da3317962e9b20a0584975e3c96dd87ccbae89bd3e95a"},
|
||||
{file = "pywry-0.5.12-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c83dc23ce363322343fe21a2fbbac6f0488a3881042026b2c5fabf2b4f53c"},
|
||||
{file = "pywry-0.5.12-cp311-none-win_amd64.whl", hash = "sha256:7bb6b4a2726b4a7db62afe9fba3bf46a86db92b1a0c290266b20c5b777956f5e"},
|
||||
{file = "pywry-0.5.12-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:efe90cefbeeb2ae2b8c0b3b931fcd82631b9b125351140f113e3a96229475f01"},
|
||||
{file = "pywry-0.5.12-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:bfbcc91ad389fd931059e4013c0c74a3924da5728a2aa2c5203104845c5b3a0d"},
|
||||
{file = "pywry-0.5.12-cp38-none-win_amd64.whl", hash = "sha256:edf25b8d7ce6d735f8561bacac37864373c6f568d1e4e44705bc0b60af86d6d7"},
|
||||
{file = "pywry-0.5.12-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:ca3ad7d6b4350ae2d3f516f997dbfb00229927ace3906434ff0fbef64b253940"},
|
||||
{file = "pywry-0.5.12-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:6cde2c32a7177d17d418cde9bdafff6b05c1146aaef0fa3be3d9375c1eb0e37a"},
|
||||
{file = "pywry-0.5.12-cp39-none-win_amd64.whl", hash = "sha256:446c52bca13d00cb1965353fa9954fa7930ad47d024a520fe8b3b67777996f71"},
|
||||
{file = "pywry-0.5.12.tar.gz", hash = "sha256:3c20830c9a14dbd8557bbe147122eeb79c6a588064960a2d754e8917b0d511e7"},
|
||||
{file = "pywry-0.5.13-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:fc2d39cbaa7479ba2170192930288d94cdf17a9e3f9cf44b3884903f264b70fa"},
|
||||
{file = "pywry-0.5.13-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:de9e75a2b24433c5a12adcf0ba4bf6e29c50edcaac3bae09c0073ba3484237a9"},
|
||||
{file = "pywry-0.5.13-cp310-none-win_amd64.whl", hash = "sha256:c284428dceb64063026541b37d7786136ce4b281d0cd7aa716ced1e64a276c13"},
|
||||
{file = "pywry-0.5.13-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:0d1f94bcfc9713c6194667f14f472be34640e9f3e8013faa02aea276d4571c8a"},
|
||||
{file = "pywry-0.5.13-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a3627d92bed1a8e02bf87b18ef0a12868f8468a18b0b74925a73c507b1b8964f"},
|
||||
{file = "pywry-0.5.13-cp311-none-win_amd64.whl", hash = "sha256:7d8f884e853466fb1ee8003aaf0ea1c643721adb2d0c75300ebc0f314008420b"},
|
||||
{file = "pywry-0.5.13-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:ba97dc7406086748a16e4f21efc73c006d4f02f71941fcbbd11e17946ab878cb"},
|
||||
{file = "pywry-0.5.13-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:c142839551c5e468cae3171dee7b230ba753cb38027a03079f3fa283671e190a"},
|
||||
{file = "pywry-0.5.13-cp38-none-win_amd64.whl", hash = "sha256:646e41c18d3a0f762d2b59e14281fca223d7fe1f0b2a882ecf054840ee28d10d"},
|
||||
{file = "pywry-0.5.13-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9e950d076f1a2d7980753576c65e6540ea05f6b5b0a29b734035aaae64027dea"},
|
||||
{file = "pywry-0.5.13-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:d6654cd7d45d66f359872d4e9dd2e70372daf96ea2458706eeafda198471a45e"},
|
||||
{file = "pywry-0.5.13-cp39-none-win_amd64.whl", hash = "sha256:03b5fa018f1e5be8d42aff2f969b4cc068d13c894521341e8e59ec33af794324"},
|
||||
{file = "pywry-0.5.13.tar.gz", hash = "sha256:b5344ddbe63b72ed22c5a3f7f6c4a59a5bd27f250fbca7af979f3972d3a1855c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -9707,4 +9707,4 @@ optimization = ["Riskfolio-Lib"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8.1,<3.11, !=3.9.7"
|
||||
content-hash = "cb24f854b046f29289e3f1ad584ed733337408cafe5bb989362030f759efdddc"
|
||||
content-hash = "8fda0a5968218020cf85c39956d6eb6e3e9780aac53e697dd6b81f4e686622eb"
|
||||
|
||||
2
pyproject.toml
vendored
2
pyproject.toml
vendored
@@ -101,7 +101,7 @@ jupyterlab-widgets = "^3.0.3"
|
||||
mstarpy = "^0.0.4"
|
||||
packaging = ">=22.0"
|
||||
streamlit = "^1.22.0"
|
||||
pywry = "^0.5.12"
|
||||
pywry = "^0.5.13"
|
||||
svglib = "^1.5.0"
|
||||
sparqlwrapper = "^2.0.0"
|
||||
y-py = "!=0.5.5" # Untraceable third level dependency that requires cargo to be built
|
||||
|
||||
2
requirements-full.txt
vendored
2
requirements-full.txt
vendored
@@ -278,7 +278,7 @@ pytz==2022.7.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.
|
||||
pywin32-ctypes==0.2.0 ; python_full_version >= "3.8.1" and python_version < "3.11" and python_full_version != "3.9.7" and sys_platform == "win32"
|
||||
pywin32==305 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pywinpty==2.0.10 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and os_name == "nt"
|
||||
pywry==0.5.12 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pywry==0.5.13 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pyyaml==6.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pyzmq==25.0.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
qdldl==0.1.5.post3 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
|
||||
2
requirements.txt
vendored
2
requirements.txt
vendored
@@ -195,7 +195,7 @@ pytz-deprecation-shim==0.1.0.post0 ; python_full_version >= "3.8.1" and python_f
|
||||
pytz==2022.7.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pywin32==305 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pywinpty==2.0.10 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11" and os_name == "nt"
|
||||
pywry==0.5.12 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pywry==0.5.13 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pyyaml==6.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
pyzmq==25.0.1 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
quandl==3.7.0 ; python_full_version >= "3.8.1" and python_full_version != "3.9.7" and python_version < "3.11"
|
||||
|
||||
@@ -29,14 +29,13 @@ def main():
|
||||
else:
|
||||
from openbb_terminal.core.session import session_controller
|
||||
|
||||
if (
|
||||
prompt_login = (
|
||||
is_auth_enabled()
|
||||
and ("--login" in sys.argv[1:] or is_installer())
|
||||
and sys.stdin.isatty()
|
||||
):
|
||||
session_controller.main()
|
||||
else:
|
||||
session_controller.launch_terminal()
|
||||
)
|
||||
|
||||
session_controller.main(prompt=prompt_login)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -42,7 +42,7 @@ def test_prompt():
|
||||
"openbb_terminal.core.session.session_controller.login_and_launch",
|
||||
return_value=True,
|
||||
):
|
||||
session_controller.prompt()
|
||||
session_controller.prompt_cli()
|
||||
assert get_user_input_mock.call_count == 1
|
||||
create_session_mock.assert_called_once_with("email", "password", False)
|
||||
assert create_session_mock.call_count == 1
|
||||
@@ -76,7 +76,7 @@ def test_login_and_launch_failed():
|
||||
"openbb_terminal.core.session.session_controller.login",
|
||||
return_value=session_controller.LoginStatus.FAILED,
|
||||
) as login_mock, patch(
|
||||
"openbb_terminal.core.session.session_controller.prompt", return_value=True
|
||||
"openbb_terminal.core.session.session_controller.prompt_cli", return_value=True
|
||||
) as prompt_mock:
|
||||
session_controller.login_and_launch(session={})
|
||||
assert login_mock.call_count == 1
|
||||
@@ -89,7 +89,7 @@ def test_login_and_launch_no_response():
|
||||
"openbb_terminal.core.session.session_controller.login",
|
||||
return_value=session_controller.LoginStatus.NO_RESPONSE,
|
||||
) as login_mock, patch(
|
||||
"openbb_terminal.core.session.session_controller.prompt", return_value=True
|
||||
"openbb_terminal.core.session.session_controller.prompt_cli", return_value=True
|
||||
) as prompt_mock:
|
||||
session_controller.login_and_launch(session={})
|
||||
assert login_mock.call_count == 1
|
||||
@@ -98,7 +98,7 @@ def test_login_and_launch_no_response():
|
||||
|
||||
def test_main_local_session():
|
||||
with patch(
|
||||
"openbb_terminal.core.session.session_controller.prompt", return_value=True
|
||||
"openbb_terminal.core.session.session_controller.prompt_cli", return_value=True
|
||||
) as prompt_mock, patch(
|
||||
"openbb_terminal.core.session.session_controller.Local.get_session",
|
||||
return_value=False,
|
||||
|
||||
Reference in New Issue
Block a user