Skip to content

proxystore.endpoint.cli

proxystore-endpoint command-line interface.

See the CLI Reference for the proxystore-endpoint usage instructions.

cli()

cli(ctx: Context, log_level: str) -> None

Manage and start ProxyStore Endpoints.

Source code in proxystore/endpoint/cli.py
@click.group()
@click.option(
    '--log-level',
    default='INFO',
    type=click.Choice(
        ['ERROR', 'WARNING', 'INFO', 'DEBUG'],
        case_sensitive=False,
    ),
    help='Minimum logging level.',
)
@click.pass_context
def cli(ctx: click.Context, log_level: str) -> None:
    """Manage and start ProxyStore Endpoints."""
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(_CLIFormatter())
    logging.basicConfig(level=log_level, handlers=[handler])
    ctx.ensure_object(dict)
    ctx.obj['LOG_LEVEL'] = log_level

show_help()

show_help() -> None

Show available commands and options.

Source code in proxystore/endpoint/cli.py
@cli.command(name='help')
def show_help() -> None:
    """Show available commands and options."""
    with click.Context(cli) as ctx:
        click.echo(cli.get_help(ctx))

version()

version() -> None

Show the ProxyStore version.

Source code in proxystore/endpoint/cli.py
@cli.command()
def version() -> None:
    """Show the ProxyStore version."""
    click.echo(f'ProxyStore v{proxystore.__version__}')

check_nat_command()

check_nat_command(host: str, port: int) -> None

Check the type of NAT you are behind.

Source code in proxystore/endpoint/cli.py
@cli.command(name='check-nat')
@click.option(
    '--host',
    default='0.0.0.0',
    metavar='ADDR',
    help='Network interface address to listen on.',
)
@click.option(
    '--port',
    default=54320,
    type=int,
    metavar='PORT',
    help='Port to listen on.',
)
def check_nat_command(host: str, port: int) -> None:
    """Check the type of NAT you are behind."""
    check_nat_and_log(host, port)

configure()

configure(
    name: str,
    port: int,
    relay_address: str,
    relay_auth: bool,
    relay_server: bool,
    peer_channels: int,
    persist: bool,
) -> None

Configure a new endpoint.

Source code in proxystore/endpoint/cli.py
@cli.command()
@click.argument('name', metavar='NAME', required=True)
@click.option(
    '--port',
    default=8765,
    type=int,
    metavar='PORT',
    help='Port to listen on.',
)
@click.option(
    '--relay-address',
    default='wss://relay.proxystore.dev',
    metavar='ADDR',
    help='Relay server address.',
)
@click.option(
    '--relay-auth/--no-relay-auth',
    default=True,
    metavar='BOOL',
    help='Disable relay server authentication.',
)
@click.option(
    '--relay-server/--no-relay-server',
    default=True,
    metavar='BOOL',
    help='Disable connecting to the relay server on start.',
)
@click.option(
    '--peer-channels',
    default=1,
    type=int,
    metavar='COUNT',
    help='Datachannels to use per peer connection.',
)
@click.option(
    '--persist/--no-persist',
    default=False,
    metavar='BOOL',
    help='Optionally persist data to a database.',
)
def configure(
    name: str,
    port: int,
    relay_address: str,
    relay_auth: bool,
    relay_server: bool,
    peer_channels: int,
    persist: bool,
) -> None:
    """Configure a new endpoint."""
    raise SystemExit(
        configure_endpoint(
            name,
            port=port,
            relay_server=relay_address if relay_server else None,
            relay_auth=relay_auth,
            peer_channels=peer_channels,
            persist_data=persist,
        ),
    )

list_all()

list_all() -> None

List all user endpoints.

Source code in proxystore/endpoint/cli.py
@cli.command(name='list')
def list_all() -> None:
    """List all user endpoints."""
    raise SystemExit(list_endpoints())

remove()

remove(name: str) -> None

Remove an endpoint.

Source code in proxystore/endpoint/cli.py
@cli.command()
@click.argument('name', metavar='NAME', required=True)
def remove(name: str) -> None:
    """Remove an endpoint."""
    raise SystemExit(remove_endpoint(name))

start()

start(ctx: Context, name: str, detach: bool) -> None

Start an endpoint.

Source code in proxystore/endpoint/cli.py
@cli.command()
@click.argument('name', metavar='NAME', required=True)
@click.option('--detach/--no-detach', default=True, help='Run as daemon.')
@click.pass_context
def start(ctx: click.Context, name: str, detach: bool) -> None:
    """Start an endpoint."""
    raise SystemExit(
        start_endpoint(name, detach=detach, log_level=ctx.obj['LOG_LEVEL']),
    )

stop()

stop(name: str) -> None

Stop a detached endpoint.

Source code in proxystore/endpoint/cli.py
@cli.command()
@click.argument('name', metavar='NAME', required=True)
def stop(name: str) -> None:
    """Stop a detached endpoint."""
    raise SystemExit(stop_endpoint(name))

test()

test(ctx: Context, name: str, remote: str | None) -> None

Execute test commands on an endpoint.

Source code in proxystore/endpoint/cli.py
@cli.group()
@click.argument('name', metavar='NAME', required=True)
@click.option(
    '--remote',
    metavar='UUID',
    help='Optional UUID of remote endpoint to use.',
)
@click.pass_context
def test(
    ctx: click.Context,
    name: str,
    remote: str | None,
) -> None:
    """Execute test commands on an endpoint."""
    ctx.ensure_object(dict)

    proxystore_dir = home_dir()
    endpoint_dir = os.path.join(proxystore_dir, name)
    if os.path.isdir(endpoint_dir):
        cfg = read_config(endpoint_dir)
    else:
        logger.error(f'An endpoint named {name} does not exist.')
        raise SystemExit(1)

    ctx.obj['ENDPOINT_ADDRESS'] = f'http://{cfg.host}:{cfg.port}'
    ctx.obj['REMOTE_ENDPOINT_UUID'] = remote

evict()

evict(ctx: Context, key: str) -> None

Evict object from an endpoint.

Source code in proxystore/endpoint/cli.py
@test.command()
@click.argument('key', metavar='KEY', required=True)
@click.pass_context
def evict(ctx: click.Context, key: str) -> None:
    """Evict object from an endpoint."""
    address = ctx.obj['ENDPOINT_ADDRESS']
    remote = ctx.obj['REMOTE_ENDPOINT_UUID']
    try:
        client.evict(address, key, remote)
    except requests.exceptions.ConnectionError as e:
        logger.error(f'Unable to connect to endpoint at {address}.')
        logger.debug(e)
        sys.exit(1)
    except requests.exceptions.RequestException as e:
        logger.error(e)
        sys.exit(1)
    else:
        logger.info('Evicted object from endpoint.')

exists()

exists(ctx: Context, key: str) -> None

Check if object exists in an endpoint.

Source code in proxystore/endpoint/cli.py
@test.command()
@click.argument('key', metavar='KEY', required=True)
@click.pass_context
def exists(ctx: click.Context, key: str) -> None:
    """Check if object exists in an endpoint."""
    address = ctx.obj['ENDPOINT_ADDRESS']
    remote = ctx.obj['REMOTE_ENDPOINT_UUID']
    try:
        res = client.exists(address, key, remote)
    except requests.exceptions.ConnectionError as e:
        logger.error(f'Unable to connect to endpoint at {address}.')
        logger.debug(e)
        sys.exit(1)
    except requests.exceptions.RequestException as e:
        logger.error(e)
        sys.exit(1)
    else:
        logger.info(f'Object exists: {res}')

get()

get(ctx: Context, key: str) -> None

Get an object from an endpoint.

Source code in proxystore/endpoint/cli.py
@test.command()
@click.argument('key', metavar='KEY', required=True)
@click.pass_context
def get(ctx: click.Context, key: str) -> None:
    """Get an object from an endpoint."""
    address = ctx.obj['ENDPOINT_ADDRESS']
    remote = ctx.obj['REMOTE_ENDPOINT_UUID']
    try:
        res = client.get(address, key, remote)
    except requests.exceptions.ConnectionError as e:
        logger.error(f'Unable to connect to endpoint at {address}.')
        logger.debug(e)
        sys.exit(1)
    except requests.exceptions.RequestException as e:
        logger.error(e)
        sys.exit(1)

    if res is None:
        logger.info('Object does not exist.')
    else:
        obj = deserialize(res)
        logger.info(f'Result: {obj}')

put()

put(ctx: Context, data: str) -> None

Put an object in an endpoint.

Source code in proxystore/endpoint/cli.py
@test.command()
@click.argument('data', required=True)
@click.pass_context
def put(ctx: click.Context, data: str) -> None:
    """Put an object in an endpoint."""
    address = ctx.obj['ENDPOINT_ADDRESS']
    remote = ctx.obj['REMOTE_ENDPOINT_UUID']
    key = str(uuid.uuid4())
    data_ = serialize(data)
    try:
        client.put(address, key, data_, remote)
    except requests.exceptions.ConnectionError as e:
        logger.error(f'Unable to connect to endpoint at {address}.')
        logger.debug(e)
        sys.exit(1)
    except requests.exceptions.RequestException as e:
        logger.error(e)
        sys.exit(1)
    else:
        logger.info(f'Put object in endpoint with key {key}')