diff --git a/pkgs/clan-cli/clan_cli/config.py b/pkgs/clan-cli/clan_cli/config.py index 3534ba4..0f9de51 100644 --- a/pkgs/clan-cli/clan_cli/config.py +++ b/pkgs/clan-cli/clan_cli/config.py @@ -19,3 +19,15 @@ dlg_url = f"http://{host}:{port_dlg}/docs" ap_url = f"http://{host}:{port_ap}/docs" c1_url = f"http://{host}:{c1_port}/docs" c2_url = f"http://{host}:{c2_port}/docs" + + +msg_type_to_label = { + 1: "Attachement", + 2: "Connection Setup", + 3: "Presentation", + 4: "DID Resolution", + 5: "Service De-registration", + 6: "Service Registration", + 7: "Service Discovery", + 8: "Service Operation", +} diff --git a/pkgs/clan-cli/clan_cli/webui/routers/endpoints.py b/pkgs/clan-cli/clan_cli/webui/routers/endpoints.py index cf56329..56016d9 100644 --- a/pkgs/clan-cli/clan_cli/webui/routers/endpoints.py +++ b/pkgs/clan-cli/clan_cli/webui/routers/endpoints.py @@ -1,12 +1,15 @@ import logging import time -from typing import Any, List +import typing +from typing import Any, List, Optional import httpx from fastapi import APIRouter, BackgroundTasks, Depends, Query -from fastapi.responses import HTMLResponse +from fastapi.responses import HTMLResponse, JSONResponse from sqlalchemy.orm import Session +from clan_cli.config import ap_url, c1_url, c2_url, dlg_url, msg_type_to_label + from ...errors import ClanError from .. import sql_crud, sql_db, sql_models from ..schemas import ( @@ -108,10 +111,8 @@ def get_service_by_uuid( skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db), -) -> sql_models.Service: +) -> Optional[sql_models.Service]: service = sql_crud.get_service_by_uuid(db, uuid=uuid) - if service is None: - raise ClanError(f"Service with uuid '{uuid}' not found") return service @@ -177,10 +178,8 @@ def get_all_entities( def get_entity_by_did( entity_did: str = "did:sov:test:120", db: Session = Depends(sql_db.get_db), -) -> sql_models.Entity: +) -> Optional[sql_models.Entity]: entity = sql_crud.get_entity_by_name_or_did(db, name=entity_did) - if entity is None: - raise ClanError(f"Entity with did '{entity_did}' not found") return entity @@ -358,16 +357,46 @@ def create_eventmessage( return sql_crud.create_eventmessage(db, eventmsg) +@typing.no_type_check @router.get( "/api/v1/event_messages", - response_model=List[Eventmessage], + response_class=JSONResponse, tags=[Tags.eventmessages], ) def get_all_eventmessages( skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db) -) -> List[sql_models.Eventmessage]: +) -> JSONResponse: eventmessages = sql_crud.get_eventmessages(db, skip=skip, limit=limit) - return eventmessages + result: dict[int, dict[int, List[Eventmessage]]] = {} + + for msg in eventmessages: + msg_name = msg_type_to_label.get(msg.msg_type, None) + src_name = sql_crud.get_entity_by_did(db, msg.src_did) + src_name = src_name if src_name is None else src_name.name + des_name = sql_crud.get_entity_by_did(db, msg.des_did) + des_name = des_name if des_name is None else des_name.name + + if result.get(msg.group) is None: + result[msg.group] = {} + if result[msg.group].get(msg.group_id) is None: + result[msg.group][msg.group_id] = [] + + result[msg.group][msg.group_id].append( + Eventmessage( + id=msg.id, + timestamp=msg.timestamp, + group=msg.group, + group_id=msg.group_id, + msg_type=msg.msg_type, + msg_type_name=msg_name, + src_did=msg.src_did, + src_name=src_name, + des_did=msg.des_did, + des_name=des_name, + msg=msg.msg, + ).dict() + ) + return JSONResponse(content=result, status_code=200) ############################## @@ -377,8 +406,6 @@ def get_all_eventmessages( ############################## @router.get("/emulate", response_class=HTMLResponse) def get_emulated_enpoints() -> HTMLResponse: - from clan_cli.config import ap_url, c1_url, c2_url, dlg_url - html_content = f""" diff --git a/pkgs/clan-cli/clan_cli/webui/schemas.py b/pkgs/clan-cli/clan_cli/webui/schemas.py index e8e7b44..c87c4b5 100644 --- a/pkgs/clan-cli/clan_cli/webui/schemas.py +++ b/pkgs/clan-cli/clan_cli/webui/schemas.py @@ -1,7 +1,7 @@ # Imports import logging from datetime import datetime -from typing import List +from typing import List, Optional from pydantic import BaseModel, Field, validator @@ -173,7 +173,7 @@ class EventmessageBase(BaseModel): ..., example=12345 ) # specific to one group needed to enable visually nested groups msg_type: int = Field(..., example=1) # message type for the label - src_did: str = Field(..., example="did:sov:test:2234") + src_did: str = Field(..., example="did:sov:test:121") des_did: str = Field(..., example="did:sov:test:120") @@ -183,6 +183,9 @@ class EventmessageCreate(EventmessageBase): class Eventmessage(EventmessageCreate): id: int = Field(...) + des_name: Optional[str] = Field(default=None, example="C2") + src_name: Optional[str] = Field(default=None, example="C1") + msg_type_name: Optional[str] = Field(default=None, example="Service Usage") class Config: orm_mode = True diff --git a/pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py b/pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py index b509802..772aae7 100644 --- a/pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py +++ b/pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py @@ -20,7 +20,7 @@ from pydantic import validate_arguments, ValidationError from pydantic import StrictInt -from typing import List, Optional +from typing import Optional from openapi_client.models.eventmessage import Eventmessage from openapi_client.models.eventmessage_create import EventmessageCreate @@ -192,7 +192,7 @@ class EventmessagesApi: _request_auth=_params.get('_request_auth')) @validate_arguments - def get_all_eventmessages(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> List[Eventmessage]: # noqa: E501 + def get_all_eventmessages(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> None: # noqa: E501 """Get All Eventmessages # noqa: E501 This method makes a synchronous HTTP request by default. To make an @@ -214,7 +214,7 @@ class EventmessagesApi: :return: Returns the result object. If the method is called asynchronously, returns the request thread. - :rtype: List[Eventmessage] + :rtype: None """ kwargs['_return_http_data_only'] = True if '_preload_content' in kwargs: @@ -258,7 +258,7 @@ class EventmessagesApi: :return: Returns the result object. If the method is called asynchronously, returns the request thread. - :rtype: tuple(List[Eventmessage], status_code(int), headers(HTTPHeaderDict)) + :rtype: None """ _params = locals() @@ -316,10 +316,7 @@ class EventmessagesApi: # authentication setting _auth_settings = [] # noqa: E501 - _response_types_map = { - '200': "List[Eventmessage]", - '422': "HTTPValidationError", - } + _response_types_map = {} return self.api_client.call_api( '/api/v1/event_messages', 'GET', diff --git a/pkgs/clan-cli/tests/openapi_client/api/services_api.py b/pkgs/clan-cli/tests/openapi_client/api/services_api.py index 8955601..835897e 100644 --- a/pkgs/clan-cli/tests/openapi_client/api/services_api.py +++ b/pkgs/clan-cli/tests/openapi_client/api/services_api.py @@ -1258,3 +1258,157 @@ class ServicesApi: _request_timeout=_params.get('_request_timeout'), collection_formats=_collection_formats, _request_auth=_params.get('_request_auth')) + + @validate_arguments + def update_service(self, service_create : ServiceCreate, uuid : Optional[StrictStr] = None, **kwargs) -> Service: # noqa: E501 + """Update Service # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.update_service(service_create, uuid, async_req=True) + >>> result = thread.get() + + :param service_create: (required) + :type service_create: ServiceCreate + :param uuid: + :type uuid: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _request_timeout: timeout setting for this request. + If one number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: Service + """ + kwargs['_return_http_data_only'] = True + if '_preload_content' in kwargs: + message = "Error! Please call the update_service_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 + raise ValueError(message) + return self.update_service_with_http_info(service_create, uuid, **kwargs) # noqa: E501 + + @validate_arguments + def update_service_with_http_info(self, service_create : ServiceCreate, uuid : Optional[StrictStr] = None, **kwargs) -> ApiResponse: # noqa: E501 + """Update Service # noqa: E501 + + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + + >>> thread = api.update_service_with_http_info(service_create, uuid, async_req=True) + >>> result = thread.get() + + :param service_create: (required) + :type service_create: ServiceCreate + :param uuid: + :type uuid: str + :param async_req: Whether to execute the request asynchronously. + :type async_req: bool, optional + :param _preload_content: if False, the ApiResponse.data will + be set to none and raw_data will store the + HTTP response body without reading/decoding. + Default is True. + :type _preload_content: bool, optional + :param _return_http_data_only: response data instead of ApiResponse + object with status code, headers, etc + :type _return_http_data_only: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :type _request_auth: dict, optional + :type _content_type: string, optional: force content-type for the request + :return: Returns the result object. + If the method is called asynchronously, + returns the request thread. + :rtype: tuple(Service, status_code(int), headers(HTTPHeaderDict)) + """ + + _params = locals() + + _all_params = [ + 'service_create', + 'uuid' + ] + _all_params.extend( + [ + 'async_req', + '_return_http_data_only', + '_preload_content', + '_request_timeout', + '_request_auth', + '_content_type', + '_headers' + ] + ) + + # validate the arguments + for _key, _val in _params['kwargs'].items(): + if _key not in _all_params: + raise ApiTypeError( + "Got an unexpected keyword argument '%s'" + " to method update_service" % _key + ) + _params[_key] = _val + del _params['kwargs'] + + _collection_formats = {} + + # process the path parameters + _path_params = {} + + # process the query parameters + _query_params = [] + if _params.get('uuid') is not None: # noqa: E501 + _query_params.append(('uuid', _params['uuid'])) + + # process the header parameters + _header_params = dict(_params.get('_headers', {})) + # process the form parameters + _form_params = [] + _files = {} + # process the body parameter + _body_params = None + if _params['service_create'] is not None: + _body_params = _params['service_create'] + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + ['application/json']) # noqa: E501 + + # set the HTTP header `Content-Type` + _content_types_list = _params.get('_content_type', + self.api_client.select_header_content_type( + ['application/json'])) + if _content_types_list: + _header_params['Content-Type'] = _content_types_list + + # authentication setting + _auth_settings = [] # noqa: E501 + + _response_types_map = { + '200': "Service", + '422': "HTTPValidationError", + } + + return self.api_client.call_api( + '/api/v1/service', 'PUT', + _path_params, + _query_params, + _header_params, + body=_body_params, + post_params=_form_params, + files=_files, + response_types_map=_response_types_map, + auth_settings=_auth_settings, + async_req=_params.get('async_req'), + _return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=_params.get('_preload_content', True), + _request_timeout=_params.get('_request_timeout'), + collection_formats=_collection_formats, + _request_auth=_params.get('_request_auth')) diff --git a/pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md b/pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md index ee4ed36..c0d8c72 100644 --- a/pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md +++ b/pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md @@ -12,6 +12,9 @@ Name | Type | Description | Notes **des_did** | **str** | | **msg** | **object** | | **id** | **int** | | +**des_name** | **str** | | [optional] +**src_name** | **str** | | [optional] +**msg_type_name** | **str** | | [optional] ## Example diff --git a/pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md b/pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md index c752559..96387ca 100644 --- a/pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md +++ b/pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md @@ -76,7 +76,7 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **get_all_eventmessages** -> List[Eventmessage] get_all_eventmessages(skip=skip, limit=limit) +> get_all_eventmessages(skip=skip, limit=limit) Get All Eventmessages @@ -86,7 +86,6 @@ Get All Eventmessages import time import os import openapi_client -from openapi_client.models.eventmessage import Eventmessage from openapi_client.rest import ApiException from pprint import pprint @@ -106,9 +105,7 @@ with openapi_client.ApiClient(configuration) as api_client: try: # Get All Eventmessages - api_response = api_instance.get_all_eventmessages(skip=skip, limit=limit) - print("The response of EventmessagesApi->get_all_eventmessages:\n") - pprint(api_response) + api_instance.get_all_eventmessages(skip=skip, limit=limit) except Exception as e: print("Exception when calling EventmessagesApi->get_all_eventmessages: %s\n" % e) ``` @@ -124,7 +121,7 @@ Name | Type | Description | Notes ### Return type -[**List[Eventmessage]**](Eventmessage.md) +void (empty response body) ### Authorization diff --git a/pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md b/pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md index c2c0542..3b072e2 100644 --- a/pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md +++ b/pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md @@ -12,6 +12,7 @@ Method | HTTP request | Description [**get_service_by_uuid**](ServicesApi.md#get_service_by_uuid) | **GET** /api/v1/service | Get Service By Uuid [**get_services_without_entity**](ServicesApi.md#get_services_without_entity) | **GET** /api/v1/services_without_entity | Get Services Without Entity [**inc_service_usage**](ServicesApi.md#inc_service_usage) | **PUT** /api/v1/inc_service_usage | Inc Service Usage +[**update_service**](ServicesApi.md#update_service) | **PUT** /api/v1/service | Update Service # **add_service_usage** @@ -564,3 +565,72 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **update_service** +> Service update_service(service_create, uuid=uuid) + +Update Service + +### Example + +```python +import time +import os +import openapi_client +from openapi_client.models.service import Service +from openapi_client.models.service_create import ServiceCreate +from openapi_client.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = openapi_client.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with openapi_client.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = openapi_client.ServicesApi(api_client) + service_create = openapi_client.ServiceCreate() # ServiceCreate | + uuid = 'bdd640fb-0667-1ad1-1c80-317fa3b1799d' # str | (optional) (default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d') + + try: + # Update Service + api_response = api_instance.update_service(service_create, uuid=uuid) + print("The response of ServicesApi->update_service:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling ServicesApi->update_service: %s\n" % e) +``` + + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **service_create** | [**ServiceCreate**](ServiceCreate.md)| | + **uuid** | **str**| | [optional] [default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d'] + +### Return type + +[**Service**](Service.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/pkgs/clan-cli/tests/openapi_client/models/eventmessage.py b/pkgs/clan-cli/tests/openapi_client/models/eventmessage.py index 4f0eb94..555c0ef 100644 --- a/pkgs/clan-cli/tests/openapi_client/models/eventmessage.py +++ b/pkgs/clan-cli/tests/openapi_client/models/eventmessage.py @@ -18,7 +18,7 @@ import re # noqa: F401 import json -from typing import Any, Dict +from typing import Any, Dict, Optional from pydantic import BaseModel, Field, StrictInt, StrictStr class Eventmessage(BaseModel): @@ -33,7 +33,10 @@ class Eventmessage(BaseModel): des_did: StrictStr = Field(...) msg: Dict[str, Any] = Field(...) id: StrictInt = Field(...) - __properties = ["timestamp", "group", "group_id", "msg_type", "src_did", "des_did", "msg", "id"] + des_name: Optional[StrictStr] = None + src_name: Optional[StrictStr] = None + msg_type_name: Optional[StrictStr] = None + __properties = ["timestamp", "group", "group_id", "msg_type", "src_did", "des_did", "msg", "id", "des_name", "src_name", "msg_type_name"] class Config: """Pydantic configuration""" @@ -78,7 +81,10 @@ class Eventmessage(BaseModel): "src_did": obj.get("src_did"), "des_did": obj.get("des_did"), "msg": obj.get("msg"), - "id": obj.get("id") + "id": obj.get("id"), + "des_name": obj.get("des_name"), + "src_name": obj.get("src_name"), + "msg_type_name": obj.get("msg_type_name") }) return _obj diff --git a/pkgs/clan-cli/tests/test_db_api.py b/pkgs/clan-cli/tests/test_db_api.py index 5f6e0ec..bd381fc 100644 --- a/pkgs/clan-cli/tests/test_db_api.py +++ b/pkgs/clan-cli/tests/test_db_api.py @@ -173,11 +173,12 @@ def create_eventmessages(num: int = 2) -> list[EventmessageCreate]: def test_create_eventmessages(api_client: ApiClient) -> None: api = EventmessagesApi(api_client=api_client) - assert [] == api.get_all_eventmessages() + + assert api.get_all_eventmessages() is None for idx, own_eventmsg in enumerate(create_eventmessages()): res: Eventmessage = api.create_eventmessage(own_eventmsg) assert res.msg == own_eventmsg.msg assert res.src_did == own_eventmsg.src_did assert res.des_did == own_eventmsg.des_did - assert [] != api.get_all_eventmessages() + assert {} != api.get_all_eventmessages()