Skip to content

Commit

Permalink
ENH: Resource-based functions parsed in Interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jhuguetn committed Jan 26, 2024
1 parent e4e255a commit 75df908
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 49 deletions.
42 changes: 37 additions & 5 deletions pyxnat/core/interfaces.py
Expand Up @@ -4,11 +4,6 @@
import json
import requests

try:
import socks
except ImportError:
socks = None

from urllib.parse import urlparse

from .select import Select
Expand All @@ -21,11 +16,38 @@
from .array import ArrayData
from .xpath_store import XpathStore
from . import xpass
from . import derivatives


DEBUG = False
STUBBORN = False


# generic classes
def __get_modules__(m):
import pkgutil
modules = []
prefix = m.__name__ + '.'
for importer, modname, ispkg in pkgutil.iter_modules(m.__path__, prefix):
module = __import__(modname, fromlist='dummy')
if not ispkg:
modules.append(module)
else:
modules.extend(__get_modules__(module))
return modules


def __find_all_functions__(m):
import inspect
functions = {}
modules = __get_modules__(m)
for m in modules:
for name, obj in inspect.getmembers(m):
if inspect.isfunction(obj):
functions.setdefault(m, []).append(obj)
return functions


# main entry point
class Interface(object):
""" Main entry point to access an XNAT server.
Expand Down Expand Up @@ -174,6 +196,16 @@ def __init__(self, server=None, user=None, password=None, config=None,
self.manage = GlobalManager(self)
self.xpath = XpathStore(self)

functions = __find_all_functions__(derivatives)
d = {}
for m, mod_functions in functions.items():
if hasattr(m, 'XNAT_RESOURCE_NAME'):
d[m.XNAT_RESOURCE_NAME] = mod_functions
elif hasattr(m, 'XNAT_RESOURCE_NAMES'):
for each in m.XNAT_RESOURCE_NAMES:
d[each] = mod_functions
self._mod_functions = d

if _DRAW_GRAPHS:
self._get_graph = GraphData(self)
self.draw = PaintGraph(self)
Expand Down
65 changes: 21 additions & 44 deletions pyxnat/core/resources.py
Expand Up @@ -30,10 +30,7 @@
from . import schema
from . import httputil
from . import downloadutils
from . import derivatives
import types
import pkgutil
import inspect
from urllib.parse import quote, unquote

DEBUG = False
Expand Down Expand Up @@ -121,29 +118,6 @@ def __init__(cls, name, bases, dct):
super(CollectionType, cls).__init__(name, bases, dct)


# generic classes
def __get_modules__(m):
modules = []
prefix = m.__name__ + '.'
for importer, modname, ispkg in pkgutil.iter_modules(m.__path__, prefix):
module = __import__(modname, fromlist='dummy')
if not ispkg:
modules.append(module)
else:
modules.extend(__get_modules__(module))
return modules


def __find_all_functions__(m):
functions = {}
modules = __get_modules__(m)
for m in modules:
for name, obj in inspect.getmembers(m):
if inspect.isfunction(obj):
functions.setdefault(m, []).append(obj)
return functions


class EObject(object):
""" Generic Object for an element URI.
"""
Expand All @@ -165,20 +139,6 @@ def __init__(self, uri, interface):
self._intf = interface
self.attrs = EAttrs(self)

functions = __find_all_functions__(derivatives)

for m, mod_functions in functions.items():
is_resource = False
if (hasattr(m, 'XNAT_RESOURCE_NAME') and
self._urn == m.XNAT_RESOURCE_NAME) or \
(hasattr(m, 'XNAT_RESOURCE_NAMES') and
self._urn in m.XNAT_RESOURCE_NAMES):
is_resource = True

if is_resource:
for f in mod_functions:
setattr(self, f.__name__, types.MethodType(f, self))

def __getstate__(self):
return {'uri': self._uri,
'interface': self._intf}
Expand Down Expand Up @@ -1793,14 +1753,12 @@ def __repr__(self):
return output
else:
return '<%s Object> %s' % (self.__class__.__name__,
unquote(uri_last(self._uri))
)
unquote(uri_last(self._uri)))

def set_param(self, key, value):
self.attrs.set('%s/parameters/addParam[name=%s]/addField'
% (self.datatype(), key),
value
)
value)

def get_param(self, key):
return self.xpath(
Expand All @@ -1815,6 +1773,25 @@ def params(self):

class Resource(EObject, metaclass=ElementType):

def __init__(self, cbase, interface):
from pyxnat.core.errors import DatabaseError
super(Resource, self).__init__(cbase, interface)

mf = interface._mod_functions.get(self._urn, [])
if len(mf) == 0:
uri = uri_parent(self._uri)
try:
d = self._intf._get_json(uri)
r = [e for e in d if e['xnat_abstractresource_id'] == self._urn]
if len(r) == 1:
label = r[0]['label']
mf = interface._mod_functions.get(label, [])
except DatabaseError:
print('Warning:', self._uri, 'raising DatabaseError')

for f in mf:
setattr(self, f.__name__, types.MethodType(f, self))

def __repr__(self):

def sizeof_fmt(num, suffix='B'):
Expand Down

0 comments on commit 75df908

Please sign in to comment.