Skip to content

Commit

Permalink
Refacto Page System
Browse files Browse the repository at this point in the history
  • Loading branch information
pbrochar authored Feb 20, 2024
1 parent 7a47b45 commit 8f9d885
Show file tree
Hide file tree
Showing 17 changed files with 169 additions and 154 deletions.
13 changes: 3 additions & 10 deletions blitz/api/blitz_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ def _create_crud_router(self, resource: BlitzResource) -> CRUDGenerator:
# Rebuild the model to include forward ref types that was not available at the time of the model creation
# We need to use the model AFTER the rebuild because if not, all the relationship and cie will not be set
# correctly.
types_namespace = {
resource.model.__name__: resource.model
for resource in self.blitz_app.resources
}
types_namespace = {resource.model.__name__: resource.model for resource in self.blitz_app.resources}
read_model.model_rebuild(_types_namespace=types_namespace)
create_model.model_rebuild(_types_namespace=types_namespace)
update_model.model_rebuild(_types_namespace=types_namespace)
Expand Down Expand Up @@ -189,12 +186,8 @@ def create_blitz_api(
warnings.simplefilter("ignore", category=SAWarning)
BlitzAdmin(blitz_app).mount_to(blitz_api)

print(
"\n[bold yellow]This is still an alpha. Please do not use in production.[/bold yellow]"
)
print(
"[bold yellow]Please report any issues on https://github.com/Paperz-org/blitz[/bold yellow]"
)
print("\n[bold yellow]This is still an alpha. Please do not use in production.[/bold yellow]")
print("[bold yellow]Please report any issues on https://github.com/Paperz-org/blitz[/bold yellow]")
print(
"\n".join(
(
Expand Down
29 changes: 7 additions & 22 deletions blitz/cli/commands/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,12 @@


def start_blitz(
blitz_app_name: Annotated[
Optional[str], typer.Argument(help="Blitz app name")
] = None,
blitz_app_name: Annotated[Optional[str], typer.Argument(help="Blitz app name")] = None,
admin: Annotated[bool, typer.Option(help="Don't create admin.")] = True,
port: Annotated[
int, typer.Option(help="Define the port of the server")
] = get_settings().BLITZ_PORT,
config_route: Annotated[
bool, typer.Option(help="Enable the blitz config route.")
] = True,
port: Annotated[int, typer.Option(help="Define the port of the server")] = get_settings().BLITZ_PORT,
config_route: Annotated[bool, typer.Option(help="Enable the blitz config route.")] = True,
hot_reload: Annotated[bool, typer.Option(help="Enable the hot reload.")] = True,
version: Annotated[
Optional[str], typer.Option(help="Define the version of the app.")
] = None,
version: Annotated[Optional[str], typer.Option(help="Define the version of the app.")] = None,
) -> None:
blitz = BlitzCore()

Expand Down Expand Up @@ -87,14 +79,7 @@ def start_blitz(
log_level="info",
)
server = uvicorn.Server(server_config)
ChangeReload(
server_config, target=server.run, sockets=[server_config.bind_socket()]
).run()
ChangeReload(server_config, target=server.run, sockets=[server_config.bind_socket()]).run()
else:

blitz_api = create_blitz_api(
blitz_app, enable_config_route=config_route, admin=admin
)
uvicorn.run(
blitz_api, host="localhost", port=port, log_config=None, log_level="warning"
)
blitz_api = create_blitz_api(blitz_app, enable_config_route=config_route, admin=admin)
uvicorn.run(blitz_api, host="localhost", port=port, log_config=None, log_level="warning")
1 change: 1 addition & 0 deletions blitz/models/blitz/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def from_dict(
resources_configs: list[BlitzResourceConfig] = []
resource_name: str
resource_config: dict[str, Any]

for resource_name, resource_config in blitz_file.get(cls.RESOURCES_FIELD_NAME, {}).items():
settings_fields = {}
fields = {}
Expand Down
5 changes: 5 additions & 0 deletions blitz/ui/blitz_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ def __init__(self, settings: Settings = get_settings()) -> None:
def current_project(self) -> str | None:
return self._current_project

@current_project.setter
def current_project(self, project: str) -> None:
print(project)
self._current_project = project

@property
def current_app(self) -> BlitzApp | None:
return self._current_app
Expand Down
8 changes: 8 additions & 0 deletions blitz/ui/components/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui


class BaseComponent:
def __init__(self, blitz_ui: BlitzUI = get_blitz_ui()) -> None:
self.blitz_ui: BlitzUI = blitz_ui
self.current_project = blitz_ui.current_project
self.current_app = blitz_ui.current_app
10 changes: 8 additions & 2 deletions blitz/ui/components/gpt_chat_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def validate_blitz_file(self, json: dict[str, Any]) -> bool:
BlitzFile.from_dict(json)
except ValidationError:
return False
except Exception:
return False
else:
return True

Expand Down Expand Up @@ -75,7 +77,7 @@ def action_buttons(self) -> None:

def download_dialog(self) -> None:
with ui.dialog() as self._dialog, ui.card().classes("w-full px-4"):
if not self.is_valid_blitz_file:
if self.is_valid_blitz_file is False:
self.invalid_blitz_file()
# with ui.expansion("Edit File", icon="edit").classes("w-full h-auto rounded-lg border-solid border overflow-hidden grow overflow-hidden"):
# JsonEditorComponent(self.json).render()
Expand Down Expand Up @@ -209,6 +211,7 @@ class GPTResponse(GPTChatComponent):
def __init__(self, text: str = "", text_is_finished: bool = False) -> None:
super().__init__(label=self.LABEL, text=text, icon=self.ICON, avatar_color=self.AVATAR_COLOR)
self._text_is_finished = text_is_finished
self.text_is_finished = text_is_finished

def add(self, text: str) -> None:
self.text += text
Expand Down Expand Up @@ -254,4 +257,7 @@ def split_response(text: str) -> list[Any]:

@classmethod
def from_gpt_dict(cls, gpt_dict: dict[str, Any]) -> "GPTChatComponent":
return cls(text=gpt_dict.get("content", ""), text_is_finished=gpt_dict.get("text_is_finished", False))
return cls(
text=gpt_dict.get("content", ""),
text_is_finished=gpt_dict.get("text_is_finished", False),
)
16 changes: 10 additions & 6 deletions blitz/ui/components/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from nicegui import ui
from nicegui.page_layout import LeftDrawer
from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui
from blitz.ui.components.base import BaseComponent

MAIN_PINK = "#cd87ff"
DARK_PINK = "#a72bff"
Expand All @@ -17,7 +18,12 @@ def render(self) -> None:


class HeaderComponent:
def __init__(self, title: str = "", blitz_ui: BlitzUI = get_blitz_ui(), drawer: LeftDrawer | None = None) -> None:
def __init__(
self,
title: str = "",
blitz_ui: BlitzUI = get_blitz_ui(),
drawer: LeftDrawer | None = None,
) -> None:
self.title = title
self.blitz_ui = blitz_ui

Expand Down Expand Up @@ -92,15 +98,13 @@ def go_to(self) -> None:
ui.open(self.link)


class FrameComponent:
class FrameComponent(BaseComponent):
def __init__(
self,
blitz_ui: BlitzUI = get_blitz_ui(),
show_drawer: bool = True,
drawer_open: bool = True,
) -> None:
self.blitz_ui = blitz_ui
self.current_project = blitz_ui.current_project
super().__init__()
self.show_drawer = show_drawer
self.drawer_open = drawer_open

Expand Down Expand Up @@ -131,6 +135,6 @@ def left_drawer(self) -> None:
MenuLink("Logs", f"/projects/{self.current_project}/logs", "list").render()

def render(self) -> None:
if self.show_drawer and self.current_project is not None:
if self.show_drawer and self.blitz_ui.current_project is not None:
self.left_drawer()
HeaderComponent(drawer=self.drawer).render()
85 changes: 21 additions & 64 deletions blitz/ui/main.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,32 @@
import logging
from typing import TYPE_CHECKING, Annotated

from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui
from blitz.ui.pages.blitz_file import BlitzFilePage
from blitz.ui.pages.dashboard import DashboardPage
from blitz.ui.pages.diagram import MermaidPage
from blitz.ui.pages.gpt_builder import AskGPTPage
from blitz.ui.pages.log import LogPage
from blitz.ui.pages.swagger import SwaggerPage
from typing import TYPE_CHECKING
from blitz.ui.blitz_ui import get_blitz_ui
from blitz.ui.pages import (
BlitzFilePage,
DashboardPage,
MermaidPage,
AskGPTPage,
LogPage,
SwaggerPage,
)
from pathlib import Path
from blitz.ui.router import BlitzRouter
from nicegui import ui

from nicegui import app

from blitz.ui.components.header import FrameComponent


from fastapi import Depends, Request


if TYPE_CHECKING:
from blitz.api.blitz_api import BlitzAPI


async def _post_dark_mode(request: Request) -> None:
print("dark mode")
app.storage.browser["dark_mode"] = (await request.json()).get("value")


@ui.page("/projects/{uuid}", title="Dashboard")
def dashboard_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
DashboardPage().render_page()
FrameComponent().render()


@ui.page("/projects/{uuid}/diagram", title="Diagram")
def diagram_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
MermaidPage().render_page()
FrameComponent().render()


@ui.page("/projects/{uuid}/blitz-file", title="Blitz File")
def blitz_file_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
BlitzFilePage().render_page()
FrameComponent().render()


@ui.page("/projects/{uuid}/swagger", title="Swagger")
def swagger_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
SwaggerPage().render_page()
FrameComponent().render()


@ui.page("/projects/{uuid}/logs")
def log_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
ui.page_title("Logs")
LogPage().render_page()
FrameComponent().render()


# @ui.page("/projects/{uuid}/admin")
# def log_page(uuid: str, blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
# ui.page_title("Admin")
# AdminPage().render_page()
# FrameComponent(drawer_open=False).render()

def init_routers() -> None:
router = BlitzRouter("/")
router.add_page("gpt", AskGPTPage)

@ui.page("/gpt")
def ask_gpt_page(blitz_ui: Annotated[BlitzUI, Depends(get_blitz_ui)]) -> None:
ui.page_title("GPT Builder")
AskGPTPage().render_page()
FrameComponent(show_drawer=False).render()
project_router = BlitzRouter("/projects/{uuid}/")
project_router.add_page("logs", LogPage)
project_router.add_page("swagger", SwaggerPage)
project_router.add_page("blitz-file", BlitzFilePage)
project_router.add_page("diagram", MermaidPage)
project_router.add_page("", DashboardPage)


# @ui.page("/projects")
Expand All @@ -89,6 +45,7 @@ def init_ui(
logging.getLogger("niceGUI").setLevel(logging.WARNING)
blitz_ui = get_blitz_ui()
blitz_ui.current_app = blitz_api.blitz_app
init_routers()
ui.run_with(
app=blitz_api,
title=title,
Expand Down
8 changes: 8 additions & 0 deletions blitz/ui/pages/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .blitz_file import BlitzFilePage
from .dashboard import DashboardPage
from .diagram import MermaidPage
from .gpt_builder import AskGPTPage
from .log import LogPage
from .swagger import SwaggerPage

__all__ = ["BlitzFilePage", "DashboardPage", "MermaidPage", "AskGPTPage", "LogPage", "SwaggerPage"]
41 changes: 41 additions & 0 deletions blitz/ui/pages/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from typing import Any, Self
from blitz.ui.components.base import BaseComponent
from nicegui import ui
from starlette.requests import Request

from blitz.ui.components.header import FrameComponent


class BasePage(BaseComponent):
PAGE_NAME = "Blitz Dashboard"
FRAME: FrameComponent

def __init__(self) -> None:
super().__init__()
self.setup()
self.render()
self.frame()

def __new__(cls, *args: Any, **kwargs: Any) -> Self:
instance = super().__new__(cls, *args, **kwargs)
if not hasattr(instance, "FRAME"):
instance.FRAME = FrameComponent()
return instance

def frame(self) -> None:
"""The frame method HAVE to render a frame."""
if self.FRAME is not None:
self.FRAME.render()

def setup(self) -> None:
"""The setup method is called before the render method."""
pass

def render(self) -> None:
ui.label("Base Page")

@classmethod
def entrypoint(cls, request: Request) -> None:
print(request.url.path)
ui.page_title(cls.PAGE_NAME)
cls()
15 changes: 7 additions & 8 deletions blitz/ui/pages/blitz_file.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from blitz.ui.blitz_ui import BlitzUI, get_blitz_ui
from blitz.ui.components.json_editor import BlitzFileEditorComponent

from blitz.ui.pages.base import BasePage

class BlitzFilePage:
def __init__(self, blitz_ui: BlitzUI = get_blitz_ui(), project: str | None = None) -> None:
self.blitz_ui = blitz_ui
self.blitz_app = blitz_ui.current_app

def render_page(self) -> None:
if self.blitz_app is None:
class BlitzFilePage(BasePage):
PAGE_NAME = "Blitz File"

def render(self) -> None:
if self.blitz_ui.current_app is None:
# TODO handle error
raise Exception
BlitzFileEditorComponent(self.blitz_app.file.raw_file).render()
BlitzFileEditorComponent(self.blitz_ui.current_app.file.raw_file).render()
Loading

0 comments on commit 8f9d885

Please sign in to comment.