1
0

Initial public releases

* `bthlabs-jsonrpc-aiohttp` v1.0.0
* `bthlabs-jsonrpc-core` v1.0.0
* `bthlabs-jsonrpc-django` v1.0.0
This commit is contained in:
2022-06-04 10:41:53 +02:00
commit c75ea4ea9d
111 changed files with 7193 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# django-jsonrpc-aiohttp | (c) 2022-present Tomek Wójcik | MIT License
from .views import JSONRPCView # noqa
__version__ = '1.0.0'

View File

@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# django-jsonrpc-aiohttp | (c) 2022-present Tomek Wójcik | MIT License
import logging
from bthlabs_jsonrpc_core import Executor, JSONRPCAccessDeniedError
from bthlabs_jsonrpc_core.exceptions import JSONRPCParseError
LOGGER = logging.getLogger('bthlabs_jsonrpc.aiohttp.executor')
class AioHttpExecutor(Executor):
def __init__(self, request, can_call, namespace=None):
super().__init__(namespace=namespace)
self.request = request
self.can_call = can_call
async def list_methods(self, *args, **kwargs):
return super().list_methods()
async def deserialize_data(self, request):
try:
return await request.json()
except Exception as exception:
LOGGER.error('Error deserializing RPC call!', exc_info=exception)
raise JSONRPCParseError()
def enrich_args(self, args):
return [self.request, *super().enrich_args(args)]
async def before_call(self, method, args, kwargs):
can_call = await self.can_call(self.request, method, args, kwargs)
if can_call is False:
raise JSONRPCAccessDeniedError(data='can_call')
async def execute(self):
with self.execute_context() as execute_context:
data = await self.deserialize_data(self.request)
calls = self.get_calls(data)
for call in calls:
with self.call_context(execute_context, call) as call_context:
if call_context.is_valid is True:
await self.before_call(
call_context.method,
call_context.args,
call_context.kwargs,
)
call_context.result = await call_context.handler(
*call_context.args, **call_context.kwargs,
)
return execute_context.serializer

View File

@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# django-jsonrpc-aiohttp | (c) 2022-present Tomek Wójcik | MIT License
import typing
from aiohttp import web
from bthlabs_jsonrpc_aiohttp.executor import AioHttpExecutor
class JSONRPCView:
"""
The JSONRPC View. This is the main JSONRPC entry point. Use it to register
your JSONRPC endpoints.
Example:
.. code-block:: python
from bthlabs_jsonrpc_aiohttp import JSONRPCView
app.add_routes([
web.post('/rpc', JSONRPCView()),
web.post('/example/rpc', JSONRPCView(namespace='examnple')),
])
"""
# pragma mark - Public interface
def __init__(self, namespace: typing.Optional[str] = None):
self.namespace: typing.Optional[str] = namespace
async def can_call(self,
request: web.Request,
method: str,
args: list,
kwargs: dict) -> bool:
"""
Hook for subclasses to perform additional per-call permissions checks
etc. The default implementation returns ``True``.
"""
return True
async def __call__(self, request: web.Request) -> web.Response:
"""The request handler."""
executor = AioHttpExecutor(
request, self.can_call, namespace=self.namespace,
)
serializer = await executor.execute()
if serializer is None:
return web.Response(body='')
return web.json_response(serializer.data)