Skip to content

Commit

Permalink
feat: add login process in init command
Browse files Browse the repository at this point in the history
  • Loading branch information
Romazes committed Aug 14, 2024
1 parent 80cbae6 commit 28a05a2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
7 changes: 7 additions & 0 deletions lean/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from click import command, option, Choice, confirm, prompt

from lean.click import LeanCommand
from lean.commands.login import get_credentials, validate_credentials, get_lean_config_credentials
from lean.constants import DEFAULT_DATA_DIRECTORY_NAME, DEFAULT_LEAN_CONFIG_FILE_NAME
from lean.container import container
from lean.models.errors import MoreInfoError
Expand Down Expand Up @@ -128,6 +129,12 @@ def init(organization: Optional[str], language: Optional[str]) -> None:
from shutil import copytree
from zipfile import ZipFile

# Retrieve current credentials from the Lean CLI configuration
# If credentials are not available, prompt the user to provide them
current_user_id, current_api_token = get_lean_config_credentials()
user_id, api_token = get_credentials(current_user_id, current_api_token, False)
validate_credentials(user_id, api_token)

# Select and set organization

if organization is not None:
Expand Down
59 changes: 46 additions & 13 deletions lean/commands/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,71 @@
from lean.components.api.api_client import APIClient


@command(cls=LeanCommand)
@option("--user-id", "-u", type=str, help="QuantConnect user id")
@option("--api-token", "-t", type=str, help="QuantConnect API token")
@option("--show-secrets", is_flag=True, show_default=True, default=False, help="Show secrets as they are input")
def login(user_id: Optional[str], api_token: Optional[str], show_secrets: bool) -> None:
"""Log in with a QuantConnect account.
def get_lean_config_credentials() -> tuple[str, str]:
"""Retrieve the QuantConnect credentials from the Lean CLI configuration.
If user id or API token is not provided an interactive prompt will show.
This function accesses the Lean CLI configuration manager to obtain the
stored user ID and API token. The credentials are retrieved from the
configuration settings managed by the Lean CLI.
Credentials are stored in ~/.lean/credentials and are removed upon running `lean logout`.
Returns:
tuple[str, str]: A tuple containing the user ID and API token as strings.
"""
cli_config_manager = container.cli_config_manager

user_id = cli_config_manager.user_id.get_value()
api_token = cli_config_manager.api_token.get_value()

return user_id, api_token


def get_credentials(user_id: Optional[str], api_token: Optional[str], show_secrets: bool) -> tuple[str, str]:
"""Fetch user credentials, prompting the user if necessary."""
logger = container.logger
credentials_storage = container.credentials_storage
current_user_id, current_api_token = get_lean_config_credentials()

if user_id is None or api_token is None:
logger.info("Your user id and API token are needed to make authenticated requests to the QuantConnect API")
logger.info("You can request these credentials on https://www.quantconnect.com/account")
logger.info(f"Both will be saved in {credentials_storage.file}")

if user_id is None:
user_id = prompt("User id")
user_id = prompt("User id", current_user_id)

if api_token is None:
api_token = logger.prompt_password("API token", hide_input=not show_secrets)
api_token = logger.prompt_password("API token", current_api_token, hide_input=not show_secrets)

return user_id, api_token


def validate_credentials(user_id: str, api_token: str) -> None:
"""Validate the user credentials by attempting to authenticate with the QuantConnect API."""
container.api_client.set_user_token(user_id=user_id, api_token=api_token)

if not container.api_client.is_authenticated():
raise MoreInfoError("Credentials are invalid. Please ensure your computer clock is correct, or try using another terminal, or enter API token manually instead of copy-pasting.",
"https://www.lean.io/docs/v2/lean-cli")
raise MoreInfoError(
"Credentials are invalid. Please ensure your computer clock is correct, or try using another terminal, or enter API token manually instead of copy-pasting.",
"https://www.lean.io/docs/v2/lean-cli"
)

cli_config_manager = container.cli_config_manager
cli_config_manager.user_id.set_value(user_id)
cli_config_manager.api_token.set_value(api_token)

logger.info("Successfully logged in")
container.logger.info("Successfully logged in")

@command(cls=LeanCommand)
@option("--user-id", "-u", type=str, help="QuantConnect user id")
@option("--api-token", "-t", type=str, help="QuantConnect API token")
@option("--show-secrets", is_flag=True, show_default=True, default=False, help="Show secrets as they are input")
def login(user_id: Optional[str], api_token: Optional[str], show_secrets: bool) -> None:
"""Log in with a QuantConnect account.
If user id or API token is not provided an interactive prompt will show.
Credentials are stored in ~/.lean/credentials and are removed upon running `lean logout`.
"""

user_id, api_token = get_credentials(user_id, api_token, show_secrets)
validate_credentials(user_id, api_token)

0 comments on commit 28a05a2

Please sign in to comment.