Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CLI command to list and delete custom actions #28

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions admyral/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from admyral.cli.action import (
action,
push as action_push,
list as action_list,
delete as action_delete,
)
from admyral.cli.server import up, down
from admyral.cli.setup import init
Expand All @@ -11,6 +13,8 @@
__all__ = [
"action",
"action_push",
"action_list",
"action_delete",
"up",
"down",
"init",
Expand Down
26 changes: 26 additions & 0 deletions admyral/cli/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,29 @@ def push(ctx: click.Context, action_type: str, action: str) -> None:
return

click.echo(f"Action {action_type} pushed successfully.")


@action.command(
"list",
help="List all pushed custom actions",
)
@click.pass_context
def list(ctx: click.Context) -> None:
"""List all pushed custom actions"""
capture(event_name="action:list")
client: AdmyralClient = ctx.obj
actions = client.list_actions()
click.echo("Pushed actions:")
for action in actions:
click.echo(action.action_type)


@action.command("delete", help="Delete a pushed custom action")
@click.argument("action_type", type=str)
@click.pass_context
def delete(ctx: click.Context, action_type: str) -> None:
"""Delete a pushed custom action"""
capture(event_name="action:delete")
client: AdmyralClient = ctx.obj
client.delete_action(action_type)
click.echo(f"Action {action_type} deleted successfully.")
21 changes: 21 additions & 0 deletions admyral/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
WorkflowPushRequest,
WorkflowTriggerResponse,
SecretMetadata,
ActionMetadata,
)
from admyral.config.config import API_V1_STR

Expand Down Expand Up @@ -192,6 +193,26 @@ def get_action(self, action_type: str) -> PythonAction | None:
result = self._get(f"{API_V1_STR}/actions/{action_type}")
return PythonAction.model_validate(result) if result else None

def list_actions(self) -> list[ActionMetadata]:
"""
Returns a list of action names.

Returns:
A list of action names.
"""

result = self._get(f"{API_V1_STR}/actions")
return [ActionMetadata.model_validate(r) for r in result]

def delete_action(self, action_type: str) -> None:
"""
Deletes the action with the given type.

Args:
action_type: The action type.
"""
self._delete(f"{API_V1_STR}/actions/{action_type}")

########################################################
# Secrets
########################################################
Expand Down
9 changes: 9 additions & 0 deletions admyral/db/admyral_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,15 @@ async def store_action(self, user_id: str, action: PythonAction) -> None:

await db.commit()

async def delete_action(self, user_id: str, action_type: str) -> None:
async with self._get_async_session() as db:
await db.exec(
delete(PythonActionSchema)
.where(PythonActionSchema.action_type == action_type)
.where(PythonActionSchema.user_id == user_id)
)
await db.commit()

########################################################
# Pip Lockfile Cache
########################################################
Expand Down
3 changes: 3 additions & 0 deletions admyral/db/store_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ async def get_action(
@abstractmethod
async def store_action(self, user_id: str, action: PythonAction) -> None: ...

@abstractmethod
async def delete_action(self, user_id: str, action_type: str) -> None: ...

########################################################
# Pip Lockfile Cache
########################################################
Expand Down
32 changes: 30 additions & 2 deletions admyral/server/endpoints/action_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from fastapi import APIRouter, status, Depends

from admyral.server.auth import authenticate
from admyral.models import PythonAction, AuthenticatedUser
from admyral.models import PythonAction, AuthenticatedUser, ActionMetadata
from admyral.server.deps import get_admyral_store


Expand All @@ -13,7 +13,7 @@
async def push_action(
python_action: PythonAction,
authenticated_user: AuthenticatedUser = Depends(authenticate),
):
) -> None:
"""
Push a Python action to the store. If the action for the provided action type already exists for the user,
it will be overwritten.
Expand All @@ -26,6 +26,34 @@ async def push_action(
)


@router.get("", status_code=status.HTTP_200_OK)
async def list_actions(
authenticated_user: AuthenticatedUser = Depends(authenticate),
) -> list[ActionMetadata]:
"""
List all stored custom Python actions.

Returns:
A list of stored custom Python action objects.
"""
return await get_admyral_store().list_actions(user_id=authenticated_user.user_id)


@router.delete("/{action_type}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_action(
action_type: str, authenticated_user: AuthenticatedUser = Depends(authenticate)
) -> None:
"""
Delete a stored custom Python action by its action type.

Args:
action_type: function name of the custom Python action.
"""
await get_admyral_store().delete_action(
action_type=action_type, user_id=authenticated_user.user_id
)


@router.get("/{action_type}", status_code=status.HTTP_200_OK)
async def get_action(
action_type: str, authenticated_user: AuthenticatedUser = Depends(AuthenticatedUser)
Expand Down
14 changes: 14 additions & 0 deletions docs/pages/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ admyral action push your_custom_action -a path/to/your/action.py

where `your_custom_action` is the Python function name and `file_path` is the path to the Python file where the action is defined.

List all pushed actions:

```bash
admyral action list
```

Delete a pushed action:

```bash
admyral action delete your_custom_action
```

where `your_custom_action` is the Python function name.

## Secrets Management

Manages secrets in Admyral. Secrets are encrypted values, such as API keys or passwords. See [Secrets Management](/secrets) for more information.
Expand Down
Loading