Module jumpscale.servers.gedis_http
Expand source code
import json
from jumpscale.core.base import Base, fields
from jumpscale.loader import j
from gevent.pool import Pool
from bottle import Bottle, abort, request, response
from jumpscale.servers.gedis.server import GedisErrorTypes
from gevent.pywsgi import WSGIServer
from jumpscale.core.base import StoredFactory
class GedisHTTPServer(Base):
host = fields.String(default="127.0.0.1")
port = fields.Integer(default=8000)
allow_cors = fields.Boolean(default=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._app = Bottle()
self._client = None
http_methods = ["GET", "POST"]
if self.allow_cors:
http_methods.extend(["OPTIONS", "PUT", "DELETE"])
self._app.route("/<package>/<actor>/<method>", http_methods, self.enable_cors(self.handler, self.allow_cors))
@property
def client(self):
if self._client is None:
self._client = j.clients.gedis.get(self.instance_name)
self._client.disable_deserialization = True
return self._client
def make_response(self, code, content):
response.status = code
response.content_type = "application/json"
return json.dumps(content)
def enable_cors(self, fn, allow_cors=True):
def _enable_cors(*args, **kwargs):
# set CORS headers
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS, DELETE"
response.headers[
"Access-Control-Allow-Headers"
] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token"
if request.method != "OPTIONS":
# actual request; reply with the actual response
return fn(*args, **kwargs)
if allow_cors:
return _enable_cors
else:
return fn
def handler(self, package, actor, method):
actors = self.client.actors
actor = getattr(actors, f"{package}_{actor}", None)
if not actor:
return self.make_response(400, {"error": "actor not found"})
method = getattr(actor, method, None)
if not method:
return self.make_response(400, {"error": "method not found"})
kwargs = request.json or dict()
response = method(**kwargs)
if not response.success:
if response.error_type == GedisErrorTypes.NOT_FOUND:
return self.make_response(404, {"error": response.error})
elif response.error_type == GedisErrorTypes.BAD_REQUEST:
return self.make_response(400, {"error": response.error})
elif response.error_type == GedisErrorTypes.PERMISSION_ERROR:
return self.make_response(403, {"error": response.error})
else:
return self.make_response(500, {"error": response.error})
return self.make_response(200, response.result)
@property
def gevent_server(self):
return WSGIServer((self.host, self.port), self._app, spawn=Pool())
def export_module_as():
return StoredFactory(GedisHTTPServer)
Functions
def export_module_as()
-
Expand source code
def export_module_as(): return StoredFactory(GedisHTTPServer)
Classes
class GedisHTTPServer (*args, **kwargs)
-
A simple attribute-based namespace.
SimpleNamespace(**kwargs)
base class implementation for any class with fields which supports getting/setting raw data for any instance fields.
any instance can have an optional name and a parent.
class Person(Base): name = fields.String() age = fields.Float() p = Person(name="ahmed", age="19") print(p.name, p.age)
Args
parent_
:Base
, optional- parent instance. Defaults to None.
instance_name_
:str
, optional- instance name. Defaults to None.
**values
- any given field values to initiate the instance with
Expand source code
class GedisHTTPServer(Base): host = fields.String(default="127.0.0.1") port = fields.Integer(default=8000) allow_cors = fields.Boolean(default=True) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._app = Bottle() self._client = None http_methods = ["GET", "POST"] if self.allow_cors: http_methods.extend(["OPTIONS", "PUT", "DELETE"]) self._app.route("/<package>/<actor>/<method>", http_methods, self.enable_cors(self.handler, self.allow_cors)) @property def client(self): if self._client is None: self._client = j.clients.gedis.get(self.instance_name) self._client.disable_deserialization = True return self._client def make_response(self, code, content): response.status = code response.content_type = "application/json" return json.dumps(content) def enable_cors(self, fn, allow_cors=True): def _enable_cors(*args, **kwargs): # set CORS headers response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS, DELETE" response.headers[ "Access-Control-Allow-Headers" ] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token" if request.method != "OPTIONS": # actual request; reply with the actual response return fn(*args, **kwargs) if allow_cors: return _enable_cors else: return fn def handler(self, package, actor, method): actors = self.client.actors actor = getattr(actors, f"{package}_{actor}", None) if not actor: return self.make_response(400, {"error": "actor not found"}) method = getattr(actor, method, None) if not method: return self.make_response(400, {"error": "method not found"}) kwargs = request.json or dict() response = method(**kwargs) if not response.success: if response.error_type == GedisErrorTypes.NOT_FOUND: return self.make_response(404, {"error": response.error}) elif response.error_type == GedisErrorTypes.BAD_REQUEST: return self.make_response(400, {"error": response.error}) elif response.error_type == GedisErrorTypes.PERMISSION_ERROR: return self.make_response(403, {"error": response.error}) else: return self.make_response(500, {"error": response.error}) return self.make_response(200, response.result) @property def gevent_server(self): return WSGIServer((self.host, self.port), self._app, spawn=Pool())
Ancestors
- Base
- types.SimpleNamespace
Instance variables
var allow_cors
-
getter method this property
will call
_get_value
, which would if the value is already defined and will get the default value if notReturns
any
- the field value
Expand source code
def getter(self): """ getter method this property will call `_get_value`, which would if the value is already defined and will get the default value if not Returns: any: the field value """ return self._get_value(name, field)
var client
-
Expand source code
@property def client(self): if self._client is None: self._client = j.clients.gedis.get(self.instance_name) self._client.disable_deserialization = True return self._client
var gevent_server
-
Expand source code
@property def gevent_server(self): return WSGIServer((self.host, self.port), self._app, spawn=Pool())
var host
-
getter method this property
will call
_get_value
, which would if the value is already defined and will get the default value if notReturns
any
- the field value
Expand source code
def getter(self): """ getter method this property will call `_get_value`, which would if the value is already defined and will get the default value if not Returns: any: the field value """ return self._get_value(name, field)
var port
-
getter method this property
will call
_get_value
, which would if the value is already defined and will get the default value if notReturns
any
- the field value
Expand source code
def getter(self): """ getter method this property will call `_get_value`, which would if the value is already defined and will get the default value if not Returns: any: the field value """ return self._get_value(name, field)
Methods
def enable_cors(self, fn, allow_cors=True)
-
Expand source code
def enable_cors(self, fn, allow_cors=True): def _enable_cors(*args, **kwargs): # set CORS headers response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, OPTIONS, DELETE" response.headers[ "Access-Control-Allow-Headers" ] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token" if request.method != "OPTIONS": # actual request; reply with the actual response return fn(*args, **kwargs) if allow_cors: return _enable_cors else: return fn
def handler(self, package, actor, method)
-
Expand source code
def handler(self, package, actor, method): actors = self.client.actors actor = getattr(actors, f"{package}_{actor}", None) if not actor: return self.make_response(400, {"error": "actor not found"}) method = getattr(actor, method, None) if not method: return self.make_response(400, {"error": "method not found"}) kwargs = request.json or dict() response = method(**kwargs) if not response.success: if response.error_type == GedisErrorTypes.NOT_FOUND: return self.make_response(404, {"error": response.error}) elif response.error_type == GedisErrorTypes.BAD_REQUEST: return self.make_response(400, {"error": response.error}) elif response.error_type == GedisErrorTypes.PERMISSION_ERROR: return self.make_response(403, {"error": response.error}) else: return self.make_response(500, {"error": response.error}) return self.make_response(200, response.result)
def make_response(self, code, content)
-
Expand source code
def make_response(self, code, content): response.status = code response.content_type = "application/json" return json.dumps(content)
Inherited members