From 421c6a17ffbfcb7d76cbec7f988f9a71760240dc Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Sat, 22 Nov 2025 22:01:16 -0600 Subject: [PATCH] wip --- .gitignore | 1 + fastapi_timezone/__about__.py | 1 + fastapi_timezone/models.py | 27 +++++++++++++++ pyproject.toml | 62 ++++++++++++++++++++++++++++++----- tui.py | 50 ++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 fastapi_timezone/__about__.py create mode 100644 fastapi_timezone/models.py create mode 100644 tui.py diff --git a/.gitignore b/.gitignore index e1a3186..9d6f21d 100644 --- a/.gitignore +++ b/.gitignore @@ -962,3 +962,4 @@ FodyWeavers.xsd # Additional files built by Visual Studio # End of https://www.toptal.com/developers/gitignore/api/vim,node,data,emacs,python,pycharm,executable,sublimetext,visualstudio,visualstudiocode +database.db diff --git a/fastapi_timezone/__about__.py b/fastapi_timezone/__about__.py new file mode 100644 index 0000000..5b708fa --- /dev/null +++ b/fastapi_timezone/__about__.py @@ -0,0 +1 @@ +__version__='0.0.1' diff --git a/fastapi_timezone/models.py b/fastapi_timezone/models.py new file mode 100644 index 0000000..6423ed4 --- /dev/null +++ b/fastapi_timezone/models.py @@ -0,0 +1,27 @@ +from datetime import datetime +from sqlmodel import Field, Session, SQLModel, create_engine + + +class Message(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + author: str + message: str + created_at: datetime = Field(default_factory=datetime.utcnow) + + def save(self): + with Session(engine) as session: + session.add(self) + session.commit() + + @classmethod + def get(cls, id: int): + with Session(engine) as session: + return session.get(cls, id) + +sqlite_file_name = "database.db" +sqlite_url = f"sqlite:///{sqlite_file_name}" + +engine = create_engine(sqlite_url, echo=True) + +SQLModel.metadata.create_all(engine) + diff --git a/pyproject.toml b/pyproject.toml index 4ae51d6..bdfd9bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,62 @@ [project] name = "fastapi-timezone" -version = "0.1.1" -description = "Add your description here" +dynamic = ["version"] +description = 'A demo fastapi application that automatically responds with the users localized timezone.' readme = "README.md" -requires-python = ">=3.11" +requires-python = ">=3.8" +license = "MIT" +keywords = [] +authors = [ + { name = "Waylon Walker", email = "waylon@waylonwalker.com" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] dependencies = [ "fastapi>=0.115.0", - "jinja2>=3.1.4", - "sqlmodel>=0.0.22", + "rich>=13.9.2", "uvicorn>=0.31.1", ] -[tool.setuptools.packages.find] -include = ["fastapi_timezone"] -exclude = ["templates", "node_modules"] +[project.urls] +Documentation = "https://github.com/U.N. Owen/fastapi-dynamic-response#readme" +Issues = "https://github.com/U.N. Owen/fastapi-dynamic-response/issues" +Source = "https://github.com/U.N. Owen/fastapi-dynamic-response" + +[tool.hatch.version] +path = "fastapi_timezone/__about__.py" + +[tool.hatch.envs.types] +extra-dependencies = [ + "mypy>=1.0.0", +] +[tool.hatch.envs.types.scripts] +check = "mypy --install-types --non-interactive {args:src/fastapi_dynamic_response tests}" + +[tool.coverage.run] +source_pkgs = ["fastapi_dynamic_response", "tests"] +branch = true +parallel = true +omit = [ + "src/fastapi_dynamic_response/__about__.py", +] + +[tool.coverage.paths] +fastapi_dynamic_response = ["src/fastapi_dynamic_response", "*/fastapi-dynamic-response/src/fastapi_dynamic_response"] +tests = ["tests", "*/fastapi-dynamic-response/tests"] + +[tool.coverage.report] +exclude_lines = [ + "no cov", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", +] + diff --git a/tui.py b/tui.py new file mode 100644 index 0000000..66fba91 --- /dev/null +++ b/tui.py @@ -0,0 +1,50 @@ +from textual.app import App +from textual.containers import Vertical +from textual.reactive import Reactive +from textual.widgets import Footer, Input, Static +from datetime import datetime + +# class MessageFeed(ScrollView): +# """A scrollable widget to display chat messages.""" + +# def __init__(self): +# super().__init__() +# self.messages = Vertical() +# self.set_content(self.messages) + +# def add_message(self, sender: str, text: str): +# """Add a message to the feed.""" +# timestamp = datetime.now().strftime('%H:%M:%S') +# message = Static(f"[{timestamp}] {sender}: {text}") +# self.messages.mount(message) +# self.scroll_end(animate=False) + +class ChatApp(App): + """A simple chat application using Textual.""" + + CSS_PATH = "chat.css" + message_input: Reactive[str] = Reactive("") + + def compose(self): + """Compose the layout of the chat app.""" + # self.message_feed = MessageFeed() + self.input_box = Input(placeholder="Type your message...", id="input") + self.footer = Footer() + # yield self.message_feed + yield self.input_box + yield self.footer + + async def on_input_submitted(self, event: Input.Submitted) -> None: + """Handle the input submission to send a message.""" + if event.value.strip(): + # self.message_feed.add_message("You", event.value.strip()) + event.input.value = "" # Clear input after sending + + def on_key(self, event): + """Handle key events for focus and usability.""" + if event.key == "escape": + self.input_box.focus() + +if __name__ == "__main__": + ChatApp.run() +