ai-accelerator 0.1.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.
- AI_Accelerator/__init__.py +3 -0
- AI_Accelerator/asgi.py +16 -0
- AI_Accelerator/celery.py +11 -0
- AI_Accelerator/settings.py +203 -0
- AI_Accelerator/urls.py +33 -0
- AI_Accelerator/wsgi.py +16 -0
- ai_accelerator-0.1.0.dist-info/METADATA +1079 -0
- ai_accelerator-0.1.0.dist-info/RECORD +30 -0
- ai_accelerator-0.1.0.dist-info/WHEEL +5 -0
- ai_accelerator-0.1.0.dist-info/entry_points.txt +2 -0
- ai_accelerator-0.1.0.dist-info/licenses/LICENSE +200 -0
- ai_accelerator-0.1.0.dist-info/top_level.txt +2 -0
- aiac/__init__.py +0 -0
- aiac/admin.py +3 -0
- aiac/aiac_cli.py +31 -0
- aiac/apps.py +6 -0
- aiac/client.py +29 -0
- aiac/config.py +26 -0
- aiac/console.py +15 -0
- aiac/deployment/commands.py +236 -0
- aiac/governance/commands.py +150 -0
- aiac/main.py +8 -0
- aiac/migrations/__init__.py +0 -0
- aiac/models.py +3 -0
- aiac/monitoring/commands.py +141 -0
- aiac/requirments.txt +4 -0
- aiac/tests.py +3 -0
- aiac/urls.py +4 -0
- aiac/user/auth.py +52 -0
- aiac/views.py +3 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from aiac.client import AIACClient
|
|
3
|
+
from aiac.console import console
|
|
4
|
+
from rich.table import Table
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
table = Table(title="Governance Policies")
|
|
9
|
+
|
|
10
|
+
governance_api_app = typer.Typer(help="Governance related commands for AIAC.")
|
|
11
|
+
|
|
12
|
+
@governance_api_app.command("create-policy")
|
|
13
|
+
def create_policy(name: str, policy_type: str, description: str = "", rules: str = "{}"):
|
|
14
|
+
"""Create a new governance policy."""
|
|
15
|
+
|
|
16
|
+
client = AIACClient()
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
# Parse rules if it's a string
|
|
20
|
+
if isinstance(rules, str):
|
|
21
|
+
import json
|
|
22
|
+
rules = json.loads(rules)
|
|
23
|
+
|
|
24
|
+
data = {
|
|
25
|
+
"name": name,
|
|
26
|
+
"policy_type": policy_type,
|
|
27
|
+
"description": description,
|
|
28
|
+
"rules": rules
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
response = client.api_request("/policies/", method="POST", data=data)
|
|
32
|
+
typer.echo(f"Policy '{name}' created successfully.")
|
|
33
|
+
except Exception as e:
|
|
34
|
+
typer.echo(f"Failed to create policy: {str(e)}")
|
|
35
|
+
|
|
36
|
+
@governance_api_app.command("list-policies")
|
|
37
|
+
def list_policies():
|
|
38
|
+
"""List all governance policies."""
|
|
39
|
+
|
|
40
|
+
client = AIACClient()
|
|
41
|
+
try:
|
|
42
|
+
policies = client.api_request("/policies/")
|
|
43
|
+
|
|
44
|
+
table = Table(title="Governance Policies")
|
|
45
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
46
|
+
table.add_column("Name", style="magenta")
|
|
47
|
+
table.add_column("Type", style="green")
|
|
48
|
+
table.add_column("Description")
|
|
49
|
+
|
|
50
|
+
for policy in policies:
|
|
51
|
+
table.add_row(
|
|
52
|
+
str(policy['id']),
|
|
53
|
+
policy['name'],
|
|
54
|
+
policy['policy_type'],
|
|
55
|
+
policy.get('description', '')
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
console.print(table)
|
|
59
|
+
except Exception as e:
|
|
60
|
+
typer.echo(f"Failed to retrieve policies: {str(e)}")
|
|
61
|
+
|
|
62
|
+
@governance_api_app.command("delete-policy")
|
|
63
|
+
def delete_policy(policy_id: int):
|
|
64
|
+
|
|
65
|
+
"""Delete a governance policy by its ID."""
|
|
66
|
+
|
|
67
|
+
client = AIACClient()
|
|
68
|
+
response = client.delete(f"/policies/{policy_id}/")
|
|
69
|
+
|
|
70
|
+
if response.status_code == 204:
|
|
71
|
+
typer.echo(f"Policy with ID '{policy_id}' deleted successfully.")
|
|
72
|
+
else:
|
|
73
|
+
typer.echo(f"Failed to delete policy. Status code: {response.status_code}, Response: {response.text}")
|
|
74
|
+
|
|
75
|
+
@governance_api_app.command("view-violations")
|
|
76
|
+
def view_violations():
|
|
77
|
+
"""View all policy violations."""
|
|
78
|
+
|
|
79
|
+
client = AIACClient()
|
|
80
|
+
response = client.get("/policy-violations/")
|
|
81
|
+
|
|
82
|
+
if response.status_code == 200:
|
|
83
|
+
violations = response.json()
|
|
84
|
+
for violation in violations:
|
|
85
|
+
table.add_column("Deployment_ID", "Policy_Name", "Violation_Type", "Severity","Resolved", justify="right", style="cyan", no_wrap=True)
|
|
86
|
+
table.add_row(str(violation['deployment_id']), str(violation['policy_name']), str(violation['violation_type']), str(violation['severity']), str(violation['resolved']))
|
|
87
|
+
console.print(table)
|
|
88
|
+
else:
|
|
89
|
+
typer.echo(f"Failed to retrieve violations. Status code: {response.status_code}, Response: {response.text}")
|
|
90
|
+
|
|
91
|
+
@governance_api_app.command("metrics")
|
|
92
|
+
def violation_metrics():
|
|
93
|
+
"""View metrics related to policy violations."""
|
|
94
|
+
|
|
95
|
+
client = AIACClient()
|
|
96
|
+
response = client.get("/policy-violations/")
|
|
97
|
+
|
|
98
|
+
if response.status_code == 200:
|
|
99
|
+
violations = response.json()
|
|
100
|
+
if violations:
|
|
101
|
+
for metrics in violations:
|
|
102
|
+
typer.echo("Violation Metrics:{metrics[policy_name]} --- {metrics[violation_type]}")
|
|
103
|
+
for key, value in metrics.items():
|
|
104
|
+
typer.echo(f"{key}: {value}")
|
|
105
|
+
typer.echo("-------------------------------------------------------------------------")
|
|
106
|
+
else:
|
|
107
|
+
typer.echo("No violations found.")
|
|
108
|
+
else:
|
|
109
|
+
typer.echo(f"Failed to retrieve violation metrics. Status code: {response.status_code}, Response: {response.text}")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@governance_api_app.command("apply-policy")
|
|
113
|
+
def apply_policy(policy_id: int, deployment_id: int):
|
|
114
|
+
"""Apply a policy to a deployment."""
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
client = AIACClient()
|
|
118
|
+
data = {
|
|
119
|
+
"policy": policy_id,
|
|
120
|
+
"deployment": deployment_id
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
response = client.post("/policy-assignments/", json=data)
|
|
124
|
+
|
|
125
|
+
if response.status_code == 201:
|
|
126
|
+
typer.echo(f"Policy '{policy_id}' applied to deployment '{deployment_id}' successfully.")
|
|
127
|
+
typer.echo(f"applied_at: {response.json().get('applied_at')}")
|
|
128
|
+
typer.echo(f"applied_by: {response.json().get('applied_by')}")
|
|
129
|
+
else:
|
|
130
|
+
typer.echo(f"Failed to apply policy. Status code: {response.status_code}, Response: {response.text}")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@governance_api_app.command("alert-logs")
|
|
136
|
+
def alert_logs():
|
|
137
|
+
"""View alert logs for policy violations."""
|
|
138
|
+
|
|
139
|
+
client = AIACClient()
|
|
140
|
+
response = client.get("/alerts/")
|
|
141
|
+
|
|
142
|
+
if response.status_code == 200:
|
|
143
|
+
typer.echo("Alert Logs:")
|
|
144
|
+
logs = response.json()
|
|
145
|
+
for log in logs:
|
|
146
|
+
table.add_column("Policy_Violation", "Message","Sent", justify="right", style="cyan", no_wrap=True)
|
|
147
|
+
table.add_row(str(log['policy_violation']), str(log['message']), str(log['sent']))
|
|
148
|
+
console.print(table)
|
|
149
|
+
else:
|
|
150
|
+
typer.echo(f"Failed to retrieve alert logs. Status code: {response.status_code}, Response: {response.text}")
|
aiac/main.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from aiac.deployment.commands import api_app_deployment as deployment_app
|
|
2
|
+
from aiac.monitoring.commands import monitoring_api_app as monitoring_app
|
|
3
|
+
from aiac.governance.commands import governance_api_app as governance_app
|
|
4
|
+
|
|
5
|
+
def register_commands(main_app):
|
|
6
|
+
main_app.add_typer(governance_app, name="governance", help="Governance related commands for AIAC.")
|
|
7
|
+
main_app.add_typer(deployment_app, name="deployment", help="Deployment related commands for AIAC.")
|
|
8
|
+
main_app.add_typer(monitoring_app , name="monitoring", help="Monitoring related commands for AIAC.")
|
|
File without changes
|
aiac/models.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from aiac.client import AIACClient
|
|
3
|
+
from aiac.console import console , print_message , print_warning , print_info
|
|
4
|
+
from rich.table import Table
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
table = Table()
|
|
8
|
+
|
|
9
|
+
monitoring_api_app = typer.Typer(help = "monitoring commands")
|
|
10
|
+
|
|
11
|
+
@monitoring_api_app.command("deploy-stats")
|
|
12
|
+
def deployment_stats(deployment_id: int = typer.Option(..., prompt=True, help="deployment stats")):
|
|
13
|
+
client = AIACClient()
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
response = client.api_request(f"deployments/{deployment_id}/stats/", method="GET")
|
|
17
|
+
print_message(f"Fetching stats for deployment_id: {deployment_id}")
|
|
18
|
+
|
|
19
|
+
table = Table(title="Deployment Stats")
|
|
20
|
+
table.add_column("Deployment", style="cyan")
|
|
21
|
+
table.add_column("CPU Usage", style="green")
|
|
22
|
+
table.add_column("RAM Usage", style="yellow")
|
|
23
|
+
table.add_column("Latency (ms)", style="red")
|
|
24
|
+
table.add_column("Request Count", style="blue")
|
|
25
|
+
table.add_column("Error Count", style="magenta")
|
|
26
|
+
table.add_column("Updated At", style="white")
|
|
27
|
+
|
|
28
|
+
# Assuming response is a single stats object
|
|
29
|
+
table.add_row(
|
|
30
|
+
str(deployment_id),
|
|
31
|
+
str(response.get('cpu_usage', 'N/A')),
|
|
32
|
+
str(response.get('ram_usage', 'N/A')),
|
|
33
|
+
str(response.get('latency_ms', 'N/A')),
|
|
34
|
+
str(response.get('request_count', 'N/A')),
|
|
35
|
+
str(response.get('error_count', 'N/A')),
|
|
36
|
+
str(response.get('updated_at', 'N/A'))
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
console.print(table)
|
|
40
|
+
except Exception as e:
|
|
41
|
+
typer.echo(f"Failed to fetch stats for deployment_id {deployment_id}: {str(e)}")
|
|
42
|
+
|
|
43
|
+
@monitoring_api_app.command("deploy-records")
|
|
44
|
+
def deployment_records(deployment_id: int = typer.Option(..., prompt=True, help="deployment records")):
|
|
45
|
+
client = AIACClient()
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
records = client.api_request(f"deployments/{deployment_id}/records/", method="GET")
|
|
49
|
+
print_message(f"Fetching records for deployment_id: {deployment_id}")
|
|
50
|
+
|
|
51
|
+
table = Table(title="Deployment Records")
|
|
52
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
53
|
+
table.add_column("Deployment", style="magenta")
|
|
54
|
+
table.add_column("CPU Usage", style="green")
|
|
55
|
+
table.add_column("RAM Usage", style="yellow")
|
|
56
|
+
table.add_column("Latency (ms)", style="red")
|
|
57
|
+
table.add_column("Request Count", style="blue")
|
|
58
|
+
table.add_column("Error Count", style="magenta")
|
|
59
|
+
table.add_column("Created At", style="white")
|
|
60
|
+
|
|
61
|
+
# Assuming records is a list of record objects
|
|
62
|
+
for record in records if isinstance(records, list) else [records]:
|
|
63
|
+
table.add_row(
|
|
64
|
+
str(record.get('id', 'N/A')),
|
|
65
|
+
str(deployment_id),
|
|
66
|
+
str(record.get('cpu_usage', 'N/A')),
|
|
67
|
+
str(record.get('ram_usage', 'N/A')),
|
|
68
|
+
str(record.get('latency_ms', 'N/A')),
|
|
69
|
+
str(record.get('request_count', 'N/A')),
|
|
70
|
+
str(record.get('error_count', 'N/A')),
|
|
71
|
+
str(record.get('created_at', 'N/A'))
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
console.print(table)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
typer.echo(f"Failed to fetch records for deployment_id {deployment_id}: {str(e)}")
|
|
77
|
+
|
|
78
|
+
@monitoring_api_app.command("alert")
|
|
79
|
+
def receive_metrics(deployment_id: int = typer.Option(..., prompt=True, help="deployment alerts")):
|
|
80
|
+
client = AIACClient()
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
alerts = client.api_request(f"deployments/{deployment_id}/alerts/", method="GET")
|
|
84
|
+
print_warning(f"Fetching alerts for deployment_id: {deployment_id}")
|
|
85
|
+
|
|
86
|
+
table = Table(title="Deployment Alerts")
|
|
87
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
88
|
+
table.add_column("Deployment", style="magenta")
|
|
89
|
+
table.add_column("Alert Type", style="red")
|
|
90
|
+
table.add_column("Message", style="yellow")
|
|
91
|
+
table.add_column("Created At", style="green")
|
|
92
|
+
table.add_column("Resolved", style="blue")
|
|
93
|
+
|
|
94
|
+
# Assuming alerts is a list of alert objects
|
|
95
|
+
for alert in alerts if isinstance(alerts, list) else [alerts]:
|
|
96
|
+
table.add_row(
|
|
97
|
+
str(alert.get('id', 'N/A')),
|
|
98
|
+
str(deployment_id),
|
|
99
|
+
str(alert.get('alert_type', 'N/A')),
|
|
100
|
+
str(alert.get('message', 'N/A')),
|
|
101
|
+
str(alert.get('created_at', 'N/A')),
|
|
102
|
+
str(alert.get('resolved', 'N/A'))
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
console.print(table)
|
|
106
|
+
except Exception as e:
|
|
107
|
+
typer.echo(f"Failed to fetch alerts for deployment_id {deployment_id}: {str(e)}")
|
|
108
|
+
|
|
109
|
+
@monitoring_api_app.command("resolve-alert")
|
|
110
|
+
def resolve_alert(alert_id: str = typer.Option(..., prompt=True, help="resolve alert by id")):
|
|
111
|
+
client = AIACClient()
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
response = client.api_request(f"alerts/{alert_id}/resolve/", method="POST")
|
|
115
|
+
print_info(f"Resolving alert with alert_id: {alert_id}")
|
|
116
|
+
typer.echo(f"Alert resolved successfully: {response}")
|
|
117
|
+
except Exception as e:
|
|
118
|
+
typer.echo(f"Failed to resolve alert with alert_id {alert_id}: {str(e)}")
|
|
119
|
+
|
|
120
|
+
@monitoring_api_app.command("detect-drift")
|
|
121
|
+
def detect_drift(model_version_id: int = typer.Option(..., prompt=True, help="detect data drift for model version")):
|
|
122
|
+
client = AIACClient()
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
response = client.api_request(f"drifts/{model_version_id}/", method="GET")
|
|
126
|
+
print_info(f"Detecting drift for model_version_id: {model_version_id}")
|
|
127
|
+
typer.echo(f"Drift detection result: {response}")
|
|
128
|
+
except Exception as e:
|
|
129
|
+
typer.echo(f"Failed to detect drift for model_version_id {model_version_id}: {str(e)}")
|
|
130
|
+
|
|
131
|
+
@monitoring_api_app.command("samples")
|
|
132
|
+
def get_samples(model_version_id: int = typer.Option(..., prompt=True, help="post samples for model version")):
|
|
133
|
+
client = AIACClient()
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
response = client.api_request("deployments/samples/", method="POST", data={"model_version_id": model_version_id})
|
|
137
|
+
print_info(f"Posting samples for model_version_id: {model_version_id}")
|
|
138
|
+
typer.echo(f"Samples posted successfully: {response}")
|
|
139
|
+
except Exception as e:
|
|
140
|
+
typer.echo(f"Failed to post samples for model_version_id {model_version_id}: {str(e)}")
|
|
141
|
+
|
aiac/requirments.txt
ADDED
aiac/tests.py
ADDED
aiac/urls.py
ADDED
aiac/user/auth.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import typer , requests
|
|
2
|
+
from aiac.config import get_config , save_config
|
|
3
|
+
|
|
4
|
+
auth_app = typer.Typer(help="user authentication commands")
|
|
5
|
+
|
|
6
|
+
@auth_app.command("register")
|
|
7
|
+
def register(username: str = typer.Option(..., prompt=True, help="Username for registration"),
|
|
8
|
+
password: str = typer.Option(..., prompt=True, hide_input=True, help="Password for registration"),
|
|
9
|
+
email: str = typer.Option(..., prompt=True, help="Email address for registration"),
|
|
10
|
+
role: str = typer.Option(..., prompt=True, help="Role of the user (client or admin)")):
|
|
11
|
+
|
|
12
|
+
"Register a new user"
|
|
13
|
+
config = get_config()
|
|
14
|
+
url = f"{config.api_base_url}/register/"
|
|
15
|
+
data = {"username": username, "password": password, "email": email, "role": role}
|
|
16
|
+
response = requests.post(url, json=data)
|
|
17
|
+
if response.status_code == 201:
|
|
18
|
+
typer.echo("Registration successful! Please check your email to activate your account.")
|
|
19
|
+
else:
|
|
20
|
+
typer.echo(f"Registration failed: {response.text}")
|
|
21
|
+
|
|
22
|
+
@auth_app.command("login")
|
|
23
|
+
def login(email: str = typer.Option(..., prompt=True, help="Email address for login"),
|
|
24
|
+
password: str = typer.Option(..., prompt=True, hide_input=True, help="Password for login")):
|
|
25
|
+
|
|
26
|
+
"Login a user"
|
|
27
|
+
config = get_config()
|
|
28
|
+
url = f"{config.api_base_url}/login/"
|
|
29
|
+
data = {"email": email, "password": password}
|
|
30
|
+
response = requests.post(url, json=data)
|
|
31
|
+
|
|
32
|
+
if response.status_code == 200:
|
|
33
|
+
access = response.json().get("access")
|
|
34
|
+
refresh = response.json().get("refresh")
|
|
35
|
+
save_config({"access": access, "refresh": refresh}, config.api_base_url)
|
|
36
|
+
typer.echo(f"Login successful! Tokens saved.")
|
|
37
|
+
else:
|
|
38
|
+
typer.echo(f"Login failed: {response.text}")
|
|
39
|
+
|
|
40
|
+
@auth_app.command("logout")
|
|
41
|
+
def logout(refresh_token: str = typer.Option(..., prompt=True, hide_input=True, help="Refresh token to logout")):
|
|
42
|
+
|
|
43
|
+
"Logout a user"
|
|
44
|
+
config = get_config()
|
|
45
|
+
url = f"{config.api_base_url}/logout/"
|
|
46
|
+
data = {"refresh": refresh_token}
|
|
47
|
+
response = requests.post(url, json=data)
|
|
48
|
+
if response.status_code == 200:
|
|
49
|
+
typer.echo("Logout successful!")
|
|
50
|
+
else:
|
|
51
|
+
typer.echo(f"Logout failed: {response.text}")
|
|
52
|
+
|
aiac/views.py
ADDED