Skip to content

Commit

Permalink
Merge pull request #65 from unum-cloud/main-dev
Browse files Browse the repository at this point in the history
Safer UX for Python users
  • Loading branch information
ashvardanian authored May 19, 2023
2 parents 7663cf3 + 83cabd1 commit 1c41417
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 28 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"endregion",
"fastapi",
"iovecs",
"ndarray",
"numpy",
"posix",
"SIMD",
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ if(LINUX)
target_include_directories(py_ucall_uring PUBLIC src/ include/)
target_link_libraries(py_ucall_uring PRIVATE ucall_server_uring base64)
set_target_properties(py_ucall_uring PROPERTIES OUTPUT_NAME uring)
target_compile_definitions(py_ucall_uring PRIVATE UKV_PYTHON_MODULE_NAME=uring)
target_compile_definitions(py_ucall_uring PRIVATE UCALL_PYTHON_MODULE_NAME=uring)
endif()

Python3_add_library(py_ucall_posix src/python.c)
target_include_directories(py_ucall_posix PUBLIC src/ include/)
target_link_libraries(py_ucall_posix PRIVATE ucall_server_posix base64)
set_target_properties(py_ucall_posix PROPERTIES OUTPUT_NAME posix)
target_compile_definitions(py_ucall_posix PRIVATE UKV_PYTHON_MODULE_NAME=posix)
target_compile_definitions(py_ucall_posix PRIVATE UCALL_PYTHON_MODULE_NAME=posix)
2 changes: 1 addition & 1 deletion include/ucall/ucall.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @date Feb 3, 2023
* @addtogroup C
*
* @brief Binary Interface for Uninterrupted JSON RPC.
* @brief Binary Interface for UCall.
*
* ## Basic Usage
*
Expand Down
10 changes: 5 additions & 5 deletions src/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define stringify_m(a) #a
#define concat_m(A, B) A##B
#define macro_concat_m(A, B) concat_m(A, B)
#define pyinit_f_m macro_concat_m(PyInit_, UKV_PYTHON_MODULE_NAME)
#define pyinit_f_m macro_concat_m(PyInit_, UCALL_PYTHON_MODULE_NAME)

#define get_attr_safe_m(name, obj, attr) \
PyObject* name = PyObject_GetAttrString(obj, attr); \
Expand Down Expand Up @@ -463,7 +463,7 @@ static int server_init(py_server_t* self, PyObject* args, PyObject* keywords) {

// Order: https://docs.python.org/3/c-api/typeobj.html#quick-reference
static PyTypeObject ucall_type = {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "ucall." stringify_value_m(UKV_PYTHON_MODULE_NAME) ".Server",
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME) ".Server",
.tp_basicsize = sizeof(py_server_t),
.tp_itemsize = 0,
.tp_dealloc = (destructor)server_dealloc,
Expand All @@ -482,7 +482,7 @@ static PyTypeObject ucall_type = {

static PyModuleDef server_module = {
PyModuleDef_HEAD_INIT,
.m_name = "ucall." stringify_value_m(UKV_PYTHON_MODULE_NAME),
.m_name = "ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME),
.m_doc = "Uninterrupted JSON Remote Procedure Calls library.",
.m_size = -1,
};
Expand Down Expand Up @@ -513,7 +513,7 @@ int main(int argc, char* argv[]) {
}

/* Add a built-in module, before Py_Initialize */
if (PyImport_AppendInittab("ucall." stringify_value_m(UKV_PYTHON_MODULE_NAME), pyinit_f_m) == -1) {
if (PyImport_AppendInittab("ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME), pyinit_f_m) == -1) {
fprintf(stderr, "Error: could not extend in-built modules table\n");
exit(1);
}
Expand All @@ -528,7 +528,7 @@ int main(int argc, char* argv[]) {
/* Optionally import the module; alternatively,
import can be deferred until the embedded script
imports it. */
PyObject* pmodule = PyImport_ImportModule("ucall." stringify_value_m(UKV_PYTHON_MODULE_NAME));
PyObject* pmodule = PyImport_ImportModule("ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME));
if (!pmodule) {
PyErr_Print();
fprintf(stderr, "Error: could not import module 'ucall'\n");
Expand Down
17 changes: 10 additions & 7 deletions src/ucall/_server.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import numpy as np
from PIL import Image
from typing import Callable, get_type_hints
import inspect
from typing import Callable, get_type_hints
from functools import wraps
from io import BytesIO

import numpy as np
from PIL import Image


class _Server:
server = None

def __init__(self) -> None:
self.server = None

def __call__(self, func: Callable):
return self.route(func)

def run(self, max_cycles: int = -1, max_seconds: float = -1):
return self.server.run(max_cycles, max_seconds)

def unpack(self, arg: bytes, hint):
def unpack(self, arg: bytes, hint: type):
if hint == bytes or hint == bytearray:
return arg

Expand All @@ -36,8 +39,7 @@ def pack(self, res):
buf = BytesIO()
if not res.format:
res.format = 'tiff'
res.save(buf, res.format, compression='raw',
compression_level=0)
res.save(buf, res.format, compression='raw', compression_level=0)

return buf.getvalue()

Expand All @@ -52,6 +54,7 @@ def wrapper(*args, **kwargs):
new_kwargs = {}

for arg, hint in zip(args, hints.values()):
assert isinstance(hint, type), 'Hint must be a type!'
if isinstance(arg, bytes):
new_args.append(self.unpack(arg, hint))
else:
Expand Down
19 changes: 10 additions & 9 deletions src/ucall/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,23 @@ def cli():

def get_parser():
parser = argparse.ArgumentParser(description='UCall Client CLI')
parser.add_argument('method', type=str, help='method name')
parser.add_argument('method', type=str, help='Method name')

parser.add_argument('--uri', type=str,
help='Server uri', default='localhost')
parser.add_argument('-p', '--port', type=int,
help='Server port', default=8545)
parser.add_argument('--uri', type=str, default='localhost',
help='Server URI')
parser.add_argument('-p', '--port', type=int, default=8545,
help='Server port')

parser.add_argument('kwargs', nargs='*', help='KEY[:TYPE]=VALUE arguments')
parser.add_argument('-f', '--file', nargs='*', help='Binary Files')
parser.add_argument('-i', '--image', nargs='*', help='Image Files')
parser.add_argument('-f', '--file', nargs='*', help='Binary files')
parser.add_argument('-i', '--image', nargs='*', help='Image files')

parser.add_argument('--positional', nargs='*',
help='Switch to positional arguments VALUE[:TYPE]')

parser.add_argument('--format', type=str, choices=[
'json', 'bytes', 'numpy', 'image', 'raw'], help='How to parse response', default='raw')
parser.add_argument('--format', type=str,
choices=['json', 'bytes', 'numpy', 'image', 'raw'], default='raw',
help='How to parse and format the response')
return parser


Expand Down
10 changes: 6 additions & 4 deletions src/ucall/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from PIL import Image


def _recvall(sock, buffer_size=4096):
def _receive_all(sock, buffer_size=4096):
header = sock.recv(4)
body = None
content_len = -1
Expand Down Expand Up @@ -174,7 +174,7 @@ def _send(self, json_data: dict):
self.sock.send(request.encode())

def _recv(self) -> Response:
response_bytes = _recvall(self.sock)
response_bytes = _receive_all(self.sock)
response = json.loads(response_bytes)
return Response(response)

Expand All @@ -184,8 +184,10 @@ def __call__(self, jsonrpc: object) -> Response:


class ClientTLS(Client):
def __init__(self, uri: str = '127.0.0.1', port: int = 8545,
ssl_context: ssl.SSLContext = None, allow_self_signed=False, enable_session_resumption=True) -> None:
def __init__(
self, uri: str = '127.0.0.1', port: int = 8545, ssl_context: ssl.SSLContext = None,
allow_self_signed: bool = False, enable_session_resumption: bool = True) -> None:

super().__init__(uri, port, use_http=True)

if ssl_context is None:
Expand Down

0 comments on commit 1c41417

Please sign in to comment.