Skip to content
Snippets Groups Projects
api.py 13.3 KiB
Newer Older
import webapp2
import webapp2_extras.routes

from .download                      import Download
from .handlers.collectionshandler   import CollectionsHandler
from .handlers.confighandler        import Config, Version
from .handlers.containerhandler     import ContainerHandler
from .handlers.dataexplorerhandler  import DataExplorerHandler
from .handlers.devicehandler        import DeviceHandler
from .handlers.grouphandler         import GroupHandler
from .handlers.listhandler          import ListHandler, FileListHandler, NotesListHandler, PermissionsListHandler, TagsListHandler
from .handlers.refererhandler       import AnalysesHandler
from .handlers.reporthandler        import ReportHandler
from .handlers.resolvehandler       import ResolveHandler
from .handlers.roothandler          import RootHandler
from .handlers.schemahandler        import SchemaHandler
from .handlers.userhandler          import UserHandler
from .jobs.handlers                 import BatchHandler, JobsHandler, JobHandler, GearsHandler, GearHandler, RulesHandler, RuleHandler
from .upload                        import Upload
from .web.base                      import RequestHandler
Gunnar Schaefer's avatar
Gunnar Schaefer committed
log = config.log

Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
routing_regexes = {
Renzo Frigato's avatar
Renzo Frigato committed

Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
    # Group ID: 2-32 characters of form [0-9a-z.@_-]. Start and ends with alphanum.
    'gid': '[0-9a-z][0-9a-z.@_-]{0,30}[0-9a-z]',
Renzo Frigato's avatar
Renzo Frigato committed

Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
    # Container ID: 24-character hex
    'cid': '[0-9a-f]{24}',
Renzo Frigato's avatar
Renzo Frigato committed

Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
    # User ID: any length, [0-9a-z.@_-]
    'uid': '[0-9a-zA-Z.@_-]*',
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
    # Container name
    'cname': 'projects|sessions|acquisitions|collections|analyses',
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

    # Tag name
    'tag': '[^/]{1,32}',

    # Filename
    'fname': '[^/]+',

    # Note ID
    'nid': '[0-9a-f]{24}',

    # Schema path
    'schema': r'[^/.]{3,60}/[^/.]{3,60}\.json'
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
def route(path, target, h=None, m=None, name=None):

    # https://webapp2.readthedocs.io/en/latest/api/webapp2.html#webapp2.Route
    return webapp2.Route(
        # re.compile(path)
        path.format(**routing_regexes),
        target,
        handler_method=h,
        methods=m,
        name=name
    )

def prefix(path, routes):

    # https://webapp2.readthedocs.io/en/latest/api/webapp2_extras/routes.html#webapp2_extras.routes.PathPrefixRoute
    return webapp2_extras.routes.PathPrefixRoute(
        path.format(**routing_regexes),
        routes
    )

endpoints = [
    route('/api',                  RootHandler),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
    prefix('/api', [

        # System configuration

        route('/config',           Config,              m=['GET']),
        route('/config.js',        Config,  h='get_js', m=['GET']),
        route('/version',          Version,             m=['GET']),


        # General-purpose upload & download

        route('/download',                                      Download, h='download',              m=['GET', 'POST']),
        route('/upload/<strategy:label|uid|uid-match|reaper>',  Upload,   h='upload',                m=['POST']),
        route('/clean-packfiles',                               Upload,   h='clean_packfile_tokens', m=['POST']),
        route('/engine',                                        Upload,   h='engine',                m=['POST']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed


        # Top-level endpoints

Megan Henning's avatar
Megan Henning committed
        route('/login',                                         RequestHandler, h='log_in',   m=['POST']),
        route('/logout',                                        RequestHandler, h='log_out',  m=['POST']),
        route('/resolve',                                       ResolveHandler, h='resolve',  m=['POST']),
        route('/schemas/<schema:{schema}>',                     SchemaHandler,                m=['GET']),
        route('/report/<report_type:site|project|accesslog|usage>',   ReportHandler,                m=['GET']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed


        # Search
        route('/dataexplorer/search',                   DataExplorerHandler,   h='search',                 m=['POST']),
        route('/dataexplorer/facets',                   DataExplorerHandler,   h='get_facets',             m=['POST']),
        route('/dataexplorer/search/fields',            DataExplorerHandler,   h='search_fields',          m=['POST']),
        route('/dataexplorer/search/fields/aggregate',  DataExplorerHandler,   h='aggregate_field_values', m=['POST']),
        route('/dataexplorer/index/fields',             DataExplorerHandler,   h='index_field_names',      m=['POST']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

        # Users

        route( '/users',                   UserHandler, h='get_all', m=['GET']),
        route( '/users',                   UserHandler,              m=['POST']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        prefix('/users', [
            route('/self',                 UserHandler, h='self',            m=['GET']),
            route('/self/avatar',          UserHandler, h='self_avatar',     m=['GET']),
            route('/self/key',             UserHandler, h='generate_api_key',m=['POST']),

            route('/<_id:{uid}>',                       UserHandler),
            route('/<uid:{uid}>/groups',                GroupHandler,                h='get_all',               m=['GET']),
            route('/<uid:{uid}>/avatar',                UserHandler,                 h='avatar',                m=['GET']),
            route('/<uid:{uid}>/reset-registration',    UserHandler,                 h='reset_registration',    m=['POST']),
            route('/<uid:{uid}>/<cont_name:{cname}>',   ContainerHandler, h='get_all_for_user', m=['GET']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

        ]),


        # Jobs & gears

        prefix('/jobs', [
            route('/next',                 JobsHandler, h='next',       m=['GET']),
            route('/stats',                JobsHandler, h='stats',      m=['GET']),
            route('/reap',                 JobsHandler, h='reap_stale', m=['POST']),
            route('/add',                  JobsHandler, h='add',        m=['POST']),
            route('/<:[^/]+>',             JobHandler),
            route('/<:[^/]+>/config.json', JobHandler,  h='get_config'),
            route('/<:[^/]+>/retry',       JobHandler,  h='retry',         m=['POST']),
            route('/<:[^/]+>/logs',        JobHandler,  h='get_logs',      m=['GET']),
            route('/<:[^/]+>/logs/text',   JobHandler,  h='get_logs_text', m=['GET']),
            route('/<:[^/]+>/logs/html',   JobHandler,  h='get_logs_html', m=['GET']),
            route('/<:[^/]+>/logs',        JobHandler,  h='add_logs',      m=['POST']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        ]),
        route('/gears',                                  GearsHandler),
Harsha Kethineni's avatar
Harsha Kethineni committed
        route('/gears/temp',                             GearHandler, h='upload', m=['POST']),
        route('/gears/temp/<cid:{cid}>',  GearHandler, h='download', m=['GET']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        prefix('/gears', [
            route('/<:[^/]+>',                           GearHandler),
            route('/<:[^/]+>/invocation',                GearHandler, h='get_invocation'),
            route('/<:[^/]+>/suggest/<:[^/]+>/<:[^/]+>', GearHandler, h='suggest'),
        ]),

Megan Henning's avatar
Megan Henning committed
        # Batch jobs

        route('/batch',                 BatchHandler,   h='get_all',    m=['GET']),
        route('/batch',                 BatchHandler,                   m=['POST']),
        prefix('/batch', [
            route('/<:[^/]+>',          BatchHandler,   h='get',        m=['GET']),
            route('/<:[^/]+>/run',      BatchHandler,   h='run',        m=['POST']),
            route('/<:[^/]+>/cancel',   BatchHandler,   h='cancel',     m=['POST']),
        ]),


Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        # Devices

        route( '/devices',              DeviceHandler, h='get_all',    m=['GET']),
        route( '/devices',              DeviceHandler,                 m=['POST']),
        prefix('/devices', [
            route('/status',            DeviceHandler, h='get_status', m=['GET']),
            route('/self',              DeviceHandler, h='get_self',   m=['GET']),
            route('/<device_id:[^/]+>', DeviceHandler,                 m=['GET']),
        ]),


        # Groups

        route('/groups',             GroupHandler, h='get_all', m=['GET']),
        route('/groups',             GroupHandler,              m=['POST']),
        route('/groups/<_id:{gid}>', GroupHandler,              m=['GET', 'DELETE', 'PUT']),

        prefix('/<cont_name:groups>', [
            route('/<cid:{gid}>/<list_name:roles>',                          ListHandler,     m=['POST']),
            route('/<cid:{gid}>/<list_name:roles>/<_id:{uid}>',              ListHandler,     m=['GET', 'PUT', 'DELETE']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

            route('/<cid:{gid}>/<list_name:tags>',                           TagsListHandler, m=['POST']),
            route('/<cid:{gid}>/<list_name:tags>/<value:{tag}>',             TagsListHandler, m=['GET', 'PUT', 'DELETE']),
        ]),


        # Projects

        prefix('/projects', [
            route('/groups',               ContainerHandler, h='get_groups_with_project',      m=['GET']),
            route('/recalc',               ContainerHandler, h='calculate_project_compliance', m=['POST']),
            route('/<cid:{cid}>/template', ContainerHandler, h='set_project_template',         m=['POST']),
            route('/<cid:{cid}>/template', ContainerHandler, h='delete_project_template',      m=['DELETE']),
            route('/<cid:{cid}>/recalc',   ContainerHandler, h='calculate_project_compliance', m=['POST']),
            route('/<cid:{cid}>/rules',    RulesHandler,                                       m=['GET', 'POST']),
            route('/<cid:{cid}>/rules/<rid:{cid}>',  RuleHandler,                              m=['GET', 'PUT', 'DELETE']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        ]),


        # Sessions

        prefix('/sessions', [
            route('/<cid:{cid}>/jobs',          ContainerHandler, h='get_jobs',     m=['GET']),
            route('/<cid:{cid}>/subject',       ContainerHandler, h='get_subject',  m=['GET']),
        ]),

Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

        # Collections

        route( '/collections',                 CollectionsHandler, h='get_all',                    m=['GET']),
        route( '/collections',                 CollectionsHandler,                                 m=['POST']),
        prefix('/collections', [
            route('/curators',                 CollectionsHandler, h='curators',                   m=['GET']),
            route('/<cid:{cid}>',              CollectionsHandler,                                 m=['GET', 'PUT', 'DELETE']),
            route('/<cid:{cid}>/sessions',     CollectionsHandler, h='get_sessions',               m=['GET']),
            route('/<cid:{cid}>/acquisitions', CollectionsHandler, h='get_acquisitions',           m=['GET']),
        ]),


        # Collections / Projects

        prefix('/<cont_name:collections|projects>', [
            prefix('/<cid:{cid}>', [
                route('/<list_name:permissions>',                          PermissionsListHandler, m=['POST']),
                route('/<list_name:permissions>/<_id:{uid}>',              PermissionsListHandler, m=['GET', 'PUT', 'DELETE']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
            ]),
        ]),


        # Containers

        route( '/<cont_name:{cname}>', ContainerHandler, name='cont_list', h='get_all', m=['GET']),
        route( '/<cont_name:{cname}>', ContainerHandler,                                m=['POST']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        prefix('/<cont_name:{cname}>', [
            route( '/<cid:{cid}>',     ContainerHandler,                                m=['GET','PUT','DELETE']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
            prefix('/<cid:{cid}>', [
                route('/<list_name:tags>',               TagsListHandler, m=['POST']),
                route('/<list_name:tags>/<value:{tag}>', TagsListHandler, m=['GET', 'PUT', 'DELETE']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

                route('/packfile-start',                        FileListHandler, h='packfile_start', m=['POST']),
                route('/packfile',                              FileListHandler, h='packfile',       m=['POST']),
                route('/packfile-end',                          FileListHandler, h='packfile_end'),
                route('/<list_name:files>',                     FileListHandler,                     m=['POST']),
                route('/<list_name:files>/<name:{fname}>',      FileListHandler,                     m=['GET', 'DELETE']),
                route('/<list_name:files>/<name:{fname}>/info', FileListHandler, h='get_info',       m=['GET']),
Nathaniel Kofalt's avatar
Nathaniel Kofalt committed

                route( '/analyses',                                AnalysesHandler,                  m=['POST']),
                    route('/<_id:{cid}>',                          AnalysesHandler,                  m=['GET', 'DELETE']),
Harsha Kethineni's avatar
Harsha Kethineni committed
                    route('/<_id:{cid}>/files',                    AnalysesHandler, h='download',    m=['GET']),
                    route('/<_id:{cid}>/files/<filename:{fname}>', AnalysesHandler, h='download',    m=['GET']),
                ]),

                route('/<list_name:notes>',             NotesListHandler,               m=['POST']),
                route('/<list_name:notes>/<_id:{nid}>', NotesListHandler, name='notes', m=['GET', 'PUT', 'DELETE']),
        prefix('/<:{cname}>/<:{cid}>/<cont_name:analyses>/<cid:{cid}>', [
            route('/<list_name:notes>',             NotesListHandler,               m=['POST']),
            route('/<list_name:notes>/<_id:{nid}>', NotesListHandler, name='notes', m=['GET', 'PUT', 'DELETE']),
        ]),


Nathaniel Kofalt's avatar
Nathaniel Kofalt committed
        # Misc (to be cleaned up later)

        route('/<par_cont_name:groups>/<par_id:{gid}>/<cont_name:projects>', ContainerHandler, h='get_all', m=['GET']),
        route('/<par_cont_name:{cname}>/<par_id:{cid}>/<cont_name:{cname}>', ContainerHandler, h='get_all', m=['GET']),