Przeglądaj źródła

Factor out concerns to standalone units

Arkadiusz Ryś 2 lat temu
rodzic
commit
9912a55430

+ 25 - 0
mocka/artefact.py

@@ -0,0 +1,25 @@
+from dataclasses import dataclass, fields, Field
+from typing import Tuple
+
+
+@dataclass
+class Artefact:
+    """"""
+    type: str
+    content: str
+    name: str
+    encoding: str
+
+    def as_dict(self):
+        """Returns the artefact in a dict format."""
+        cls_fields: Tuple[Field, ...] = fields(self.__class__)
+        return {field.name: getattr(self, field.name) for field in cls_fields}
+
+# def fill_artefact(data: dict) -> Artefact:
+#     """"""
+#     type = data.get("")
+#     content = data.get("")
+#     encoding = data.get("")
+#     if type and content and encoding:
+#         return Artefact(type, content, encoding)
+#     raise ValueError

+ 5 - 5
mocka/endpoint.py

@@ -4,9 +4,7 @@ import time
 from typing import Any
 from fastapi import FastAPI, Request, Response
 from fastapi.middleware.cors import CORSMiddleware
-
-from mocka.octiva import OctivaRouter
-from mocka.router import MockRouter
+from mocka.routers import ExampleRouter, OctivaRouter, TemplateRouter
 
 arklog.set_config_logging()
 
@@ -21,9 +19,11 @@ class MockActivityEndpoint(FastAPI):
         self.configuration = configuration
         super().__init__(*args, title=title, description=description, version=version, **kwargs)
         logging.debug(self.description)
-        sparql_router = MockRouter(title=title, description=description, version=version, configuration=configuration)
-        self.include_router(sparql_router)
+
+        self.include_router(ExampleRouter(title=title, description=description, version=version, configuration=configuration))
         self.include_router(OctivaRouter(title=title, description=description, version=version, configuration=configuration), prefix="/octiva")
+        self.include_router(TemplateRouter(title=title, description=description, version=version, configuration=configuration), prefix="/template")
+
         self.add_middleware(
             CORSMiddleware,
             allow_origins=["*"],

+ 9 - 0
mocka/routers/__init__.py

@@ -0,0 +1,9 @@
+from mocka.routers.octiva import OctivaRouter
+from mocka.routers.template import TemplateRouter
+from mocka.routers.example import ExampleRouter
+
+all = [
+    "OctivaRouter",
+    "TemplateRouter",
+    "ExampleRouter",
+]

+ 2 - 4
mocka/routers/example.py

@@ -5,10 +5,9 @@ import magic
 import arklog
 from fastapi import APIRouter, Query, Request, Response
 from fastapi.responses import JSONResponse
-import time
 
 
-class MockRouter(APIRouter):
+class ExampleRouter(APIRouter):
     """"""
 
     def __init__(self, *args: Any, title: str, description: str, version: str, configuration, **kwargs: Any):
@@ -32,10 +31,9 @@ class MockRouter(APIRouter):
             control = body.get("ctrl")
             arklog.debug(control)
             content = body.get("input").get("din").get("content")
-            file_path = Path(__file__).parent.parent / Path("data/mock_requirements.txt")
+            file_path = Path(__file__).parent.parent.parent / Path("data/mock_requirements.txt")
             requirements = file_path.read_text() + "\n\nChecked!"
             mime = magic.Magic(mime=True).from_file(file_path)
-            #time.sleep(5)
             assert content + "\n\nChecked!" == requirements
             return JSONResponse(status_code=200, content={
                 "ctrl": "ok",

+ 8 - 24
mocka/routers/octiva.py

@@ -1,34 +1,18 @@
 import math
-from dataclasses import dataclass
 
 import cv2 as cv
 import numpy as np
 from pathlib import Path
 from typing import Any
-import magic
 import arklog
 from fastapi import APIRouter, Query, Request, Response
 from fastapi.responses import JSONResponse
-from PIL import Image
 import base64
-from io import BytesIO
 
-@dataclass
-class Artefact:
-    """"""
-    type: str
-    content: str
-    name: str
-    encoding: str
-
-# def fill_artefact(data: dict) -> Artefact:
-#     """"""
-#     type = data.get("")
-#     content = data.get("")
-#     encoding = data.get("")
-#     if type and content and encoding:
-#         return Artefact(type, content, encoding)
-#     raise ValueError
+from mocka.artefact import Artefact
+
+
+
 
 def find_parallel(lines) -> []:
     """Find parallel lines and return their index."""
@@ -66,7 +50,7 @@ def rail_finder_algo_one(filename: str) -> (Artefact, Artefact):
         x1, y1, x2, y2 = detected_lines[parallel_line_index][0]
         cv.line(source_color_image, (x1, y1), (x2, y2), (0, 255, 0), 6, cv.LINE_AA)
     # cv.imshow("Probabilistic Line Transform", source_color_image)
-    temp_image_loc = Path(__file__).parent.parent / Path("data") / Path("rail_image_annotated.jpg")
+    temp_image_loc = Path(__file__).parent.parent.parent / Path("data") / Path("rail_image_annotated.jpg")
     cv.imwrite(str(temp_image_loc), source_color_image)
     with temp_image_loc.open("rb") as image_file:
         data = base64.b64encode(image_file.read()).decode()
@@ -123,8 +107,8 @@ class OctivaRouter(APIRouter):
             # algorithm = fill_artefact(algorithm_data)
 
             # TODO Error checking
-            rail_image = Image.open(BytesIO(base64.b64decode(rail_image_data.get("content"))))
-            temp_image_loc = Path(__file__).parent.parent / Path("data") / Path("rail_image.jpg")
+            # rail_image = Image.open(BytesIO(base64.b64decode(rail_image_data.get("content"))))
+            temp_image_loc = Path(__file__).parent.parent.parent / Path("data") / Path("rail_image.jpg")
             # rail_image.save(str(temp_image_loc), temp_image_loc.suffix[1:])
             orig = base64.b64decode(rail_image_data.get("content"))
             with temp_image_loc.open("wb") as f_output:
@@ -162,7 +146,7 @@ class OctivaRouter(APIRouter):
 
 
 def main():
-    filename = str(Path(__file__).parent.parent / Path("tests/octiva") / Path("rails_0.jpg"))
+    filename = str(Path(__file__).parent.parent.parent / Path("tests/octiva") / Path("rails_0.jpg"))
     rail_finder_algo_one(filename)
     # rail_finder_algo_two(filename)
     cv.waitKey()

+ 57 - 0
mocka/routers/template.py

@@ -0,0 +1,57 @@
+from pathlib import Path
+from typing import Any
+import magic
+import arklog
+from fastapi import APIRouter, Query, Request, Response
+from fastapi.responses import JSONResponse
+
+from mocka.artefact import Artefact
+
+
+class TemplateRouter(APIRouter):
+    """"""
+
+    def __init__(self, *args: Any, title: str, description: str, version: str, configuration, **kwargs: Any):
+        self.title = title
+        self.description = description
+        self.version = version
+        self.configuration = configuration
+        super().__init__(*args, **kwargs)
+
+        @self.get("/")
+        async def root_mock(request: Request, query: str | None = Query(None)) -> Response:
+            """Template request response for a simulated activity."""
+            if query:
+                match query.lower():
+                    case "error":
+                        return JSONResponse(status_code=400, content={"ctrl": "error"})
+                    case "get":
+                        return JSONResponse(status_code=200, content={"ctrl": "ok"})
+
+            body = await request.json()
+            # Check if we were provided all the data we need to abort early
+            control = body.get("ctrl")
+            arklog.debug(control)
+            content = body.get("input").get("din").get("content")
+            name = body.get("input").get("din").get("name")
+            mime_type = body.get("input").get("din").get("encoding")
+
+            # The example uses a mock requirements file.
+            # This activity checks a local file and appends checked to it to send to the requester.
+            requirements = content + "\n\nChecked!"
+            return_artefact = Artefact("inline", requirements, name, mime_type)
+
+            return JSONResponse(status_code=200, content={
+                "ctrl": "ok",
+                "output": {
+                    "dout": return_artefact.as_dict()
+                }
+            })
+
+        @self.put("/")
+        async def root_put_mock(request: Request, query: str | None = Query(None)) -> Response:
+            return await root_mock(request, query)
+
+        @self.post("/")
+        async def root_post_mock(request: Request, query: str | None = Query(None)) -> Response:
+            return await root_mock(request, query)

+ 6 - 0
tests/test_artefact.py

@@ -0,0 +1,6 @@
+from mocka.artefact import Artefact
+
+
+def test_artefact():
+    artefact = Artefact("inline", "Don't be evil!", "motto.txt", "text/plain")
+    assert artefact.as_dict() == {'type': 'inline', 'content': "Don't be evil!", 'name': 'motto.txt', 'encoding': 'text/plain'}

+ 1 - 1
tests/test_octiva.py

@@ -50,7 +50,7 @@ client = TestClient(get_application(Configuration(Server("localhost", 8585))))
 
 
 def test_post_octiva():
-    file_path = Path(__file__).parent.parent / Path("tests/octiva/rails_0.jpg")
+    file_path = Path(__file__).parent / Path("octiva/rails_0.jpg")
     rail_image = cv2.imread(str(file_path))
     retval, buffer = cv2.imencode(file_path.suffix, rail_image)
     data = base64.b64encode(buffer).decode()

+ 45 - 0
tests/test_template.py

@@ -0,0 +1,45 @@
+from pathlib import Path
+
+import magic
+from fastapi.testclient import TestClient
+
+from mocka.artefact import Artefact
+from mocka.main import get_application
+from mocka.configuration import Configuration, Server
+
+client = TestClient(get_application(Configuration(Server("localhost", 8585))))
+
+
+# def test_read_main():
+#     response = client.get("/", headers={})
+#     assert response.status_code == 201
+#     assert response.json() == {
+#                 "port": "ok",
+#                 "output": {
+#                     "artefact_1": "<uri>",
+#                     "artefact_2": "<uri>",
+#                 }
+#             }
+
+def test_post_template():
+    file_path = Path(__file__).parent / Path("template/mock_requirements.txt")
+    requirements = file_path.read_text()
+    mime = magic.Magic(mime=True).from_file(file_path)
+    input_artefact = Artefact("inline", requirements, str(file_path.name), mime)
+
+    mock_input = {
+        "ctrl": "cin",
+        "input": {
+            "din": input_artefact.as_dict()
+        }
+    }
+    response = client.post("/template/", json=mock_input)
+    assert response.status_code == 200
+
+    expected_artefact = Artefact("inline", requirements + "\n\nChecked!", str(file_path.name), mime)
+    assert response.json() == {
+        "ctrl": "ok",
+        "output": {
+            "dout": expected_artefact.as_dict()
+        }
+    }