<commit_before>import argparse
import json
from functools import partial
from flask import Flask, request
from flask_restful import Resource, Api, reqparse
from indra.pipeline import AssemblyPipeline, pipeline_functions
from indra.tools.assemble_corpus import *
from indra.statements import stmts_from_json


boolean_args = [
    'do_rename', 'use_adeft', 'do_methionine_offset', 'do_orthology_mapping',
    'do_isoform_mapping', 'use_cache', 'return_toplevel', 'flatten_evidence',
    'normalize_equivalences', 'normalize_opposites', 'invert', 'remove_bound',
    'specific_only', 'allow_families', 'match_suffix', 'update_belief']
list_args = [
    'gene_list', 'name_list', 'values', 'source_apis', 'uuids', 'curations',
    'correct_tags', 'ignores']
dict_args = [
    'grounding_map', 'misgrounding_map', 'hierarchies', 'whitelist',
    'mutations']
float_args = ['score_threshold', 'belief_cutoff']
int_args = ['poolsize', 'size_cutoff']
app = Flask(__name__)
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument('statements')


def _return_stmts(stmts):
    if stmts:
        stmts_json = stmts_to_json(stmts)
        res = {'statements': stmts_json}
    else:
        res = {'statements': []}
    return res


def add_arg_to_parser(arg, parser):
    if arg in list_args:
        dtype = list
    elif arg in boolean_args:
        dtype = inputs.boolean
    elif arg in int_args:
        dtype = int
    elif arg in float_args:
        dtype = float
    elif arg in dict_args:
        dtype = dict
    else:
        dtype = str
    parser.add_argument(arg, location='json')


class PreassembleStatements(Resource):
    def post(self, func_name):
        args = request.form.to_dict()
        # args = parser.parse_args()
        stmts = stmts_from_json(json.loads(args['statements']))
        stmts_out = pipeline_functions[func_name](stmts)
        return _return_stmts(stmts_out)


api.add_resource(PreassembleStatements, '/preassembly/<func_name>')


if __name__ == '__main__':
    argparser = argparse.ArgumentParser('Run the INDRA REST API')
    argparser.add_argument('--host', default='0.0.0.0')
    argparser.add_argument('--port', default=8081, type=int)
    args = argparser.parse_args()
    app.run(host=args.host, port=args.port)
<commit_msg>Implement preassembly resources with flask-restx<commit_after>import argparse
import inspect
from collections import namedtuple
from flask import Flask, request
from flask_restx import Api, Resource, reqparse, Namespace, inputs
from indra.pipeline import AssemblyPipeline, pipeline_functions
from indra.tools.assemble_corpus import *
from indra.statements import stmts_from_json, get_statement_by_name


boolean_args = [
    'do_rename', 'use_adeft', 'do_methionine_offset', 'do_orthology_mapping',
    'do_isoform_mapping', 'use_cache', 'return_toplevel', 'flatten_evidence',
    'normalize_equivalences', 'normalize_opposites', 'invert', 'remove_bound',
    'specific_only', 'allow_families', 'match_suffix', 'update_belief']
list_args = [
    'gene_list', 'name_list', 'values', 'source_apis', 'uuids', 'curations',
    'correct_tags', 'ignores']
dict_args = [
    'grounding_map', 'misgrounding_map', 'hierarchies', 'whitelist',
    'mutations']
float_args = ['score_threshold', 'belief_cutoff']
int_args = ['poolsize', 'size_cutoff']
app = Flask(__name__)
api = Api(app, title='INDRA REST API')
preassembly = Namespace('preassembly', path='/preassembly/')
api.add_namespace(preassembly)
parsers = {}


def _return_stmts(stmts):
    if stmts:
        stmts_json = stmts_to_json(stmts)
        res = {'statements': stmts_json}
    else:
        res = {'statements': []}
    return res


def add_arg_to_parser(arg, parser):
    if arg in list_args:
        dtype = list
    elif arg in boolean_args:
        dtype = inputs.boolean
    elif arg in int_args:
        dtype = int
    elif arg in float_args:
        dtype = float
    elif arg in dict_args:
        dtype = dict
    else:
        dtype = str
    parser.add_argument(arg, location='json')


class PreassembleStatements(Resource):
    func_name = None

    def process_args(self, args_json):
        args = parsers[self.func_name].parse_args()
        for arg in args_json:
            if arg not in args:
                add_arg_to_parser(arg, parsers[self.func_name])
        args = parsers[self.func_name].parse_args()
        for arg in args:
            if arg == 'stmt_type':
                args[arg] = get_statement_by_name(args[arg])
            elif arg in ['matches_fun', 'refinement_fun']:
                args[arg] = pipeline_functions[args[arg]]
            elif arg == 'curations':
                Curation = namedtuple(
                    'Curation', ['pa_hash', 'source_hash', 'tag'])
                args[arg] = [
                    Curation(cur['pa_hash'], cur['source_hash'], cur['tag'])
                    for cur in args[arg]]
        return args

    def post(self):
        args = self.process_args(request.json)
        stmts = stmts_from_json(args.pop('statements'))
        print(args)
        stmts_out = pipeline_functions[self.func_name](stmts, **args)
        return _return_stmts(stmts_out)


for func_name, func in pipeline_functions.items():
    if func.__module__ == 'indra.tools.assemble_corpus':
        doc = ''
        if func.__doc__:
            doc = func.__doc__.split('\n')[0]
        parser = reqparse.RequestParser()
        parser.add_argument('statements', type=list, location='json')
        for arg in inspect.getargspec(func).args:
            if arg != 'stmts_in':
                add_arg_to_parser(arg, parser)
        parsers[func_name] = parser

        @preassembly.expect(parsers[func_name])
        @preassembly.route(f'/{func_name}', doc={'description': doc})
        class NewFunction(PreassembleStatements):
            func_name = func_name


if __name__ == '__main__':
    argparser = argparse.ArgumentParser('Run the INDRA REST API')
    argparser.add_argument('--host', default='0.0.0.0')
    argparser.add_argument('--port', default=8081, type=int)
    argparserargs = argparser.parse_args()
    app.run(host=argparserargs.host, port=argparserargs.port)

{'fraction_non_alphanumeric': 0.11942235924062956, 'fraction_numerical': 0.0027583968846341066, 'mean_word_length': 3.434532374100719, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4700551', 'n_tokens_mistral': 2039, 'n_tokens_neox': 1991, 'n_words': 427}