Skip to content
Snippets Groups Projects
Commit b1bbfa83 authored by Nathaniel Kofalt's avatar Nathaniel Kofalt
Browse files

Add gear suggestion endpoint

parent fb58d867
No related branches found
No related tags found
No related merge requests found
......@@ -125,6 +125,7 @@ routes = [
webapp2_extras.routes.PathPrefixRoute(r'/api/gears', [
webapp2.Route(r'/<:[^/]+>', GearHandler),
webapp2.Route(r'/<:[^/]+>/invocation', GearHandler, handler_method='get_invocation'),
webapp2.Route(r'/<:[^/]+>/suggest/<:[^/]+>/<:[^/]+>', GearHandler, handler_method='suggest'),
]),
webapp2.Route(r'/api/rules', RulesHandler),
webapp2.Route(r'/api/groups', grouphandler.GroupHandler, handler_method='get_all', methods=['GET']),
......
......@@ -122,3 +122,17 @@ class GroupStorage(ContainerStorage):
},
upsert=True)
def inflate_container(cr):
"""
Given a container reference, inflate its hierarchy into a map.
Eeventually, this might want to deduplicate with logic in hierarchy.py.
"""
if cr.type != 'session':
raise Exception('Only sessions are supported for inflation right now')
oid = bson.ObjectId(cr.id)
root = ContainerStorage('sessions', True).exec_op('GET', oid, projection={'permissions': 0})
root['acquisitions'] = ContainerStorage('acquisitions', True).exec_op('GET', query={'session': oid}, projection={'permissions': 0})
return root
......@@ -2,10 +2,15 @@
Gears
"""
import bson.objectid
import jsonschema
from jsonschema import Draft4Validator
import gear_tools
from .. import config
from .jobs import Job
from ..dao.containerstorage import inflate_container
import gear_tools
log = config.log
......@@ -51,9 +56,31 @@ def get_gear_by_name(name):
# Mongo returns the full document: { '_id' : 'gears', 'gear_list' : [ { .. } ] }, so strip that out
return gear_doc[SINGLETON_KEY][0]
def get_invocation(gear):
def get_invocation_schema(gear):
return gear_tools.derive_invocation_schema(gear['manifest'])
def suggest_container(gear, cr):
"""
Given a container reference, suggest files that would work well for each input on a gear.
"""
root = inflate_container(cr)
invocation_schema = get_invocation_schema(gear)
schemas = {}
for x in gear['manifest']['inputs']:
schema = gear_tools.isolate_file_invocation(invocation_schema, x)
schemas[x] = Draft4Validator(schema)
# It would be nice to have use a visitor here instead of manual key loops.
for acq in root['acquisitions']:
for f in acq.get('files', []):
f['suggested'] = {}
for x in schemas:
f['suggested'][x] = schemas[x].is_valid({})
return root
def insert_gear(doc):
config.db.singletons.update(
{"_id" : "gears"},
......
......@@ -5,11 +5,11 @@ API request handlers for the jobs module
import json
import StringIO
from ..dao.containerutil import create_filereference_from_dictionary, create_containerreference_from_dictionary, create_containerreference_from_filereference
from ..dao.containerutil import create_filereference_from_dictionary, create_containerreference_from_dictionary, create_containerreference_from_filereference, ContainerReference
from .. import base
from .. import config
from .gears import get_gears, get_gear_by_name, get_invocation, remove_gear, upsert_gear
from .gears import get_gears, get_gear_by_name, get_invocation_schema, remove_gear, upsert_gear, suggest_container
from .jobs import Job
from .queue import Queue
......@@ -47,7 +47,19 @@ class GearHandler(base.RequestHandler):
self.abort(403, 'Request requires login')
gear = get_gear_by_name(_id)
return get_invocation(gear)
return get_invocation_schema(gear)
def suggest(self, _id, cont_name, cid):
if self.public_request:
self.abort(403, 'Request requires login')
cr = ContainerReference(cont_name, cid)
if not self.superuser_request:
cr.check_access(self.uid, 'ro')
gear = get_gear_by_name(_id)
return suggest_container(gear, cr)
def post(self, _id):
"""Upsert an entire gear document."""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment