blocks-cli 0.1.24__tar.gz → 0.1.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/PKG-INFO +1 -2
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/README.md +1 -1
- blocks-cli-0.1.25/blocks_cli/builds.py +20 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/configure.py +7 -12
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/create.py +1 -1
- blocks-cli-0.1.25/blocks_cli/commands/init.py +79 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/push.py +39 -10
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/test.py +10 -9
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/config/auth.py +1 -1
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/setup.py +1 -1
- blocks-cli-0.1.24/blocks_cli/builds.py +0 -11
- blocks-cli-0.1.24/blocks_cli/commands/init.py +0 -63
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/LICENSE +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/MANIFEST.in +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/__init__.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/api.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/bundles.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/__base__.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/commands/__init__.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/config/__init__.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/config/config.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/console.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/fs.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/package.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli/registration.py +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/blocks_cli.egg-info/SOURCES.txt +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/requirements.txt +0 -0
- {blocks-cli-0.1.24 → blocks-cli-0.1.25}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: blocks-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.25
|
|
4
4
|
Summary: CLI tool for Blocks, a platform for writing custom AI-enabled codebase automations in Python. Leverage a full codebase-aware API. Automatically trigger automations from Github, Slack, and other providers.
|
|
5
5
|
Home-page: https://github.com/BlocksOrg/sdk
|
|
6
6
|
Author: BlocksOrg
|
|
@@ -69,4 +69,3 @@ blocks init --api-key <your-api-key>
|
|
|
69
69
|
blocks push automation.py
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from blocks_cli.api import api_client
|
|
4
|
+
from blocks_cli.config.config import config
|
|
5
|
+
|
|
6
|
+
def poll_build_status(image_id: str, build_id: str):
|
|
7
|
+
build_completed = False
|
|
8
|
+
while not build_completed:
|
|
9
|
+
time.sleep(0.5)
|
|
10
|
+
res = api_client.get(f"{config.clients.orchestrator_url}/v1/images/{image_id}/builds/{build_id}")
|
|
11
|
+
build_status_response = res.json()
|
|
12
|
+
|
|
13
|
+
is_completed = build_status_response.get("is_completed")
|
|
14
|
+
is_succeeded = build_status_response.get("is_succeeded")
|
|
15
|
+
|
|
16
|
+
build_completed = is_completed
|
|
17
|
+
|
|
18
|
+
if is_completed and not is_succeeded:
|
|
19
|
+
raise Exception("Build failed")
|
|
20
|
+
|
|
@@ -33,7 +33,6 @@ def configure(apikey: str = typer.Option(None, "--key", help="Blocks API key")):
|
|
|
33
33
|
print()
|
|
34
34
|
|
|
35
35
|
new_api_key = typer.prompt("API Key", existing_api_key, show_default=False)
|
|
36
|
-
|
|
37
36
|
else:
|
|
38
37
|
new_api_key = apikey
|
|
39
38
|
|
|
@@ -44,7 +43,7 @@ def configure(apikey: str = typer.Option(None, "--key", help="Blocks API key")):
|
|
|
44
43
|
with Progress(
|
|
45
44
|
SpinnerColumn(),
|
|
46
45
|
TextColumn("[progress.description]{task.description}"),
|
|
47
|
-
transient=
|
|
46
|
+
transient=False,
|
|
48
47
|
) as init_progress:
|
|
49
48
|
try:
|
|
50
49
|
api_task = init_progress.add_task(description="Verifying API key...", total=None)
|
|
@@ -54,21 +53,17 @@ def configure(apikey: str = typer.Option(None, "--key", help="Blocks API key")):
|
|
|
54
53
|
})
|
|
55
54
|
|
|
56
55
|
if response.status_code > 299:
|
|
57
|
-
raise Exception("API Key is invalid. Please check your API key at [
|
|
56
|
+
raise Exception("API Key is invalid. Please check your API key at [white]https://app.blocksorg.com[/white]")
|
|
58
57
|
|
|
59
58
|
config.auth.save_api_key(new_api_key)
|
|
60
|
-
|
|
61
|
-
init_progress.
|
|
59
|
+
last_digits = new_api_key[-8:]
|
|
60
|
+
init_progress.update(api_task, description=f"[green]API key verified and saved successfully [italic][dim]...{last_digits}[/dim][/italic][/green]")
|
|
62
61
|
except Exception as e:
|
|
63
|
-
raise InvalidApiKeyError(f"
|
|
64
|
-
|
|
65
|
-
last_digits = new_api_key[-8:]
|
|
66
|
-
|
|
67
|
-
console.print(f"[green]API key saved successfully [italic][dim]...{last_digits}[/dim][/italic][/green]")
|
|
62
|
+
raise InvalidApiKeyError(f"Failed to verify API key. Please check your API key at [white]https://app.blocksorg.com[/white]")
|
|
68
63
|
|
|
69
64
|
except InvalidApiKeyError as e:
|
|
70
|
-
console.print(f"
|
|
65
|
+
console.print(f"[red]{e}[/red]")
|
|
71
66
|
raise typer.Exit(code=1)
|
|
72
67
|
except Exception as e:
|
|
73
|
-
console.print(f"
|
|
68
|
+
console.print(f"[red]Error configuring blocks[/red]")
|
|
74
69
|
raise typer.Exit(code=1)
|
|
@@ -63,7 +63,7 @@ def {name}(input):
|
|
|
63
63
|
f.write('''blocks-sdk>={version}'''.format(version=latest_version))
|
|
64
64
|
|
|
65
65
|
console.print(f"Successfully created automation [green]{name}[/green] in [green]{automation_dir.absolute()}[/green]")
|
|
66
|
-
console.print(
|
|
66
|
+
console.print(f"[green]{name}/\n main.py\n requirements.txt[/green]")
|
|
67
67
|
console.print(f"[blue]Choose an event from [white]https://docs.blocksorg.com/events[/white] and run [white]blocks test .blocks/{name}/main.py[/white] to test the automation[/blue]")
|
|
68
68
|
|
|
69
69
|
except Exception as e:
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import git
|
|
2
|
+
import typer
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
6
|
+
|
|
7
|
+
from blocks_cli.api import api_client
|
|
8
|
+
from blocks_cli.commands.__base__ import blocks_cli
|
|
9
|
+
from blocks_cli.package import warn_current_package_version
|
|
10
|
+
from blocks_cli.config.config import config
|
|
11
|
+
from blocks_cli.console import console
|
|
12
|
+
from blocks_cli.fs import find_dir
|
|
13
|
+
|
|
14
|
+
class AlreadyInitializedError(Exception):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
@blocks_cli.command()
|
|
18
|
+
def init(apikey: str = typer.Option(None, "--key", help="API key for authentication")):
|
|
19
|
+
"""Initialize blocks in the current directory."""
|
|
20
|
+
try:
|
|
21
|
+
warn_current_package_version()
|
|
22
|
+
|
|
23
|
+
# finds .blocks directory already inside or .blocks is below the current directory
|
|
24
|
+
blocks_dir = find_dir(target=".blocks")
|
|
25
|
+
|
|
26
|
+
if blocks_dir is not None:
|
|
27
|
+
if apikey:
|
|
28
|
+
console.print(f"[yellow]To change your API key, use [white]blocks configure --key {apikey}[/white][/yellow]")
|
|
29
|
+
raise AlreadyInitializedError(f"Blocks is already initialized: [white]{blocks_dir}[/white]")
|
|
30
|
+
else:
|
|
31
|
+
# We are in some other subdirectory
|
|
32
|
+
working_dir = Path.cwd()
|
|
33
|
+
try:
|
|
34
|
+
# Try to find the root of the directory if git is initialized
|
|
35
|
+
repo = git.Repo(search_parent_directories=True)
|
|
36
|
+
working_dir = repo.working_dir
|
|
37
|
+
except Exception as e:
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
# working_dir is equal to root of the directory or the current directory if git is not initialized
|
|
41
|
+
working_dir = Path(working_dir)
|
|
42
|
+
blocks_dir = working_dir / ".blocks"
|
|
43
|
+
if not blocks_dir.exists():
|
|
44
|
+
blocks_dir.mkdir()
|
|
45
|
+
console.print(f"[green]Created [white].blocks[/white] folder: [white]{blocks_dir}[/white][/green]")
|
|
46
|
+
else:
|
|
47
|
+
if apikey:
|
|
48
|
+
console.print(f"[yellow]To change your API key, use [white]blocks configure --key {apikey}[/white][/yellow]")
|
|
49
|
+
raise AlreadyInitializedError(f"[yellow]Blocks is already initialized: [white]{blocks_dir}[/white][/yellow]")
|
|
50
|
+
|
|
51
|
+
# Verify and save API key if provided
|
|
52
|
+
if apikey:
|
|
53
|
+
with Progress(
|
|
54
|
+
SpinnerColumn(),
|
|
55
|
+
TextColumn("[progress.description]{task.description}"),
|
|
56
|
+
transient=False,
|
|
57
|
+
) as progress:
|
|
58
|
+
api_task = progress.add_task(description="Verifying API key...", total=None, style="blue")
|
|
59
|
+
|
|
60
|
+
response = api_client.get(f"{config.clients.client_url}/v1/apikeys/{apikey}", headers={
|
|
61
|
+
"Authorization": f"ApiKey {apikey}"
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if response.status_code > 299:
|
|
65
|
+
raise Exception("API Key is invalid. Please check your API key at [white]https://app.blocksorg.com[/white]")
|
|
66
|
+
|
|
67
|
+
config.auth.save_api_key(apikey)
|
|
68
|
+
last_digits = apikey[-8:]
|
|
69
|
+
progress.update(api_task, description=f"[green]API key verified and saved successfully [italic][dim]...{last_digits}[/dim][/italic][/green]")
|
|
70
|
+
progress.refresh()
|
|
71
|
+
|
|
72
|
+
console.print("[green]Blocks has been successfully initialized.[/green]")
|
|
73
|
+
|
|
74
|
+
except AlreadyInitializedError as e:
|
|
75
|
+
console.print(f"[yellow]{str(e)}[/yellow]")
|
|
76
|
+
raise typer.Exit(code=0)
|
|
77
|
+
except Exception as e:
|
|
78
|
+
console.print(f"[red]{str(e)}[/red]")
|
|
79
|
+
raise typer.Exit(code=1)
|
|
@@ -2,8 +2,9 @@ import git
|
|
|
2
2
|
import typer
|
|
3
3
|
import importlib.util
|
|
4
4
|
import sys
|
|
5
|
-
|
|
5
|
+
import re
|
|
6
6
|
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
8
9
|
|
|
9
10
|
from blocks_cli.console import console
|
|
@@ -28,6 +29,32 @@ def push(file: Path = typer.Argument(..., help="Name of blocks file to push.")):
|
|
|
28
29
|
) as init_progress:
|
|
29
30
|
init_task = init_progress.add_task(description="Initializing...", total=None)
|
|
30
31
|
|
|
32
|
+
state, _ = get_blocks_state_and_module_from_file(file)
|
|
33
|
+
|
|
34
|
+
if not state.automations:
|
|
35
|
+
raise Exception(f"No automations found in the specified file")
|
|
36
|
+
|
|
37
|
+
automation_names = []
|
|
38
|
+
try:
|
|
39
|
+
automation_names = [automation.get("task_kwargs",{})["name"] for automation in state.automations]
|
|
40
|
+
except Exception as e:
|
|
41
|
+
raise Exception("Automations must have a name defined in the [white]@task[/white] decorator")
|
|
42
|
+
|
|
43
|
+
for automation_name in automation_names:
|
|
44
|
+
is_valid = re.match(r"^[a-zA-Z0-9][a-zA-Z0-9_-]*$", automation_name)
|
|
45
|
+
if is_valid is None:
|
|
46
|
+
raise Exception(f"[red]Automation [white]'{automation_name}'[/white] is not a valid name. Automation names must start with a letter or number and can only contain letters, numbers, dashes, and underscores.[/red]")
|
|
47
|
+
|
|
48
|
+
trigger_aliases = []
|
|
49
|
+
try:
|
|
50
|
+
trigger_aliases = [automation.get("trigger_alias") for automation in state.automations]
|
|
51
|
+
except Exception as e:
|
|
52
|
+
raise Exception("Event must be defined in the [white]@on[/white] decorator")
|
|
53
|
+
|
|
54
|
+
for trigger_alias in trigger_aliases:
|
|
55
|
+
if trigger_alias is None or trigger_alias == "":
|
|
56
|
+
raise Exception(f"Event [white]'{trigger_alias}'[/white] is not a valid. For a list of supported events, please visit [white]https://docs.blocksorg.com/docs/events[/white]")
|
|
57
|
+
|
|
31
58
|
# working directory from where the command was invoked
|
|
32
59
|
cwd = file.resolve().parent
|
|
33
60
|
|
|
@@ -57,9 +84,7 @@ def push(file: Path = typer.Argument(..., help="Name of blocks file to push.")):
|
|
|
57
84
|
)
|
|
58
85
|
|
|
59
86
|
# get pip dependencies
|
|
60
|
-
|
|
61
87
|
pip_dependencies = []
|
|
62
|
-
|
|
63
88
|
if Path(requirements_path).exists():
|
|
64
89
|
with open(requirements_path, "r") as f:
|
|
65
90
|
pip_dependencies = f.read().splitlines()
|
|
@@ -68,8 +93,6 @@ def push(file: Path = typer.Argument(..., help="Name of blocks file to push.")):
|
|
|
68
93
|
init_task, total=1, description="Collecting automations..."
|
|
69
94
|
)
|
|
70
95
|
|
|
71
|
-
state, _ = get_blocks_state_and_module_from_file(file)
|
|
72
|
-
|
|
73
96
|
# Construct payload
|
|
74
97
|
with Progress(
|
|
75
98
|
SpinnerColumn(),
|
|
@@ -161,10 +184,16 @@ def push(file: Path = typer.Argument(..., help="Name of blocks file to push.")):
|
|
|
161
184
|
image_id = res.json().get("image_id")
|
|
162
185
|
is_build_triggered = res.json().get("is_build_triggered")
|
|
163
186
|
if is_build_triggered:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
try:
|
|
188
|
+
poll_build_status(image_id, build_id)
|
|
189
|
+
build_progress.update(
|
|
190
|
+
build_task, total=1, description="Build succeeded"
|
|
191
|
+
)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
build_progress.update(
|
|
194
|
+
build_task, total=1, description="Build failed, please try again. If the issue persists check your automation's requirements.txt to ensure all dependencies are valid and/or our status page at https://status.blocksorg.com"
|
|
195
|
+
)
|
|
196
|
+
raise typer.Exit(1)
|
|
168
197
|
except Exception as e:
|
|
169
|
-
console.print(f"[red]
|
|
198
|
+
console.print(f"[red]{str(e)}[/red]")
|
|
170
199
|
raise typer.Exit(1)
|
|
@@ -26,6 +26,8 @@ def invoke_automation_with_test_event(automation_module, automation):
|
|
|
26
26
|
transient=False,
|
|
27
27
|
) as test_event_progress:
|
|
28
28
|
test_event_task = test_event_progress.add_task(description="Preparing automation...", total=None)
|
|
29
|
+
if trigger_alias is None or trigger_alias == "":
|
|
30
|
+
raise Exception("Event must be defined in the [white]@on[/white] decorator. For a list of supported events, please visit [white]https://docs.blocksorg.com/docs/events[/white]")
|
|
29
31
|
res = api_client.get(f"{config.clients.client_url}/v1/test_events", params={
|
|
30
32
|
"trigger_alias": trigger_alias,
|
|
31
33
|
})
|
|
@@ -35,18 +37,17 @@ def invoke_automation_with_test_event(automation_module, automation):
|
|
|
35
37
|
event_response = res.json()
|
|
36
38
|
event_data = event_response.get("event_data")
|
|
37
39
|
|
|
38
|
-
console.print(f"Invoking automation [
|
|
40
|
+
console.print(f"[blue]Invoking automation [white]{automation_name}[/white] with event [white]{trigger_alias}[/white][/blue]")
|
|
39
41
|
console.print(
|
|
40
|
-
Rule("Automation Logs", characters="=", style="
|
|
42
|
+
Rule("BEGIN Automation Logs", characters="=", style="blue")
|
|
41
43
|
)
|
|
42
44
|
|
|
43
45
|
res = function(event_data)
|
|
44
|
-
|
|
45
46
|
console.print(
|
|
46
|
-
Rule("
|
|
47
|
+
Rule("END Automation Logs", characters="=", style="blue")
|
|
47
48
|
)
|
|
48
49
|
|
|
49
|
-
console.print(f"Automation [
|
|
50
|
+
console.print(f"[green]Automation [white]{automation_name}[/white] invoked successfully[/green]")
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
|
|
@@ -72,17 +73,17 @@ def test(
|
|
|
72
73
|
invoke_automation_with_test_event(automation_module, automation)
|
|
73
74
|
|
|
74
75
|
elif num_automations > 1 and not name:
|
|
75
|
-
raise Exception("
|
|
76
|
+
raise Exception("Multiple automations found in the file, please specify which one to test with the [white]--name[/white] flag.")
|
|
76
77
|
elif num_automations > 1 and name:
|
|
77
78
|
# find in automations
|
|
78
79
|
automation = next((a for a in automations if a.get("task_kwargs",{}).get("name") == name), None)
|
|
79
80
|
if not automation:
|
|
80
|
-
raise Exception(f"
|
|
81
|
+
raise Exception(f"Automation with name [white]{name}[/white] not found.")
|
|
81
82
|
|
|
82
83
|
invoke_automation_with_test_event(automation_module, automation)
|
|
83
84
|
else:
|
|
84
|
-
raise Exception("
|
|
85
|
+
raise Exception("No valid automations found in the specified file.")
|
|
85
86
|
|
|
86
87
|
except Exception as e:
|
|
87
|
-
console.print(f"[red]
|
|
88
|
+
console.print(f"[red]{e}[/red]")
|
|
88
89
|
raise typer.Exit(1)
|
|
@@ -17,7 +17,7 @@ class AuthConfig(BaseModel):
|
|
|
17
17
|
# Allow only base64url characters (alphanumeric, '-', '_', and '=')
|
|
18
18
|
# This prevents invalid characters from blowing up the config file
|
|
19
19
|
if re.search(r'[^a-zA-Z0-9\-_=]', api_key):
|
|
20
|
-
raise ValueError("Invalid API key supplied. Please check your API key at [
|
|
20
|
+
raise ValueError("Invalid API key supplied. Please check your API key at [white]https://app.blocksorg.com[/white]")
|
|
21
21
|
|
|
22
22
|
config_file = Config.get_config_file()
|
|
23
23
|
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
|
|
3
|
-
from blocks_cli.api import api_client
|
|
4
|
-
from blocks_cli.config.config import config
|
|
5
|
-
|
|
6
|
-
def poll_build_status(image_id: str, build_id: str):
|
|
7
|
-
build_completed = False
|
|
8
|
-
while not build_completed:
|
|
9
|
-
res = api_client.get(f"{config.clients.orchestrator_url}/v1/images/{image_id}/builds/{build_id}")
|
|
10
|
-
build_completed = res.json().get("is_completed")
|
|
11
|
-
time.sleep(1)
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import git
|
|
2
|
-
import typer
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
6
|
-
|
|
7
|
-
from blocks_cli.api import api_client
|
|
8
|
-
from blocks_cli.commands.__base__ import blocks_cli
|
|
9
|
-
from blocks_cli.package import warn_current_package_version
|
|
10
|
-
from blocks_cli.config.config import config
|
|
11
|
-
from blocks_cli.console import console
|
|
12
|
-
|
|
13
|
-
@blocks_cli.command()
|
|
14
|
-
def init(apikey: str = typer.Option(None, "--key", help="API key for authentication")):
|
|
15
|
-
"""Initialize blocks in the current directory."""
|
|
16
|
-
try:
|
|
17
|
-
warn_current_package_version()
|
|
18
|
-
|
|
19
|
-
with Progress(
|
|
20
|
-
SpinnerColumn(),
|
|
21
|
-
TextColumn("[progress.description]{task.description}"),
|
|
22
|
-
transient=False,
|
|
23
|
-
) as progress:
|
|
24
|
-
|
|
25
|
-
working_dir = Path.cwd()
|
|
26
|
-
try:
|
|
27
|
-
repo = git.Repo(search_parent_directories=True)
|
|
28
|
-
working_dir = repo.working_dir
|
|
29
|
-
except Exception as e:
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
working_dir = Path(working_dir)
|
|
33
|
-
|
|
34
|
-
# Create .blocks directory if it doesn't exist
|
|
35
|
-
blocks_dir = working_dir / ".blocks"
|
|
36
|
-
|
|
37
|
-
if not blocks_dir.exists():
|
|
38
|
-
blocks_dir.mkdir()
|
|
39
|
-
folder_task = progress.add_task(description="Creating .blocks folder...", total=None)
|
|
40
|
-
progress.update(folder_task, description="[green]Created .blocks folder[/green]")
|
|
41
|
-
|
|
42
|
-
progress.refresh()
|
|
43
|
-
|
|
44
|
-
# Verify and save API key if provided
|
|
45
|
-
if apikey:
|
|
46
|
-
api_task = progress.add_task(description="Verifying API key...", total=None)
|
|
47
|
-
|
|
48
|
-
response = api_client.get(f"{config.clients.client_url}/v1/apikeys/{apikey}", headers={
|
|
49
|
-
"Authorization": f"ApiKey {apikey}"
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
if response.status_code > 299:
|
|
53
|
-
raise Exception("API Key is invalid. Please check your API key at [link=https://app.blocksorg.com]https://app.blocksorg.com[/link]")
|
|
54
|
-
|
|
55
|
-
config.auth.save_api_key(apikey)
|
|
56
|
-
progress.update(api_task, description="[green]API key verified and saved successfully[/green]")
|
|
57
|
-
progress.refresh()
|
|
58
|
-
|
|
59
|
-
console.print("[green]Blocks has been successfully initialized.[/green]")
|
|
60
|
-
|
|
61
|
-
except Exception as e:
|
|
62
|
-
console.print(f"[red]Error initializing blocks: {str(e)}[/red]")
|
|
63
|
-
raise typer.Exit(code=1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|