summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Maslek <jmaslek11@gmail.com>2023-08-28 10:50:30 -0400
committerJames Maslek <jmaslek11@gmail.com>2023-08-28 10:50:30 -0400
commitf0e1fb79fee1378abaf55c9b8403ec07bc819583 (patch)
tree9195c68605dc2b517124abd2212a3073170cf29f
parent0b7b63ebfa0c10861c257617a1f51eac10e24392 (diff)
parentdb9d462188d6115d9a3e215ea3b633bb26fcd97e (diff)
Merge branch 'develop' of https://github.com/OpenBB-finance/OpenBBTerminal into develop
-rwxr-xr-xbuild/pyinstaller/macOS_package_assets/OpenBB Terminal/OpenBB Terminal10
-rw-r--r--openbb_terminal/alternative/alt_controller.py12
-rw-r--r--openbb_terminal/alternative/companieshouse/companieshouse_controller.py337
-rw-r--r--openbb_terminal/alternative/companieshouse/companieshouse_model.py481
-rw-r--r--openbb_terminal/alternative/companieshouse/companieshouse_view.py253
-rw-r--r--openbb_terminal/alternative/companieshouse/company.py14
-rw-r--r--openbb_terminal/alternative/companieshouse/company_doc.py31
-rw-r--r--openbb_terminal/alternative/companieshouse/filing_data.py19
-rw-r--r--openbb_terminal/core/config/paths_helper.py1
-rw-r--r--openbb_terminal/core/models/preferences_model.py1
-rw-r--r--openbb_terminal/core/sdk/controllers/alt_sdk_controller.py17
-rw-r--r--openbb_terminal/core/sdk/models/alt_sdk_model.py37
-rw-r--r--openbb_terminal/core/sdk/sdk_init.py2
-rw-r--r--openbb_terminal/core/sdk/trail_map.csv8
-rw-r--r--openbb_terminal/keys_controller.py30
-rw-r--r--openbb_terminal/keys_model.py77
-rw-r--r--openbb_terminal/miscellaneous/i18n/en.yml15
-rw-r--r--openbb_terminal/miscellaneous/models/hub_credentials.json1
-rw-r--r--openbb_terminal/sdk.py1
-rw-r--r--poetry.lock87
-rw-r--r--pyproject.toml2
-rw-r--r--requirements-full.txt4
-rw-r--r--requirements.txt4
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/test_companieshouse_controller.py172
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/test_companieshouse_model.py299
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/test_companieshouse_view.py283
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_controller/test_print_help.txt10
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_view/test_display_charges.txt11
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_view/test_display_filings.txt5
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_view/test_display_officers.txt3
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_view/test_display_persons_with_significant_control.txt3
-rw-r--r--tests/openbb_terminal/alternative/companieshouse/txt/test_companieshouse_view/test_display_search.txt4
-rw-r--r--tests/openbb_terminal/alternative/txt/test_alt_controller/test_print_help.txt7
-rw-r--r--website/content/sdk/usage/guides/api-keys.md28
-rw-r--r--website/content/terminal/usage/guides/api-keys.md23
35 files changed, 2209 insertions, 83 deletions
diff --git a/build/pyinstaller/macOS_package_assets/OpenBB Terminal/OpenBB Terminal b/build/pyinstaller/macOS_package_assets/OpenBB Terminal/OpenBB Terminal
index cec491e5f10..8975d7a8604 100755
--- a/build/pyinstaller/macOS_package_assets/OpenBB Terminal/OpenBB Terminal
+++ b/build/pyinstaller/macOS_package_assets/OpenBB Terminal/OpenBB Terminal
@@ -15,7 +15,17 @@ echo " |___/ "
BOOTUP_MESSAGE="
The boot up process might take a while. Please be patient...
+
+Have you checked out Community Routines yet? You can access them through the OpenBB Hub!
+Get started in less than 3 minutes: https://www.youtube.com/watch?v=UFh_Ku0fdtY
+
"
echo "$BOOTUP_MESSAGE"
+# Add some messages we can print out
+messages=("" "" "" "" "Did you know that you can search for stocks from a given country by running stocks/search --exchangecountry COUNTRY")
+# Pick a random one
+index=$((RANDOM % ${#messages[@]}))
+echo ${messages[$index]}
+
"$SCRIPTDIR"/.OpenBB/OpenBBTerminal
diff --git a/openbb_terminal/alternative/alt_controller.py b/openbb_terminal/alternative/alt_controller.py
index cc4e7e1713d..4352e8193df 100644
--- a/openbb_terminal/alternative/alt_controller.py
+++ b/openbb_terminal/alternative/alt_controller.py
@@ -22,7 +22,7 @@ class AlternativeDataController(BaseController):
"""Alternative Controller class"""
CHOICES_COMMANDS: List[str] = ["hn"]
- CHOICES_MENUS = ["covid", "oss", "realestate"]
+ CHOICES_MENUS = ["covid", "oss", "realestate", "companieshouse"]
PATH = "/alternative/"
CHOICES_GENERATION = True
@@ -41,6 +41,7 @@ class AlternativeDataController(BaseController):
mt.add_menu("covid")
mt.add_menu("oss")
mt.add_menu("realestate")
+ mt.add_menu("companieshouse")
mt.add_raw("\n")
mt.add_cmd("hn")
console.print(text=mt.menu_text, menu="Alternative")
@@ -94,3 +95,12 @@ class AlternativeDataController(BaseController):
)
self.queue = self.load_class(RealEstateController, self.queue)
+
+ @log_start_end(log=logger)
+ def call_companieshouse(self, _):
+ """Process companieshouse command."""
+ from openbb_terminal.alternative.companieshouse.companieshouse_controller import (
+ CompaniesHouseController,
+ )
+
+ self.queue = self.load_class(CompaniesHouseController, self.queue)
diff --git a/openbb_terminal/alternative/companieshouse/companieshouse_controller.py b/openbb_terminal/alternative/companieshouse/companieshouse_controller.py
new file mode 100644
index 00000000000..40353ba5b00
--- /dev/null
+++ b/openbb_terminal/alternative/companieshouse/companieshouse_controller.py
@@ -0,0 +1,337 @@
+"""Companies House Controller."""
+__docformat__ = "numpy"
+
+import argparse
+import logging
+from typing import List, Optional
+
+from openbb_terminal.alternative.companieshouse import companieshouse_view
+from openbb_terminal.core.session.current_user import get_current_user
+from openbb_terminal.custom_prompt_toolkit import NestedCompleter
+from openbb_terminal.decorators import check_api_key, log_start_end
+from openbb_terminal.helper_funcs import (
+ EXPORT_ONLY_RAW_DATA_ALLOWED,
+ check_positive,
+)
+from openbb_terminal.menu import session
+from openbb_terminal.parent_classes import BaseController
+from openbb_terminal.rich_config import MenuText, console
+
+logger = logging.getLogger(__name__)
+
+
+class CompaniesHouseController(BaseController):
+
+ """Companies House Controller class."""
+
+ CHOICES_COMMANDS = [
+ "search",
+ "load",
+ "officers",
+ "signifcontrol",
+ "filings",
+ "filingdocument",
+ "charges",
+ ]
+ PATH = "/alternative/companieshouse/"
+ CHOICES_GENERATION = True
+
+ def __init__(self, queue: Optional[List[str]] = None):
+ """Construct Data."""
+ super().__init__(queue)
+
+ self.companyNo = ""
+ self.companyName = ""
+ self.filingCategory = ""
+ self.filing_total_count = 0
+ self.filing_end_index = 0
+ self.filing_start_index = 0
+ if session and get_current_user().preferences.USE_PROMPT_TOOLKIT:
+ choices: dict = self.choices_default
+ self.completer = NestedCompleter.from_nested_dict(choices)
+
+ def print_help(self):
+ """Print help"""
+ company_string = (
+ f"{self.companyNo} ({self.companyName})" if self.companyNo else ""
+ )
+
+ mt = MenuText("alternative/companieshouse/")
+ mt.add_param("_company", company_string)
+ mt.add_raw("\n")
+ mt.add_cmd("search")
+ mt.add_cmd("load")
+ mt.add_cmd("officers")
+ mt.add_cmd("signifcontrol")
+ mt.add_cmd("filings")
+ mt.add_cmd("filingdocument")
+ mt.add_cmd("charges")
+
+ console.print(text=mt.menu_text, menu="UK Companies House Data")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_search(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="search",
+ description="Select the company name to search for. [Source: UK Companies House]",
+ )
+ parser.add_argument(
+ "-n",
+ "--name",
+ help="name",
+ type=str.upper,
+ required="-h" not in other_args,
+ dest="name",
+ metavar="name",
+ nargs="+",
+ )
+
+ parser.add_argument(
+ "-l",
+ "--limit",
+ help="Number of entries to return",
+ type=check_positive,
+ required=False,
+ dest="limit",
+ metavar="limit",
+ default=20,
+ )
+
+ if (
+ other_args
+ and "-n" not in other_args[0]
+ and "--name" not in other_args[0]
+ and "-h" not in other_args
+ ):
+ other_args.insert(0, "-n")
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if ns_parser:
+ if ns_parser.name:
+ query = " ".join(ns_parser.name)
+ companieshouse_view.display_search(
+ query, ns_parser.limit, export=ns_parser.export
+ )
+ else:
+ console.print("[red]No entries found for search string[/red]\n")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_load(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="load",
+ description="Select the company number to get detailed info on. [Source: UK Companies House]",
+ )
+ parser.add_argument(
+ "-c",
+ "--companyNo",
+ help="companyNo",
+ type=str.upper,
+ required="-h" not in other_args,
+ dest="companyNo",
+ metavar="companyNo",
+ )
+
+ if (
+ other_args
+ and "-c" not in other_args[0]
+ and "--companyNo" not in other_args[0]
+ and "-h" not in other_args
+ ):
+ other_args.insert(0, "-c")
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if ns_parser and ns_parser.companyNo:
+ self.companyNo = ns_parser.companyNo
+ company = companieshouse_view.display_company_info(
+ ns_parser.companyNo, export=ns_parser.export
+ )
+ if company.dataAvailable():
+ self.companyName = company.name
+ self.filing_total_count = 0
+ self.filing_end_index = 0
+ console.print(company.name)
+ console.print(company.address)
+ console.print(company.lastAccounts)
+ else:
+ console.print(
+ f"[red]No data found for company number {ns_parser.companyNo}[/red]\n"
+ )
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_officers(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="officers",
+ description="Select the company number to retrieve officers for. [Source: UK Companies House]",
+ )
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if self.companyNo:
+ if ns_parser:
+ companieshouse_view.display_officers(
+ self.companyNo, export=ns_parser.export
+ )
+ else:
+ console.print("Must load a company prior to using this command")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_signifcontrol(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="signifcontrol",
+ description="Select the company number to retrieve persons with significant control of company. \
+ [Source: UK Companies House]",
+ )
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if self.companyNo:
+ if ns_parser:
+ companieshouse_view.display_persons_with_significant_control(
+ self.companyNo, export=ns_parser.export
+ )
+ else:
+ console.print("Must load a company prior to using this command")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_filings(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="filings",
+ description="Select the company number to retrieve filling history for. [Source: UK Companies House]",
+ )
+
+ parser.add_argument(
+ "-k",
+ "--category",
+ help="category",
+ type=str.lower,
+ required=False,
+ dest="category",
+ metavar="category",
+ choices=[
+ "accounts",
+ "address",
+ "capital",
+ "incorporation",
+ "officers",
+ "resolution",
+ ],
+ )
+
+ parser.add_argument(
+ "-l",
+ "--limit",
+ help="Number of entries to return",
+ type=check_positive,
+ required=False,
+ dest="limit",
+ metavar="limit",
+ default=100,
+ )
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if self.companyNo:
+ if ns_parser:
+ category = ns_parser.category if ns_parser.category else ""
+ self.filingCategory = category
+ filing_data = companieshouse_view.display_filings(
+ self.companyNo, category, ns_parser.limit, export=ns_parser.export
+ )
+ self.filing_total_count = filing_data.total_count
+ self.filing_end_index = filing_data.end_index
+ self.filing_start_index = filing_data.start_index
+ else:
+ console.print("Must load a company prior to using this command")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_filingdocument(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="filingdocument",
+ description="Select the company number and transaction ID to retrieve filling history for. \
+ [Source: UK Companies House]",
+ )
+
+ parser.add_argument(
+ "-t",
+ "--transactionID",
+ help="transactionID",
+ action="store",
+ required=("-h" not in other_args),
+ dest="transactionID",
+ metavar="transactionID",
+ )
+
+ if (
+ other_args
+ and "-t" not in other_args[0]
+ and "--transactionID" not in other_args[0]
+ and "-h" not in other_args
+ ):
+ other_args.insert(0, "-t")
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if self.companyNo:
+ if ns_parser:
+ companieshouse_view.download_filing_document(
+ self.companyNo,
+ self.companyName,
+ ns_parser.transactionID,
+ export=ns_parser.export,
+ )
+ else:
+ console.print("Must load a company prior to using this command")
+
+ @log_start_end(log=logger)
+ @check_api_key(["API_COMPANIESHOUSE_KEY"])
+ def call_charges(self, other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prog="charges",
+ description="Select the company number to retrieve officers for. [Source: UK Companies House]",
+ )
+
+ ns_parser = self.parse_known_args_and_warn(
+ parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
+ )
+
+ if self.companyNo:
+ if ns_parser:
+ companieshouse_view.display_charges(
+ self.companyNo, export=ns_parser.export
+ )
+ else:
+ console.print("Must load a company prior to using this command")
diff --git a/openbb_terminal/alternative/companieshouse/companieshouse_model.py b/openbb_terminal/alternative/companieshouse/companieshouse_model.py
new file mode 100644
index 00000000000..462553956f8
--- /dev/null
+++ b/openbb_terminal/alternative/companieshouse/companieshouse_model.py
@@ -0,0 +1,481 @@
+""" UK Companies House Model """
+__docformat__ = "numpy"
+
+import logging
+
+import pandas as pd
+import requests
+
+from openbb_terminal.alternative.companieshouse.company import Company
+from openbb_terminal.alternative.companieshouse.company_doc import CompanyDocument
+from openbb_terminal.alternative.companieshouse.filing_data import Filing_data
+from openbb_terminal.core.session.constants import (
+ TIMEOUT,
+)
+from openbb_terminal.core.session.current_user import get_current_user
+from openbb_terminal.decorators import check_api_key, log_start_end
+
+logger = logging.getLogger(__name__)
+
+
+@log_start_end(log=logger)
+@check_api_key(["API_COMPANIESHOUSE_KEY"])
+def get_search_results(searchStr: str, limit: int = 20) -> pd.DataFrame:
+ """All companies with searchStr in their name.
+
+ Parameters
+ ----------
+ searchStr : str
+ The search string
+ limit : int
+ number of rows to return
+
+ Returns
+ -------
+ pd.DataFrame
+ All comapanies with the search string in their name.
+
+ Example
+ -------
+ >>> from openbb_terminal.sdk import openbb
+ >>> companies = openbb.alt.companieshouse.get_search_results("AstraZeneca")
+ """
+
+ df = pd.DataFrame()
+
+ if not searchStr:
+ return df
+
+ auth = requests.auth.HTTPBasicAuth(
+ get_current_user().credentials.API_COMPANIESHOUSE_KEY, ""
+ )
+ r = requests.get(
+ "https://api.company-information.service.gov.uk/search/companies?q="
+ + searchStr
+ + f"&items_per_page={limit}",
+ auth=auth,
+ timeout=TIMEOUT,
+ )
+ returned_data = r.json()
+ company_data = []
+ for index, item in enumerate(returned_data["items"]):
+ company_data.append(
+ {
+ "Name": item["title"],
+ "Company Number": item["company_number"],
+ "Status": item["company_status"],
+ }
+ )
+
+ df = pd.DataFrame(company_data)
+ return df
+
+
+@log_start_end(log=logger)
+@check_api_key(["API_COMPANIESHOUSE_KEY"])
+def get_company_info(company_number: str) -> Company:
+ """Gets company info by company number
+
+ Parameters
+ ----------
+ company_number : str
+ The company number. Use get_search_results() to lookup company numbers.
+
+ Returns
+ -------
+ self.address: str
+ Company address.
+ self.name: str
+ Company name.
+ self.dataAvailable(): bool
+ True if data is available.
+ self.lastAccounts: str
+ Period start and end.
+
+ Example
+ -------
+ >>> companies = openbb.alt.companieshouse.get_search_results("AstraZeneca")
+ >>> company_info = openbb.alt.companieshouse.get_company_info("02723534")
+ >>> name = company_info.name
+ """
+
+ auth = requests.auth.HTTPBasicAuth(
+ get_current_user().credentials.API_COMPANIESHOUSE_KEY, ""
+ )
+ r = requests.get(
+ f"https://api.company-information.service.gov.uk/company/{company_number}",
+ auth=auth,
+ timeout=TIMEOUT,
+ )
+
+ last_accounts = {}
+ returned_data = r.json()
+ if returned_data.get("company_name"):
+ company_name = returned_data["company_name"]
+ if returned_data.get("accounts"):
+ last_accounts = returned_data["accounts"]["last_accounts"]
+ address = returned_data["registered_office_address"]
+ address_lines = []
+ if address.get("address_line_1"):
+ address_lines.append(address.get("address_line_1")