Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions examples/run.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from datetime import date, datetime, timezone

import uvicorn
from fastapi import Request
from pydantic import BaseModel

from examples.data import df
from uiwiz import UiwizApp, ui
from data import df
from uiwiz import UiwizApp, ui, server
from uiwiz.element import Element as element

app = UiwizApp()
Expand Down Expand Up @@ -94,4 +93,4 @@ def replace(request: Request, input: DataInput):


if __name__ == "__main__":
uvicorn.run("run:app", reload=True)
server.run("run:app")
16 changes: 16 additions & 0 deletions src/uiwiz/server/_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dataclasses import dataclass
from collections import deque
from contextlib import suppress
import copy

from uvicorn._types import (
ASGI3Application,
Expand All @@ -19,6 +20,7 @@

from uvicorn.protocols.http.flow_control import HIGH_WATER_LIMIT
from uiwiz.app import UiwizApp
from uiwiz import shared
import logging

formatter = logging.Formatter(
Expand Down Expand Up @@ -47,10 +49,23 @@ class Config:
def import_app_instance(config: Config) -> None:
start = perf_counter()
if isinstance(config.app, str):
routes = []
if config.app_instance is not None:
# As the user can register new endpoints with a lambda function and this can happen inside of an endpoint
# i.e not when the application is first loaded but during the exeuction of the endpoint. It is nesscary to
# save the endpoint data and transfer it to the newly created application
routes = copy.copy(config.app_instance.router.routes)
_page_map = copy.copy(shared.page_map)
_resources = copy.copy(shared.resources)

module_name, _, app = config.app.partition(":")
module = importlib.import_module(module_name)
module = importlib.reload(module)
config.app_instance = getattr(module, app)
if routes:
config.app_instance.router.routes = routes
shared.page_map = _page_map
shared.resources = _resources
else:
config.app_instance = config.app
end = perf_counter()
Expand Down Expand Up @@ -425,6 +440,7 @@ async def run_asgi(self, app: ASGI3Application) -> None:

class Server:
def __init__(self, config: Config):
logger.warning("Development server. Do not use in production!")
self.config = config
self.server_state = None
import_app_instance(config)
Expand Down
13 changes: 6 additions & 7 deletions src/uiwiz/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
resources: Dict[str, Path] = {}
page_map: Dict[Callable, str] = {}


@lru_cache(maxsize=None)
def hash_function_extended(func):
def _hash_function_extended(func) -> str:
"""
This was an interesting problem. I needed to hash the function
to be able to store the route in a dictionary. Nothing special
Expand All @@ -26,19 +25,19 @@ def hash_function_extended(func):
return hashlib.sha256(source.encode("utf-8")).hexdigest()


def register_resource(key: str, resource: Path):
def register_resource(key: str, resource: Path) -> None:
resources[key] = resource


def register_path(key: str, func: Callable):
page_map[hash_function_extended(func)] = key
def register_path(key: str, func: Callable) -> None:
page_map[_hash_function_extended(func)] = key


def fetch_route(func: Callable) -> Optional[str]:
return page_map.get(hash_function_extended(func))
return page_map.get(_hash_function_extended(func))


def reset_resources():
def reset_resources() -> None:
resources.clear()
page_map.clear()

Expand Down