Skip to content

Commit

Permalink
working pitaya example, pip package published
Browse files Browse the repository at this point in the history
  • Loading branch information
felipejfc committed Mar 6, 2019
1 parent e28631b commit 8bc5722
Show file tree
Hide file tree
Showing 33 changed files with 405 additions and 174 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -15,6 +15,8 @@ csharp-example/csharp-example/bin
Assets/AssetStoreTools*
venv
out
dist
*.egg-info

NugetOutput/lib
NugetOutput/*.nupkg
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Expand Up @@ -60,9 +60,9 @@ protos-compile: submodules
@protoc --csharp_out=./csharp-example/csharp-example/gen/ ./go-server/protos/*.proto
@protoc --csharp_out=./unity-example/Assets/Gen/ ./go-server/protos/*.proto
@protoc --proto_path=pitaya-protos --csharp_out=./csharp-lib/cluster-lib/gen ./pitaya-protos/*.proto
@protoc --proto_path=pitaya-protos --python_out=./python-lib/gen ./pitaya-protos/*.proto
@protoc --proto_path=./go-server/protos --python_out=./python-lib/gen ./go-server/protos/cluster.proto
@sed -i '.old' 's/^\(import.*_pb2\)/from . \1/' ./python-lib/gen/*.py && rm ./python-lib/gen/*.old ## dirty python hack, see https://github.com/protocolbuffers/protobuf/issues/1491
@protoc --proto_path=pitaya-protos --python_out=./python-lib/pitayaserver/gen ./pitaya-protos/*.proto
@protoc --proto_path=./go-server/protos --python_out=./python-lib/pitayaserver/gen ./go-server/protos/cluster.proto
@sed -i '.old' 's/^\(import.*_pb2\)/from . \1/' ./python-lib/pitayaserver/gen/*.py && rm ./python-lib/pitayaserver/gen/*.old ## dirty python hack, see https://github.com/protocolbuffers/protobuf/issues/1491
@protoc --go_out=. ./go-server/protos/*.proto

start-deps:
Expand Down
9 changes: 9 additions & 0 deletions python-example/README.md
@@ -0,0 +1,9 @@
pitaya-example
==============

### dependencies
* python > 3.6

### Running
First install package dependencies with ```pip install -r requirements.txt```
Then run the example with ```python example.py```
Empty file added python-example/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions python-example/example.py
@@ -0,0 +1,45 @@
from uuid import uuid4
from time import sleep
import pitayaserver as pc
from gen import cluster_pb2 as cluster_pb
from example_remote import ExampleRemote


def send_test_rpc(route):
rpc_msg = cluster_pb.RPCMsg()
rpc_msg.Msg = "hello from python"
print("sending test rpc with route %s" % route)
ret = pc.send_rpc(route,
rpc_msg, cluster_pb.RPCRes)
print("got rpc res {}".format(ret))


def run():
sv_id = uuid4().hex
pc.initialize_pitaya(
pc.SdConfig(b'http://127.0.0.1:4001', b'pitaya/', 30,
True, True, True, 60, pc.LOGLEVEL_DEBUG),
pc.NatsConfig(b'127.0.0.1:4222', 5, 5000, 5, 100),
pc.Server(sv_id.encode('utf-8'), b'python',
b'{}', b'localhost', False),
)
print('successfully initialized pitaya!')

# wait for server to be registered
sleep(1)

# send a test RPC to connector
send_test_rpc("connector.testremote.test")

# register the example remote
r = ExampleRemote()
pc.register_remote(r, "exampleRemote", pc.default_name_func)

# send a test RPC to self
send_test_rpc("python.exampleRemote.testRemote")

input('Press enter to exit')
pc.shutdown()


run()
15 changes: 15 additions & 0 deletions python-example/example_remote.py
@@ -0,0 +1,15 @@
import pitayaserver as pc
from gen import cluster_pb2 as cluster_pb


class ExampleRemote(pc.BaseRemote):
""" example remote for testing purposes """

# a valid remote should receive 1 argument that subclasses message.Message
# and return a class that also subclasses message.Message

def TestRemote(self, msg: cluster_pb.RPCMsg) -> cluster_pb.RPCMsg:
invoke_res = cluster_pb.RPCRes()
invoke_res.Msg = "success! called testremote with msg: %s" % msg.Msg
invoke_res.Code = 200
return invoke_res
File renamed without changes.
1 change: 1 addition & 0 deletions python-example/libpitaya_cluster.dylib
1 change: 1 addition & 0 deletions python-example/libpitaya_cluster.so
4 changes: 4 additions & 0 deletions python-example/requirements.txt
@@ -0,0 +1,4 @@
pitayaserver==0.2.0
protobuf==3.7.0
six==1.12.0
uuid==1.30
13 changes: 13 additions & 0 deletions python-lib/README.md
@@ -0,0 +1,13 @@
python pitayaserver
====================

This lib helps creating pitaya backend servers using python.

### Installing

pip install pitayaserver

### Usage
For using the lib, you should assure that libpitaya-server compiled library is in the same path you are trying to run python, or specify it manually setting the env var PITAYA_LIB_DIR.

See python-example folder in root directory.
91 changes: 0 additions & 91 deletions python-lib/c_interop.py

This file was deleted.

40 changes: 0 additions & 40 deletions python-lib/example.py

This file was deleted.

6 changes: 6 additions & 0 deletions python-lib/pitayaserver/__init__.py
@@ -0,0 +1,6 @@
from .c_interop import *
from .remote import *
from .pitayaserver import *
from .route import *

name = "pitayaserver"
132 changes: 132 additions & 0 deletions python-lib/pitayaserver/c_interop.py
@@ -0,0 +1,132 @@
""" this module interops with the c dll"""
from ctypes import (c_char_p, c_int, c_longlong, c_void_p, cdll, Structure, POINTER,
c_bool, CFUNCTYPE)
import platform
import os
import sys

FREECB = CFUNCTYPE(None, c_void_p)


class SdConfig(Structure): # pylint: disable=too-few-public-methods
""" service discovery configuration class """
_fields_ = [
("endpoints", c_char_p),
("etcd_prefix", c_char_p),
("heartbeat_ttl_sec", c_int),
("log_heartbeat", c_int),
("log_server_sync", c_int),
("log_server_details", c_int),
("sync_servers_interval_sec", c_int),
("log_level", c_int)]


(LOGLEVEL_DEBUG, LOGLEVEL_INFO, LOGLEVEL_WARN, LOGLEVEL_ERROR,
LOGLEVEL_CRITICAL) = (0, 1, 2, 3, 4)


class NatsConfig(Structure): # pylint: disable=too-few-public-methods
""" nats configuration class """
_fields_ = [
("endpoint", c_char_p),
("connection_timeout_ms", c_longlong),
("request_timeout_ms", c_int),
("max_reconnection_attempts", c_int),
("max_pending_msgs", c_int)]


class Server(Structure): # pylint: disable=too-few-public-methods
""" server class """
_fields_ = [
("id", c_char_p),
("type", c_char_p),
("metadata", c_char_p),
("hostname", c_char_p),
("frontend", c_int)]


class PitayaError(Structure): # pylint: disable=too-few-public-methods
""" pitaya error class """
_fields_ = [
("code", c_char_p),
("msg", c_char_p)]


class MemoryBuffer(Structure): # pylint: disable=too-few-public-methods
""" memory buffer class, this is used to send pointer to data to and from c """
_fields_ = [
("data", c_void_p),
("size", c_int)]


class RPCReq(Structure): # pylint: disable=too-few-public-methods
""" rpc req class used in sendrpc and rpc cbs """
_fields_ = [
("buffer", MemoryBuffer),
("route", c_char_p)]


RPCCB = CFUNCTYPE(c_void_p, POINTER(RPCReq))


class Native(object):
__instance = None

class __impl:
def __init__(self):
lib_dir = os.environ.get('PITAYA_LIB_DIR')
if lib_dir == None:
system = platform.system()

if system == "Linux":
lib_dir = "libpitaya_cluster.so"
elif system == "Darwin":
lib_dir = "libpitaya_cluster.dylib"
elif system == "Windows":
lib_dir = "libpitaya_cluster.dll"

print (
"PITAYA_LIB_DIR env var not set, defaulting lib to %s, make sure it's in the current dir" % lib_dir)

""" Implementation of the singleton interface """

self.LIB = cdll.LoadLibrary(lib_dir)

self.LIB.tfg_pitc_Initialize.restype = c_bool
self.LIB.tfg_pitc_Initialize.argtypes = [POINTER(Server), POINTER(SdConfig), POINTER(NatsConfig),
RPCCB, FREECB, c_char_p]

self.LIB.tfg_pitc_GetServerById.restype = c_bool
self.LIB.tfg_pitc_GetServerById.argtypes = [
c_char_p, POINTER(Server)]

self.LIB.tfg_pitc_FreeServer.argtypes = [POINTER(Server)]

self.LIB.tfg_pitc_Terminate.restype = None

self.LIB.tfg_pitc_FreeMemoryBuffer.argtypes = [
POINTER(MemoryBuffer)]

self.LIB.tfg_pitc_FreePitayaError.argtypes = [POINTER(PitayaError)]

self.LIB.tfg_pitc_RPC.restype = c_bool
self.LIB.tfg_pitc_RPC.argtypes = [c_char_p, c_char_p, c_void_p, c_int,
POINTER(POINTER(MemoryBuffer)), POINTER(PitayaError)]

self.LIB.tfg_pitc_FreeMem.argtypes = [c_void_p]

self.LIB.tfg_pitc_AllocMem.restype = c_void_p
self.LIB.tfg_pitc_AllocMem.argtypes = [c_int]

def __init__(self):
if Native.__instance is None:
Native.__instance = Native.__impl()
self.__dict__['_Native__instance'] = Native.__instance

def __getattr__(self, attr):
""" Delegate access to implementation """
return getattr(self.__instance, attr)

def __setattr__(self, attr, value):
""" Delegate access to implementation """
return setattr(self.__instance, attr, value)
3 changes: 3 additions & 0 deletions python-lib/pitayaserver/gen/__init__.py
@@ -0,0 +1,3 @@
__all__ = ['bind_pb2', 'doc_pb2', 'docmsg_pb2', 'error_pb2',
'kick_pb2', 'msg_pb2', 'pitaya_pb2', 'protodescriptor_pb2',
'push_pb2', 'request_pb2', 'response_pb2', 'session_pb2']
File renamed without changes.

0 comments on commit 8bc5722

Please sign in to comment.