Skip to content

Commit 4eec9e5

Browse files
Allow custom method names other than the default on server side
This new feature is usefull for a user that wants to use dot ('.') in the xmlrpc method names available in its xmlrpc server. Indeed, this is not possible in python function definition. Therefore, this feature can be used to "simulate" nested methods. The implementation of this feature does not use true nested methods (i.e. in subclasses of the main class, inheriting from handler.XMLRPCView). Instead, it simply allows the user to overwrite the method names thanks to a `METHOD_NAMES` dictionary attribute in the user class (the one inheriting from `handler.XMLRPCView`). This approach has been used in order to not modify the whole code structure of the 'handler.py' and still offer 'nested' methods from the client point of view. The README.rst and the tests have been updated and completed accordingly. Signed-off-by: Armand Bénéteau <[email protected]>
1 parent 5617649 commit 4eec9e5

File tree

5 files changed

+35
-12
lines changed

5 files changed

+35
-12
lines changed

README.rst

+9-5
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ Server example
3131
3232
from aiohttp import web
3333
from aiohttp_xmlrpc import handler
34-
from tornado.testing import *
34+
from aiohttp_xmlrpc.handler import rename
3535
3636
3737
class XMLRPCExample(handler.XMLRPCView):
38+
39+
@rename("nested.test")
3840
def rpc_test(self):
3941
return None
4042
@@ -47,6 +49,7 @@ Server example
4749
def rpc_args_kwargs(self, *args, **kwargs):
4850
return len(args) + len(kwargs)
4951
52+
@rename("nested.exception")
5053
def rpc_exception(self):
5154
raise Exception("YEEEEEE!!!")
5255
@@ -59,6 +62,7 @@ Server example
5962
6063
6164
65+
6266
Client example
6367
--------------
6468

@@ -72,11 +76,11 @@ Client example
7276
client = ServerProxy("http://127.0.0.1:8080/", loop=loop)
7377
7478
async def main():
75-
print(await client.test())
79+
# 'nested.test' method call
80+
print(await client.nested.test())
7681
77-
# Or via __getitem__
78-
method = client['args']
79-
print(await method(1, 2, 3))
82+
# 'args' method call
83+
print(await client.args(1, 2, 3))
8084
8185
client.close()
8286

aiohttp_xmlrpc/handler.py

+3
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,16 @@ def __new__(cls, clsname, superclasses, attributedict):
4242
if not key.startswith(instance.METHOD_PREFIX):
4343
continue
4444

45+
# Get the value of the corresponding function
4546
value = getattr(instance, key)
4647

4748
method_name = getattr(value, "__xmlrpc_name__", None)
4849
if method_name is None:
4950
method_name = key.replace(instance.METHOD_PREFIX, "", 1)
5051

5152
allowed_methods[method_name] = key
53+
54+
# Add the arg mapping in all cases
5255
argmapping[method_name] = inspect.getfullargspec(value)
5356

5457
setattr(

examples/client.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77

88

99
async def main():
10-
print(await client.test())
10+
# 'nested.test' method call
11+
print(await client.nested.test())
1112

12-
# Or via __getitem__
13-
method = client['args']
14-
print(await method(1, 2, 3))
15-
16-
client.close()
13+
# 'args' method call
14+
print(await client.args(1, 2, 3))
1715

16+
await client.close()
1817

1918
if __name__ == "__main__":
2019
loop.run_until_complete(main())

examples/server.py

+4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from aiohttp import web
22
from aiohttp_xmlrpc import handler
3+
from aiohttp_xmlrpc.handler import rename
34

45

56
class XMLRPCExample(handler.XMLRPCView):
7+
8+
@rename("nested.test")
69
def rpc_test(self):
710
return None
811

@@ -15,6 +18,7 @@ def rpc_kwargs(self, **kwargs):
1518
def rpc_args_kwargs(self, *args, **kwargs):
1619
return len(args) + len(kwargs)
1720

21+
@rename("nested.exception")
1822
def rpc_exception(self):
1923
raise Exception("YEEEEEE!!!")
2024

tests/test_handler.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818

1919
class XMLRPCMain(handler.XMLRPCView):
20+
2021
def rpc_test(self):
2122
return None
2223

@@ -54,14 +55,19 @@ def rpc_dict_kw_only_args(self, d, *, foo, **kw):
5455
return (d, foo, kw)
5556

5657
@rename("method_with.new_name")
57-
def rpc_ranamed(self):
58+
def rpc_renamed(self):
5859
return "renamed_function"
5960

6061

6162
class XMLRPCChild(XMLRPCMain):
63+
6264
def rpc_child(self):
6365
return 42
6466

67+
@rename("child.test")
68+
def rpc_child_nested_method(self):
69+
return "My name has the nested format and I am in child class"
70+
6571

6672
def create_app(loop):
6773
app = web.Application()
@@ -224,3 +230,10 @@ async def test_13_kw_only_args(client):
224230
async def test_14_method_renaming(client):
225231
result = await client.method_with.new_name()
226232
assert result == "renamed_function"
233+
234+
235+
async def test_15_nested_method_in_child(aiohttp_xmlrpc_client):
236+
client = await aiohttp_xmlrpc_client(create_app, path="/clone")
237+
238+
result = await client.child.test()
239+
assert result == "My name has the nested format and I am in child class"

0 commit comments

Comments
 (0)