From f3ae82351f9afd4e79f209896ce6f94e162d8068 Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 1 Aug 2026 15:26:44 -0600 Subject: [PATCH] Add initial project structure with main application and transport layer --- .python-version | 1 + main.py | 12 +++++ pyproject.toml | 9 ++++ src/__init__.py | 2 + src/cli/__init__.py | 1 + src/cli/client.py | 0 src/cli/sever.py | 9 ++++ src/transport/__init__.py | 1 + src/transport/sever.py | 35 ++++++++++++++ uv.lock | 99 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 169 insertions(+) create mode 100644 .python-version create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 src/__init__.py create mode 100644 src/cli/__init__.py create mode 100644 src/cli/client.py create mode 100644 src/cli/sever.py create mode 100644 src/transport/__init__.py create mode 100644 src/transport/sever.py create mode 100644 uv.lock diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..2c07333 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 diff --git a/main.py b/main.py new file mode 100644 index 0000000..4dce37e --- /dev/null +++ b/main.py @@ -0,0 +1,12 @@ +import typer +from src import severcli + + +app = typer.Typer(help="An awesome task manager CLI.") + +@app.add_typer(severcli()) +def sever(): + pass + +if __name__ == "__main__": + app() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c47f1d9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "smail" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.11" +dependencies = [ + "typer>=0.27.0", +] diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..917ce5c --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,2 @@ +from .transport import sever +from .cli import severcli \ No newline at end of file diff --git a/src/cli/__init__.py b/src/cli/__init__.py new file mode 100644 index 0000000..e9495d3 --- /dev/null +++ b/src/cli/__init__.py @@ -0,0 +1 @@ +from .sever import severcli \ No newline at end of file diff --git a/src/cli/client.py b/src/cli/client.py new file mode 100644 index 0000000..e69de29 diff --git a/src/cli/sever.py b/src/cli/sever.py new file mode 100644 index 0000000..4cc9718 --- /dev/null +++ b/src/cli/sever.py @@ -0,0 +1,9 @@ +import typer +import asyncio +from ..transport import sever + +severcli = typer.Typer(help="sever for smail") + +@severcli.command() +def start(): + asyncio.run(sever()) \ No newline at end of file diff --git a/src/transport/__init__.py b/src/transport/__init__.py new file mode 100644 index 0000000..5aa05dd --- /dev/null +++ b/src/transport/__init__.py @@ -0,0 +1 @@ +from .sever import sever \ No newline at end of file diff --git a/src/transport/sever.py b/src/transport/sever.py new file mode 100644 index 0000000..928d628 --- /dev/null +++ b/src/transport/sever.py @@ -0,0 +1,35 @@ +import asyncio + +async def handle_echo(reader, writer): + # Retrieve client connection details + addr = writer.get_extra_info('peername') + print(f"Received connection from {addr}") + + try: + while True: + # Read chunks up to 1024 bytes + data = await reader.read(1024) + if not data: + break # Client disconnected + + message = data.decode() + print(f"Received {message!r} from {addr}") + + # Echo the incoming data back out + writer.write(data) + await writer.drain() + + except asyncio.CancelledError: + pass + finally: + print(f"Closing the connection for {addr}") + writer.close() + await writer.wait_closed() + +async def sever(): + server = await asyncio.start_server(handle_echo, '127.0.0.1', 8888) + addr = server.sockets[0].getsockname() + print(f'Serving on {addr}') + + async with server: + await server.serve_forever() \ No newline at end of file diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..2063e30 --- /dev/null +++ b/uv.lock @@ -0,0 +1,99 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "annotated-doc" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "smail" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "typer" }, +] + +[package.metadata] +requires-dist = [{ name = "typer", specifier = ">=0.27.0" }] + +[[package]] +name = "typer" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, +]