diff --git a/CONFIG.py b/CONFIG.py index bd702cb..3a3c88e 100644 --- a/CONFIG.py +++ b/CONFIG.py @@ -21,3 +21,5 @@ AUTH_SYSTEM_ENABLED = os.getenv("AUTH_SYSTEM_ENABLED", "False").lower() in ("tru BACKEND_API_HOST = os.getenv("BACKEND_API_HOST", "127.0.0.1") BACKEND_API_PORT = os.getenv("BACKEND_API_PORT", 8000) +BACKEND_API_USERNAME = os.getenv("BACKEND_API_USERNAME", "admin") +BACKEND_API_PASSWORD = os.getenv("BACKEND_API_PASSWORD", "admin") diff --git a/backend/services/backend_api_client.py b/backend/services/backend_api_client.py index a7ae154..4fefb68 100644 --- a/backend/services/backend_api_client.py +++ b/backend/services/backend_api_client.py @@ -4,6 +4,7 @@ import pandas as pd import requests import streamlit as st from hummingbot.strategy_v2.models.executors_info import ExecutorInfo +from requests.auth import HTTPBasicAuth class BackendAPIClient: @@ -20,10 +21,11 @@ class BackendAPIClient: cls._shared_instance = BackendAPIClient(*args, **kwargs) return cls._shared_instance - def __init__(self, host: str = "localhost", port: int = 8000): + def __init__(self, host: str = "localhost", port: int = 8000, username: str = "admin", password: str = "admin"): self.host = host self.port = port self.base_url = f"http://{self.host}:{self.port}" + self.auth = HTTPBasicAuth(username, password) def post(self, endpoint: str, payload: Optional[Dict] = None, params: Optional[Dict] = None): """ @@ -34,7 +36,7 @@ class BackendAPIClient: :return: """ url = f"{self.base_url}/{endpoint}" - response = requests.post(url, json=payload, params=params) + response = requests.post(url, json=payload, params=params, auth=self.auth) return self._process_response(response) def get(self, endpoint: str): @@ -44,12 +46,15 @@ class BackendAPIClient: :return: """ url = f"{self.base_url}/{endpoint}" - response = requests.get(url) + response = requests.get(url, auth=self.auth) return self._process_response(response) @staticmethod def _process_response(response): - if response.status_code == 400: + if response.status_code == 401: + st.error("You are not authorized to access Backend API. Please check your credentials.") + return + elif response.status_code == 400: st.error(response.json()["detail"]) return return response.json() diff --git a/environment_conda.yml b/environment_conda.yml index 19faacf..1699708 100644 --- a/environment_conda.yml +++ b/environment_conda.yml @@ -19,13 +19,10 @@ dependencies: - statsmodels - pandas_ta==0.3.14b - pyyaml - - jupyter - - optuna - - optuna-dashboard - pathlib - - st-pages + - st_pages - streamlit-elements==0.1.* - - streamlit-authenticator + - streamlit-authenticator==0.3.2 - pydantic==1.10.4 - flake8 - isort diff --git a/frontend/components/launch_strategy_v2.py b/frontend/components/launch_strategy_v2.py index 98f59d1..354db3b 100644 --- a/frontend/components/launch_strategy_v2.py +++ b/frontend/components/launch_strategy_v2.py @@ -49,35 +49,41 @@ class LaunchStrategyV2(Dashboard.Item): self._controller_config_selected = [param + ".yml" for param in params] def launch_new_bot(self): - if self._bot_name and self._image_name and len(self._controller_config_selected) > 0: - start_time_str = time.strftime("%Y.%m.%d_%H.%M") - bot_name = f"{self._bot_name}-{start_time_str}" - script_config = { - "name": bot_name, - "content": { - "markets": {}, - "candles_config": [], - "controllers_config": self._controller_config_selected, - "config_update_interval": 10, - "script_file_name": "v2_with_controllers.py", - "time_to_cash_out": None, - } + if not self._bot_name: + st.warning("You need to define the bot name.") + return + if not self._image_name: + st.warning("You need to select the hummingbot image.") + return + if not self._controller_config_selected or len(self._controller_config_selected) == 0: + st.warning("You need to select the controllers configs. Please select at least one controller " + "config by clicking on the checkbox.") + return + start_time_str = time.strftime("%Y.%m.%d_%H.%M") + bot_name = f"{self._bot_name}-{start_time_str}" + script_config = { + "name": bot_name, + "content": { + "markets": {}, + "candles_config": [], + "controllers_config": self._controller_config_selected, + "config_update_interval": 10, + "script_file_name": "v2_with_controllers.py", + "time_to_cash_out": None, } + } - self._backend_api_client.add_script_config(script_config) - deploy_config = { - "instance_name": bot_name, - "script": "v2_with_controllers.py", - "script_config": bot_name + ".yml", - "image": self._image_name, - "credentials_profile": self._credentials, - } - self._backend_api_client.create_hummingbot_instance(deploy_config) - with st.spinner('Starting Bot... This process may take a few seconds'): - time.sleep(3) - else: - st.warning("You need to define the bot name and select the controllers configs " - "that you want to deploy.") + self._backend_api_client.add_script_config(script_config) + deploy_config = { + "instance_name": bot_name, + "script": "v2_with_controllers.py", + "script_config": bot_name + ".yml", + "image": self._image_name, + "credentials_profile": self._credentials, + } + self._backend_api_client.create_hummingbot_instance(deploy_config) + with st.spinner('Starting Bot... This process may take a few seconds'): + time.sleep(3) def delete_selected_configs(self): if self._controller_config_selected: diff --git a/frontend/pages/config/utils.py b/frontend/pages/config/utils.py index 591cc68..8d90252 100644 --- a/frontend/pages/config/utils.py +++ b/frontend/pages/config/utils.py @@ -3,8 +3,7 @@ import datetime import pandas as pd import streamlit as st -from backend.services.backend_api_client import BackendAPIClient -from CONFIG import BACKEND_API_HOST, BACKEND_API_PORT +from frontend.st_utils import get_backend_api_client def get_max_records(days_to_download: int, interval: str) -> int: @@ -16,7 +15,7 @@ def get_max_records(days_to_download: int, interval: str) -> int: @st.cache_data def get_candles(connector_name="binance", trading_pair="BTC-USDT", interval="1m", days=7): - backend_client = BackendAPIClient(BACKEND_API_HOST, BACKEND_API_PORT) + backend_client = get_backend_api_client() end_time = datetime.datetime.now() - datetime.timedelta(minutes=15) start_time = end_time - datetime.timedelta(days=days) diff --git a/frontend/pages/orchestration/launch_bot_v2_st/README.md b/frontend/pages/orchestration/launch_bot_v2_st/README.md deleted file mode 100644 index 18f4d94..0000000 --- a/frontend/pages/orchestration/launch_bot_v2_st/README.md +++ /dev/null @@ -1,19 +0,0 @@ -### Description - -This page helps you deploy and manage Hummingbot instances: - -- Starting and stopping Hummingbot Broker -- Creating, starting and stopping bot instances -- Managing strategy and script files that instances run -- Fetching status of running instances - -### Maintainers - -This page is maintained by Hummingbot Foundation as a template other pages: - -* [cardosfede](https://github.com/cardosfede) -* [fengtality](https://github.com/fengtality) - -### Wiki - -See the [wiki](https://github.com/hummingbot/dashboard/wiki/%F0%9F%90%99-Bot-Orchestration) for more information. \ No newline at end of file diff --git a/frontend/pages/orchestration/launch_bot_v2_st/__init__.py b/frontend/pages/orchestration/launch_bot_v2_st/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/pages/orchestration/launch_bot_v2_st/app.py b/frontend/pages/orchestration/launch_bot_v2_st/app.py deleted file mode 100644 index 0766de0..0000000 --- a/frontend/pages/orchestration/launch_bot_v2_st/app.py +++ /dev/null @@ -1,8 +0,0 @@ -from frontend.components.deploy_v2_with_controllers import LaunchV2WithControllers -from frontend.st_utils import initialize_st_page - -initialize_st_page(title="Launch Bot ST", icon="🙌") - - -launcher = LaunchV2WithControllers() -launcher() diff --git a/frontend/st_utils.py b/frontend/st_utils.py index 984399e..9b667ed 100644 --- a/frontend/st_utils.py +++ b/frontend/st_utils.py @@ -73,20 +73,16 @@ def style_metric_cards( def get_backend_api_client(): from backend.services.backend_api_client import BackendAPIClient - from CONFIG import BACKEND_API_HOST, BACKEND_API_PORT - is_docker_running = False + from CONFIG import BACKEND_API_HOST, BACKEND_API_PASSWORD, BACKEND_API_PORT, BACKEND_API_USERNAME try: - backend_api_client = BackendAPIClient.get_instance(host=BACKEND_API_HOST, port=BACKEND_API_PORT) - is_docker_running = backend_api_client.is_docker_running() - except Exception as e: - st.error( - f"There was an error trying to connect to the Backend API. Please make sure the Backend API is running.\n\n" - f"Error: \n\n{str(e)}") + backend_api_client = BackendAPIClient.get_instance(host=BACKEND_API_HOST, port=BACKEND_API_PORT, + username=BACKEND_API_USERNAME, password=BACKEND_API_PASSWORD) + if not backend_api_client.is_docker_running(): + st.error("Docker is not running. Please make sure Docker is running.") + st.stop() + return backend_api_client + except Exception: st.stop() - if not is_docker_running: - st.error("Docker is not running. Please make sure Docker is running.") - st.stop() - return backend_api_client def auth_system(): @@ -102,7 +98,6 @@ def auth_system(): config['cookie']['name'], config['cookie']['key'], config['cookie']['expiry_days'], - config['pre-authorized'] ) show_pages(main_page() + public_pages()) st.session_state.authenticator.login()