Skip to content

Commit 41575ac

Browse files
authored
Wrap all cmd args in Annotated + minor fix on file list (#339)
- Wrap all command args in Annotated to allow to easily import CLI as a lib
1 parent fbae1c4 commit 41575ac

File tree

8 files changed

+518
-448
lines changed

8 files changed

+518
-448
lines changed

src/aleph_client/commands/account.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import asyncio
44
import logging
55
from pathlib import Path
6-
from typing import Optional
6+
from typing import Annotated, Optional
77

88
import aiohttp
99
import typer
@@ -46,12 +46,12 @@
4646

4747
@app.command()
4848
async def create(
49-
private_key: Optional[str] = typer.Option(None, help=help_strings.PRIVATE_KEY),
50-
private_key_file: Optional[Path] = typer.Option(None, help=help_strings.PRIVATE_KEY_FILE),
51-
chain: Optional[Chain] = typer.Option(default=None, help=help_strings.ORIGIN_CHAIN),
52-
replace: bool = typer.Option(default=False, help=help_strings.CREATE_REPLACE),
53-
active: bool = typer.Option(default=True, help=help_strings.CREATE_ACTIVE),
54-
debug: bool = False,
49+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = None,
50+
private_key_file: Annotated[Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)] = None,
51+
chain: Annotated[Optional[Chain], typer.Option(help=help_strings.ORIGIN_CHAIN)] = None,
52+
replace: Annotated[bool, typer.Option(help=help_strings.CREATE_REPLACE)] = False,
53+
active: Annotated[bool, typer.Option(help=help_strings.CREATE_ACTIVE)] = True,
54+
debug: Annotated[bool, typer.Option()] = False,
5555
):
5656
"""Create or import a private key."""
5757

@@ -120,8 +120,10 @@ async def create(
120120

121121
@app.command(name="address")
122122
def display_active_address(
123-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
124-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
123+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
124+
private_key_file: Annotated[
125+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
126+
] = settings.PRIVATE_KEY_FILE,
125127
):
126128
"""
127129
Display your public address(es).
@@ -183,8 +185,10 @@ def path_directory():
183185

184186
@app.command()
185187
def show(
186-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
187-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
188+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
189+
private_key_file: Annotated[
190+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
191+
] = settings.PRIVATE_KEY_FILE,
188192
):
189193
"""Display current configuration."""
190194

@@ -194,8 +198,8 @@ def show(
194198

195199
@app.command()
196200
def export_private_key(
197-
private_key: Optional[str] = typer.Option(None, help=help_strings.PRIVATE_KEY),
198-
private_key_file: Optional[Path] = typer.Option(None, help=help_strings.PRIVATE_KEY_FILE),
201+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = None,
202+
private_key_file: Annotated[Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)] = None,
199203
):
200204
"""
201205
Display your private key.
@@ -220,11 +224,13 @@ def export_private_key(
220224

221225
@app.command("sign-bytes")
222226
def sign_bytes(
223-
message: Optional[str] = typer.Option(None, help="Message to sign"),
224-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
225-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
226-
chain: Optional[Chain] = typer.Option(None, help=help_strings.ADDRESS_CHAIN),
227-
debug: bool = False,
227+
message: Annotated[Optional[str], typer.Option(help="Message to sign")] = None,
228+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
229+
private_key_file: Annotated[
230+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
231+
] = settings.PRIVATE_KEY_FILE,
232+
chain: Annotated[Optional[Chain], typer.Option(help=help_strings.ADDRESS_CHAIN)] = None,
233+
debug: Annotated[bool, typer.Option()] = False,
228234
):
229235
"""Sign a message using your private key."""
230236

@@ -257,10 +263,12 @@ async def get_balance(address: str) -> dict:
257263

258264
@app.command()
259265
async def balance(
260-
address: Optional[str] = typer.Option(None, help="Address"),
261-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
262-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
263-
chain: Optional[Chain] = typer.Option(None, help=help_strings.ADDRESS_CHAIN),
266+
address: Annotated[Optional[str], typer.Option(help="Address")] = None,
267+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
268+
private_key_file: Annotated[
269+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
270+
] = settings.PRIVATE_KEY_FILE,
271+
chain: Annotated[Optional[Chain], typer.Option(help=help_strings.ADDRESS_CHAIN)] = None,
264272
):
265273
"""Display your ALEPH balance."""
266274
account = _load_account(private_key, private_key_file, chain=chain)
@@ -363,8 +371,8 @@ async def list_accounts():
363371

364372
@app.command(name="config")
365373
async def configure(
366-
private_key_file: Optional[Path] = typer.Option(None, help="New path to the private key file"),
367-
chain: Optional[Chain] = typer.Option(None, help="New active chain"),
374+
private_key_file: Annotated[Optional[Path], typer.Option(help="New path to the private key file")] = None,
375+
chain: Annotated[Optional[Chain], typer.Option(help="New active chain")] = None,
368376
):
369377
"""Configure current private key file and active chain (default selection)"""
370378

src/aleph_client/commands/domain.py

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
from pathlib import Path
55
from time import sleep
6-
from typing import Optional, cast
6+
from typing import Annotated, Optional, cast
77

88
import typer
99
from aleph.sdk.account import _load_account
@@ -176,13 +176,15 @@ async def detach_resource(account: AccountFromPrivateKey, fqdn: Hostname, intera
176176

177177
@app.command()
178178
async def add(
179-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
180-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
181-
fqdn: str = typer.Argument(..., help=help_strings.CUSTOM_DOMAIN_NAME),
182-
target: Optional[TargetType] = typer.Option(None, help=help_strings.CUSTOM_DOMAIN_TARGET_TYPES),
183-
item_hash: Optional[str] = typer.Option(None, help=help_strings.CUSTOM_DOMAIN_ITEM_HASH),
184-
owner: Optional[str] = typer.Option(None, help=help_strings.CUSTOM_DOMAIN_OWNER_ADDRESS),
185-
ask: bool = typer.Option(default=True, help=help_strings.ASK_FOR_CONFIRMATION),
179+
fqdn: Annotated[str, typer.Argument(help=help_strings.CUSTOM_DOMAIN_NAME)],
180+
target: Annotated[Optional[TargetType], typer.Option(help=help_strings.CUSTOM_DOMAIN_TARGET_TYPES)] = None,
181+
item_hash: Annotated[Optional[str], typer.Option(help=help_strings.CUSTOM_DOMAIN_ITEM_HASH)] = None,
182+
owner: Annotated[Optional[str], typer.Option(help=help_strings.CUSTOM_DOMAIN_OWNER_ADDRESS)] = None,
183+
ask: Annotated[bool, typer.Option(help=help_strings.ASK_FOR_CONFIRMATION)] = True,
184+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
185+
private_key_file: Annotated[
186+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
187+
] = settings.PRIVATE_KEY_FILE,
186188
):
187189
"""Add and link a Custom Domain."""
188190
account: AccountFromPrivateKey = _load_account(private_key, private_key_file)
@@ -260,12 +262,14 @@ async def add(
260262

261263
@app.command()
262264
async def attach(
263-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
264-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
265-
fqdn: str = typer.Argument(..., help=help_strings.CUSTOM_DOMAIN_NAME),
266-
item_hash: Optional[str] = typer.Option(None, help=help_strings.CUSTOM_DOMAIN_ITEM_HASH),
267-
catch_all_path: str = typer.Option(default=None, help=help_strings.IPFS_CATCH_ALL_PATH),
268-
ask: bool = typer.Option(default=True, help=help_strings.ASK_FOR_CONFIRMATION),
265+
fqdn: Annotated[str, typer.Argument(help=help_strings.CUSTOM_DOMAIN_NAME)],
266+
item_hash: Annotated[Optional[str], typer.Option(help=help_strings.CUSTOM_DOMAIN_ITEM_HASH)] = None,
267+
catch_all_path: Annotated[Optional[str], typer.Option(help=help_strings.IPFS_CATCH_ALL_PATH)] = None,
268+
ask: Annotated[bool, typer.Option(help=help_strings.ASK_FOR_CONFIRMATION)] = True,
269+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
270+
private_key_file: Annotated[
271+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
272+
] = settings.PRIVATE_KEY_FILE,
269273
):
270274
"""Attach resource to a Custom Domain."""
271275
account: AccountFromPrivateKey = _load_account(private_key, private_key_file)
@@ -282,10 +286,12 @@ async def attach(
282286

283287
@app.command()
284288
async def detach(
285-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
286-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
287-
fqdn: str = typer.Argument(..., help=help_strings.CUSTOM_DOMAIN_NAME),
288-
ask: bool = typer.Option(default=True, help=help_strings.ASK_FOR_CONFIRMATION),
289+
fqdn: Annotated[str, typer.Argument(help=help_strings.CUSTOM_DOMAIN_NAME)],
290+
ask: Annotated[bool, typer.Option(help=help_strings.ASK_FOR_CONFIRMATION)] = True,
291+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
292+
private_key_file: Annotated[
293+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
294+
] = settings.PRIVATE_KEY_FILE,
289295
):
290296
"""Unlink Custom Domain."""
291297
account: AccountFromPrivateKey = _load_account(private_key, private_key_file)
@@ -296,9 +302,11 @@ async def detach(
296302

297303
@app.command()
298304
async def info(
299-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
300-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
301-
fqdn: str = typer.Argument(..., help=help_strings.CUSTOM_DOMAIN_NAME),
305+
fqdn: Annotated[str, typer.Argument(help=help_strings.CUSTOM_DOMAIN_NAME)],
306+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
307+
private_key_file: Annotated[
308+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
309+
] = settings.PRIVATE_KEY_FILE,
302310
):
303311
"""Show Custom Domain Details."""
304312
account: AccountFromPrivateKey = _load_account(private_key, private_key_file)

src/aleph_client/commands/files.py

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import logging
55
from datetime import datetime
66
from pathlib import Path
7-
from typing import Optional
7+
from typing import Annotated, Optional
88

99
import aiohttp
1010
import typer
@@ -30,12 +30,14 @@
3030

3131
@app.command()
3232
async def pin(
33-
item_hash: str = typer.Argument(..., help="IPFS hash to pin on aleph.im"),
34-
channel: Optional[str] = typer.Option(default=settings.DEFAULT_CHANNEL, help=help_strings.CHANNEL),
35-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
36-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
37-
ref: Optional[str] = typer.Option(None, help=help_strings.REF),
38-
debug: bool = False,
33+
item_hash: Annotated[str, typer.Argument(help="IPFS hash to pin on aleph.im")],
34+
channel: Annotated[Optional[str], typer.Option(help=help_strings.CHANNEL)] = settings.DEFAULT_CHANNEL,
35+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
36+
private_key_file: Annotated[
37+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
38+
] = settings.PRIVATE_KEY_FILE,
39+
ref: Annotated[Optional[str], typer.Option(help=help_strings.REF)] = None,
40+
debug: Annotated[bool, typer.Option()] = False,
3941
):
4042
"""Persist a file from IPFS on aleph.im."""
4143

@@ -58,12 +60,14 @@ async def pin(
5860

5961
@app.command()
6062
async def upload(
61-
path: Path = typer.Argument(..., help="Path of the file to upload"),
62-
channel: Optional[str] = typer.Option(default=settings.DEFAULT_CHANNEL, help=help_strings.CHANNEL),
63-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
64-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
65-
ref: Optional[str] = typer.Option(None, help=help_strings.REF),
66-
debug: bool = False,
63+
path: Annotated[Path, typer.Argument(help="Path of the file to upload")],
64+
channel: Annotated[Optional[str], typer.Option(help=help_strings.CHANNEL)] = settings.DEFAULT_CHANNEL,
65+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
66+
private_key_file: Annotated[
67+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
68+
] = settings.PRIVATE_KEY_FILE,
69+
ref: Annotated[Optional[str], typer.Option(help=help_strings.REF)] = None,
70+
debug: Annotated[bool, typer.Option()] = False,
6771
):
6872
"""Upload and store a file on aleph.im."""
6973

@@ -97,14 +101,14 @@ async def upload(
97101

98102
@app.command()
99103
async def download(
100-
hash: str = typer.Argument(..., help="hash to download from aleph."),
101-
use_ipfs: bool = typer.Option(default=False, help="Download using IPFS instead of storage"),
102-
output_path: Path = typer.Option(Path("."), help="Output directory path"),
103-
file_name: str = typer.Option(None, help="Output file name (without extension)"),
104-
file_extension: str = typer.Option(None, help="Output file extension"),
105-
only_info: bool = False,
106-
verbose: bool = True,
107-
debug: bool = False,
104+
hash: Annotated[str, typer.Argument(help="hash to download from aleph.")],
105+
use_ipfs: Annotated[bool, typer.Option(help="Download using IPFS instead of storage")] = False,
106+
output_path: Annotated[Path, typer.Option(help="Output directory path")] = Path("."),
107+
file_name: Annotated[Optional[str], typer.Option(help="Output file name (without extension)")] = None,
108+
file_extension: Annotated[Optional[str], typer.Option(help="Output file extension")] = None,
109+
only_info: Annotated[bool, typer.Option()] = False,
110+
verbose: Annotated[bool, typer.Option()] = True,
111+
debug: Annotated[bool, typer.Option()] = False,
108112
) -> Optional[StoredContent]:
109113
"""Download a file from aleph.im or display related infos."""
110114

@@ -142,14 +146,19 @@ async def download(
142146

143147
@app.command()
144148
async def forget(
145-
item_hash: str = typer.Argument(
146-
..., help="Hash(es) to forget. Must be a comma separated list. Example: `123...abc` or `123...abc,456...xyz`"
147-
),
148-
reason: str = typer.Argument("User deletion", help="reason to forget"),
149-
channel: Optional[str] = typer.Option(default=settings.DEFAULT_CHANNEL, help=help_strings.CHANNEL),
150-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
151-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
152-
debug: bool = False,
149+
item_hash: Annotated[
150+
str,
151+
typer.Argument(
152+
help="Hash(es) to forget. Must be a comma separated list. Example: `123...abc` or `123...abc,456...xyz`"
153+
),
154+
],
155+
reason: Annotated[str, typer.Argument(help="reason to forget")] = "User deletion",
156+
channel: Annotated[Optional[str], typer.Option(help=help_strings.CHANNEL)] = settings.DEFAULT_CHANNEL,
157+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
158+
private_key_file: Annotated[
159+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
160+
] = settings.PRIVATE_KEY_FILE,
161+
debug: Annotated[bool, typer.Option()] = False,
153162
):
154163
"""forget a file and his message on aleph.im."""
155164

@@ -225,20 +234,23 @@ def _show_files(files_data: dict) -> None:
225234
console.print(table)
226235

227236

228-
@app.command()
229-
async def list(
230-
address: Optional[str] = typer.Option(None, help="Address"),
231-
private_key: Optional[str] = typer.Option(settings.PRIVATE_KEY_STRING, help=help_strings.PRIVATE_KEY),
232-
private_key_file: Optional[Path] = typer.Option(settings.PRIVATE_KEY_FILE, help=help_strings.PRIVATE_KEY_FILE),
233-
pagination: int = typer.Option(100, help="Maximum number of files to return."),
234-
page: int = typer.Option(1, help="Offset in pages."),
235-
sort_order: int = typer.Option(
236-
-1,
237-
help=(
238-
"Order in which files should be listed: -1 means most recent messages first, 1 means older messages first."
237+
@app.command(name="list")
238+
async def list_files(
239+
address: Annotated[Optional[str], typer.Option(help="Address")] = None,
240+
private_key: Annotated[Optional[str], typer.Option(help=help_strings.PRIVATE_KEY)] = settings.PRIVATE_KEY_STRING,
241+
private_key_file: Annotated[
242+
Optional[Path], typer.Option(help=help_strings.PRIVATE_KEY_FILE)
243+
] = settings.PRIVATE_KEY_FILE,
244+
pagination: Annotated[int, typer.Option(help="Maximum number of files to return.")] = 100,
245+
page: Annotated[int, typer.Option(help="Offset in pages.")] = 1,
246+
sort_order: Annotated[
247+
int,
248+
typer.Option(
249+
help="Order in which files should be listed: -1 means most recent messages first,"
250+
" 1 means older messages first."
239251
),
240-
),
241-
json: bool = typer.Option(default=False, help="Print as json instead of rich table"),
252+
] = -1,
253+
json: Annotated[bool, typer.Option(help="Print as json instead of rich table")] = False,
242254
):
243255
"""List all files for a given address"""
244256
account: AccountFromPrivateKey = _load_account(private_key, private_key_file)

0 commit comments

Comments
 (0)