Commit 1319adc6 by Piotr Mitros

djobject preserves the full function definition

parent b67709a2
...@@ -2,15 +2,23 @@ ...@@ -2,15 +2,23 @@
etc. as Python objects. etc. as Python objects.
This is prototype-grade code. This is prototype-grade code.
It will remain ugly into production, however. I'm not sure if there is
a good way to make this clean, but the ugliness here will save a lot
of ugliness for the API caller.
''' '''
import requests import requests
import urllib import urllib
import json import json
import decorator
schema = None schema = None
def find_in_schema(cls = None, name = None): def find_in_schema(cls = None, name = None):
''' Search for a given class/name combo in schema. Return all
matching objects. Either can be passed alone.
'''
items = [] items = []
for item in schema: for item in schema:
if cls and item['class'] != cls: if cls and item['class'] != cls:
...@@ -21,6 +29,8 @@ def find_in_schema(cls = None, name = None): ...@@ -21,6 +29,8 @@ def find_in_schema(cls = None, name = None):
return items return items
def http_rpc_helper(baseurl, view_or_query, function, headers = {}): def http_rpc_helper(baseurl, view_or_query, function, headers = {}):
''' Make an RPC call to a remote djanalytics instance
'''
if baseurl: if baseurl:
baseembedurl = baseurl+view_or_query+"/" baseembedurl = baseurl+view_or_query+"/"
...@@ -28,7 +38,6 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}): ...@@ -28,7 +38,6 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}):
url = urllib.basejoin(baseembedurl, function) url = urllib.basejoin(baseembedurl, function)
if kwargs: if kwargs:
url = url+"?"+urllib.urlencode(kwargs) url = url+"?"+urllib.urlencode(kwargs)
print url
response = requests.get(url, headers = headers) response = requests.get(url, headers = headers)
if response.status_code == 200: if response.status_code == 200:
return response.content return response.content
...@@ -36,10 +45,11 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}): ...@@ -36,10 +45,11 @@ def http_rpc_helper(baseurl, view_or_query, function, headers = {}):
raise AttributeError(function) raise AttributeError(function)
error = "Error calling {func} {status}".format(func=function, status=response.status_code) error = "Error calling {func} {status}".format(func=function, status=response.status_code)
raise Exception(error) raise Exception(error)
rpc_call.__doc__ = find_in_schema(cls = view_or_query, name = function)[0]['doc']
return rpc_call return rpc_call
def local_call_helper(view_or_query, function): def local_call_helper(view_or_query, function):
''' Make a call (functionally identical to RPC) to the local djanalytics instance
'''
import djanalytics.core.views import djanalytics.core.views
def rpc_call(**kwargs): def rpc_call(**kwargs):
return djanalytics.core.views.handle_request(view_or_query, function, **kwargs) return djanalytics.core.views.handle_request(view_or_query, function, **kwargs)
...@@ -68,22 +78,42 @@ class embed(): ...@@ -68,22 +78,42 @@ class embed():
## and similar overwritten ## and similar overwritten
if attr[0] == '_': if attr[0] == '_':
return return
# Return a caller to the function
if self._baseurl: if self._baseurl:
helper = http_rpc_helper(self._baseurl, self._view_or_query, attr) helper = http_rpc_helper(self._baseurl, self._view_or_query, attr)
else: else:
helper = local_call_helper(self._view_or_query, attr) helper = local_call_helper(self._view_or_query, attr)
# Modified the function to have the proper function spec.
# The internals of decorator.FunctionMaker make me sick.
try:
rpcspec = find_in_schema(cls = self._view_or_query, name = attr)[0]
except IndexError:
raise AttributeError(function)
category = rpcspec['category']
# Set the docstring def_params = category.replace('+',',') # Is this still needed?
helper.__doc__ = find_in_schema(cls = self._view_or_query, name = attr)[0]['doc'] if def_params:
helper.__name__ = "remote_"+attr call_params = ",".join(["{p}={p}".format(p=p) for p in category.split('+')])
return helper else:
call_params = ""
funcspec = "{name}({params})".format(name='rpc_'+attr,
params=def_params)
callspec = "return helper({params})".format(params=call_params)
return decorator.FunctionMaker.create(funcspec,
callspec,
{'helper':helper},
doc = rpcspec['doc'])
## TODO: Use probe/schema to populate this
def __dir__(self): def __dir__(self):
''' Allow tab completion on function names in ipython, and
other sorts of introspection. '''
self._refresh_schema() self._refresh_schema()
return [i["name"] for i in find_in_schema(cls = self._view_or_query)] return [i["name"] for i in find_in_schema(cls = self._view_or_query)]
def __repr__(self): def __repr__(self):
''' Pretty representation of the object. '''
return self._view_or_query+" object host: ["+self._baseurl+"]" return self._view_or_query+" object host: ["+self._baseurl+"]"
class djobject(): class djobject():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment