From e84379c0cbe1f9c2305750bfe448d33fd88facea Mon Sep 17 00:00:00 2001 From: James Maslek Date: Tue, 27 Feb 2024 14:00:28 -0500 Subject: [PATCH 1/6] remove ultima + althub --- .../app/model/hub/features_keys.py | 1 - .../common/ultima_newsmonitor_model.py | 240 ------------------ .../common/ultima_newsmonitor_view.py | 130 ---------- openbb_terminal/keys_model.py | 69 ----- .../miscellaneous/models/all_api_keys.json | 6 - .../miscellaneous/models/hub_credentials.json | 2 - .../behavioural_analysis/ba_controller.py | 83 ------ .../news_sentiment_model.py | 98 ------- .../news_sentiment_view.py | 72 ------ openbb_terminal/stocks/stocks_controller.py | 22 -- 10 files changed, 723 deletions(-) delete mode 100644 openbb_terminal/common/ultima_newsmonitor_model.py delete mode 100644 openbb_terminal/common/ultima_newsmonitor_view.py delete mode 100644 openbb_terminal/stocks/behavioural_analysis/news_sentiment_model.py delete mode 100644 openbb_terminal/stocks/behavioural_analysis/news_sentiment_view.py diff --git a/openbb_platform/core/openbb_core/app/model/hub/features_keys.py b/openbb_platform/core/openbb_core/app/model/hub/features_keys.py index 31f828017d95..ad342f6345b6 100644 --- a/openbb_platform/core/openbb_core/app/model/hub/features_keys.py +++ b/openbb_platform/core/openbb_core/app/model/hub/features_keys.py @@ -37,5 +37,4 @@ class FeaturesKeys(BaseModel): API_TWITTER_BEARER_TOKEN: Optional[str] = Field(default=None) API_TWITTER_KEY: Optional[str] = Field(default=None) API_TWITTER_SECRET_KEY: Optional[str] = Field(default=None) - API_ULTIMA_KEY: Optional[str] = Field(default=None) API_WHALE_ALERT_KEY: Optional[str] = Field(default=None) diff --git a/openbb_terminal/common/ultima_newsmonitor_model.py b/openbb_terminal/common/ultima_newsmonitor_model.py deleted file mode 100644 index 0fb041dda163..000000000000 --- a/openbb_terminal/common/ultima_newsmonitor_model.py +++ /dev/null @@ -1,240 +0,0 @@ -""" Ultima News Monitor Model """ - -__docformat__ = "numpy" - -import logging -import os -from urllib.parse import quote - -import certifi -import pandas as pd - -from openbb_terminal.core.session.current_user import get_current_user -from openbb_terminal.decorators import log_start_end - -# from openbb_terminal.decorators import check_api_key -from openbb_terminal.helper_funcs import request -from openbb_terminal.rich_config import console - -logger = logging.getLogger(__name__) - - -ULTIMA_BASE_URL = "https://api.ultimainsights.ai/v1" -NO_API_KEY = "REPLACE_ME" - - -@log_start_end(log=logger) -# @check_api_key(["API_ULTIMA_KEY"]) -def get_news(term: str = "", sort: str = "articlePublishedDate") -> pd.DataFrame: - """Get news for a given term and source. [Source: Ultima Insights News Monitor] - - Parameters - ---------- - term : str - term to search on the news articles - sort: str - the column to sort by - - Returns - ------- - articles: pd.DataFrame - term to search on the news articles - - Examples - -------- - >>> from openbb_terminal.sdk import openbb - >>> openbb.news() - """ - # Necessary for installer so that it can locate the correct certificates for - # API calls and https - # 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() - - current_user = get_current_user() - if current_user.credentials.API_ULTIMA_KEY == NO_API_KEY: - auth_header = None - else: - auth_header = { - "Authorization": f"Bearer {current_user.credentials.API_ULTIMA_KEY}" - } - - have_data = False - limit = 0 - - while not have_data: - if term: - term = quote(term) - term = term.upper() - term = term.strip() - if term in supported_terms(): - if auth_header: - data = request( - f"{ULTIMA_BASE_URL}/getNewsArticles/{term}", headers=auth_header - ) - else: - data = request(f"{ULTIMA_BASE_URL}/getNewsArticles/{term}") - else: - console.print( - "[red]Ticker not supported. Unable to retrieve data\n[/red]" - ) - return pd.DataFrame() - else: - console.print("[red]No term specified. Unable to retrieve data\n[/red]") - return pd.DataFrame() - - if ( - hasattr(data, "status") and data.status_code == 200 - ): # Checking if data has status attribute and if data request succeeded - if data.content: - have_data = True - elif limit == 60: # Breaking if 60 successful requests return no data - console.print("[red]Timeout occurred. Please try again\n[/red]") - break - limit = limit + 1 - - elif ( - hasattr(data, "status") and data.status_code == 429 - ): # If data request failed - console.print( - "[red]Too many requests. Please get an API Key from https://www.ultimainsights.ai/[/red]" - ) - break - elif ( - hasattr(data, "status") and data.status_code != 200 - ): # If data request failed - console.print("[red]Status code not 200. Unable to retrieve data\n[/red]") - break - else: - # console.print("[red]Could not retrieve data\n[/red]") - break - if not data.json(): - return pd.DataFrame() - df = pd.DataFrame( - data.json(), - columns=[ - "articleHeadline", - "articleURL", - "articlePublishedDate", - "riskCategory", - "riskElaboratedDescription", - "relevancyScore", - ], - ) - df = df[df["relevancyScore"] < 5] - df = df[df["relevancyScore"] > 3.5] - df["riskElaboratedDescription"] = df["riskElaboratedDescription"].str.replace( - "\n", "" - ) - df["riskElaboratedDescription"] = df["riskElaboratedDescription"].str.replace( - "\n", "" - ) - df["articlePublishedDate"] = pd.to_datetime(df["articlePublishedDate"]) - df = df.sort_values(by=[sort], ascending=False) - return df - - -@log_start_end(log=logger) -# @check_api_key(["API_ULTIMA_KEY"]) -def supported_terms() -> list: - """Get supported terms for news. [Source: Ultima] - - Returns - ------- - terms: list - list of supported terms (tickers) - - """ - - # Necessary for installer so that it can locate the correct certificates for - # API calls and https - # 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"{ULTIMA_BASE_URL}/supportedTickers") - return list(data.json()) - - -@log_start_end(log=logger) -def get_company_info(ticker: str) -> dict: - """Get company info for a given ticker. [Source: Ultima Insights] - - Parameters - ---------- - ticker : str - ticker to search for company info - - Returns - ------- - company_info: dict - dictionary of company info - """ - - # Necessary for installer so that it can locate the correct certificates for - # API calls and https - # 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() - - if ticker in supported_terms(): - data = request(f"{ULTIMA_BASE_URL}/getCompanyInfo/{ticker}") - return data.json() - console.print("[red]Ticker not supported. Unable to retrieve data\n[/red]") - return {} - - -@log_start_end(log=logger) -def get_top_headlines(ticker: str) -> dict: - """Get top headlines for a given ticker. [Source: Ultima Insights] - - Parameters - ---------- - ticker : str - ticker to get top headlines for - - Returns - ------- - top_headlines: dict - dictionary of top headlines - """ - - # Necessary for installer so that it can locate the correct certificates for - # API calls and https - # 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() - - current_user = get_current_user() - if current_user.credentials.API_ULTIMA_KEY == NO_API_KEY: - auth_header = None - else: - auth_header = { - "Authorization": f"Bearer {current_user.credentials.API_ULTIMA_KEY}" - } - - if ticker in supported_terms(): - if auth_header: - data = request( - f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}", headers=auth_header - ) - else: - data = request(f"{ULTIMA_BASE_URL}/getTopHeadlines/{ticker}") - if ( - hasattr(data, "status") and data.status_code == 429 - ): # If data request failed - console.print( - "[red]Too many requests. Please get an API Key from https://www.ultimainsights.ai/[/red]" - ) - return {} - if ( - hasattr(data, "status") and data.status_code != 200 - ): # If data request failed - console.print("[red]Status code not 200. Unable to retrieve data\n[/red]") - return {} - json = data.json() - if "message" in json: - console.print(f"[red]{json['message']}[/red]") - return {} - return json - console.print("[red]Ticker not supported. Unable to retrieve data\n[/red]") - return {} diff --git a/openbb_terminal/common/ultima_newsmonitor_view.py b/openbb_terminal/common/ultima_newsmonitor_view.py deleted file mode 100644 index 3e01dd14a536..000000000000 --- a/openbb_terminal/common/ultima_newsmonitor_view.py +++ /dev/null @@ -1,130 +0,0 @@ -""" News View """ - -__docformat__ = "numpy" - -import datetime as dt -import logging -import os -from typing import Optional - -import pandas as pd - -from openbb_terminal.common import feedparser_model, ultima_newsmonitor_model -from openbb_terminal.decorators import log_start_end -from openbb_terminal.helper_funcs import export_data -from openbb_terminal.rich_config import console - -logger = logging.getLogger(__name__) - - -@log_start_end(log=logger) -def display_news( - term: str, - sources: str = "", - limit: int = 5, - export: str = "", - sheet_name: Optional[str] = None, - sort: str = "articlePublishedDate", -): - """Plots news for a given term and source. [Source: Ultima Insights] - - Parameters - ---------- - term : str - term to search on the news articles - sources : str - sources to exclusively show news from - limit : int - number of articles to display - export : str - Export dataframe data to csv,json,xlsx file - sort: str - the column to sort by - """ - console.print() - if term not in ultima_newsmonitor_model.supported_terms(): - console.print(f"[red]Unsupported ticker: {term}[/red]") - return - company_info = ultima_newsmonitor_model.get_company_info(term) - company_name = company_info.get("companyShortName", term) - # TODO: calling them all together does not work with feedparser - bbg = feedparser_model.get_news( - company_name, sources="bloomberg", sort="published", display_message=False - ) - wsj = feedparser_model.get_news( - company_name, sources="wsj", sort="published", display_message=False - ) - reuters = feedparser_model.get_news( - company_name, sources="reuters", sort="published", display_message=False - ) - cnbc = feedparser_model.get_news( - company_name, sources="cnbc", sort="published", display_message=False - ) - breaking_news = pd.concat([bbg, wsj, reuters, cnbc]) - if len(breaking_news) > 0: - breaking_news = breaking_news.sort_values(by="Date", ascending=False) - breaking_news["DateNorm"] = ( - pd.to_datetime(breaking_news["Date"]).dt.tz_convert(None).dt.normalize() - ) - today = pd.to_datetime("today").normalize() - breaking_news = breaking_news[breaking_news["DateNorm"] == today] - if len(breaking_news) > 0: - console.print( - "Uncategorized Breaking News (Bloomberg, Reuters, WSJ, CNBC):" - ) - for _, row in breaking_news.head(limit).iterrows(): - console.print(f"> {row['Date']} - {row['Description']}") - console.print(row["URL"] + "\n") - console.print("------------------------") - - top_headlines = ultima_newsmonitor_model.get_top_headlines(term) - if "summary" in top_headlines: - top_headlines = top_headlines["summary"] - else: - return - if "Ultima Insights was unable to identify" in top_headlines: - console.print( - f"[red]Most Relevant Articles for {term} - {dt.datetime.now().strftime('%Y-%m-%d')}\n{top_headlines}[/red]" - ) - else: - split = top_headlines.split("\n") - header = split[0] - if "Most" not in header: - header = f'Most Relevant Articles for {term} - {dt.datetime.now().strftime("%Y-%m-%d")}' - console.print(f"[purple][bold]{header}[/bold][/purple]\n") - for idx, row in enumerate(split[1:]): - if len(row) > 0: - inner_split = row.split(" - ") - risk = inner_split[0] - description = " - ".join(inner_split[1:]) - console.print(f"[green]{risk}[/green] (\x1B[3m{description}\x1B[0m)") - if idx < len(split[1:]) - 1: - console.print() - console.print("------------------------") - articles = ultima_newsmonitor_model.get_news(term, sort) - articles = articles.head(limit).sort_values(by="relevancyScore", ascending=False) - console.print(f"\n[purple][bold]News for {company_name}:[/bold][/purple]\n\n") - for _, row in articles.iterrows(): - console.print( - f"> {row['articlePublishedDate']} - {row['articleHeadline']}\n" - f"[purple]Relevancy score: {round(row['relevancyScore'], 2) if row['relevancyScore'] < 5 else 5}" - f"/5 Stars[/purple]\n[green]{row['riskCategory']}[/green] " - f"(\x1B[3m{row['riskElaboratedDescription']}\x1B[0m)" - ) - console.print(f"Read more: {row['articleURL']}\n") - # console.print("[purple]To report any issues, please visit https://beta.ultimainsights.ai/my-account/support[/purple]\n") - console.print() - - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - f"news_{'_'.join(term)}_{'_'.join(sources)}", - articles, - sheet_name, - ) - - -@log_start_end(log=logger) -def supported_terms() -> list: - """Returns supported terms for news""" - return ultima_newsmonitor_model.supported_terms() diff --git a/openbb_terminal/keys_model.py b/openbb_terminal/keys_model.py index 18b09a773903..e07bf2daae7d 100644 --- a/openbb_terminal/keys_model.py +++ b/openbb_terminal/keys_model.py @@ -2546,75 +2546,6 @@ def check_databento_key(show_output: bool = False) -> str: return str(status) -def set_ultima_key(key: str, persist: bool = False, show_output: bool = False) -> str: - """Set Ultima Insights key - - Parameters - ---------- - key: str - API key - persist: bool, optional - If False, api key change will be contained to where it was changed. For example, a Jupyter notebook session. - If True, api key change will be global, i.e. it will affect terminal environment variables. - By default, False. - show_output: bool, optional - Display status string or not. By default, False. - - Returns - ------- - str - Status of key set - - Examples - -------- - >>> from openbb_terminal.sdk import openbb - >>> openbb.keys.ultima(key="example_key") - """ - - handle_credential("API_ULTIMA_KEY", key, persist) - return check_ultima_key(show_output) - - -def check_ultima_key(show_output: bool = False) -> str: - """Check Ultima Insights key - - Parameters - ---------- - show_output: bool - Display status string or not. By default, False. - - Returns - ------- - str - Status of key set - """ - - current_user = get_current_user() - - if current_user.credentials.API_ULTIMA_KEY == "REPLACE_ME": - status = KeyStatus.NOT_DEFINED - else: - r = request( - "https://api.ultimainsights.ai/v1/checkAPIKey", - headers={ - "Authorization": f"Bearer {current_user.credentials.API_ULTIMA_KEY}" - }, - ) - if r.status_code in [403, 401, 429]: - logger.warning("Ultima Insights key defined, test failed") - status = KeyStatus.DEFINED_TEST_FAILED - elif r.status_code == 200: - status = KeyStatus.DEFINED_TEST_PASSED - else: - logger.warning("Ultima Insights key defined, test inconclusive") - status = KeyStatus.DEFINED_TEST_INCONCLUSIVE - - if show_output: - console.print(status.colorize()) - - return str(status) - - def set_dappradar_key( key: str, persist: bool = False, show_output: bool = False ) -> str: diff --git a/openbb_terminal/miscellaneous/models/all_api_keys.json b/openbb_terminal/miscellaneous/models/all_api_keys.json index 9989944f2168..1b9cf1fba77e 100644 --- a/openbb_terminal/miscellaneous/models/all_api_keys.json +++ b/openbb_terminal/miscellaneous/models/all_api_keys.json @@ -1,10 +1,4 @@ [ - { - "name": "API_ULTIMA_KEY", - "source": "Ultima Insights", - "link": "https://www.ultimainsights.ai/", - "markdown": "Go to: https://ultimainsights.ai/openbb\n\n![Ultima Insights](https://user-images.githubusercontent.com/1911913/229215125-e3419788-eef3-4389-a3bd-5c08f3333347.png)\n\nClick on, \"Get Started\", to start the sign-up process. After the account has been setup, navigate to [Generate API Key](https://beta.ultimainsights.ai/my-account/generate-api-key) and click \"Generate Key\"." - }, { "name": "API_KEY_ALPHAVANTAGE", "source": "Alpha Vantage", diff --git a/openbb_terminal/miscellaneous/models/hub_credentials.json b/openbb_terminal/miscellaneous/models/hub_credentials.json index dfc75bc84301..9f5b57cadaa9 100644 --- a/openbb_terminal/miscellaneous/models/hub_credentials.json +++ b/openbb_terminal/miscellaneous/models/hub_credentials.json @@ -1,6 +1,4 @@ { - "API_OPENAI_KEY": "", - "API_ULTIMA_KEY": "", "API_DATABENTO_KEY": "", "API_KEY_ALPHAVANTAGE": "", "API_KEY_FINANCIALMODELINGPREP": "", diff --git a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py index 09bcd28bd957..262eafd42c26 100644 --- a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py +++ b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py @@ -30,7 +30,6 @@ from openbb_terminal.rich_config import MenuText, console from openbb_terminal.stocks.behavioural_analysis import ( finnhub_view, - news_sentiment_view, ) # pylint:disable=R0904,C0302 @@ -57,7 +56,6 @@ class BehaviouralAnalysisController(StockBaseController): "headlines", "snews", "interest", - "ns", ] historical_sort = ["date", "value"] @@ -100,7 +98,6 @@ def print_help(self): mt.add_cmd("interest", self.ticker) mt.add_cmd("queries", self.ticker) mt.add_cmd("rise", self.ticker) - mt.add_cmd("ns") console.print(text=mt.menu_text, menu="Stocks - Behavioural Analysis") def custom_reset(self): @@ -587,83 +584,3 @@ def call_headlines(self, other_args: List[str]): ) else: console.print("No ticker loaded. Please load using 'load '\n") - - def call_ns(self, other_args: List[str]): - """Process ns command.""" - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="ns", - description="Shows the News Sentiment articles data", - ) - parser.add_argument( - "-t", - "--ticker", - dest="ticker", - type=str, - default=None, - help="Ticker to search for.", - ) - parser.add_argument( - "-s", - "--start_date", - dest="start_date", - type=str, - default=None, - help="The starting date (format YYYY-MM-DD) to search news articles from", - ) - parser.add_argument( - "-e", - "--end_date", - dest="end_date", - type=str, - default=None, - help="The end date (format YYYY-MM-DD) to search news articles upto", - ) - parser.add_argument( - "-d", - "--date", - dest="date", - type=str, - default=None, - help="""Shows the news articles data on this day (format YYYY-MM-DD). - If you use this Argument start date and end date will be ignored - """, - ) - parser.add_argument( - "-l", - "--limit", - default=10, - dest="limit", - type=check_non_negative, - help="Number of news articles to be displayed.", - ) - parser.add_argument( - "-o", - "--offset", - default=0, - dest="offset", - type=check_non_negative, - help="offset indicates the starting position of news articles.", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - ns_parser = self.parse_known_args_and_warn( - parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED - ) - if ns_parser: - if ns_parser.ticker: - self.ticker = ns_parser.ticker - - news_sentiment_view.display_articles_data( - ticker=self.ticker, - start_date=ns_parser.start_date, - end_date=ns_parser.end_date, - date=ns_parser.date, - limit=ns_parser.limit, - offset=ns_parser.offset, - export=ns_parser.export, - sheet_name=( - " ".join(ns_parser.sheet_name) if ns_parser.sheet_name else None - ), - ) diff --git a/openbb_terminal/stocks/behavioural_analysis/news_sentiment_model.py b/openbb_terminal/stocks/behavioural_analysis/news_sentiment_model.py deleted file mode 100644 index a1346f6a4590..000000000000 --- a/openbb_terminal/stocks/behavioural_analysis/news_sentiment_model.py +++ /dev/null @@ -1,98 +0,0 @@ -"""Onclusive Data Model""" - -import datetime - -import pandas as pd -import requests - -from openbb_terminal.rich_config import console - - -def get_data( - ticker: str = "", - start_date: str = "", - end_date: str = "", - date: str = "", - limit: int = 100, - offset: int = 0, -) -> pd.DataFrame: - """Getting Onclusive Data. [Source: Invisage Platform] - - Parameters - ---------- - ticker : str - Stock ticker - start_date : str - Records are coming from this day (Start date in YYYY-MM-DD format) - end_date : str - Records will get upto this day (End date in YYYY-MM-DD format) - date : str - Show that the records on this day (date in YYYY-MM-DD format) - limit: int - The number of records to get - offset : int - The number of records to offset - """ - - headers = {"accept": "application/json"} - - df = pd.DataFrame(data=None) - - query_params = { - "all_feilds": "False", - "ordering": "-published_on,-entity_score,-share_of_article,-pagerank", - } - if ticker: - query_params["ticker"] = ticker - if start_date: - query_params["published_on__gte"] = start_date - if end_date: - query_params["published_on__lte"] = end_date - - if start_date and end_date and not date and start_date > end_date: - console.print("start_date must be less than end_date") - return df - - if date: - dtdate = datetime.datetime.strptime(date, "%Y-%m-%d").date() - query_params["published_on"] = str(dtdate) - if start_date: - if str(dtdate) < start_date: - console.print("date must be grater than or equal to start_date") - return df - del query_params["published_on__gte"] - if end_date: - del query_params["published_on__lte"] - - if limit: - query_params["limit"] = limit # type:ignore - if offset: - query_params["offset"] = offset # type:ignore - - response = requests.get( - "https://data-access.althub.com/api/OnclusiveSentiment/", - headers=headers, - params=query_params, - timeout=5, - ).json() - df = pd.DataFrame(data=response["results"]) - if not df.empty: - df["adjusted_sentiment"] = df["adjusted_sentiment"].astype(float) - - def condition(x): - if x >= 250: - return "Super Positive" - if 0 < x < 250: - return "Positive" - if x == 0: - return "Neutral" - if -250 < x < 0: - return "Negative" - return "Super Negative" - - sentiment = {50: "Positive", -50: "Negative", 0: "Neutral", None: "Neutral"} - - if not df.empty: - df["raw_sentiment"] = df["raw_sentiment"].map(sentiment) - df["adjusted_sentiment"] = df["adjusted_sentiment"].apply(condition) - return df diff --git a/openbb_terminal/stocks/behavioural_analysis/news_sentiment_view.py b/openbb_terminal/stocks/behavioural_analysis/news_sentiment_view.py deleted file mode 100644 index 67762854a6cf..000000000000 --- a/openbb_terminal/stocks/behavioural_analysis/news_sentiment_view.py +++ /dev/null @@ -1,72 +0,0 @@ -"""Onclusive Data Model""" - -__docformat__ = "numpy" - - -import os -from typing import Optional - -from openbb_terminal.helper_funcs import export_data -from openbb_terminal.rich_config import console -from openbb_terminal.stocks.behavioural_analysis import news_sentiment_model - - -def display_articles_data( - ticker: str = "", - start_date: str = "", - end_date: str = "", - date: str = "", - limit: int = 100, - offset: int = 0, - export: str = "", - sheet_name: Optional[str] = None, -) -> None: - """Display Onclusive Data. [Source: Invisage Plotform] - - Parameters - ---------- - ticker : str - Stock ticker - start_date : str - Records are coming from this day (Start date in YYYY-MM-DD format) - end_date : str - Records will get upto this day (End date in YYYY-MM-DD format) - date : str - Show that the records on this day (date in YYYY-MM-DD format) - limit: int - The number of records to get - offset : int - The number of records to offset - export : str - Export dataframe data to csv,json,xlsx file - """ - - df = news_sentiment_model.get_data( - ticker=ticker, - start_date=start_date, - end_date=end_date, - date=date, - limit=limit, - offset=offset, - ) - df.dropna(how="all", axis=1, inplace=True) - df = df.replace(float("NaN"), "") - if df.empty: - console.print("No data found.") - else: - for row in df.itertuples(): - console.print() - console.print("Date : ", row.published_on) - console.print("Ticker : ", row.ticker) - console.print("Article Name : ", row.article_title) - console.print("Article URL : ", row.article_url) - console.print("Article Sentiment : ", row.raw_sentiment) - console.print("Article Adjusted Sentiment : ", row.adjusted_sentiment) - console.print() - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "News Sentiment", - df, - sheet_name, - ) diff --git a/openbb_terminal/stocks/stocks_controller.py b/openbb_terminal/stocks/stocks_controller.py index 94c64d9b876a..f187819ae3ba 100644 --- a/openbb_terminal/stocks/stocks_controller.py +++ b/openbb_terminal/stocks/stocks_controller.py @@ -14,7 +14,6 @@ from openbb_terminal.common import ( feedparser_view, newsapi_view, - ultima_newsmonitor_view, ) from openbb_terminal.common.quantitative_analysis import qa_view from openbb_terminal.core.session.current_user import get_current_user @@ -608,27 +607,6 @@ def call_news(self, other_args: List[str]): show_newest=ns_parser.n_oldest, sources=ns_parser.sources, ) - elif str(ns_parser.source).lower() == "ultima": - query = str(self.ticker).upper() - if query not in ultima_newsmonitor_view.supported_terms(): - console.print( - "[red]Ticker not supported by Ultima Insights News Monitor. Falling back to default.\n[/red]" - ) - feedparser_view.display_news( - term=query, - sources=ns_parser.sources, - limit=ns_parser.limit, - export=ns_parser.export, - sheet_name=ns_parser.sheet_name, - ) - else: - ultima_newsmonitor_view.display_news( - term=query, - sources=ns_parser.sources, - limit=ns_parser.limit, - export=ns_parser.export, - sheet_name=ns_parser.sheet_name, - ) elif ns_parser.source == "Feedparser": feedparser_view.display_news( term=self.ticker, From 8b68f23f94adb23044ab4af8e8e1eb0df9325697 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Tue, 27 Feb 2024 15:36:51 -0500 Subject: [PATCH 2/6] move twitter keys --- .../core/openbb_core/app/model/hub/features_keys.py | 3 --- openbb_terminal/miscellaneous/models/hub_credentials.json | 3 --- openbb_terminal/stocks/behavioural_analysis/ba_controller.py | 1 - 3 files changed, 7 deletions(-) diff --git a/openbb_platform/core/openbb_core/app/model/hub/features_keys.py b/openbb_platform/core/openbb_core/app/model/hub/features_keys.py index ad342f6345b6..c0653ff443c7 100644 --- a/openbb_platform/core/openbb_core/app/model/hub/features_keys.py +++ b/openbb_platform/core/openbb_core/app/model/hub/features_keys.py @@ -34,7 +34,4 @@ class FeaturesKeys(BaseModel): API_SMARTSTAKE_KEY: Optional[str] = Field(default=None) API_SMARTSTAKE_TOKEN: Optional[str] = Field(default=None) API_TOKEN_TERMINAL_KEY: Optional[str] = Field(default=None) - API_TWITTER_BEARER_TOKEN: Optional[str] = Field(default=None) - API_TWITTER_KEY: Optional[str] = Field(default=None) - API_TWITTER_SECRET_KEY: Optional[str] = Field(default=None) API_WHALE_ALERT_KEY: Optional[str] = Field(default=None) diff --git a/openbb_terminal/miscellaneous/models/hub_credentials.json b/openbb_terminal/miscellaneous/models/hub_credentials.json index 9f5b57cadaa9..8edb791283af 100644 --- a/openbb_terminal/miscellaneous/models/hub_credentials.json +++ b/openbb_terminal/miscellaneous/models/hub_credentials.json @@ -29,9 +29,6 @@ "API_REDDIT_USERNAME": "", "API_REDDIT_USER_AGENT": "", "API_REDDIT_PASSWORD": "", - "API_TWITTER_KEY": "", - "API_TWITTER_SECRET_KEY": "", - "API_TWITTER_BEARER_TOKEN": "", "API_COMPANIESHOUSE_KEY": "", "API_DAPPRADAR_KEY": "", "API_KEY_NIXTLA": "" diff --git a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py index 262eafd42c26..ff30679539a8 100644 --- a/openbb_terminal/stocks/behavioural_analysis/ba_controller.py +++ b/openbb_terminal/stocks/behavioural_analysis/ba_controller.py @@ -21,7 +21,6 @@ from openbb_terminal.helper_funcs import ( EXPORT_BOTH_RAW_DATA_AND_FIGURES, EXPORT_ONLY_RAW_DATA_ALLOWED, - check_non_negative, check_positive, valid_date, ) From 62334ea270c7682ea56d8bf1cce837e232088439 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 8 Jul 2024 13:37:04 -0400 Subject: [PATCH 3/6] Extract provider from kwargs and add to logs --- .../core/openbb_core/app/logs/logging_service.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/openbb_platform/core/openbb_core/app/logs/logging_service.py b/openbb_platform/core/openbb_core/app/logs/logging_service.py index 9bbbb71cee38..73b578e49b61 100644 --- a/openbb_platform/core/openbb_core/app/logs/logging_service.py +++ b/openbb_platform/core/openbb_core/app/logs/logging_service.py @@ -14,9 +14,14 @@ from openbb_core.app.model.abstract.singleton import SingletonMeta from openbb_core.app.model.system_settings import SystemSettings from openbb_core.app.model.user_settings import UserSettings +from pydantic import BaseModel from pydantic_core import to_jsonable_python +class DummyProvider(BaseModel): + provider: str = "not_passed_to_kwargs" + + class LoggingService(metaclass=SingletonMeta): """Logging Manager class responsible for managing logging settings and handling logs. @@ -221,9 +226,16 @@ def log( # Remove CommandContext if any kwargs.pop("cc", None) + # Get provider for posthog logs + passed_model = kwargs.get("provider_choices", DummyProvider()) + provider = ( + passed_model.provider + if hasattr(passed_model, "provider") + else "not_passed_to_kwargs" + ) + # Truncate kwargs if too long kwargs = {k: str(v)[:100] for k, v in kwargs.items()} - # Get execution info error = None if all(i is None for i in exec_info) else str(exec_info[1]) @@ -234,6 +246,7 @@ def log( "route": route, "input": kwargs, "error": error, + "provider": provider, "custom_headers": custom_headers, }, default=to_jsonable_python, From 16527d5f1aef2daa887c4a92c811858f6de14452 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 8 Jul 2024 13:48:26 -0400 Subject: [PATCH 4/6] pydocstyle --- openbb_platform/core/openbb_core/app/logs/logging_service.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openbb_platform/core/openbb_core/app/logs/logging_service.py b/openbb_platform/core/openbb_core/app/logs/logging_service.py index 73b578e49b61..032069f7c786 100644 --- a/openbb_platform/core/openbb_core/app/logs/logging_service.py +++ b/openbb_platform/core/openbb_core/app/logs/logging_service.py @@ -19,6 +19,8 @@ class DummyProvider(BaseModel): + """Dummy Provider for error handling with logs""" + provider: str = "not_passed_to_kwargs" From f5cb30cde0ca39ccc274d4caf886f9471590e8f1 Mon Sep 17 00:00:00 2001 From: James Maslek Date: Mon, 8 Jul 2024 16:26:45 -0400 Subject: [PATCH 5/6] update test --- openbb_platform/core/tests/app/logs/test_logging_service.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openbb_platform/core/tests/app/logs/test_logging_service.py b/openbb_platform/core/tests/app/logs/test_logging_service.py index 422f25947ab5..1404ddf4ccb9 100644 --- a/openbb_platform/core/tests/app/logs/test_logging_service.py +++ b/openbb_platform/core/tests/app/logs/test_logging_service.py @@ -146,7 +146,8 @@ class MockCredentials(BaseModel): {}, (None, None, None), None, - 'CMD: {"route": "mock_route", "input": {}, "error": null, "custom_headers": null}', + 'CMD: {"route": "mock_route", "input": {}, "error": null, ' + '"custom_headers": null,"provider":"not_passed_to_kwargs"}', ), ( "mock_settings", @@ -160,7 +161,7 @@ class MockCredentials(BaseModel): ..., ), # ... is of TracebackType, but unnecessary for the test {"X-OpenBB-Test": "test"}, - 'ERROR: {"route": "mock_route", "input": {}, "error": "mock_error", "custom_headers": {"X-OpenBB-Test": "test"}}', # noqa: E501 + 'ERROR: {"route": "mock_route", "input": {}, "error": "mock_error", "provider":"not_passed_to_kwargs","custom_headers": {"X-OpenBB-Test": "test"}}', # noqa: E501 ), ( "mock_settings", From ef7467b6ded552e475b376c1cd456524cb256179 Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:16:08 -0700 Subject: [PATCH 6/6] fix tests --- openbb_platform/core/tests/app/logs/test_logging_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbb_platform/core/tests/app/logs/test_logging_service.py b/openbb_platform/core/tests/app/logs/test_logging_service.py index 1404ddf4ccb9..89e56a777cba 100644 --- a/openbb_platform/core/tests/app/logs/test_logging_service.py +++ b/openbb_platform/core/tests/app/logs/test_logging_service.py @@ -147,7 +147,7 @@ class MockCredentials(BaseModel): (None, None, None), None, 'CMD: {"route": "mock_route", "input": {}, "error": null, ' - '"custom_headers": null,"provider":"not_passed_to_kwargs"}', + + '"provider": "not_passed_to_kwargs", "custom_headers": null}', ), ( "mock_settings", @@ -161,7 +161,7 @@ class MockCredentials(BaseModel): ..., ), # ... is of TracebackType, but unnecessary for the test {"X-OpenBB-Test": "test"}, - 'ERROR: {"route": "mock_route", "input": {}, "error": "mock_error", "provider":"not_passed_to_kwargs","custom_headers": {"X-OpenBB-Test": "test"}}', # noqa: E501 + 'ERROR: {"route": "mock_route", "input": {}, "error": "mock_error", "provider": "not_passed_to_kwargs", "custom_headers": {"X-OpenBB-Test": "test"}}', # noqa: E501 ), ( "mock_settings",