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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.ten
__pycache__
.pytest_cache
.coverage
28 changes: 28 additions & 0 deletions http_server_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AsyncExtension,
AsyncTenEnv,
Cmd,
Data,
StatusCode,
CmdResult,
)
Expand Down Expand Up @@ -54,6 +55,32 @@ async def handle_post_cmd(self, request):
"failed to handle request with unknown exception, err {}".format(e))
return web.Response(status=500)

# POST /data/{data_name}
async def handle_post_data(self, request):
ten_env = self.ten_env

try:
data_name = request.match_info.get('data_name')

req_json = await request.json()
input = json.dumps(req_json, ensure_ascii=False)

ten_env.log_debug(
f"process incoming request {request.method} {request.path} {input}")

data = Data.create(data_name)
data.set_property_from_json("", input)
await ten_env.send_data(data)

# return response
return web.Response(status=200)
except json.JSONDecodeError:
return web.Response(status=400)
except Exception as e:
ten_env.log_warn(
"failed to handle request with unknown exception, err {}".format(e))
return web.Response(status=500)

async def on_start(self, ten_env: AsyncTenEnv):
if await ten_env.is_property_exist("listen_addr"):
self.listen_addr = await ten_env.get_property_string("listen_addr")
Expand All @@ -65,6 +92,7 @@ async def on_start(self, ten_env: AsyncTenEnv):
f"http server listening on {self.listen_addr}:{self.listen_port}")

self.app.router.add_post("/cmd/{cmd_name}", self.handle_post_cmd)
self.app.router.add_post("/data/{data_name}", self.handle_post_data)
self.runner = web.AppRunner(self.app)
await self.runner.setup()
site = web.TCPSite(self.runner, self.listen_addr, self.listen_port)
Expand Down
27 changes: 20 additions & 7 deletions tests/test_4xx.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def on_start(self, ten_env: TenEnvTester) -> None:

property_json = {"num": 1, "str": "111"}
r = httpx.post("http://127.0.0.1:8888/cmd", json=property_json)
print(r)
ten_env.log_debug(f"{r}")
if r.status_code == httpx.codes.NOT_FOUND:
ten_env.stop_test()

Expand All @@ -29,21 +29,30 @@ def on_start(self, ten_env: TenEnvTester) -> None:

property_json = {"num": 1, "str": "111"}
r = httpx.post("http://127.0.0.1:8888/cmd/aaa/123", json=property_json)
print(r)
ten_env.log_debug(f"{r}")
if r.status_code == httpx.codes.NOT_FOUND:
ten_env.stop_test()


class ExtensionTester400BadRequest(ExtensionTester):
class ExtensionTesterCmd400BadRequest(ExtensionTester):
def on_start(self, ten_env: TenEnvTester) -> None:
ten_env.on_start_done()

property_str = '{num": 1, "str": "111"}' # not a valid json
r = httpx.post("http://127.0.0.1:8888/cmd/aaa", content=property_str)
print(r)
ten_env.log_debug(f"{r}")
if r.status_code == httpx.codes.BAD_REQUEST:
ten_env.stop_test()

class ExtensionTesterData400BadRequest(ExtensionTester):
def on_start(self, ten_env: TenEnvTester) -> None:
ten_env.on_start_done()

property_str = '{num": 1, "str": "111"}' # not a valid json
r = httpx.post("http://127.0.0.1:8888/data/aaa", content=property_str)
ten_env.log_debug(f"{r}")
if r.status_code == httpx.codes.BAD_REQUEST:
ten_env.stop_test()

def test_4xx():
tester_404_1 = ExtensionTester404NotFound1()
Expand All @@ -54,6 +63,10 @@ def test_4xx():
tester_404_2.set_test_mode_single("http_server_python")
tester_404_2.run()

tester_400 = ExtensionTester400BadRequest()
tester_400.set_test_mode_single("http_server_python")
tester_400.run()
tester_cmd_400 = ExtensionTesterCmd400BadRequest()
tester_cmd_400.set_test_mode_single("http_server_python")
tester_cmd_400.run()

tester_data_400 = ExtensionTesterData400BadRequest()
tester_data_400.set_test_mode_single("http_server_python")
tester_data_400.run()
4 changes: 2 additions & 2 deletions tests/test_5xx.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self):
self.thread = None

def on_cmd(self, ten_env: TenEnvTester, cmd: Cmd) -> None:
print(f"on_cmd name {cmd.get_name()}")
ten_env.log_debug(f"on_cmd name {cmd.get_name()}")
ten_env.return_result(CmdResult.create(StatusCode.ERROR), cmd)

def on_start(self, ten_env: TenEnvTester) -> None:
Expand All @@ -38,7 +38,7 @@ def _async_test(self, ten_env: TenEnvTester) -> None:
property_json = {"num": 1, "str": "111"}
r = httpx.post("http://127.0.0.1:8888/cmd/abc",
json=property_json, timeout=5)
print(r)
ten_env.log_debug(f"{r}")

if r.status_code >= 500:
ten_env.stop_test()
Expand Down
12 changes: 6 additions & 6 deletions tests/test_basic.py → tests/test_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
import math


class ExtensionTesterBasic(ExtensionTester):
class ExtensionTesterCmd(ExtensionTester):
def __init__(self):
super().__init__()
self.thread = None

def on_cmd(self, ten_env: TenEnvTester, cmd: Cmd) -> None:
print(f"on_cmd name {cmd.get_name()}")
ten_env.log_debug(f"on_cmd name {cmd.get_name()}")

num_val = cmd.get_property_int('num')
assert num_val == 1
Expand All @@ -50,17 +50,17 @@ def _async_test(self, ten_env: TenEnvTester) -> None:

r = httpx.post("http://127.0.0.1:8888/cmd/abc",
json=property_json, timeout=5)
print(r)
ten_env.log_debug(f"{r}")

if r.status_code == httpx.codes.OK:
ten_env.stop_test()


def test_basic():
tester = ExtensionTesterBasic()
def test_cmd():
tester = ExtensionTesterCmd()
tester.set_test_mode_single("http_server_python")
tester.run()


if __name__ == "__main__":
test_basic()
test_cmd()
66 changes: 66 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# Copyright © 2025 Agora
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0, with certain conditions.
# Refer to the "LICENSE" file in the root directory for more information.
#
from pathlib import Path
from ten import (
ExtensionTester,
TenEnvTester,
Cmd,
Data,
CmdResult,
StatusCode,
)
import httpx
import threading
import math


class ExtensionTesterData(ExtensionTester):
def __init__(self):
super().__init__()
self.thread = None

def on_data(self, ten_env: TenEnvTester, data: Data) -> None:
ten_env.log_debug(f"on_data name {data.get_name()}")

num_val = data.get_property_int('num')
assert num_val == 1
str_val = data.get_property_string('str')
assert str_val == '111'
unicode_str_val = data.get_property_string('unicode_str')
assert unicode_str_val == '你好!'
num_float_val = data.get_property_float('num_float')
assert math.isclose(num_float_val, -1.5)


def on_start(self, ten_env: TenEnvTester) -> None:

self.thread = threading.Thread(
target=self._async_test, args=[ten_env])
self.thread.start()

ten_env.on_start_done()

def _async_test(self, ten_env: TenEnvTester) -> None:
property_json = {"num": 1, "num_float": -
1.5, "str": "111", "unicode_str": "你好!"}

r = httpx.post("http://127.0.0.1:8888/data/abc",
json=property_json, timeout=5)
ten_env.log_debug(f"{r}")

if r.status_code == httpx.codes.OK:
ten_env.stop_test()


def test_data():
tester = ExtensionTesterData()
tester.set_test_mode_single("http_server_python")
tester.run()


if __name__ == "__main__":
test_data()
4 changes: 2 additions & 2 deletions tests/test_set_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self):
self.thread = None

def on_cmd(self, ten_env: TenEnvTester, cmd: Cmd) -> None:
print(f"on_cmd name {cmd.get_name()}")
ten_env.log_debug(f"on_cmd name {cmd.get_name()}")
ten_env.return_result(CmdResult.create(StatusCode.OK), cmd)

def on_start(self, ten_env: TenEnvTester) -> None:
Expand All @@ -37,7 +37,7 @@ def _async_test(self, ten_env: TenEnvTester) -> None:
property_json = {"num": 1, "str": "111"}
r = httpx.post("http://127.0.0.1:8899/cmd/abc",
json=property_json, timeout=5)
print(r)
ten_env.log_debug(f"{r}")

if r.status_code == httpx.codes.OK:
ten_env.stop_test()
Expand Down
4 changes: 2 additions & 2 deletions tests/test_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

class ExtensionTesterTimeout(ExtensionTester):
def on_cmd(self, ten_env: TenEnvTester, cmd: Cmd) -> None:
print(f"on_cmd name {cmd.get_name()}")
ten_env.log_debug(f"on_cmd name {cmd.get_name()}")
# NOTE: DON'T return result so that timeout will occur
# ten_env.return_result(CmdResult.create(StatusCode.OK), cmd)
pass
Expand All @@ -30,7 +30,7 @@ def on_start(self, ten_env: TenEnvTester) -> None:
property_json = {"num": 1, "str": "111"}
r = httpx.post("http://127.0.0.1:8888/cmd/abc",
json=property_json, timeout=10)
print(r)
ten_env.log_debug(f"{r}")
if r.status_code == httpx.codes.GATEWAY_TIMEOUT:
ten_env.stop_test()

Expand Down
Loading