So far we have a very lightweight server running with aiohttp.
Routes are added via the decorators async_get and async_post
For beards these are implemented in a routes registering method very similar to how __commands__ works. This works as follows:
The user defines a __routes__ in their chat handler class which looks like
__routes__ = [(endpoint, coro, http_method)]
eg.
__routes__ = [('/testPoint', my_coro, 'post')]
The Beard class then loops over these when __new__ is called, and registers a function that wraps the chat handler's coro using the corresponding get or post decorator.
This is simple and works, however, a lot of there is a lot of "manual work" that has to be done for each coroutine that is used to handle an route. For instance, a simple function that echoes back the client's json data looks like so:
from skybeard.server import web
async def test_post(request):
data = await request.json()
return web.json_response(data)
and, for key authentication one has to do, for instance:
from skybeard.server import web
from skybeard.api.database import is_key_match
async def test_post(request):
data = await request.json()
if not is_key_match(data['key'])
return web.json_response({'status': 'ERROR: Not authenticated'})
return web.json_response(data)
auth
Being able to decorate those which require an auth token would be really useful.
For this to be the case, we could move the key into the url, as it used to be. Then a decorator can
add a regex match to the route registration step for, e.g. /key[A-z]+/myEndPoint.
Additionally, with this technique we can register the handler with a beard name prefix to the route, e.g,
/key[A-z]/myBeardName/myEndPoint. This will ensure there are no conflicts, as uniqueness of beard names is enforced anyway.
database
Making some helpers for using the beardDBtable with these handlers would also be a bonus. Possibly with search functions, for instance date ranges. The client can then include start, end in the json payload and a search utility is able to parse these into a query for the beardDB.
Telegram proxy
Sending messages, or calling any other method of the telegram bot api is relatively easy with BeardChatHandler.key. However, it would be good to have a method generator, like the one that was being implemented with sanic, that would allow users to do such things as:
telegramAPI.request(method, **params)
where method is taken from the skybeard query url (e.g /relay/sendMessage) and the key parameter is automatically filled from BeardChatHandler.key. Being able to use skybeard (telepots) telegram methods directly would be great... but that brings me to the next point:
BeardChatHandler instances
This might be more trouble than it is worth, but it would be nice to be able to have handlers called in BeardChatHandler instances. The issue is, they destruct after a time out is reached, there is one per chat_id, it will have to be decorated in some way to allow self to be passed, etc.
Beyond the decorating, one solution that may be possible is that, when accessing these via the web API, it could spawn an instance with a fake msg object generated from the payload parameters, and the payload parameters included under the data key in msg The one required parameter in the API call (apart from the auth token) would be chat_id.
For example:
The client would send the request,
url/key<key>/myEndPoint
with the json,
{"chat_id": 12345, "my_parameter": "Hello world!"}
where sender is faked from the chat_id parameter in the json. The others that cannot be auto-generated (user name, id, etc) can be included optionally if needed for the method.
I'll write more in comments when thing's progress ...
Current Status:
aiohttp
.async_get
andasync_post
__commands__
works. This works as follows:__routes__
in their chat handler class which looks like__routes__ = [(endpoint, coro, http_method)]
eg.__routes__ = [('/testPoint', my_coro, 'post')]
Beard
class then loops over these when__new__
is called, and registers a function that wraps the chat handler's coro using the corresponding get or post decorator.and, for key authentication one has to do, for instance:
auth Being able to decorate those which require an auth token would be really useful. For this to be the case, we could move the key into the url, as it used to be. Then a decorator can add a regex match to the route registration step for, e.g.
/key[A-z]+/myEndPoint
. Additionally, with this technique we can register the handler with a beard name prefix to the route, e.g,/key[A-z]/myBeardName/myEndPoint
. This will ensure there are no conflicts, as uniqueness of beard names is enforced anyway.database Making some helpers for using the beardDBtable with these handlers would also be a bonus. Possibly with search functions, for instance date ranges. The client can then include
start
,end
in the json payload and a search utility is able to parse these into a query for the beardDB.Telegram proxy Sending messages, or calling any other method of the telegram bot api is relatively easy with
BeardChatHandler.key
. However, it would be good to have a method generator, like the one that was being implemented with sanic, that would allow users to do such things as:telegramAPI.request(method, **params)
where method is taken from the skybeard query url (e.g/relay/sendMessage
) and the key parameter is automatically filled from BeardChatHandler.key. Being able to use skybeard (telepots) telegram methods directly would be great... but that brings me to the next point:BeardChatHandler instances This might be more trouble than it is worth, but it would be nice to be able to have handlers called in BeardChatHandler instances. The issue is, they destruct after a time out is reached, there is one per chat_id, it will have to be decorated in some way to allow
self
to be passed, etc.Beyond the decorating, one solution that may be possible is that, when accessing these via the web API, it could spawn an instance with a fake
msg
object generated from the payload parameters, and the payload parameters included under thedata
key inmsg
The one required parameter in the API call (apart from the auth token) would be chat_id.For example: The client would send the request,
url/key<key>/myEndPoint
with the json,{"chat_id": 12345, "my_parameter": "Hello world!"}
The code in the beard would look something like:
where sender is faked from the
chat_id
parameter in the json. The others that cannot be auto-generated (user name, id, etc) can be included optionally if needed for the method.I'll write more in comments when thing's progress ...