diff --git a/server/.env b/server/.env new file mode 100644 index 0000000..3dad52c --- /dev/null +++ b/server/.env @@ -0,0 +1 @@ +DEBUG_FLAG=True diff --git a/server/api/api.py b/server/api/api.py index d1bb910..ab2ea29 100644 --- a/server/api/api.py +++ b/server/api/api.py @@ -7,7 +7,7 @@ from rest_framework.decorators import api_view, permission_classes, authentication_classes from rest_framework.permissions import IsAuthenticated, AllowAny from .models import LibraryRegistration -from webcligui_api import ParameterList, ParameterOptionsToList, ParameterPreference, ParameterStringValue +# from webcligui_api import ParameterList, ParameterOptionsToList, ParameterPreference, ParameterStringValue libraryApis = [] library2Idx = {} @@ -15,6 +15,7 @@ def instantiateLibraryModule(obj): module = importlib.import_module(obj.module_path) cls = getattr(module, obj.class_name) + print(f"api.py-- cls={cls} obj={obj} class_name={obj.class_name} module={module} ") libraryAPIImpl = cls() return libraryAPIImpl @@ -24,9 +25,11 @@ def load_library_apis(): return for idx, obj in enumerate(LibraryRegistration.objects.all()): + print(f"api.py-- idx={idx} obj={obj} name={obj.library_name} module={obj.module_path} ") libraryAPIImpl = instantiateLibraryModule(obj) libraryApis.append(libraryAPIImpl) library2Idx[obj.library_name] = idx + # library2Idx[obj.module_path] = idx def to_json_safe(obj): if isinstance(obj, Enum): @@ -69,7 +72,7 @@ def get_description(request): libraryApiImpl = getLibraryApi(libraryName) if not libraryApiImpl: errMsg = f'Libraryname "{libraryName}" not known!' - print('get_description():', errMsg) + print('api.py--get_description():', errMsg) return HttpResponseBadRequest(errMsg) operationBranch = body["operationBranch"][1:] @@ -84,9 +87,10 @@ def get_parameters(request): body = json.loads(request.body) libraryName = body["operationBranch"][0] libraryApiImpl = getLibraryApi(libraryName) + print(f"api.py--get_parameters(): libraryName={libraryName}") if not libraryApiImpl: errMsg = f'Libraryname "{libraryName}" not known!' - print('get_parameters():', errMsg) + print('api.py--get_parameters():', errMsg) return HttpResponseBadRequest(errMsg) operationBranch = body["operationBranch"][1:] @@ -100,16 +104,20 @@ def get_parameters(request): @permission_classes([AllowAny]) def submit_operation(request): body = json.loads(request.body) + libraryName = body["operationBranch"][0] + libraryApiImpl = getLibraryApi(libraryName) + if not libraryApiImpl: + errMsg = f'Libraryname "{libraryName}" not known!' + print('api.py--submit_operation():', errMsg) + return HttpResponseBadRequest(errMsg) + + operationBranch = body["operationBranch"][1:] command = body['command'] servers = body["servers"] + + print(f"api.py--submit_operation(): libraryName={libraryName}, operationBranch={operationBranch}") + print(f"command={command}, servers={servers}") + + result = libraryApiImpl.submitOperation(body['operationBranch'], command, servers) - print('command:', command, 'servers:', servers) - fullCommand = command + ['localhost'] - print('fullCommand:', fullCommand) - try: - subprocess.run(fullCommand, check=True) - except Exception as exc: - print('Exception:', exc) - return HttpResponseServerError(str(exc)); - - return HttpResponse('OK') + return JsonResponse(result, safe=False) diff --git a/server/djangoProc.spcs b/server/djangoProc.spcs index ce6b463..9741419 100755 --- a/server/djangoProc.spcs +++ b/server/djangoProc.spcs @@ -52,6 +52,12 @@ def examples_spcs() -> None: cs.examples.menuSection(f'*Register csLib*') literal(f"manage.py register_library csLib csLib LibraryAPIImpl --description 'Command Services Library'") + literal(f"manage.py register_library static bisos.csPlayer.drf_csPlayer_static LibraryAPIImpl --description 'A Static CSXU Library For Testing'") + literal(f"manage.py register_library pip:bisos3 bisos.csPlayer.drf_csPlayer_pipBisos3 LibraryAPIImpl --description 'pip bisos3 CSXUs'") + literal(f"manage.py register_library pip:dev-bisos3 bisos.csPlayer.drf_csPlayer_pipDevBisos3 LibraryAPIImpl --description 'pip dev-bisos3 CSXUs'") + literal(f"manage.py register_library pipx bisos.csPlayer.drf_csPlayer_pipx LibraryAPIImpl --description 'pipx Packages and CSXUs'") + literal(f"manage.py register_library modules:facter bisos.csPlayer.drf_modPlayer_facter LibraryAPIImpl --description 'CSXU Modules for facterModule.cs'") + literal(f"manage.py register_library modules:soncli bisos.csPlayer.drf_modPlayer_soncli LibraryAPIImpl --description 'Uploadable Modules for soncli.cs'") cs.examples.menuSection(f'*Virtual Domain Deployment Preparations*') literal(f"sudo chown {userName}:www-data .") # Make the current directory writable by www-data @@ -66,6 +72,8 @@ def examples_spcs() -> None: cmnd('dotEnv', wrapper="rm .env ; ", comment="# Create .env with DEBUG_FLAG=True for development") cmnd('bxDjango_report') cmnd('bxDjango_fullUpdate') + literal(f"(pushd {gitClonesBaseDir}/webCliGui/webcligui_api && pip install -e .)") + literal(f"(pushd {gitClonesBaseDir}/csLib && pip install -e .)") class bxDjango_fullUpdate(cs.Cmnd): cmndParamsMandatory = [ ] diff --git a/server/webCliGui/settings.py b/server/webCliGui/settings.py index 451131a..eb068fa 100644 --- a/server/webCliGui/settings.py +++ b/server/webCliGui/settings.py @@ -43,6 +43,8 @@ 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', + 'drf_spectacular', + 'drf_spectacular_sidecar', # Optional, for serving static files 'api', ] @@ -136,4 +138,12 @@ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ], + 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', +} + +SPECTACULAR_SETTINGS = { + 'TITLE': 'Your Project API', + 'DESCRIPTION': 'Documentation for Your Project API', + 'VERSION': '1.0.0', + # Other settings like authentication can be added here } diff --git a/server/webCliGui/urls.py b/server/webCliGui/urls.py index 15878d6..5ec9c09 100644 --- a/server/webCliGui/urls.py +++ b/server/webCliGui/urls.py @@ -3,8 +3,19 @@ """ from django.contrib import admin from django.urls import path, include +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView urlpatterns = [ -path('admin/', admin.site.urls), -path('api/', include("api.urls")), + path('admin/', admin.site.urls), + path('api/', include("api.urls")), + + # OpenAPI 3 Schema + path('api/schema/', SpectacularAPIView.as_view(), name='schema'), + + # Optional: Swagger UI web interface + path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), + + # Optional: ReDoc web interface + path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), + ] diff --git a/src/components/App.tsx b/src/components/App.tsx index 2194cfc..6a851f1 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -7,8 +7,7 @@ const App = () => { return (