From c6a7940d81aacd429ae4016510c4e97c94f0e41f Mon Sep 17 00:00:00 2001
From: "Alexie (Boyong) Madolid" <maex@tuta.io>
Date: Fri, 6 Sep 2024 01:54:44 +0800
Subject: [PATCH] [MINOR]: FastAPI is served checker

---
 jaclang_jaseci/jaseci/__init__.py | 38 +++++++++++++++++++------------
 jaclang_jaseci/plugin/cli.py      |  1 +
 jaclang_jaseci/plugin/jaseci.py   | 20 ++++++++--------
 3 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/jaclang_jaseci/jaseci/__init__.py b/jaclang_jaseci/jaseci/__init__.py
index 589f432..32967f6 100644
--- a/jaclang_jaseci/jaseci/__init__.py
+++ b/jaclang_jaseci/jaseci/__init__.py
@@ -15,13 +15,12 @@ class FastAPI:
     """FastAPI Handler."""
 
     __app__ = None
-    __is_imported__: bool | None = None
+    __is_served__: bool | None = None
 
     @staticmethod
-    def is_imported() -> bool:
-        """Check if fastapi is used."""
+    def serve() -> None:
+        """Tag Fastapi as served."""
         from jaclang.plugin.feature import JacFeature as Jac
-        from jaclang.runtimelib.machine import JacMachine
 
         from ..core.architype import (
             EdgeArchitype,
@@ -31,17 +30,28 @@ def is_imported() -> bool:
             WalkerArchitype,
         )
 
-        if not isinstance(FastAPI.__is_imported__, bool):
+        FastAPI.__is_served__ = True
+
+        Jac.RootType = Root  # type: ignore[assignment]
+        Jac.Obj = ObjectArchitype  # type: ignore[assignment]
+        Jac.Node = NodeArchitype  # type: ignore[assignment]
+        Jac.Edge = EdgeArchitype  # type: ignore[assignment]
+        Jac.Walker = WalkerArchitype  # type: ignore[assignment]
+
+    @staticmethod
+    def is_served() -> bool:
+        """Check if FastAPI is already served."""
+        if FastAPI.__is_served__ is None:
+            from jaclang.runtimelib.machine import JacMachine
+
             main = JacMachine.get().loaded_modules.get("__main__")
-            FastAPI.__is_imported__ = getattr(main, "FastAPI", None) is FastAPI
-            if FastAPI.__is_imported__:
-                Jac.RootType = Root  # type: ignore[assignment]
-                Jac.Obj = ObjectArchitype  # type: ignore[assignment]
-                Jac.Node = NodeArchitype  # type: ignore[assignment]
-                Jac.Edge = EdgeArchitype  # type: ignore[assignment]
-                Jac.Walker = WalkerArchitype  # type: ignore[assignment]
-
-        return FastAPI.__is_imported__
+            if getattr(main, "FastAPI", None) is FastAPI:
+                FastAPI.serve()
+                return True
+            else:
+                FastAPI.__is_served__ = False
+
+        return FastAPI.__is_served__
 
     @classmethod
     def get(cls) -> _FaststAPI:
diff --git a/jaclang_jaseci/plugin/cli.py b/jaclang_jaseci/plugin/cli.py
index d167eeb..12abbc2 100644
--- a/jaclang_jaseci/plugin/cli.py
+++ b/jaclang_jaseci/plugin/cli.py
@@ -27,6 +27,7 @@ def serve(filename: str, host: str = "0.0.0.0", port: int = 8000) -> None:
             base = base if base else "./"
             mod = mod[:-4]
 
+            FastAPI.serve()
             jctx = ExecutionContext.create()
 
             if filename.endswith(".jac"):
diff --git a/jaclang_jaseci/plugin/jaseci.py b/jaclang_jaseci/plugin/jaseci.py
index 654c6ed..a6e504b 100644
--- a/jaclang_jaseci/plugin/jaseci.py
+++ b/jaclang_jaseci/plugin/jaseci.py
@@ -246,7 +246,7 @@ class JacPlugin:
     @hookimpl
     def get_context() -> ExecutionContext:
         """Get current execution context."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             return JaseciContext.get()
         return JacFeatureDefaults.get_context()
 
@@ -259,7 +259,7 @@ def make_architype(
         on_exit: list[DSFunc],
     ) -> Type[Architype]:
         """Create a new architype."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             for i in on_entry + on_exit:
                 i.resolve(cls)
             if not hasattr(cls, "_jac_entry_funcs_") or not hasattr(
@@ -306,7 +306,7 @@ def make_obj(
         on_entry: list[DSFunc], on_exit: list[DSFunc]
     ) -> Callable[[type], type]:
         """Create a new architype."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
 
             def decorator(cls: Type[Architype]) -> Type[Architype]:
                 """Decorate class."""
@@ -327,7 +327,7 @@ def make_node(
         on_entry: list[DSFunc], on_exit: list[DSFunc]
     ) -> Callable[[type], type]:
         """Create a obj architype."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
 
             def decorator(cls: Type[Architype]) -> Type[Architype]:
                 """Decorate class."""
@@ -345,7 +345,7 @@ def make_edge(
         on_entry: list[DSFunc], on_exit: list[DSFunc]
     ) -> Callable[[type], type]:
         """Create a edge architype."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
 
             def decorator(cls: Type[Architype]) -> Type[Architype]:
                 """Decorate class."""
@@ -363,7 +363,7 @@ def make_walker(
         on_entry: list[DSFunc], on_exit: list[DSFunc]
     ) -> Callable[[type], type]:
         """Create a walker architype."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
 
             def decorator(cls: Type[Architype]) -> Type[Architype]:
                 """Decorate class."""
@@ -383,7 +383,7 @@ def decorator(cls: Type[Architype]) -> Type[Architype]:
     @hookimpl
     def report(expr: Any) -> None:  # noqa:ANN401
         """Jac's report stmt feature."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             JaseciContext.get().reports.append(expr)
             return
         JacFeatureDefaults.report(expr=expr)
@@ -392,7 +392,7 @@ def report(expr: Any) -> None:  # noqa:ANN401
     @hookimpl
     def get_root() -> Root:
         """Jac's assign comprehension feature."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             return JaseciContext.get_root()
         return JacFeatureDefaults.get_root()  # type:ignore[return-value]
 
@@ -400,7 +400,7 @@ def get_root() -> Root:
     @hookimpl
     def get_root_type() -> Type[Root]:
         """Jac's root getter."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             return Root
         return JacFeatureDefaults.get_root_type()  # type:ignore[return-value]
 
@@ -412,7 +412,7 @@ def build_edge(
         conn_assign: tuple[tuple, tuple] | None,
     ) -> Callable[[NodeAnchor, NodeAnchor], EdgeArchitype]:
         """Jac's root getter."""
-        if FastAPI.is_imported():
+        if FastAPI.is_served():
             conn_type = conn_type if conn_type else GenericEdge
 
             def builder(source: NodeAnchor, target: NodeAnchor) -> EdgeArchitype: