CLI URLs
URL configuration for the Smarter API command-line interface (CLI).
Endpoints
Endpoint |
Description |
|---|---|
/api/v1/cli/get/ |
Return information about the specified resource |
/api/v1/cli/apply/ |
Apply a manifest |
/api/v1/cli/validate/ |
Validate a manifest, without applying it |
/api/v1/cli/describe/ |
Print the manifest |
/api/v1/cli/deploy/ |
Deploy a resource |
/api/v1/cli/logs/ |
Get logs for a resource |
/api/v1/cli/delete/ |
Delete a resource |
/api/v1/cli/status/ |
Smarter platform status |
/api/v1/cli/version/ |
Returns detailed version information on the platform |
/api/v1/cli/whoami/ |
Return information about the current IAM user |
URL Patterns
1 - Return information about the current IAM user
2"""
3
4from django.urls import path, re_path
5from django.views.generic.base import RedirectView
6
7from smarter.common.utils import to_snake_case
8
9from .const import namespace
10from .views.apply import ApiV1CliApplyApiView
11from .views.delete import ApiV1CliDeleteApiView
12from .views.deploy import ApiV1CliDeployApiView
13from .views.describe import ApiV1CliDescribeApiView
14from .views.get import ApiV1CliGetApiView
15from .views.logs import ApiV1CliLogsApiView
16from .views.manifest import ApiV1CliManifestApiView
17from .views.nonbrokered.prompt import ApiV1CliPromptApiView
18from .views.nonbrokered.prompt_config import ApiV1CliPromptConfigApiView
19from .views.nonbrokered.resources import ApiV1CliResourcesApiView
20from .views.nonbrokered.status import ApiV1CliStatusApiView
21from .views.nonbrokered.version import ApiV1CliVersionApiView
22from .views.nonbrokered.whoami import ApiV1CliWhoamiApiView
23from .views.schema import ApiV1CliSchemaApiView
24from .views.undeploy import ApiV1CliUndeployApiView
25from .views.validate import ApiV1CliValidateApiView
26
27app_name = namespace
28
29
30class ApiV1CliReverseViews:
31 """
32 Reverse views for the CLI commands.
33
34 Provides named references for reversing CLI-related API endpoints.
35
36 This class is used for reverse URL resolution in Django, where each attribute
37 corresponds to a CLI command endpoint. The names are derived from the actual
38 API view class names, ensuring consistency and reducing the risk of typos
39 when using Django's URL reversing features.
40
41 All CLI commands available in the Smarter platform are included as attributes
42 of this class. This centralizes the reverse URL names for all CLI endpoints,
43 making it easier to maintain and reference them throughout the codebase.
44
45 Usage
46 -----
47 Use these attributes with Django's ``reverse()`` function or in templates
48 to generate URLs for CLI API endpoints based on the view class names.
49
50 Example
51 -------
52 .. code-block:: python
53
54 from smarter.lib.django.shortcuts import reverse
55 url = reverse(ApiV1CliReverseViews.deploy, kwargs={'kind': 'Plugin'})
56
57 str(ApiV1CliReverseViews.deploy)
58 returns 'api_v1_cli_deploy_api_view'
59 """
60
61 namespace = f"api:v1:{namespace}:"
62
63 manifest = to_snake_case(ApiV1CliManifestApiView.__name__)
64 apply = to_snake_case(ApiV1CliApplyApiView.__name__)
65 prompt = to_snake_case(ApiV1CliPromptApiView.__name__)
66 chat_config = to_snake_case(ApiV1CliPromptConfigApiView.__name__)
67 delete = to_snake_case(ApiV1CliDeleteApiView.__name__)
68 deploy = to_snake_case(ApiV1CliDeployApiView.__name__)
69 undeploy = to_snake_case(ApiV1CliUndeployApiView.__name__)
70 describe = to_snake_case(ApiV1CliDescribeApiView.__name__)
71 get = to_snake_case(ApiV1CliGetApiView.__name__)
72 logs = to_snake_case(ApiV1CliLogsApiView.__name__)
73 example_manifest = to_snake_case(ApiV1CliManifestApiView.__name__)
74 status = to_snake_case(ApiV1CliStatusApiView.__name__)
75 json_schema = to_snake_case(ApiV1CliSchemaApiView.__name__)
76 version = to_snake_case(ApiV1CliVersionApiView.__name__)
77 whoami = to_snake_case(ApiV1CliWhoamiApiView.__name__)
78 resources = to_snake_case(ApiV1CliResourcesApiView.__name__)
79 validate = to_snake_case(ApiV1CliValidateApiView.__name__)
80
81
82urlpatterns = [
83 path("apply/", ApiV1CliApplyApiView.as_view(), name=ApiV1CliReverseViews.apply),
84 path("validate/", ApiV1CliValidateApiView.as_view(), name=ApiV1CliReverseViews.validate),
85 path("prompt/<str:name>/", ApiV1CliPromptApiView.as_view(), name=ApiV1CliReverseViews.prompt),
86 path("prompt/config/<str:name>/", ApiV1CliPromptConfigApiView.as_view(), name=ApiV1CliReverseViews.chat_config),
87 path("delete/<str:kind>/", ApiV1CliDeleteApiView.as_view(), name=ApiV1CliReverseViews.delete),
88 path("deploy/<str:kind>/", ApiV1CliDeployApiView.as_view(), name=ApiV1CliReverseViews.deploy),
89 path("undeploy/<str:kind>/", ApiV1CliUndeployApiView.as_view(), name=ApiV1CliReverseViews.undeploy),
90 path("describe/<str:kind>/", ApiV1CliDescribeApiView.as_view(), name=ApiV1CliReverseViews.describe),
91 path("get/<str:kind>/", ApiV1CliGetApiView.as_view(), name=ApiV1CliReverseViews.get),
92 path("logs/<str:kind>/", ApiV1CliLogsApiView.as_view(), name=ApiV1CliReverseViews.logs),
93 path("example-manifest/<str:kind>/", ApiV1CliManifestApiView.as_view(), name=ApiV1CliReverseViews.example_manifest),
94 path("json-schema/<str:kind>/", ApiV1CliSchemaApiView.as_view(), name=ApiV1CliReverseViews.json_schema),
95 # Legacy path, still requested without a trailing slash by smarter-vscode-yaml.
96 # Redirect rather than route to the view, which derives its command from the url.
97 re_path(
98 r"^schema/(?P<kind>[^/]+)/?$",
99 RedirectView.as_view(
100 pattern_name=ApiV1CliReverseViews.namespace + ApiV1CliReverseViews.json_schema,
101 permanent=True,
102 query_string=True,
103 ),
104 ),
105 path("status/", ApiV1CliStatusApiView.as_view(), name=ApiV1CliReverseViews.status),
106 path("version/", ApiV1CliVersionApiView.as_view(), name=ApiV1CliReverseViews.version),
107 path("whoami/", ApiV1CliWhoamiApiView.as_view(), name=ApiV1CliReverseViews.whoami),
108 path("resources/", ApiV1CliResourcesApiView.as_view(), name=ApiV1CliReverseViews.resources),
109]
Base Class Reference
- class smarter.apps.api.v1.cli.views.base.CliBaseApiView(*args, **kwargs)[source]
Bases:
APIView,SmarterRequestMixinBase class for all Smarter API v1 command-line interface (CLI) views.
This class provides common functionality for all /api/v1/cli endpoints, including:
Authentication using either Knox TokenAuthentication or Django SessionAuthentication.
Initialization of the
SAMLoaderandAbstractBrokerinstances.Resolution of the manifest kind and broker for the YAML manifest document.
Setting the user profile for the request.
The base class is responsible for as much request “housekeeping” as possible, so that child views can focus on business logic. The following attributes are set up and managed:
Notes
The base class is designed to minimize boilerplate in child views.
Manifest parsing and broker instantiation are implemented lazily.
Authentication is enforced by default, but can be bypassed for internal API requests.
Examples
- Example URL with a manifest name:
/api/v1/cli/describe/llm-client/<str:name>/- Example command extraction:
If the URL path is
/api/v1/cli/apply/, then the command will beSmarterJournalCliCommands.APPLY.
- property BrokerClass: Type[AbstractBroker]
Get the broker class for the manifest kind.
This is used to instantiate a broker for the manifest kind.
- Returns:
Broker class for the manifest kind
- Return type:
Type[AbstractBroker]
- __init__(*args, **kwargs)[source]
Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.
- authentication_classes = (<class 'smarter.lib.drf.token_authentication.SmarterTokenAuthentication'>, <class 'rest_framework.authentication.SessionAuthentication'>)
- property broker: AbstractBroker | None
Use a loader to try to instantiate a broker.
A broker is a class that implements the broker service pattern. It provides a service interface that ‘brokers’ the http request for the underlying object that provides the object-specific service (create, update, get, delete, etc).
- Returns:
Broker instance for the manifest kind
- Return type:
Optional[AbstractBroker]
- property cba_ready: bool
Check if the CliBaseApiView is ready.
- Returns:
True if the view is ready, False otherwise
- Return type:
- property command: SmarterJournalCliCommands
Translate the request route into a SmarterJournalCliCommands enum instance.
For example, if the route is ‘/api/v1/cli/apply/’, then the corresponding command will be SmarterJournalCliCommands.APPLY.
- url:
- Returns:
SmarterJournalCliCommands enum instance
- Return type:
- dispatch(request, *args, **kwargs)[source]
Dispatch the request to the appropriate handler method.
This method is a core part of the Django REST Framework (DRF) view lifecycle. It is called automatically by DRF when an HTTP request is received and is responsible for routing the request to the correct handler method (such as
get(),post(),put(), etc.) based on the HTTP method of the request.In DRF, the
dispatch()method performs several critical functions:It determines which handler method should process the request.
It manages the execution of middleware and mixins.
It handles exceptions that may be raised during request processing.
It returns a DRF
Responseobject to the client.
In this base class implementation, the primary objective is to provide robust exception handling for all CLI API views. The method attempts to map known exceptions to appropriate HTTP status codes and, where possible, adds additional context to error messages. This ensures that clients receive meaningful and actionable error responses, even if an unexpected error occurs.
Ideally, child views should handle their own exceptions and return a
SmarterJournaledJsonErrorResponseor similar structured response. However, this base implementation acts as a safety net, catching any unhandled exceptions and returning a generic error message along with a bug report URL for further trouble shooting.Signals are emitted to indicate the completion or failure of API requests, which can be used for logging, auditing, or triggering other side effects.
- Parameters:
request (
Request) – The HTTP request object provided by DRF, containing all request data, headers, and user context.*args – Additional positional arguments passed to the view.
**kwargs – Additional keyword arguments passed to the view, often including URL parameters.
- Returns:
A DRF
Responseobject representing the result of the request, or an error response if an exception was raised.- Return type:
Response
Notes
This method is a critical integration point with DRF’s request/response lifecycle.
Exception mapping is comprehensive, covering both application-specific and DRF exceptions.
Unhandled exceptions are logged and reported with a generic message and bug report instructions.
Signals are used for observability and integration with other parts of the application.
See also
https//www.django-rest-framework.org/api-guide/views/#view-methods DRF documentation on view methods and the dispatch process.
- property formatted_class_name: str
Returns the class name in a formatted string along with the name of this mixin.
- Returns:
Formatted class name string
- Return type:
- get_permissions()[source]
Do not require authentication for OPTIONS requests.
OPTIONS requests are used both for DRF’s own metadata introspection and, more importantly, as CORS preflight probes issued by browsers. Preflight requests never carry credentials (no cookies, no Authorization header), so if CORS middleware doesn’t intercept them first (e.g. a misconfigured/disallowed origin, or the middleware being disabled), enforcing authentication here causes the preflight itself to fail with a 401. That, in turn, makes the browser abort the real (authenticated) request before it’s ever sent, which looks like “I’m logged in but I still get an authentication error”.
- initial(request, *args, **kwargs)[source]
Perform view initialization after setup and before dispatch.
This method is called by Django REST Framework (DRF) after the setup() method but before the dispatch() method. It is the earliest point in the DRF view lifecycle where the request object is fully available and can be used to complete any additional initialization required by the view.
In DRF, the initial() method is responsible for performing tasks such as: - Completing any remaining setup that depends on the request object. - Enforcing authentication and permission checks. - Raising appropriate exceptions if the request is not valid or not authenticated.
In this implementation, initial() ensures that the SmarterRequestMixin and any related mixins are fully initialized with the request object. It also performs authentication checks, sets up user and account context, and prepares manifest data or prompt text for downstream processing. If authentication fails, it raises a custom error with detailed logging.
- Parameters:
request (
Request) – The HTTP request object provided by DRF. This object contains all request data, headers, user information, and other context needed for processing the API call.*args – Additional positional arguments passed to the view.
**kwargs – Additional keyword arguments passed to the view, often including URL parameters extracted by the router.
- Raises:
SmarterAPIV1CLIViewErrorNotAuthenticated – If the request is not authenticated and is not an internal API request, this exception is raised to indicate authentication failure.
SmarterConfigurationError – If the request object is not properly set up in the view, this error is raised to indicate a misconfiguration.
Notes
This method is a critical part of the DRF request lifecycle, ensuring that all necessary context and validation is in place before the main handler methods (get, post, etc.) are called.
Manifest parsing and broker instantiation are deferred (lazy) and only performed when needed by child views.
The method also logs key events and warnings for observability.
See also
https//www.django-rest-framework.org/api-guide/views/#view-initialization DRF documentation on the view initialization process.
- property is_cli_base_api_view_ready_state: str
Get a string representation of the readiness state of the CliBaseApiView.
- Returns:
Readiness state as a string
- Return type:
- property loader: SAMLoader | None
Get the SAMLoader instance.
a SAMLoader instance is used to load raw manifest text into a Pydantic model. It performs cursory validations such as validating the file format, and identifying required dict key values such as the api version, the manifest kind and its name.
The loader is instantiated lazily, so it will only be created when it is first accessed.
- Returns:
SAMLoader instance or None
- Return type:
Optional[SAMLoader]
- property logger_prefix: str
Get the logger prefix for this class.
- Returns:
Logger prefix string
- Return type:
- property manifest_data: dict[str, Any] | None
The raw manifest data from the request body.
The manifest data is a json object which needs to be rendered into a Pydantic model. The Pydantic model is then used to instantiate a broker for the manifest kind.
- Returns:
Raw manifest data as a json object
- Return type:
Optional[dict]
- property manifest_kind: str | None
The kind of the manifest.
The manifest kind is used to identify the type of resource that the manifest is describing. The kind is used to identify the broker that will be used to broker the http request for the resource.
- Returns:
The kind of the manifest
- Return type:
Optional[str]
- property manifest_name: str | None
The name of the manifest.
The manifest name is used to identify the resource within a Kind. For example, the manifest name for a LLMClient resource is the name of the llmclient. The manifest name is used to identify the resource within a Kind. The name can be passed from inside the raw manifest data, or it can be passed as part of a url path.
Example url path with a name: /api/v1/cli/describe/llm-client/<str:name>/
- Returns:
The name of the manifest
- Return type:
Optional[str]
- permission_classes = (<class 'smarter.lib.drf.views.helpers.SmarterAuthenticatedPermissionClass'>,)