aevum-cli 0.2.0__py3-none-any.whl
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.
- aevum/cli/__init__.py +14 -0
- aevum/cli/__main__.py +9 -0
- aevum/cli/app.py +22 -0
- aevum/cli/commands/__init__.py +1 -0
- aevum/cli/commands/complication.py +60 -0
- aevum/cli/commands/conformance.py +46 -0
- aevum/cli/commands/server.py +92 -0
- aevum/cli/commands/store.py +51 -0
- aevum/cli/commands/version.py +32 -0
- aevum/cli/py.typed +0 -0
- aevum_cli-0.2.0.dist-info/METADATA +36 -0
- aevum_cli-0.2.0.dist-info/RECORD +14 -0
- aevum_cli-0.2.0.dist-info/WHEEL +4 -0
- aevum_cli-0.2.0.dist-info/entry_points.txt +2 -0
aevum/cli/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum.cli -- Command-line interface for operating Aevum nodes.
|
|
3
|
+
|
|
4
|
+
Usage: aevum <command> [options]
|
|
5
|
+
|
|
6
|
+
Commands:
|
|
7
|
+
version Print installed package versions
|
|
8
|
+
server start Start the HTTP API server
|
|
9
|
+
store migrate Migrate between graph backends
|
|
10
|
+
complication Manage installed complications
|
|
11
|
+
conformance run Run the conformance suite
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__version__ = "0.1.0"
|
aevum/cli/__main__.py
ADDED
aevum/cli/app.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Top-level typer app. Sub-commands registered here.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from aevum.cli.commands import complication, conformance, server, store, version
|
|
10
|
+
|
|
11
|
+
app = typer.Typer(
|
|
12
|
+
name="aevum",
|
|
13
|
+
help="Aevum context kernel -- command-line interface.",
|
|
14
|
+
no_args_is_help=True,
|
|
15
|
+
pretty_exceptions_enable=False,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
app.add_typer(server.app, name="server")
|
|
19
|
+
app.add_typer(store.app, name="store")
|
|
20
|
+
app.add_typer(complication.app, name="complication")
|
|
21
|
+
app.add_typer(conformance.app, name="conformance")
|
|
22
|
+
app.command(name="version")(version.version_command)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""aevum.cli.commands -- sub-command modules."""
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum complication list/suspend/resume -- manage complications.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
app = typer.Typer(help="Manage installed complications.")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@app.command("list")
|
|
15
|
+
def list_complications(
|
|
16
|
+
graph: Annotated[str, typer.Option(help="Graph backend")] = "memory",
|
|
17
|
+
) -> None:
|
|
18
|
+
"""List all installed complications with state and health."""
|
|
19
|
+
from aevum.core.engine import Engine
|
|
20
|
+
engine = Engine()
|
|
21
|
+
complications = engine.list_complications()
|
|
22
|
+
if not complications:
|
|
23
|
+
typer.echo("No complications installed.")
|
|
24
|
+
return
|
|
25
|
+
typer.echo(f"Installed complications ({len(complications)}):")
|
|
26
|
+
for name, entry in complications.items():
|
|
27
|
+
state = entry["state"]
|
|
28
|
+
typer.echo(f" {name}: {state}")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.command("suspend")
|
|
32
|
+
def suspend(
|
|
33
|
+
name: Annotated[str, typer.Argument(help="Complication name to suspend")],
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Suspend an ACTIVE complication."""
|
|
36
|
+
from aevum.core.engine import Engine
|
|
37
|
+
from aevum.core.exceptions import ComplicationError
|
|
38
|
+
engine = Engine()
|
|
39
|
+
try:
|
|
40
|
+
engine.suspend_complication(name)
|
|
41
|
+
typer.echo(f"Suspended: {name}")
|
|
42
|
+
except ComplicationError as e:
|
|
43
|
+
typer.echo(f"Error: {e}", err=True)
|
|
44
|
+
raise typer.Exit(code=1) from e
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@app.command("resume")
|
|
48
|
+
def resume(
|
|
49
|
+
name: Annotated[str, typer.Argument(help="Complication name to resume")],
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Resume a SUSPENDED complication."""
|
|
52
|
+
from aevum.core.engine import Engine
|
|
53
|
+
from aevum.core.exceptions import ComplicationError
|
|
54
|
+
engine = Engine()
|
|
55
|
+
try:
|
|
56
|
+
engine.resume_complication(name)
|
|
57
|
+
typer.echo(f"Resumed: {name}")
|
|
58
|
+
except ComplicationError as e:
|
|
59
|
+
typer.echo(f"Error: {e}", err=True)
|
|
60
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum conformance run -- run the conformance suite.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import subprocess
|
|
8
|
+
from typing import Annotated
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
|
|
12
|
+
app = typer.Typer(help="Run the Aevum conformance suite.")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.command("run")
|
|
16
|
+
def run(
|
|
17
|
+
impl: Annotated[
|
|
18
|
+
str,
|
|
19
|
+
typer.Option(help="Python import path to AevumProtocol implementation"),
|
|
20
|
+
] = "aevum.core.engine:Engine",
|
|
21
|
+
verbose: Annotated[bool, typer.Option("--verbose", "-v")] = False,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Run the aevum-conformance suite against an implementation.
|
|
25
|
+
|
|
26
|
+
Requires aevum-conformance to be installed separately:
|
|
27
|
+
pip install aevum-conformance
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
import importlib
|
|
31
|
+
importlib.import_module("conformance")
|
|
32
|
+
except ImportError:
|
|
33
|
+
typer.echo(
|
|
34
|
+
"aevum-conformance is not installed. "
|
|
35
|
+
"Install from: github.com/aevum-labs/aevum-conformance",
|
|
36
|
+
err=True,
|
|
37
|
+
)
|
|
38
|
+
raise typer.Exit(code=1) from None
|
|
39
|
+
|
|
40
|
+
args = ["python", "-m", "pytest", "conformance/"]
|
|
41
|
+
if verbose:
|
|
42
|
+
args.append("-v")
|
|
43
|
+
|
|
44
|
+
typer.echo(f"Running conformance suite against: {impl}")
|
|
45
|
+
result = subprocess.run(args)
|
|
46
|
+
raise typer.Exit(code=result.returncode)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum server start -- start the Aevum HTTP API server.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
import uvicorn
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from aevum.core.engine import Engine
|
|
14
|
+
|
|
15
|
+
app = typer.Typer(help="Manage the Aevum HTTP API server.")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command("start")
|
|
19
|
+
def start(
|
|
20
|
+
host: Annotated[str, typer.Option(help="Bind host")] = "0.0.0.0",
|
|
21
|
+
port: Annotated[int, typer.Option(help="Bind port")] = 8000,
|
|
22
|
+
workers: Annotated[int, typer.Option(help="Number of uvicorn workers")] = 1,
|
|
23
|
+
graph: Annotated[
|
|
24
|
+
str,
|
|
25
|
+
typer.Option(
|
|
26
|
+
help="Graph backend. Options: memory | oxigraph:<path> | postgres:<dsn>"
|
|
27
|
+
),
|
|
28
|
+
] = "memory",
|
|
29
|
+
api_key: Annotated[
|
|
30
|
+
str | None,
|
|
31
|
+
typer.Option(envvar="AEVUM_API_KEY", help="API key (overrides AEVUM_API_KEY env var)"),
|
|
32
|
+
] = None,
|
|
33
|
+
reload: Annotated[bool, typer.Option(help="Enable auto-reload (dev only)")] = False,
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Start the Aevum HTTP API server."""
|
|
36
|
+
import os
|
|
37
|
+
|
|
38
|
+
if api_key:
|
|
39
|
+
os.environ["AEVUM_API_KEY"] = api_key
|
|
40
|
+
|
|
41
|
+
engine = _build_engine(graph)
|
|
42
|
+
|
|
43
|
+
from aevum.server.app import create_app
|
|
44
|
+
from aevum.server.core.config import Settings
|
|
45
|
+
|
|
46
|
+
settings_with_overrides = Settings(
|
|
47
|
+
host=host,
|
|
48
|
+
port=port,
|
|
49
|
+
)
|
|
50
|
+
app_instance = create_app(engine=engine, settings=settings_with_overrides)
|
|
51
|
+
|
|
52
|
+
typer.echo(f"Starting Aevum server on {host}:{port} (graph={graph})")
|
|
53
|
+
uvicorn.run(
|
|
54
|
+
app_instance,
|
|
55
|
+
host=host,
|
|
56
|
+
port=port,
|
|
57
|
+
workers=workers if not reload else 1,
|
|
58
|
+
reload=reload,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _build_engine(graph: str) -> Engine:
|
|
63
|
+
"""Build an Engine from the --graph flag."""
|
|
64
|
+
from aevum.core.engine import Engine
|
|
65
|
+
|
|
66
|
+
if graph == "memory":
|
|
67
|
+
typer.echo("Graph backend: in-memory (dev only -- data lost on restart)")
|
|
68
|
+
return Engine()
|
|
69
|
+
|
|
70
|
+
if graph.startswith("oxigraph:"):
|
|
71
|
+
path = graph[len("oxigraph:"):]
|
|
72
|
+
from aevum.store.oxigraph import OxigraphStore
|
|
73
|
+
typer.echo(f"Graph backend: Oxigraph at {path}")
|
|
74
|
+
return Engine(graph_store=OxigraphStore(path=path))
|
|
75
|
+
|
|
76
|
+
if graph.startswith("postgres:"):
|
|
77
|
+
dsn = graph[len("postgres:"):]
|
|
78
|
+
try:
|
|
79
|
+
import psycopg
|
|
80
|
+
from aevum.store.postgres import PostgresStore
|
|
81
|
+
from aevum.store.postgres.store import initialize_schema
|
|
82
|
+
conn = psycopg.connect(dsn)
|
|
83
|
+
initialize_schema(conn)
|
|
84
|
+
typer.echo("Graph backend: PostgreSQL")
|
|
85
|
+
return Engine(graph_store=PostgresStore(conn))
|
|
86
|
+
except ImportError:
|
|
87
|
+
typer.echo("Error: aevum-store-postgres is not installed.", err=True)
|
|
88
|
+
raise typer.Exit(code=1) from None
|
|
89
|
+
|
|
90
|
+
typer.echo(f"Unknown graph backend: {graph!r}", err=True)
|
|
91
|
+
typer.echo("Options: memory | oxigraph:<path> | postgres:<dsn>", err=True)
|
|
92
|
+
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum store migrate -- migrate between graph backends.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
app = typer.Typer(help="Manage graph store backends.")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@app.command("migrate")
|
|
15
|
+
def migrate(
|
|
16
|
+
from_backend: Annotated[str, typer.Option("--from", help="Source backend (oxigraph:<path>)")] = "",
|
|
17
|
+
to_backend: Annotated[str, typer.Option("--to", help="Target backend (postgres:<dsn>)")] = "",
|
|
18
|
+
) -> None:
|
|
19
|
+
"""Migrate graph data between backends."""
|
|
20
|
+
if not from_backend or not to_backend:
|
|
21
|
+
typer.echo("Both --from and --to are required.", err=True)
|
|
22
|
+
raise typer.Exit(code=1)
|
|
23
|
+
|
|
24
|
+
if not from_backend.startswith("oxigraph:"):
|
|
25
|
+
typer.echo(f"Unsupported source backend: {from_backend!r}", err=True)
|
|
26
|
+
typer.echo("Currently supported source: oxigraph:<path>", err=True)
|
|
27
|
+
raise typer.Exit(code=1)
|
|
28
|
+
|
|
29
|
+
if not to_backend.startswith("postgres:"):
|
|
30
|
+
typer.echo(f"Unsupported target backend: {to_backend!r}", err=True)
|
|
31
|
+
typer.echo("Currently supported target: postgres:<dsn>", err=True)
|
|
32
|
+
raise typer.Exit(code=1)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
from aevum.store.postgres.store import migrate_from_oxigraph
|
|
36
|
+
except ImportError:
|
|
37
|
+
typer.echo("Error: aevum-store-postgres is not installed.", err=True)
|
|
38
|
+
raise typer.Exit(code=1) from None
|
|
39
|
+
|
|
40
|
+
oxigraph_path = from_backend[len("oxigraph:"):]
|
|
41
|
+
postgres_dsn = to_backend[len("postgres:"):]
|
|
42
|
+
|
|
43
|
+
typer.echo(f"Migrating: {oxigraph_path} -> PostgreSQL")
|
|
44
|
+
try:
|
|
45
|
+
import psycopg
|
|
46
|
+
conn = psycopg.connect(postgres_dsn)
|
|
47
|
+
migrated = migrate_from_oxigraph(oxigraph_path, conn)
|
|
48
|
+
typer.echo(f"Migration complete: {migrated} entities transferred.")
|
|
49
|
+
except Exception as e:
|
|
50
|
+
typer.echo(f"Migration failed: {e}", err=True)
|
|
51
|
+
raise typer.Exit(code=1) from e
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
aevum version -- print installed package versions.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
_PACKAGES = [
|
|
12
|
+
"aevum-core",
|
|
13
|
+
"aevum-server",
|
|
14
|
+
"aevum-sdk",
|
|
15
|
+
"aevum-store-oxigraph",
|
|
16
|
+
"aevum-store-postgres",
|
|
17
|
+
"aevum-mcp",
|
|
18
|
+
"aevum-oidc",
|
|
19
|
+
"aevum-llm",
|
|
20
|
+
"aevum-cli",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def version_command() -> None:
|
|
25
|
+
"""Print versions of all installed Aevum packages."""
|
|
26
|
+
typer.echo("Aevum package versions:")
|
|
27
|
+
for pkg in _PACKAGES:
|
|
28
|
+
try:
|
|
29
|
+
ver = version(pkg)
|
|
30
|
+
typer.echo(f" {pkg}: {ver}")
|
|
31
|
+
except PackageNotFoundError:
|
|
32
|
+
typer.echo(f" {pkg}: not installed")
|
aevum/cli/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aevum-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Aevum -- command-line interface for operating Aevum nodes.
|
|
5
|
+
Project-URL: Homepage, https://aevum.build
|
|
6
|
+
Project-URL: Repository, https://github.com/aevum-labs/aevum
|
|
7
|
+
License: Apache-2.0
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Requires-Dist: aevum-core
|
|
15
|
+
Requires-Dist: aevum-server
|
|
16
|
+
Requires-Dist: typer[all]>=0.12
|
|
17
|
+
Requires-Dist: uvicorn[standard]>=0.30
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# aevum-cli
|
|
26
|
+
|
|
27
|
+
Command-line interface for Aevum — start the server, manage store migrations, and inspect complication state.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install aevum-cli
|
|
31
|
+
aevum server start --graph memory
|
|
32
|
+
aevum store migrate postgres:<dsn>
|
|
33
|
+
aevum version
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
See the [main repository README](https://github.com/aevum-labs/aevum) for full usage.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
aevum/cli/__init__.py,sha256=x2aMTGkjweFxsJbQ_X5DcbrWu0otenHU1WBhbBwvqvc,405
|
|
2
|
+
aevum/cli/__main__.py,sha256=B-UQJhoC1qBUg4VNUeriZs6WB5pK2dSMJSG1q34j5ik,178
|
|
3
|
+
aevum/cli/app.py,sha256=d7r9eoftOkNOq4Djs-z4Oytq43MmEgcLw7JEDNOZIaw,613
|
|
4
|
+
aevum/cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
aevum/cli/commands/__init__.py,sha256=q7YtACQ6aH71loaw9VqG1kSpKdc26usgmhtka0JmukI,50
|
|
6
|
+
aevum/cli/commands/complication.py,sha256=kR9wAc5S6LB9PV5XPNRD-UCP2-oS8b9qvYQWoKWC3G8,1853
|
|
7
|
+
aevum/cli/commands/conformance.py,sha256=SbvXZRHXcWoxUFZl-THt9sOdAxhOtABShihdGDxURjE,1263
|
|
8
|
+
aevum/cli/commands/server.py,sha256=aYMs5Xbt7FQDoLqPf80N4hfHR06_cT-CgNBnI-Z3EG4,2981
|
|
9
|
+
aevum/cli/commands/store.py,sha256=wUs_2osNVHd90BtT5h9GEqGRmvi6kYR1hpi7d5gwZcY,1886
|
|
10
|
+
aevum/cli/commands/version.py,sha256=Gm4zassenyJ4ioAq8YHtTMwdaoUTqq9O_S0_Fu-GE4U,732
|
|
11
|
+
aevum_cli-0.2.0.dist-info/METADATA,sha256=_FE4GJFGgZc-wHByK6YW7JdIDObvPegIP00F_fpvIVM,1193
|
|
12
|
+
aevum_cli-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
13
|
+
aevum_cli-0.2.0.dist-info/entry_points.txt,sha256=bWoOLtXc2CMbW3VitiSdI0NzSnVOnnLdIdrORwDic10,49
|
|
14
|
+
aevum_cli-0.2.0.dist-info/RECORD,,
|