|
|
|
@ -2,42 +2,15 @@
|
|
|
|
|
SporeStack CLI: `sporestack`
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import importlib.util
|
|
|
|
|
import json
|
|
|
|
|
import logging
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import time
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from types import ModuleType
|
|
|
|
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
|
|
|
from typing import Any, Dict, Optional
|
|
|
|
|
|
|
|
|
|
import typer
|
|
|
|
|
|
|
|
|
|
from . import __version__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def lazy_import(name: str) -> ModuleType:
|
|
|
|
|
"""
|
|
|
|
|
Lazily import a module. Helps speed up CLI performance.
|
|
|
|
|
"""
|
|
|
|
|
spec = importlib.util.find_spec(name)
|
|
|
|
|
assert spec is not None
|
|
|
|
|
assert spec.loader is not None
|
|
|
|
|
loader = importlib.util.LazyLoader(spec.loader)
|
|
|
|
|
spec.loader = loader
|
|
|
|
|
module = importlib.util.module_from_spec(spec)
|
|
|
|
|
sys.modules[name] = module
|
|
|
|
|
loader.exec_module(module)
|
|
|
|
|
return module
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# For mypy
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from . import api_client
|
|
|
|
|
else:
|
|
|
|
|
api_client = lazy_import("sporestack.api_client")
|
|
|
|
|
|
|
|
|
|
HELP = """
|
|
|
|
|
SporeStack Python CLI
|
|
|
|
|
|
|
|
|
@ -81,9 +54,11 @@ WAITING_PAYMENT_TO_PROCESS = "Waiting for payment to process..."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_api_endpoint() -> str:
|
|
|
|
|
api_endpoint = os.getenv("SPORESTACK_ENDPOINT", api_client.CLEARNET_ENDPOINT)
|
|
|
|
|
from .api_client import CLEARNET_ENDPOINT, TOR_ENDPOINT
|
|
|
|
|
|
|
|
|
|
api_endpoint = os.getenv("SPORESTACK_ENDPOINT", CLEARNET_ENDPOINT)
|
|
|
|
|
if os.getenv("SPORESTACK_USE_TOR_ENDPOINT", None) is not None:
|
|
|
|
|
api_endpoint = api_client.TOR_ENDPOINT
|
|
|
|
|
api_endpoint = TOR_ENDPOINT
|
|
|
|
|
return api_endpoint
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -119,11 +94,13 @@ def launch(
|
|
|
|
|
"""
|
|
|
|
|
Launch a server on SporeStack.
|
|
|
|
|
"""
|
|
|
|
|
typer.echo(f"Launching server with token {token}...", err=True)
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
from . import utils
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
typer.echo(f"Launching server with token {token}...", err=True)
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
typer.echo(f"Loading SSH key from {ssh_key_file}...")
|
|
|
|
|
if not ssh_key_file.exists():
|
|
|
|
@ -137,7 +114,7 @@ def launch(
|
|
|
|
|
machine_id = utils.random_machine_id()
|
|
|
|
|
|
|
|
|
|
if quote:
|
|
|
|
|
response = api_client.launch(
|
|
|
|
|
response = api_client.server_launch(
|
|
|
|
|
machine_id=machine_id,
|
|
|
|
|
days=days,
|
|
|
|
|
flavor=flavor,
|
|
|
|
@ -145,8 +122,6 @@ def launch(
|
|
|
|
|
ssh_key=ssh_key,
|
|
|
|
|
region=region,
|
|
|
|
|
token=_token,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
quote=True,
|
|
|
|
|
hostname=hostname,
|
|
|
|
|
autorenew=autorenew,
|
|
|
|
@ -168,7 +143,7 @@ def launch(
|
|
|
|
|
|
|
|
|
|
tries = 360
|
|
|
|
|
while tries > 0:
|
|
|
|
|
response = api_client.launch(
|
|
|
|
|
response = api_client.server_launch(
|
|
|
|
|
machine_id=machine_id,
|
|
|
|
|
days=days,
|
|
|
|
|
flavor=flavor,
|
|
|
|
@ -178,8 +153,6 @@ def launch(
|
|
|
|
|
token=_token,
|
|
|
|
|
hostname=hostname,
|
|
|
|
|
autorenew=autorenew,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
if response.created is True:
|
|
|
|
|
break
|
|
|
|
@ -193,11 +166,7 @@ def launch(
|
|
|
|
|
raise typer.Exit(code=1)
|
|
|
|
|
|
|
|
|
|
typer.echo(
|
|
|
|
|
pretty_machine_info(
|
|
|
|
|
api_client.info(
|
|
|
|
|
machine_id=machine_id, api_endpoint=get_api_endpoint()
|
|
|
|
|
).dict()
|
|
|
|
|
)
|
|
|
|
|
pretty_machine_info(api_client.server_info(machine_id=machine_id).dict())
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -212,19 +181,21 @@ def topup(
|
|
|
|
|
Extend an existing SporeStack server's lifetime.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
response = api_client.topup(
|
|
|
|
|
api_client.server_topup(
|
|
|
|
|
machine_id=machine_id,
|
|
|
|
|
days=days,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
token=_token,
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
typer.echo(response.expiration)
|
|
|
|
|
typer.echo(f"Server topped up for {days} day(s)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def server_info_path() -> Path:
|
|
|
|
@ -310,13 +281,14 @@ def server_list(
|
|
|
|
|
"""
|
|
|
|
|
List all locally known servers and all servers under the given token.
|
|
|
|
|
"""
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
from .exceptions import SporeStackUserError
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
server_infos = api_client.servers_launched_from_token(
|
|
|
|
|
token=_token, api_endpoint=get_api_endpoint()
|
|
|
|
|
).servers
|
|
|
|
|
server_infos = api_client.servers_launched_from_token(token=_token).servers
|
|
|
|
|
machine_id_hostnames = {}
|
|
|
|
|
|
|
|
|
|
if local:
|
|
|
|
@ -341,20 +313,21 @@ def server_list(
|
|
|
|
|
typer.echo(f"Machine ID (keep this secret!): {info.machine_id}")
|
|
|
|
|
typer.echo(f"IPv6: {info.network_interfaces[0].ipv6}")
|
|
|
|
|
typer.echo(f"IPv4: {info.network_interfaces[0].ipv4}")
|
|
|
|
|
typer.echo(f"Running: {info.running}")
|
|
|
|
|
typer.echo(f"Region: {info.region}")
|
|
|
|
|
typer.echo(f"Flavor: {info.flavor.slug}")
|
|
|
|
|
typer.echo(f"Token: {info.token}")
|
|
|
|
|
typer.echo(f"Autorenew: {info.autorenew}")
|
|
|
|
|
human_expiration = time.strftime(
|
|
|
|
|
"%Y-%m-%d %H:%M:%S %z", time.localtime(info.expiration)
|
|
|
|
|
)
|
|
|
|
|
typer.echo(f"Expiration: {info.expiration} ({human_expiration})")
|
|
|
|
|
time_to_live = info.expiration - int(time.time())
|
|
|
|
|
hours = time_to_live // 3600
|
|
|
|
|
typer.echo(f"Server will be deleted in {hours} hours.")
|
|
|
|
|
typer.echo(f"Token: {info.token}")
|
|
|
|
|
if info.deleted:
|
|
|
|
|
typer.echo("Server was deleted!")
|
|
|
|
|
else:
|
|
|
|
|
typer.echo(f"Running: {info.running}")
|
|
|
|
|
time_to_live = info.expiration - int(time.time())
|
|
|
|
|
hours = time_to_live // 3600
|
|
|
|
|
typer.echo(f"Server will be deleted in {hours} hours.")
|
|
|
|
|
typer.echo(f"Autorenew: {info.autorenew}")
|
|
|
|
|
|
|
|
|
|
printed_machine_ids.append(info.machine_id)
|
|
|
|
|
|
|
|
|
@ -367,9 +340,8 @@ def server_list(
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
upstream_vm_info = api_client.info(
|
|
|
|
|
machine_id=saved_vm_info["machine_id"],
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
upstream_vm_info = api_client.server_info(
|
|
|
|
|
machine_id=saved_vm_info["machine_id"]
|
|
|
|
|
)
|
|
|
|
|
saved_vm_info["expiration"] = upstream_vm_info.expiration
|
|
|
|
|
saved_vm_info["running"] = upstream_vm_info.running
|
|
|
|
@ -411,9 +383,11 @@ def _get_machine_id(machine_id: str, hostname: str, token: str) -> str:
|
|
|
|
|
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
for server in api_client.servers_launched_from_token(
|
|
|
|
|
token=_token, api_endpoint=get_api_endpoint()
|
|
|
|
|
).servers:
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
for server in api_client.servers_launched_from_token(token=_token).servers:
|
|
|
|
|
if server.hostname == hostname:
|
|
|
|
|
return server.machine_id
|
|
|
|
|
|
|
|
|
@ -429,18 +403,38 @@ def info(hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN) -
|
|
|
|
|
Info on the VM
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
typer.echo(
|
|
|
|
|
api_client.info(machine_id=machine_id, api_endpoint=get_api_endpoint()).json()
|
|
|
|
|
pretty_machine_info(api_client.server_info(machine_id=machine_id).dict())
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@server_cli.command(name="json")
|
|
|
|
|
def server_info_json(
|
|
|
|
|
hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN
|
|
|
|
|
) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Info on the VM, in JSON format
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
typer.echo(api_client.server_info(machine_id=machine_id).json())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@server_cli.command()
|
|
|
|
|
def start(hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Boots the VM.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.start(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.server_start(machine_id=machine_id)
|
|
|
|
|
typer.echo(f"{hostname} started.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -450,7 +444,10 @@ def stop(hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN) -
|
|
|
|
|
Immediately shuts down the VM.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.stop(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.server_stop(machine_id=machine_id)
|
|
|
|
|
typer.echo(f"{hostname} stopped.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -462,7 +459,10 @@ def autorenew_enable(
|
|
|
|
|
Enable autorenew on a server.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.autorenew_enable(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.autorenew_enable(machine_id=machine_id)
|
|
|
|
|
typer.echo("Autorenew enabled.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -474,19 +474,25 @@ def autorenew_disable(
|
|
|
|
|
Disable autorenew on a server.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.autorenew_disable(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.autorenew_disable(machine_id=machine_id)
|
|
|
|
|
typer.echo("Autorenew disabled.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@server_cli.command()
|
|
|
|
|
def destroy(
|
|
|
|
|
def delete(
|
|
|
|
|
hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN
|
|
|
|
|
) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Deletes/destroys the VM before expiration (no refunds/credits)
|
|
|
|
|
Delete the VM before its expiration
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.destroy(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.server_delete(machine_id=machine_id)
|
|
|
|
|
# Also remove the .json file
|
|
|
|
|
server_info_path().joinpath(f"{hostname}.json").unlink(missing_ok=True)
|
|
|
|
|
typer.echo(f"{machine_id} was destroyed.")
|
|
|
|
@ -500,7 +506,10 @@ def forget(
|
|
|
|
|
Forget about a deleted server so that it doesn't show up in server list.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.forget(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.server_forget(machine_id=machine_id)
|
|
|
|
|
typer.echo(f"{machine_id} was forgotten.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -514,7 +523,10 @@ def rebuild(
|
|
|
|
|
Will take a couple minutes to complete after the request is made.
|
|
|
|
|
"""
|
|
|
|
|
machine_id = _get_machine_id(machine_id=machine_id, hostname=hostname, token=token)
|
|
|
|
|
api_client.rebuild(machine_id=machine_id, api_endpoint=get_api_endpoint())
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
api_client.server_rebuild(machine_id=machine_id)
|
|
|
|
|
typer.echo(f"{hostname} rebuilding.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -523,7 +535,10 @@ def flavors() -> None:
|
|
|
|
|
"""
|
|
|
|
|
Returns available flavors.
|
|
|
|
|
"""
|
|
|
|
|
flavors = api_client.flavors(api_endpoint=get_api_endpoint()).flavors
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
flavors = api_client.flavors().flavors
|
|
|
|
|
for flavor in flavors:
|
|
|
|
|
typer.echo(f"{flavor}: {flavors[flavor]}")
|
|
|
|
|
|
|
|
|
@ -533,9 +548,10 @@ def operating_systems() -> None:
|
|
|
|
|
"""
|
|
|
|
|
Returns available operating systems.
|
|
|
|
|
"""
|
|
|
|
|
os_list = api_client.operating_systems(
|
|
|
|
|
api_endpoint=get_api_endpoint()
|
|
|
|
|
).operating_systems
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
os_list = api_client.operating_systems().operating_systems
|
|
|
|
|
for operating_system in os_list:
|
|
|
|
|
typer.echo(operating_system)
|
|
|
|
|
|
|
|
|
@ -590,11 +606,14 @@ def token_create(
|
|
|
|
|
typer.echo("Token already created! Did you mean to `topup`?", err=True)
|
|
|
|
|
raise typer.Exit(1)
|
|
|
|
|
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
response = api_client.token_add(
|
|
|
|
|
token=_token,
|
|
|
|
|
dollars=dollars,
|
|
|
|
|
currency=currency,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -615,7 +634,6 @@ def token_create(
|
|
|
|
|
token=_token,
|
|
|
|
|
dollars=dollars,
|
|
|
|
|
currency=currency,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
if response.payment.paid is True:
|
|
|
|
@ -649,11 +667,14 @@ def token_topup(
|
|
|
|
|
"""
|
|
|
|
|
token = load_token(token)
|
|
|
|
|
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
response = api_client.token_add(
|
|
|
|
|
token,
|
|
|
|
|
dollars,
|
|
|
|
|
currency=currency,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -672,7 +693,6 @@ def token_topup(
|
|
|
|
|
token,
|
|
|
|
|
dollars,
|
|
|
|
|
currency=currency,
|
|
|
|
|
api_endpoint=get_api_endpoint(),
|
|
|
|
|
retry=True,
|
|
|
|
|
)
|
|
|
|
|
# Waiting for payment to set in.
|
|
|
|
@ -690,9 +710,11 @@ def balance(token: str = typer.Argument(DEFAULT_TOKEN)) -> None:
|
|
|
|
|
"""
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
typer.echo(
|
|
|
|
|
api_client.token_balance(token=_token, api_endpoint=get_api_endpoint()).usd
|
|
|
|
|
)
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
typer.echo(api_client.token_balance(token=_token).usd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@token_cli.command()
|
|
|
|
@ -702,11 +724,11 @@ def servers(token: str = typer.Argument(DEFAULT_TOKEN)) -> None:
|
|
|
|
|
"""
|
|
|
|
|
_token = load_token(token)
|
|
|
|
|
|
|
|
|
|
typer.echo(
|
|
|
|
|
api_client.servers_launched_from_token(
|
|
|
|
|
token=_token, api_endpoint=get_api_endpoint()
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
from .api_client import APIClient
|
|
|
|
|
|
|
|
|
|
api_client = APIClient(api_endpoint=get_api_endpoint())
|
|
|
|
|
|
|
|
|
|
typer.echo(api_client.servers_launched_from_token(token=_token))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@token_cli.command(name="list")
|
|
|
|
@ -728,6 +750,8 @@ def version() -> None:
|
|
|
|
|
"""
|
|
|
|
|
Returns the installed version.
|
|
|
|
|
"""
|
|
|
|
|
from . import __version__
|
|
|
|
|
|
|
|
|
|
typer.echo(__version__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -737,6 +761,8 @@ def api_endpoint() -> None:
|
|
|
|
|
Prints the selected API endpoint: Env var: SPORESTACK_ENDPOINT,
|
|
|
|
|
or, SPORESTACK_USE_TOR=1
|
|
|
|
|
"""
|
|
|
|
|
from . import api_client
|
|
|
|
|
|
|
|
|
|
endpoint = get_api_endpoint()
|
|
|
|
|
if ".onion" in endpoint:
|
|
|
|
|
typer.echo(f"{endpoint} using {api_client._get_tor_proxy()}")
|
|
|
|
|