3 Commits
Author SHA1 Message Date
woggioni df5906fd3c tmp 2026-06-30 00:23:32 +08:00
woggioni 77362fd05c updated dependencies 2026-06-30 00:23:15 +08:00
woggioni f158698380 temporary commit 2025-04-02 17:21:30 +08:00
8 changed files with 233 additions and 181 deletions
+39 -8
View File
@@ -1,12 +1,13 @@
from bugis.core import BugisApp, HttpContext
from bugis.core import BugisApp, HttpContext, HttpMethod
from typing import List
class Hello(BugisApp):
pass
async def handle_request(self, ctx: HttpContext) -> None:
async for chunk in ctx.request_body:
print(chunk)
await ctx.send_str(200, 'Hello World')
# async def handle_request(self, ctx: HttpContext) -> None:
# async for chunk in ctx.request_body:
# print(chunk.decode())
# await ctx.send_str(200, 'Hello World')
app = BugisApp()
@@ -16,5 +17,35 @@ app = BugisApp()
@app.GET('/hello2')
async def handle_request(ctx: HttpContext) -> None:
async for chunk in ctx.request_body:
print(chunk)
await ctx.send_str(200, 'Hello World')
print(chunk.decode())
await ctx.send_str(200, 'Hello World')
@app.GET('/hello/alice')
async def hello_alice(ctx: HttpContext) -> None:
async for _ in ctx.request_body:
pass
await ctx.send_str(200, 'Hello Alice 2')
@app.GET('/hello/*')
async def hello_alice(ctx: HttpContext, args: List[str]) -> None:
async for _ in ctx.request_body:
pass
await ctx.send_str(200, f'Hello {args[0]}')
@app.GET('/hello/*/kennedy')
async def hello_alice(ctx: HttpContext, args: List[str]) -> None:
async for _ in ctx.request_body:
pass
await ctx.send_str(200, f'Hello {args[0]} kennedy')
@app.GET('/hello/bob/marley')
async def hello_alice(ctx: HttpContext) -> None:
async for _ in ctx.request_body:
pass
await ctx.send_str(200, f'Hello bob Marley')
@app.route('/hello/*', HttpMethod.PUT, recursive=True)
async def handle_request(ctx: HttpContext, _: List[str]) -> None:
async for chunk in ctx.request_body:
print(chunk.decode())
await ctx.send_str(200, 'Message received')
+75 -59
View File
@@ -1,102 +1,127 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# pip-compile --extra=dev --output-file=requirements-dev.txt
# pip-compile --allow-unsafe --extra=dev --extra=rsgi --output-file=requirements-dev.txt pyproject.toml
#
--index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple
--extra-index-url https://pypi.org/simple
aiofiles==24.1.0
# via bugis_core (pyproject.toml)
asttokens==2.4.1
anyio==4.14.1
# via httpx
ast-serialize==0.5.0
# via mypy
asttokens==3.0.1
# via stack-data
build==1.2.2.post1
build==1.5.0
# via bugis_core (pyproject.toml)
certifi==2024.8.30
# via requests
cffi==1.17.1
certifi==2026.6.17
# via
# httpcore
# httpx
# requests
cffi==2.0.0
# via cryptography
charset-normalizer==3.4.0
charset-normalizer==3.4.7
# via requests
cryptography==43.0.3
click==8.4.2
# via granian
cryptography==49.0.0
# via secretstorage
decorator==5.1.1
decorator==5.3.1
# via
# ipdb
# ipython
docutils==0.21.2
docutils==0.23
# via readme-renderer
executing==2.1.0
executing==2.2.1
# via stack-data
idna==3.10
# via requests
importlib-metadata==8.5.0
granian==2.7.7
# via bugis_core (pyproject.toml)
h11==0.16.0
# via httpcore
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via bugis_core (pyproject.toml)
id==1.6.1
# via twine
idna==3.18
# via
# anyio
# httpx
# requests
ipdb==0.13.13
# via bugis_core (pyproject.toml)
ipython==8.29.0
ipython==9.15.0
# via ipdb
ipython-pygments-lexers==1.1.1
# via ipython
jaraco-classes==3.4.0
# via keyring
jaraco-context==6.0.1
jaraco-context==6.1.2
# via keyring
jaraco-functools==4.1.0
jaraco-functools==4.5.0
# via keyring
jedi==0.19.1
jedi==0.20.0
# via ipython
jeepney==0.8.0
jeepney==0.9.0
# via
# keyring
# secretstorage
keyring==25.5.0
keyring==25.7.0
# via twine
markdown-it-py==3.0.0
librt==0.11.0
# via mypy
markdown-it-py==4.2.0
# via rich
matplotlib-inline==0.1.7
matplotlib-inline==0.2.2
# via ipython
mdurl==0.1.2
# via markdown-it-py
more-itertools==10.5.0
more-itertools==11.1.0
# via
# jaraco-classes
# jaraco-functools
mypy==1.13.0
mypy==2.1.0
# via bugis_core (pyproject.toml)
mypy-extensions==1.0.0
mypy-extensions==1.1.0
# via mypy
nh3==0.2.18
nh3==0.3.6
# via readme-renderer
packaging==24.1
# via build
parso==0.8.4
packaging==26.2
# via
# build
# twine
parso==0.8.7
# via jedi
pathspec==1.1.1
# via mypy
pexpect==4.9.0
# via ipython
pkginfo==1.10.0
# via twine
prompt-toolkit==3.0.48
prompt-toolkit==3.0.52
# via ipython
psutil==7.2.2
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
pwo==0.0.5
pwo==0.1.2
# via bugis_core (pyproject.toml)
pycparser==2.22
pycparser==3.0
# via cffi
pygments==2.18.0
pygments==2.20.0
# via
# ipython
# ipython-pygments-lexers
# readme-renderer
# rich
pyproject-hooks==1.2.0
# via build
pyyaml==6.0.2
# via bugis_core (pyproject.toml)
readme-renderer==44.0
readme-renderer==45.0
# via twine
requests==2.32.3
requests==2.34.2
# via
# requests-toolbelt
# twine
@@ -104,35 +129,26 @@ requests-toolbelt==1.0.0
# via twine
rfc3986==2.0.0
# via twine
rich==13.9.3
rich==15.0.0
# via twine
secretstorage==3.3.3
secretstorage==3.5.0
# via keyring
six==1.16.0
# via asttokens
sortedcontainers==2.4.0
# via bugis_core (pyproject.toml)
stack-data==0.6.3
# via ipython
traitlets==5.14.3
traitlets==5.15.1
# via
# ipython
# matplotlib-inline
twine==5.1.1
twine==6.2.0
# via bugis_core (pyproject.toml)
types-pyyaml==6.0.12.20240917
# via bugis_core (pyproject.toml)
typing-extensions==4.12.2
typing-extensions==4.15.0
# via
# mypy
# pwo
urllib3==2.2.3
urllib3==2.7.0
# via
# id
# requests
# twine
watchdog==5.0.3
# via bugis_core (pyproject.toml)
wcwidth==0.2.13
wcwidth==0.8.1
# via prompt-toolkit
zipp==3.20.2
# via importlib-metadata
+7 -11
View File
@@ -1,21 +1,17 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# pip-compile --output-file=requirements.txt
# pip-compile --allow-unsafe --extra=rsgi --output-file=requirements.txt pyproject.toml
#
--index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple
--extra-index-url https://pypi.org/simple
aiofiles==24.1.0
click==8.4.2
# via granian
granian==2.7.7
# via bugis_core (pyproject.toml)
pwo==0.0.5
pwo==0.1.2
# via bugis_core (pyproject.toml)
pyyaml==6.0.2
# via bugis_core (pyproject.toml)
sortedcontainers==2.4.0
# via bugis_core (pyproject.toml)
typing-extensions==4.12.2
typing-extensions==4.15.0
# via pwo
watchdog==5.0.3
# via bugis_core (pyproject.toml)
+1 -1
View File
@@ -52,7 +52,7 @@ class RsgiContext(HttpContext):
self.server = (Maybe.of(scope.server.split(':'))
.map(lambda it: (it[0], int(it[1])))
.or_else_throw(RuntimeError))
self.request_body = aiter(protocol)
self.request_body = protocol
self.protocol = protocol
# @staticmethod
+21 -10
View File
@@ -3,7 +3,7 @@ import json
import httpx
from pwo import async_test
from bugis.core import BugisApp, HttpContext, HttpMethod
from typing import Sequence
from typing import Sequence, List
class AsgiTest(unittest.TestCase):
@@ -15,6 +15,7 @@ class AsgiTest(unittest.TestCase):
@self.app.GET('/hello')
@self.app.GET('/hello2')
@self.app.route('/hello3')
@self.app.GET('/hello/*')
async def handle_request(ctx: HttpContext) -> None:
async for chunk in ctx.request_body:
print(chunk)
@@ -53,34 +54,44 @@ class AsgiTest(unittest.TestCase):
'employee_id': employee_id
}))
@self.app.PUT('/hello/*', recursive=True)
async def handle_request(ctx: HttpContext, _: List[str]) -> None:
await ctx.stream_body(200, (chunk async for chunk in ctx.request_body))
@async_test
async def test_hello(self):
transport = httpx.ASGITransport(app=self.app)
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
r = await client.get("/hello")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual(r.text, "Hello World!")
r = await client.get("/hello2")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual(r.text, "Hello World!")
r = await client.post("/hello3")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual(r.text, "Hello World!")
r = await client.get("/hello4")
self.assertEqual(r.status_code, 404)
self.assertEqual(404, r.status_code)
self.assertTrue(len(r.text) == 0)
body = {'name': 'John', 'surname': 'Smith'}
r = await client.put("/hello/foo/bar", json=body)
self.assertEqual(200, r.status_code)
ans = json.loads(r.text)
self.assertTrue(body, ans)
@async_test
async def test_foo(self):
transport = httpx.ASGITransport(app=self.app)
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
r = await client.put("/foo/fizz/baz")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
response = json.loads(r.text)
self.assertEqual(['fizz', 'baz'], response)
@@ -90,7 +101,7 @@ class AsgiTest(unittest.TestCase):
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
r = await client.put("/foo/bar/baz")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual('/foo/bar/baz', r.text)
@async_test
@@ -99,7 +110,7 @@ class AsgiTest(unittest.TestCase):
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
r = await client.get("/employee/101325")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual(r.text, '101325')
@async_test
@@ -109,7 +120,7 @@ class AsgiTest(unittest.TestCase):
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
x = 30
r = await client.get(f"/square/{x}")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
self.assertEqual(r.text, str(x * x))
@async_test
@@ -118,7 +129,7 @@ class AsgiTest(unittest.TestCase):
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
r = await client.get("department/189350/employee/101325")
self.assertEqual(r.status_code, 200)
self.assertEqual(200, r.status_code)
response = json.loads(r.text)
self.assertEqual({
'department_id': 189350,
+1 -1
View File
@@ -35,7 +35,7 @@ services:
cpus: "4"
memory: 1G
nginx:
image: gitea.woggioni.net/woggioni/nginx:v1.27.2
image: gitea.woggioni.net/woggioni/nginx:v1.31.2
# container_name: nginx
restart: unless-stopped
depends_on:
+70 -68
View File
@@ -1,131 +1,142 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# pip-compile --extra=dev --output-file=requirements-dev.txt pyproject.toml
# pip-compile --allow-unsafe --extra=dev --output-file=requirements-dev.txt pyproject.toml
#
--index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple
--extra-index-url https://pypi.org/simple
aiofiles==24.1.0
aiofiles==25.1.0
# via bugis (pyproject.toml)
anyio==4.6.2.post1
anyio==4.14.1
# via httpx
asttokens==2.4.1
ast-serialize==0.5.0
# via mypy
asttokens==3.0.1
# via stack-data
build==1.2.2.post1
build==1.5.0
# via bugis (pyproject.toml)
certifi==2024.8.30
certifi==2026.6.17
# via
# httpcore
# httpx
# requests
cffi==1.17.1
cffi==2.0.0
# via cryptography
charset-normalizer==3.4.0
charset-normalizer==3.4.7
# via requests
click==8.1.7
click==8.4.2
# via granian
cryptography==43.0.3
cryptography==49.0.0
# via secretstorage
decorator==5.1.1
decorator==5.3.1
# via
# ipdb
# ipython
docutils==0.21.2
docutils==0.23
# via readme-renderer
executing==2.1.0
executing==2.2.1
# via stack-data
granian==1.6.1
granian==2.7.7
# via bugis (pyproject.toml)
h11==0.14.0
h11==0.16.0
# via httpcore
h2==4.1.0
h2==4.3.0
# via httpx
hpack==4.0.0
hpack==4.2.0
# via h2
httpcore==1.0.6
httpcore==1.0.9
# via httpx
httpx[http2]==0.27.2
httpx[http2]==0.28.1
# via bugis (pyproject.toml)
hyperframe==6.0.1
hyperframe==6.1.0
# via h2
idna==3.10
id==1.6.1
# via twine
idna==3.18
# via
# anyio
# httpx
# requests
importlib-metadata==8.5.0
# via twine
ipdb==0.13.13
# via bugis (pyproject.toml)
ipython==8.28.0
ipython==9.15.0
# via ipdb
ipython-pygments-lexers==1.1.1
# via ipython
jaraco-classes==3.4.0
# via keyring
jaraco-context==6.0.1
jaraco-context==6.1.2
# via keyring
jaraco-functools==4.1.0
jaraco-functools==4.5.0
# via keyring
jedi==0.19.1
jedi==0.20.0
# via ipython
jeepney==0.8.0
jeepney==0.9.0
# via
# keyring
# secretstorage
keyring==25.4.1
keyring==25.7.0
# via twine
markdown==3.7
librt==0.11.0
# via mypy
markdown==3.10.2
# via bugis (pyproject.toml)
markdown-it-py==3.0.0
markdown-it-py==4.2.0
# via rich
matplotlib-inline==0.1.7
matplotlib-inline==0.2.2
# via ipython
mdurl==0.1.2
# via markdown-it-py
more-itertools==10.5.0
more-itertools==11.1.0
# via
# jaraco-classes
# jaraco-functools
mypy==1.13.0
mypy==2.1.0
# via bugis (pyproject.toml)
mypy-extensions==1.0.0
mypy-extensions==1.1.0
# via mypy
nh3==0.2.18
nh3==0.3.6
# via readme-renderer
packaging==24.1
# via build
parso==0.8.4
packaging==26.2
# via
# build
# twine
parso==0.8.7
# via jedi
pathspec==1.1.1
# via mypy
pexpect==4.9.0
# via ipython
pkginfo==1.10.0
# via twine
prompt-toolkit==3.0.48
prompt-toolkit==3.0.52
# via ipython
psutil==7.2.2
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
pwo==0.0.4
pwo==0.1.2
# via bugis (pyproject.toml)
pycparser==2.22
pycparser==3.0
# via cffi
pygments==2.18.0
pygments==2.20.0
# via
# bugis (pyproject.toml)
# ipython
# ipython-pygments-lexers
# readme-renderer
# rich
pygraphviz==1.14
pygraphviz==2.0
# via bugis (pyproject.toml)
pyproject-hooks==1.2.0
# via build
pyyaml==6.0.2
pyyaml==6.0.3
# via bugis (pyproject.toml)
readme-renderer==44.0
readme-renderer==45.0
# via twine
requests==2.32.3
requests==2.34.2
# via
# requests-toolbelt
# twine
@@ -133,37 +144,28 @@ requests-toolbelt==1.0.0
# via twine
rfc3986==2.0.0
# via twine
rich==13.9.3
rich==15.0.0
# via twine
secretstorage==3.3.3
secretstorage==3.5.0
# via keyring
six==1.16.0
# via asttokens
sniffio==1.3.1
# via
# anyio
# httpx
stack-data==0.6.3
# via ipython
traitlets==5.14.3
traitlets==5.15.1
# via
# ipython
# matplotlib-inline
twine==5.1.1
twine==6.2.0
# via bugis (pyproject.toml)
typing-extensions==4.12.2
typing-extensions==4.15.0
# via
# mypy
# pwo
urllib3==2.2.3
urllib3==2.7.0
# via
# id
# requests
# twine
uvloop==0.21.0
# via granian
watchdog==5.0.3
watchdog==6.0.0
# via bugis (pyproject.toml)
wcwidth==0.2.13
wcwidth==0.8.1
# via prompt-toolkit
zipp==3.20.2
# via importlib-metadata
+19 -23
View File
@@ -1,51 +1,47 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.14
# by the following command:
#
# pip-compile --output-file=requirements.txt pyproject.toml
# pip-compile --allow-unsafe --output-file=requirements.txt pyproject.toml
#
--index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple
--extra-index-url https://pypi.org/simple
aiofiles==24.1.0
aiofiles==25.1.0
# via bugis (pyproject.toml)
anyio==4.6.2.post1
anyio==4.14.1
# via httpx
certifi==2024.8.30
certifi==2026.6.17
# via
# httpcore
# httpx
h11==0.14.0
h11==0.16.0
# via httpcore
h2==4.1.0
h2==4.3.0
# via httpx
hpack==4.0.0
hpack==4.2.0
# via h2
httpcore==1.0.6
httpcore==1.0.9
# via httpx
httpx[http2]==0.27.2
httpx[http2]==0.28.1
# via bugis (pyproject.toml)
hyperframe==6.0.1
hyperframe==6.1.0
# via h2
idna==3.10
idna==3.18
# via
# anyio
# httpx
markdown==3.7
markdown==3.10.2
# via bugis (pyproject.toml)
pwo==0.0.4
pwo==0.1.2
# via bugis (pyproject.toml)
pygments==2.18.0
pygments==2.20.0
# via bugis (pyproject.toml)
pygraphviz==1.14
pygraphviz==2.0
# via bugis (pyproject.toml)
pyyaml==6.0.2
pyyaml==6.0.3
# via bugis (pyproject.toml)
sniffio==1.3.1
# via
# anyio
# httpx
typing-extensions==4.12.2
typing-extensions==4.15.0
# via pwo
watchdog==5.0.3
watchdog==6.0.0
# via bugis (pyproject.toml)