示例#1
0
def metadata(id=None, dn=None):
    api_version, root_url, root = get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addMetadata(request.data, dn=dn)
        id = r['uid']
        morer = rdb.getRecord('metadata', {'uid': id}, dn=dn)
        publishEvent('mpo_metadata', onlyone(morer))
    elif request.method == 'GET':
        #Add logic to parse id if comma separated
        if id:
            ids = id.strip().split(',')
            r = {}
            for id in ids:
                rs = rdb.getRecord('metadata', {'uid': id}, dn=dn)
                if len(rs) == 1:
                    r[id] = rs[0]  #unpack single element list
                else:
                    r[id] = [
                    ]  #{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}
            if len(ids) == 1:  #return just single record if one uid
                r = rs
            else:
                r = r
        else:
            r = rdb.getRecord('metadata', request.args, dn=dn)

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json')
示例#2
0
def ontologyInstance(id=None, dn=None):
    api_version,root_url,root=get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addOntologyInstance(request.data,dn=dn)
    elif request.method == 'PUT':
        r = rdb.modifyOntologyInstance(request.data,dn=dn)
    elif request.method == 'GET':
        if id:
            r = rdb.getRecord('ontology_instances', {'uid':id}, dn=dn )
        else:
            p_uids=request.args.get('parent_uid')
            if p_uids:
                p_uids=p_uids.strip().split(',')

                r={}
                rargs=request.args.to_dict() #multidict conversion to dict
                for pid in p_uids:
                    rargs['parent_uid']=pid
                    rs = rdb.getRecord('ontology_instances', rargs, dn=dn )

                    r[pid]=rs #element list, can have multiple instances

                if len(p_uids)==1: #return just single record if one uid
                    r=rs
            else:
                r = rdb.getRecord('ontology_instances', request.args, dn=dn )

    return Response(json.dumps(r,cls=MPOSetEncoder), mimetype='application/json')
示例#3
0
def collection(id=None,dn=None):
    """
    Create and add to collections.
    Supported routes:
    /collection - GET a list of all (or filtered) collections
                - POST a new collection
    /collection/<id> - GET collection information, including list of member UUIDs
                     - DELETE a collection and the associated elements
    /collection/?element_uid=:uid - GET collections having element member giving by :uid
    """
    api_version,root_url,root=get_api_version(request.url)
    if request.method == 'POST':
        print('api post collection',request.data)
        r = rdb.addCollection(request.data,dn=dn)
        morer = rdb.getRecord('collection',{'uid':r['uid']},dn=dn)
        publishEvent('mpo_collection',onlyone(morer))
    elif request.method == 'GET':
        if id:
            r = rdb.getRecord('collection',{'uid':id}, dn=dn)
        else:
            #particular cases
            #?element_uid
            if 'element_uid' in request.args:
                r = rdb.getRecord('collection_elements',{'uid':request.args['element_uid']}, dn=dn)
            #general searches
            else:
                r = rdb.getRecord('collection',request.args, dn=dn)
    elif request.method == 'DELETE':
        if id:
            r = rdb.deleteCollection({'uid':id}, dn=dn )
        else:
            r=[]

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=200)
示例#4
0
def ontologyInstance(id=None, dn=None):
    api_version, root_url, root = get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addOntologyInstance(request.data, dn=dn)
    elif request.method == 'PUT':
        r = rdb.modifyOntologyInstance(request.data, dn=dn)
    elif request.method == 'GET':
        if id:
            r = rdb.getRecord('ontology_instances', {'uid': id}, dn=dn)
        else:
            p_uids = request.args.get('parent_uid')
            if p_uids:
                p_uids = p_uids.strip().split(',')

                r = {}
                rargs = request.args.to_dict()  #multidict conversion to dict
                for pid in p_uids:
                    rargs['parent_uid'] = pid
                    rs = rdb.getRecord('ontology_instances', rargs, dn=dn)

                    r[pid] = rs  #element list, can have multiple instances

                if len(p_uids) == 1:  #return just single record if one uid
                    r = rs
            else:
                r = rdb.getRecord('ontology_instances', request.args, dn=dn)

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json')
示例#5
0
def getWorkflowElement(wid, uid=None, dn=None):
    """
     /workflow/:wid/dataobject/:uid - GET dataobjects in workflow specified by :wid
                                      if :uid supplied, get specific dataobject
    """
    api_version, root_url, root = get_api_version(request.url)

    if uid:
        records = rdb.getRecord('dataobject_instance', {
            'work_uid': wid,
            'uid': uid
        },
                                dn=dn)
    else:
        records = rdb.getRecord('dataobject_instance', {'work_uid': wid},
                                dn=dn)

    for rr in records:
        do_uid = rr['do_uid']
        rr['do_info'] = rdb.getRecord('dataobject', {'uid': do_uid}, dn=dn)[0]

    r = {
        'result': records,
        'count': len(records),
        'link-requested': request.url,
        'status': 'ok'
    }

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=200)
示例#6
0
def activity(id=None, dn=None):
    istatus=200

    api_version,root_url,root=get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addRecord('activity',request.data,dn=dn)
        id = r['uid']
        morer = rdb.getRecord('activity',{'uid':id},dn=dn)
        publishEvent('mpo_activity',onlyone(morer))
    elif request.method == 'GET':
        if id:
            ids=id.strip().split(',')
            r={}
            for id in ids:
                rs = rdb.getRecord('activity',{'uid':id},dn=dn)
                if rs:
                    r[id]=rs
                else:
                    r[id]=[]#{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}

            if len(ids)==1: #return just single record if one uid
                r=rs

        else:
            r = rdb.getRecord('activity',request.args,dn=dn)


    #if r='[]', later set metadata with number of records
    if len(r) == 2 :
        istatus=404

    return Response(json.dumps(r,cls=MPOSetEncoder), mimetype='application/json',status=istatus)
示例#7
0
def ontologyTerm(id=None, dn=None):
    '''
    Retrieves the record of an ontology term from its <id> or path.
    valid routes:
    ontology/term/<id>
    ontology/term?path=term/term2/termN
    '''
    api_version,root_url,root=get_api_version(request.url)

    if request.method == 'POST':
        objs = json.loads(request.data)
        #allow for ontology terms with null parents
        if not objs.has_key('parent_uid'): objs['parent_uid']=None

        # make sure the term doesn't exist already
        vocab = rdb.getRecord('ontology_terms', {'parent_uid':objs['parent_uid']}, dn=dn )
        for x in vocab:
            if objs['name'] == x['name']:
                return Response(json.dumps({'uid':x['uid']}),mimetype='application/json')

        r = rdb.addRecord('ontology_terms',json.dumps(objs),dn=dn)
    elif request.method == 'DELETE':
        if id:
            r = rdb.deleteOntologyTerms({'uid':id}, dn=dn )
        else:
            r = rdb.deleteOntologyTerms(request.args, dn=dn )
    else:
        if id:
            r = rdb.getRecord('ontology_terms', {'uid':id}, dn=dn )
        else:
            r = rdb.getRecord('ontology_terms', request.args, dn=dn )

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=200)
示例#8
0
def metadata(id=None, dn=None):
    api_version,root_url,root=get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addMetadata( request.data, dn=dn)
        id = r['uid']
        morer = rdb.getRecord('metadata',{'uid':id},dn=dn)
        publishEvent('mpo_metadata',onlyone(morer))
    elif request.method == 'GET':
        #Add logic to parse id if comma separated
        if id:
            ids=id.strip().split(',')
            r={}
            for id in ids:
                rs = rdb.getRecord('metadata',{'uid':id},dn=dn)
                if len(rs)==1:
                    r[id]=rs[0] #unpack single element list
                else:
                    r[id]=[]#{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}
            if len(ids)==1: #return just single record if one uid
                r=rs
            else:
                r=r
        else:
            r = rdb.getRecord('metadata',request.args,dn=dn)

    return Response(json.dumps(r,cls=MPOSetEncoder), mimetype='application/json')
示例#9
0
def activity(id=None, dn=None):
    istatus = 200

    api_version, root_url, root = get_api_version(request.url)

    if request.method == 'POST':
        r = rdb.addRecord('activity', request.data, dn=dn)
        id = r['uid']
        morer = rdb.getRecord('activity', {'uid': id}, dn=dn)
        publishEvent('mpo_activity', onlyone(morer))
    elif request.method == 'GET':
        if id:
            ids = id.strip().split(',')
            r = {}
            for id in ids:
                rs = rdb.getRecord('activity', {'uid': id}, dn=dn)
                if rs:
                    r[id] = rs
                else:
                    r[id] = [
                    ]  #{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}

            if len(ids) == 1:  #return just single record if one uid
                r = rs

        else:
            r = rdb.getRecord('activity', request.args, dn=dn)

    #if r='[]', later set metadata with number of records
    if len(r) == 2:
        istatus = 404

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=istatus)
示例#10
0
def getWorkflowElement(wid,uid=None,dn=None):
    """
     /workflow/:wid/dataobject/:uid - GET dataobjects in workflow specified by :wid
                                      if :uid supplied, get specific dataobject
    """
    api_version,root_url,root=get_api_version(request.url)

    if uid:
        records = rdb.getRecord('dataobject_instance',{'work_uid':wid,'uid':uid}, dn=dn )
    else:
        records = rdb.getRecord('dataobject_instance',{'work_uid':wid}, dn=dn )

    for rr in records:
        do_uid=rr['do_uid']
        rr['do_info']=rdb.getRecord('dataobject',{'uid':do_uid}, dn=dn )[0]


    r={'result':records,'count':len(records),'link-requested':request.url, 'status':'ok'}

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=200)
示例#11
0
def comment(id=None, dn=None):
    api_version, root_url, root = get_api_version(request.url)

    if request.method == 'POST':
        req = json.loads(request.data)
        req['ptype'] = rdb.getRecordTable(req['parent_uid'], dn=dn)
        r = rdb.addRecord('comment', json.dumps(req), dn=dn)
        id = r['uid']
        if apidebug: print('APIDEBUG comment route:: dn = ', dn)
        try:  #JCW just being careful here on first implementation
            morer = rdb.getRecord('comment', {'uid': id}, dn=dn)
        except Exception as e:
            import sys, os
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print('get comment exception', exc_type, fname, exc_tb.tb_lineno)

        publishEvent('mpo_comment', onlyone(morer))

    elif request.method == 'GET':
        #Add logic to parse id if comma separated
        if id:
            ids = id.strip().split(',')
            r = {}
            for id in ids:
                rs = rdb.getRecord('comment', {'uid': id}, dn=dn)
                if len(rs) == 1:
                    r[id] = rs[0]  #unpack single element list
                else:
                    r[id] = [
                    ]  #{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}
            if len(ids) == 1:  #return just single record if one uid
                r = rs
            else:
                r = r
        else:
            r = rdb.getRecord('comment', request.args, dn=dn)

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json')
示例#12
0
def ontologyTerm(id=None, dn=None):
    '''
    Retrieves the record of an ontology term from its <id> or path.
    valid routes:
    ontology/term/<id>
    ontology/term?path=term/term2/termN
    '''
    api_version, root_url, root = get_api_version(request.url)

    if request.method == 'POST':
        objs = json.loads(request.data)
        #allow for ontology terms with null parents
        if not objs.has_key('parent_uid'): objs['parent_uid'] = None

        # make sure the term doesn't exist already
        vocab = rdb.getRecord('ontology_terms',
                              {'parent_uid': objs['parent_uid']},
                              dn=dn)
        for x in vocab:
            if objs['name'] == x['name']:
                return Response(json.dumps({'uid': x['uid']}),
                                mimetype='application/json')

        r = rdb.addRecord('ontology_terms', json.dumps(objs), dn=dn)
    elif request.method == 'DELETE':
        if id:
            r = rdb.deleteOntologyTerms({'uid': id}, dn=dn)
        else:
            r = rdb.deleteOntologyTerms(request.args, dn=dn)
    else:
        if id:
            r = rdb.getRecord('ontology_terms', {'uid': id}, dn=dn)
        else:
            r = rdb.getRecord('ontology_terms', request.args, dn=dn)

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=200)
示例#13
0
def comment(id=None, dn=None):
    api_version,root_url,root=get_api_version(request.url)

    if request.method == 'POST':
        req = json.loads(request.data)
        req['ptype']=rdb.getRecordTable(req['parent_uid'], dn=dn)
        r = rdb.addRecord('comment',json.dumps(req),dn=dn)
        id = r['uid']
        if apidebug: print('APIDEBUG comment route:: dn = ',dn)
        try:  #JCW just being careful here on first implementation
            morer = rdb.getRecord('comment',{'uid':id},dn=dn)
        except Exception as e:
            import sys,os
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print('get comment exception',exc_type, fname, exc_tb.tb_lineno)

        publishEvent('mpo_comment',onlyone(morer))

    elif request.method == 'GET':
        #Add logic to parse id if comma separated
        if id:
            ids=id.strip().split(',')
            r={}
            for id in ids:
                rs = rdb.getRecord('comment',{'uid':id},dn=dn)
                if len(rs)==1:
                    r[id]=rs[0] #unpack single element list
                else:
                    r[id]=[]#{'uid':'0','msg':'invalid response','len':len(rs),'resp':rs}
            if len(ids)==1: #return just single record if one uid
                r=rs
            else:
                r=r
        else:
            r = rdb.getRecord('comment',request.args,dn=dn)

    return Response(json.dumps(r,cls=MPOSetEncoder), mimetype='application/json')
示例#14
0
def collection(id=None, dn=None):
    """
    Create and add to collections.
    Supported routes:
    /collection - GET a list of all (or filtered) collections
                - POST a new collection
    /collection/<id> - GET collection information, including list of member UUIDs
                     - DELETE a collection and the associated elements
    /collection/?element_uid=:uid - GET collections having element member giving by :uid
    """
    api_version, root_url, root = get_api_version(request.url)
    if request.method == 'POST':
        print('api post collection', request.data)
        r = rdb.addCollection(request.data, dn=dn)
        morer = rdb.getRecord('collection', {'uid': r['uid']}, dn=dn)
        publishEvent('mpo_collection', onlyone(morer))
    elif request.method == 'GET':
        if id:
            r = rdb.getRecord('collection', {'uid': id}, dn=dn)
        else:
            #particular cases
            #?element_uid
            if 'element_uid' in request.args:
                r = rdb.getRecord('collection_elements',
                                  {'uid': request.args['element_uid']},
                                  dn=dn)
            #general searches
            else:
                r = rdb.getRecord('collection', request.args, dn=dn)
    elif request.method == 'DELETE':
        if id:
            r = rdb.deleteCollection({'uid': id}, dn=dn)
        else:
            r = []

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=200)
示例#15
0
def ontologyTermVocabulary(id=None, dn=None):
    '''
    Resource: ontology vocabulary

    Convenience route, equivalent to ontology/term?parent_uid=<id>


    This function returns the vocabulary of an ontology term specified by its <id>=parent_id.
    Vocabulary is defined as the next set of terms below it in the
    ontology term tree.
    It is a convenience route equivalent to GET ontology_term?parent_uid=uid
    '''

    api_version,root_url,root=get_api_version(request.url)
    if not id:
        id='None'

    r = rdb.getRecord('ontology_terms', {'parent_uid':id}, dn=dn )
    r.append(  {'link-requested':request.url} )

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=200)
示例#16
0
def ontologyTermVocabulary(id=None, dn=None):
    '''
    Resource: ontology vocabulary

    Convenience route, equivalent to ontology/term?parent_uid=<id>


    This function returns the vocabulary of an ontology term specified by its <id>=parent_id.
    Vocabulary is defined as the next set of terms below it in the
    ontology term tree.
    It is a convenience route equivalent to GET ontology_term?parent_uid=uid
    '''

    api_version, root_url, root = get_api_version(request.url)
    if not id:
        id = 'None'

    r = rdb.getRecord('ontology_terms', {'parent_uid': id}, dn=dn)
    r.append({'link-requested': request.url})

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=200)
示例#17
0
def collectionElement(id=None, oid=None, dn=None):
    """
    /collection/:id/element       - GET a list of objects in a collection
                                   - POST to add to the collection
    /collection/:id/element/:oid - GET details of a single object in a collection.
                                    Should resolve oid to full record from relevant table.
    /collection/:id/element?detail=full[sparse] - GET collection information with full
               details [or default sparse as /collection/<id>]
    """
    api_version,root_url,root=get_api_version(request.url)
    if request.method == 'POST':

        payload = json.loads(request.data)

        #make sure the element hasn't been added to the collection already
        #elems must be a list of uids that are not already in this collection, if it exists.
        elems = payload.get('elements')
        if elems:
            if not isinstance(elems,list):
                elements=[elems]
            else:
                elements=elems
        else:
            elements=[]

        #remove elements already in the collection
        for e in elements[:]:
            r = rdb.getRecord('collection_elements',{'uid':e,'parent_uid':id}, dn=dn)
            if len(r)!=0: elements.remove(e) #maybe add to response message this was done
        payload['elements'] = elements

        #add elements one and a time and create list of returned records
        r=[]
        for e in elements:
            rr=rdb.addRecord('collection_elements',json.dumps({'uid':e,'parent_uid':id}),dn=dn)
            r.append(rr)
            morer = rdb.getRecord('collection_elements',{'uid':rr['uid']},dn=dn)
            publishEvent('mpo_collection_elements',onlyone(morer))
    elif request.method == 'DELETE':
        if oid:
            r = rdb.deleteCollectionElement({'parent_uid':id,'uid':oid}, dn=None)
        else:
            r = []
    elif request.method == 'GET':
        if oid:
            r = rdb.getRecord('collection_elements',{'parent_uid':id,'uid':oid}, dn=dn)
        else:
            r = rdb.getRecord('collection_elements',{'parent_uid':id}, dn=dn)

        #Find original item and add it to record.
        for record in r:
            print ('collection element r',record)
            r_uid=record['uid']
            #getRecordTable returns a python dict
            record['type']=rdb.getRecordTable( r_uid, dn=dn )

            #set default field values
            detail={'related':'not sure','link-related':root_url,'related':'cousins',
                    'name':'what is this?','description':'empty','time':'nowhen'}
            #Translation for specific types
            if record['type']=='workflow':
                detail=rdb.getWorkflow({'uid':r_uid},dn=dn)[0]
                print('element workflow',detail)
                detail['related']=rdb.getWorkflowCompositeID(r_uid,dn=dn).get('alias')
                links={}
                links['link1']=root_url+'/workflow/'+r_uid
                links['link2']=root_url+'/workflow?alias='+detail['related']
                detail['link-related']=links
            elif record['type']=='dataobject':
                detail=rdb.getRecord('dataobject',{'uid':r_uid},dn=dn)[0]
                detail['related']=detail.get('uri')
                detail['link-related']=root_url+'/dataobject/'+r_uid
            elif record['type']=='dataobject_instance':
                do_uid=(rdb.getRecord('dataobject_instance',{'uid':record['uid']},dn=dn)[0]).get('do_uid')
                detail=rdb.getRecord('dataobject',{'uid':do_uid},dn=dn)[0]
                detail['related']=detail.get('uri')
                detail['link-related']=root_url+'/dataobject/'+do_uid
            elif record['type']=='collection':
                thisdetail=rdb.getRecord('collection',{'uid':r_uid},dn=dn)[0]
                detail['related']=None
                detail['link-related']=root_url+'/collection/'+r_uid+'/element'
                detail['description']=thisdetail.get('description')
                detail['name']=thisdetail.get('name')
                detail['time']=thisdetail.get('time')

            record['name']=detail['name']
            record['description']=detail['description']
            record['time']=detail['time']
            record['related']=detail['related']
            record['link-related']=detail['link-related']

    istatus=200
    #    if len(r) == 0:
    #    #istatus = 404
    #    r=[{'mesg':'No records found', 'number_of_records':0, 'status':404}]

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=istatus)
示例#18
0
def dataobject(id=None, dn=None):
    """
    Route to add data objects and connect their instances to workflows.

    Route: GET  /dataobject/<id>
           Retrieves information on a specific dataobject.
           In the case <id> is <id> of an instance, instance inherits properties of the original object.
           In the case <id> is <id> of an dataobject, just the properties of the dataobject are returned.
           NOT IMPLEMENTED: ?instance filter will optionally return instances of a specified dataobject.
    Route: GET  /dataobject returns all dataobjects
           GET  /dataobject?instance returns all dataobject instances
    Route: POST /dataobject
           databody:
               {'name':, 'description':,'work_uid':, 'uri':, 'parent_uid':, 'uid': }
           If 'work_uid' is present, create an instance, connect it to the parent in the workflow
           and link instance to the dataobject as determined by the 'uri'.
           If 'work_uid' is NOT present, 'parent_uid' must also not be present. A new dataobject is created.

           Dataobject instances in workflows can be created by
           supplying a URI, DO_UID, or DOI_UID.  If a doi_uid is
           given, it is resolved to the parent do_uid. If both URI and
           UID are provided, the URI takes precedence.

    """
    api_version,root_url,root=get_api_version(request.url)
    istatus=200
    messages={}
    messages['api_version']=api_version

    if request.method == 'POST':
        req = json.loads(request.data)

        #Make sure name and description are present
        if req.get('name')==None:
            req['name']="None given"
        if req.get('description')==None:
            req['description']="None given"

        #find the dataobject with the specified uri (assumed to be unique)
        #or if no URI given, find it by UID. If not found, we make it.

        if req.get('uri'):
            do = rdb.getRecord('dataobject',{'uri':req['uri']},dn=dn)
            if req.get('uid'): #check if consistent
                if do[0].get('uid'):
                    if not do[0].get('uid') == req.get('uid'):
                        messages['warning']="\nCaution, dataobject UID does not match record from URI."
        elif req.get('uid'): #if we get here, there is no URI only perhaps a UID
            do = rdb.getRecord('dataobject',{'uid':req['uid']},dn=dn)
            #now remove the uid from the request so it does not get passed to
            #the dataobject_instance creation
            popuid=req.pop('uid')
        else:
            do = False

        #If the D.O. exists, point to it, if not, make it and point to it
        if do:
            if not (req.get('work_uid') and req.get('parent_uid')):
                messages['info']='dataobject found. provide both work_uid and parent_uid to attach to a workflow.'
                do[0]['messages']=messages
                return Response(json.dumps(do,cls=MPOSetEncoder), mimetype='application/json',status=istatus)
            else:
                req['do_uid']=do[0]['uid']
        else:
            do_add = rdb.addRecord('dataobject',request.data,dn=dn)
            do = rdb.getRecord('dataobject',{'uid':do_add['uid']},dn=dn) #retrieve it to get full record
            if not (req.get('work_uid') and req.get('parent_uid')):
                messages['info']='dataobject created. provide both work_uid and parent_uid to attach to a workflow.'
                do[0]['messages']=messages
                return Response(json.dumps(do,cls=MPOSetEncoder), mimetype='application/json',status=istatus)
            else:
                if apidebug: print('do is ',str(do) )
                req['do_uid']=do[0]['uid']


        #At this point, we have a dataobject record. Now add it to the workflow since should
        #also have a work_uid and parent_uid

        #First check if we already have an instance attached to this parent_uid
        #we only permit one instance per parent of the same object
        #We needs something like get dataobject?instance&do_uid=do_uid&work_uid=wid
        #to get a list of uses in this workflow and then figure out if they have the same parent.
        #perhaps by using rdb.getWorkflowElements. This is really a topological question - we may
        #have more of these.

        #check = rdb.getRecord('dataobject_instance',{'do_uid':id},dn=dn)
        r = rdb.addRecord('dataobject_instance',json.dumps(req),dn=dn)
        id = r['uid']
        morer = rdb.getRecord('dataobject_instance',{'uid':id},dn=dn)
        publishEvent('mpo_dataobject',onlyone(morer))

    elif request.method == 'GET':

        #handling for comma separated UIDs
        if id:
            ids=id.strip().split(',')
            r={}
            for id in ids:
                rs = rdb.getRecord('dataobject',{'uid':id},dn=dn)
                if len(rs)==1:
                    rs=rs[0]
                    rs['link-related']='link to get workflows using dataobject'
                    r[id]=rs
                else: #record was not found, check other route
                    rs = rdb.getRecord('dataobject_instance',{'uid':id},dn=dn)
                    if len(rs)==1:
                        rs=rs[0]
                        #add dataobject fields
                        do_info=rdb.getRecord('dataobject',{'uid':rs.get('do_uid')},dn=dn)
                        rs['do_info']=do_info[0]
                        r[id]=rs
                    else:
                        rs={'uid':'0','msg':'not found'}
                        r[id]=rs


            if len(ids)==1: #return just single record if one uid
                r=[rs] #following convention that a list is always returned

        #Get all records, possibly with filters, support 'instance' flag
        else:
            if request.args.has_key('instance'):
                records = rdb.getRecord('dataobject_instance',request.args,dn=dn)
                for rr in records:
                        do_uid=rr['do_uid']
                        rr['do_info']=rdb.getRecord('dataobject',{'uid':do_uid}, dn=dn )[0]
                r=records
            else:
                r = rdb.getRecord('dataobject',request.args,dn=dn)

    return Response(json.dumps(r,cls=MPOSetEncoder), mimetype='application/json',status=istatus)
示例#19
0
def dataobject(id=None, dn=None):
    """
    Route to add data objects and connect their instances to workflows.

    Route: GET  /dataobject/<id>
           Retrieves information on a specific dataobject.
           In the case <id> is <id> of an instance, instance inherits properties of the original object.
           In the case <id> is <id> of an dataobject, just the properties of the dataobject are returned.
           NOT IMPLEMENTED: ?instance filter will optionally return instances of a specified dataobject.
    Route: GET  /dataobject returns all dataobjects
           GET  /dataobject?instance returns all dataobject instances
    Route: POST /dataobject
           databody:
               {'name':, 'description':,'work_uid':, 'uri':, 'parent_uid':, 'uid': }
           If 'work_uid' is present, create an instance, connect it to the parent in the workflow
           and link instance to the dataobject as determined by the 'uri'.
           If 'work_uid' is NOT present, 'parent_uid' must also not be present. A new dataobject is created.

           Dataobject instances in workflows can be created by
           supplying a URI, DO_UID, or DOI_UID.  If a doi_uid is
           given, it is resolved to the parent do_uid. If both URI and
           UID are provided, the URI takes precedence.

    """
    api_version, root_url, root = get_api_version(request.url)
    istatus = 200
    messages = {}
    messages['api_version'] = api_version

    if request.method == 'POST':
        req = json.loads(request.data)

        #Make sure name and description are present
        if req.get('name') == None:
            req['name'] = "None given"
        if req.get('description') == None:
            req['description'] = "None given"

        #find the dataobject with the specified uri (assumed to be unique)
        #or if no URI given, find it by UID. If not found, we make it.

        if req.get('uri'):
            do = rdb.getRecord('dataobject', {'uri': req['uri']}, dn=dn)
            if req.get('uid'):  #check if consistent
                if do[0].get('uid'):
                    if not do[0].get('uid') == req.get('uid'):
                        messages[
                            'warning'] = "\nCaution, dataobject UID does not match record from URI."
        elif req.get(
                'uid'):  #if we get here, there is no URI only perhaps a UID
            do = rdb.getRecord('dataobject', {'uid': req['uid']}, dn=dn)
            #now remove the uid from the request so it does not get passed to
            #the dataobject_instance creation
            popuid = req.pop('uid')
        else:
            do = False

        #If the D.O. exists, point to it, if not, make it and point to it
        if do:
            if not (req.get('work_uid') and req.get('parent_uid')):
                messages[
                    'info'] = 'dataobject found. provide both work_uid and parent_uid to attach to a workflow.'
                do[0]['messages'] = messages
                return Response(json.dumps(do, cls=MPOSetEncoder),
                                mimetype='application/json',
                                status=istatus)
            else:
                req['do_uid'] = do[0]['uid']
        else:
            do_add = rdb.addRecord('dataobject', request.data, dn=dn)
            do = rdb.getRecord('dataobject', {'uid': do_add['uid']},
                               dn=dn)  #retrieve it to get full record
            if not (req.get('work_uid') and req.get('parent_uid')):
                messages[
                    'info'] = 'dataobject created. provide both work_uid and parent_uid to attach to a workflow.'
                do[0]['messages'] = messages
                return Response(json.dumps(do, cls=MPOSetEncoder),
                                mimetype='application/json',
                                status=istatus)
            else:
                if apidebug: print('do is ', str(do))
                req['do_uid'] = do[0]['uid']

        #At this point, we have a dataobject record. Now add it to the workflow since should
        #also have a work_uid and parent_uid

        #First check if we already have an instance attached to this parent_uid
        #we only permit one instance per parent of the same object
        #We needs something like get dataobject?instance&do_uid=do_uid&work_uid=wid
        #to get a list of uses in this workflow and then figure out if they have the same parent.
        #perhaps by using rdb.getWorkflowElements. This is really a topological question - we may
        #have more of these.

        #check = rdb.getRecord('dataobject_instance',{'do_uid':id},dn=dn)
        r = rdb.addRecord('dataobject_instance', json.dumps(req), dn=dn)
        id = r['uid']
        morer = rdb.getRecord('dataobject_instance', {'uid': id}, dn=dn)
        publishEvent('mpo_dataobject', onlyone(morer))

    elif request.method == 'GET':

        #handling for comma separated UIDs
        if id:
            ids = id.strip().split(',')
            r = {}
            for id in ids:
                rs = rdb.getRecord('dataobject', {'uid': id}, dn=dn)
                if len(rs) == 1:
                    rs = rs[0]
                    rs['link-related'] = 'link to get workflows using dataobject'
                    r[id] = rs
                else:  #record was not found, check other route
                    rs = rdb.getRecord('dataobject_instance', {'uid': id},
                                       dn=dn)
                    if len(rs) == 1:
                        rs = rs[0]
                        #add dataobject fields
                        do_info = rdb.getRecord('dataobject',
                                                {'uid': rs.get('do_uid')},
                                                dn=dn)
                        rs['do_info'] = do_info[0]
                        r[id] = rs
                    else:
                        rs = {'uid': '0', 'msg': 'not found'}
                        r[id] = rs

            if len(ids) == 1:  #return just single record if one uid
                r = [rs]  #following convention that a list is always returned

        #Get all records, possibly with filters, support 'instance' flag
        else:
            if request.args.has_key('instance'):
                records = rdb.getRecord('dataobject_instance',
                                        request.args,
                                        dn=dn)
                for rr in records:
                    do_uid = rr['do_uid']
                    rr['do_info'] = rdb.getRecord('dataobject',
                                                  {'uid': do_uid},
                                                  dn=dn)[0]
                r = records
            else:
                r = rdb.getRecord('dataobject', request.args, dn=dn)

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=istatus)
示例#20
0
def workflow(id=None, dn=None):
    """
    Implementation of the /workflow route
    Enforces ontological constraints on workflows types retrieved from ontology_terms.
    /workflow?do_uri=:uri - GET workflows having dataobject member giving by :uid
    """

    #Desperately need to add field error checking. Note, we have access to db.query_map
    api_version,root_url,root=get_api_version(request.url)

    if apidebug:
        print ('APIDEBUG: You are: %s'% str(dn) )
        print ('APIDEBUG: workflow url request is %s' %request.url)

    if request.method == 'POST':
        #check for valid workflow type
        wtype = json.loads(request.data).get('type')
        ont_entry = rdb.getRecord('ontology_terms', {'path':'/Workflow/Type'}, dn )[0]
        vocab=rdb.getRecord('ontology_terms', {'parent_uid':ont_entry['uid']}, dn )
        valid= tuple(x['name'] for x in vocab)
        if (wtype in valid):
            ##Add logic to check for fields or exceptions from query
            type_uid = ont_entry.get('uid')
            p=json.loads(request.data)
            payload={"name":p['name'],"description":p['description'],"type_uid":type_uid,"value":wtype}
            r = rdb.addWorkflow(payload,dn=dn)
            #should return ENTIRE record created. use rdb.getworkflow internally
        else:
            payload={"url":request.url, "body":request.data, "hint":valid, "uid":-1}
            raise InvalidAPIUsage(message='Invalid workflow type specified',status_code=400,
                                    payload=payload)

    elif request.method == 'GET':
        if id:
            darg=dict(request.args.items(multi=True)+[('uid',id)])
            if apidebug:
                print('APIDEBUG: darg is %s' %darg)
            r = rdb.getWorkflow({'uid':id},dn=dn)
        else:
            if 'do_uri' in request.args:
                #find data object by uri
                r = rdb.getRecord('dataobject',{'uri':request.args['do_uri']}, dn=dn)
                if len(r)==1:
                    do_uid=r[0].get('uid')
                    #find dataobject instances based on do_uid
                    doi_list = rdb.getRecord('dataobject_instance',{'do_uid':do_uid}, dn=dn )
                    result=[]
                    for doi in doi_list:
                        result.append(rdb.getWorkflow({'uid':doi['work_uid']},dn=dn)[0])
                    r={'result':result,'count':len(result),'link-requested':request.url, 'status':'ok'}
                else:
                    r={'uid':'0','msg':'not found'}
            #general searches
            else:
                r = rdb.getWorkflow(request.args,dn=dn)
                #add workflow type here in return. Use complete path?

        if apidebug:
            print ('APIDEBUG: workflow returning "%s" len %d'% (r,len(r),))

    if apidebug:
        print ('APIDEBUG: workflow %s'% (r,) )

    return Response(json.dumps(r,cls=MPOSetEncoder),mimetype='application/json',status=200)
示例#21
0
def workflow(id=None, dn=None):
    """
    Implementation of the /workflow route
    Enforces ontological constraints on workflows types retrieved from ontology_terms.
    /workflow?do_uri=:uri - GET workflows having dataobject member giving by :uid
    """

    #Desperately need to add field error checking. Note, we have access to db.query_map
    api_version, root_url, root = get_api_version(request.url)

    if apidebug:
        print('APIDEBUG: You are: %s' % str(dn))
        print('APIDEBUG: workflow url request is %s' % request.url)

    if request.method == 'POST':
        #check for valid workflow type
        wtype = json.loads(request.data).get('type')
        ont_entry = rdb.getRecord('ontology_terms', {'path': '/Workflow/Type'},
                                  dn)[0]
        vocab = rdb.getRecord('ontology_terms',
                              {'parent_uid': ont_entry['uid']}, dn)
        valid = tuple(x['name'] for x in vocab)
        if (wtype in valid):
            ##Add logic to check for fields or exceptions from query
            type_uid = ont_entry.get('uid')
            p = json.loads(request.data)
            payload = {
                "name": p['name'],
                "description": p['description'],
                "type_uid": type_uid,
                "value": wtype
            }
            r = rdb.addWorkflow(payload, dn=dn)
            #should return ENTIRE record created. use rdb.getworkflow internally
        else:
            payload = {
                "url": request.url,
                "body": request.data,
                "hint": valid,
                "uid": -1
            }
            raise InvalidAPIUsage(message='Invalid workflow type specified',
                                  status_code=400,
                                  payload=payload)

    elif request.method == 'GET':
        if id:
            darg = dict(request.args.items(multi=True) + [('uid', id)])
            if apidebug:
                print('APIDEBUG: darg is %s' % darg)
            r = rdb.getWorkflow({'uid': id}, dn=dn)
        else:
            if 'do_uri' in request.args:
                #find data object by uri
                r = rdb.getRecord('dataobject',
                                  {'uri': request.args['do_uri']},
                                  dn=dn)
                if len(r) == 1:
                    do_uid = r[0].get('uid')
                    #find dataobject instances based on do_uid
                    doi_list = rdb.getRecord('dataobject_instance',
                                             {'do_uid': do_uid},
                                             dn=dn)
                    result = []
                    for doi in doi_list:
                        result.append(
                            rdb.getWorkflow({'uid': doi['work_uid']},
                                            dn=dn)[0])
                    r = {
                        'result': result,
                        'count': len(result),
                        'link-requested': request.url,
                        'status': 'ok'
                    }
                else:
                    r = {'uid': '0', 'msg': 'not found'}
            #general searches
            else:
                r = rdb.getWorkflow(request.args, dn=dn)
                #add workflow type here in return. Use complete path?

        if apidebug:
            print('APIDEBUG: workflow returning "%s" len %d' % (
                r,
                len(r),
            ))

    if apidebug:
        print('APIDEBUG: workflow %s' % (r, ))

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=200)
示例#22
0
def collectionElement(id=None, oid=None, dn=None):
    """
    /collection/:id/element       - GET a list of objects in a collection
                                   - POST to add to the collection
    /collection/:id/element/:oid - GET details of a single object in a collection.
                                    Should resolve oid to full record from relevant table.
    /collection/:id/element?detail=full[sparse] - GET collection information with full
               details [or default sparse as /collection/<id>]
    """
    api_version, root_url, root = get_api_version(request.url)
    if request.method == 'POST':

        payload = json.loads(request.data)

        #make sure the element hasn't been added to the collection already
        #elems must be a list of uids that are not already in this collection, if it exists.
        elems = payload.get('elements')
        if elems:
            if not isinstance(elems, list):
                elements = [elems]
            else:
                elements = elems
        else:
            elements = []

        #remove elements already in the collection
        for e in elements[:]:
            r = rdb.getRecord('collection_elements', {
                'uid': e,
                'parent_uid': id
            },
                              dn=dn)
            if len(r) != 0:
                elements.remove(
                    e)  #maybe add to response message this was done
        payload['elements'] = elements

        #add elements one and a time and create list of returned records
        r = []
        for e in elements:
            rr = rdb.addRecord('collection_elements',
                               json.dumps({
                                   'uid': e,
                                   'parent_uid': id
                               }),
                               dn=dn)
            r.append(rr)
            morer = rdb.getRecord('collection_elements', {'uid': rr['uid']},
                                  dn=dn)
            publishEvent('mpo_collection_elements', onlyone(morer))
    elif request.method == 'DELETE':
        if oid:
            r = rdb.deleteCollectionElement({
                'parent_uid': id,
                'uid': oid
            },
                                            dn=None)
        else:
            r = []
    elif request.method == 'GET':
        if oid:
            r = rdb.getRecord('collection_elements', {
                'parent_uid': id,
                'uid': oid
            },
                              dn=dn)
        else:
            r = rdb.getRecord('collection_elements', {'parent_uid': id}, dn=dn)

        #Find original item and add it to record.
        for record in r:
            print('collection element r', record)
            r_uid = record['uid']
            #getRecordTable returns a python dict
            record['type'] = rdb.getRecordTable(r_uid, dn=dn)

            #set default field values
            detail = {
                'related': 'not sure',
                'link-related': root_url,
                'related': 'cousins',
                'name': 'what is this?',
                'description': 'empty',
                'time': 'nowhen'
            }
            #Translation for specific types
            if record['type'] == 'workflow':
                detail = rdb.getWorkflow({'uid': r_uid}, dn=dn)[0]
                print('element workflow', detail)
                detail['related'] = rdb.getWorkflowCompositeID(
                    r_uid, dn=dn).get('alias')
                links = {}
                links['link1'] = root_url + '/workflow/' + r_uid
                links['link2'] = root_url + '/workflow?alias=' + detail[
                    'related']
                detail['link-related'] = links
            elif record['type'] == 'dataobject':
                detail = rdb.getRecord('dataobject', {'uid': r_uid}, dn=dn)[0]
                detail['related'] = detail.get('uri')
                detail['link-related'] = root_url + '/dataobject/' + r_uid
            elif record['type'] == 'dataobject_instance':
                do_uid = (rdb.getRecord('dataobject_instance',
                                        {'uid': record['uid']},
                                        dn=dn)[0]).get('do_uid')
                detail = rdb.getRecord('dataobject', {'uid': do_uid}, dn=dn)[0]
                detail['related'] = detail.get('uri')
                detail['link-related'] = root_url + '/dataobject/' + do_uid
            elif record['type'] == 'collection':
                thisdetail = rdb.getRecord('collection', {'uid': r_uid},
                                           dn=dn)[0]
                detail['related'] = None
                detail[
                    'link-related'] = root_url + '/collection/' + r_uid + '/element'
                detail['description'] = thisdetail.get('description')
                detail['name'] = thisdetail.get('name')
                detail['time'] = thisdetail.get('time')

            record['name'] = detail['name']
            record['description'] = detail['description']
            record['time'] = detail['time']
            record['related'] = detail['related']
            record['link-related'] = detail['link-related']

    istatus = 200
    #    if len(r) == 0:
    #    #istatus = 404
    #    r=[{'mesg':'No records found', 'number_of_records':0, 'status':404}]

    return Response(json.dumps(r, cls=MPOSetEncoder),
                    mimetype='application/json',
                    status=istatus)