def parse(self, id): """Parse the input word transcriptions using the morphological parser with id=``id``. :param str id: the ``id`` value of the morphological parser that will be used. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphological parser exists and foma is installed, a JSON object of the form ``{t1: p1, t2: p2, ...}`` where ``t1`` and ``t2`` are transcriptions of words from the request body and ``p1`` and ``p2`` are the most probable morphological parsers of t1 and t2. """ parser = Session.query(MorphologicalParser).get(id) if not parser: response.status_int = 404 return {'error': 'There is no morphological parser with id %s' % id} if not h.foma_installed(): response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} try: inputs = json.loads(unicode(request.body, request.charset)) schema = TranscriptionsSchema inputs = schema.to_python(inputs) inputs = [h.normalize(w) for w in inputs['transcriptions']] parses = parser.parse(inputs) # TODO: allow for a param which causes the candidates to be # returned as well as/instead of only the most probable parse # candidate. return dict((transcription, parse) for transcription, (parse, candidates) in parses.iteritems()) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def applydown(self, id): """Apply-down (i.e., phonologize) the input in the request body using a phonology. :URL: ``PUT /phonologies/applydown/id`` (or ``PUT /phonologies/phonologize/id``) :param str id: the ``id`` value of the phonology that will be used. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the phonology exists and foma is installed, a JSON object of the form ``{t1: [p1t1, p2t1, ...], ...}`` where ``t1`` is a transcription from the request body and ``p1t1``, ``p2t1``, etc. are phonologized outputs of ``t1``. """ phonology = Session.query(Phonology).get(id) if phonology: if h.foma_installed(): binary_path = phonology.get_file_path('binary') if os.path.isfile(binary_path): try: inputs = json.loads(unicode(request.body, request.charset)) inputs = MorphophonemicTranscriptionsSchema.to_python(inputs) inputs = [h.normalize(i) for i in inputs['transcriptions']] return phonology.applydown(inputs) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status_int = 400 return {'error': 'Phonology %d has not been compiled yet.' % phonology.id} else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'}
def compile(self, id): """Compile the script of a phonology as a foma FST. :URL: ``PUT /phonologies/compile/id`` :param str id: the ``id`` value of the phonology whose script will be compiled. :returns: if the phonology exists and foma is installed, the phonology model is returned; ``GET /phonologies/id`` must be polled to determine when and how the compilation task has terminated. .. note:: The script is compiled asynchronously in a worker thread. See :mod:`onlinelinguisticdatabase.lib.foma_worker`. """ phonology = Session.query(Phonology).get(id) if phonology: if h.foma_installed(): foma_worker_q.put({ 'id': h.generate_salt(), 'func': 'compile_phonology', 'args': { 'phonology_id': phonology.id, 'user_id': session['user'].id, 'timeout': h.phonology_compile_timeout } }) return phonology else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} else: response.status_int = 404 return {'error': 'There is no phonology with id %s' % id}
def apply(self, id, direction): """Call foma apply in the direction of ``direction`` on the input in the request body using a morphology. :param str id: the ``id`` value of the morphology that will be used. :param str direction: the direction of foma application. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphology exists and foma is installed, a JSON object of the form ``{t1: [p1t1, p2t1, ...], ...}`` where ``t1`` is a transcription from the request body and ``p1t1``, ``p2t1``, etc. are outputs of ``t1`` after apply up/down. """ morphology = Session.query(Morphology).get(id) if morphology: if h.foma_installed(): morphology_binary_path = morphology.get_file_path('binary') if os.path.isfile(morphology_binary_path): try: inputs = json.loads(unicode(request.body, request.charset)) inputs = MorphemeSequencesSchema.to_python(inputs) inputs = [h.normalize(i) for i in inputs['morpheme_sequences']] return morphology.apply(direction, inputs) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status_int = 400 return {'error': 'Morphology %d has not been compiled yet.' % morphology.id} else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'}
def servecompiled(self, id): """Serve the compiled foma script of the morphophonology FST of the morphological parser. :URL: ``PUT /morphologicalparsers/servecompiled/id`` :param str id: the ``id`` value of a morphological parser. :returns: a stream of bytes -- the compiled morphological parser script. """ parser = Session.query(MorphologicalParser).get(id) if parser: if h.foma_installed(): binary_path = parser.get_file_path('binary') if os.path.isfile(binary_path): return forward(FileApp(binary_path)) else: response.status_int = 400 return json.dumps({ 'error': 'The morphophonology foma script of ' 'MorphologicalParser %d has not been compiled yet.' % parser.id }) else: response.status_int = 400 return json.dumps( {'error': 'Foma and flookup are not installed.'}) else: response.status_int = 404 return json.dumps( {'error': 'There is no morphological parser with id %s' % id})
def parse(self, id): """Parse the input word transcriptions using the morphological parser with id=``id``. :param str id: the ``id`` value of the morphological parser that will be used. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphological parser exists and foma is installed, a JSON object of the form ``{t1: p1, t2: p2, ...}`` where ``t1`` and ``t2`` are transcriptions of words from the request body and ``p1`` and ``p2`` are the most probable morphological parsers of t1 and t2. """ parser = Session.query(MorphologicalParser).get(id) if not parser: response.status_int = 404 return {'error': 'There is no morphological parser with id %s' % id} if not h.foma_installed(): response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} try: inputs = json.loads(unicode(request.body, request.charset)) schema = TranscriptionsSchema inputs = schema.to_python(inputs) return parser.parse(inputs['transcriptions']) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def generate_and_compile_morphological_parser(morphological_parser_id, compile_=True): morphological_parser = Session.query(MorphologicalParser).get(morphological_parser_id) if not morphological_parser: response.status_int = 404 return {'error': 'There is no morphological parser with id %s' % id} if compile_ and not h.foma_installed(): response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} foma_worker_q.put({ 'id': h.generate_salt(), 'func': 'generate_and_compile_parser', 'args': { 'morphological_parser_id': morphological_parser.id, 'compile': compile_, 'user_id': session['user'].id, 'timeout': h.morphological_parser_compile_timeout } }) return morphological_parser
def apply(self, id, direction): """Call foma apply in the direction of ``direction`` on the input in the request body using a morphological parser. :param str id: the ``id`` value of the morphological parser that will be used. :param str direction: the direction of foma application. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphological parser exists and foma is installed, a JSON object of the form ``{t1: [p1t1, p2t1, ...], ...}`` where ``t1`` is a transcription from the request body and ``p1t1``, ``p2t1``, etc. are outputs of ``t1`` after apply up/down. """ parser = Session.query(MorphologicalParser).get(id) if parser: if h.foma_installed(): binary_path = parser.get_file_path('binary') if os.path.isfile(binary_path): try: inputs = json.loads( unicode(request.body, request.charset)) schema, key = {'up': (TranscriptionsSchema, 'transcriptions'), 'down': (MorphemeSequencesSchema, 'morpheme_sequences')}.\ get(direction, (MorphemeSequencesSchema, 'morpheme_sequences')) inputs = schema.to_python(inputs) return parser.apply(direction, inputs[key]) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status_int = 400 return json.dumps({ 'error': 'The morphophonology foma script of ' 'MorphologicalParser %d has not been compiled yet.' % parser.id }) else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'}
def generate_and_compile_morphological_parser(morphological_parser_id, compile_=True): morphological_parser = Session.query(MorphologicalParser).get( morphological_parser_id) if not morphological_parser: response.status_int = 404 return {'error': 'There is no morphological parser with id %s' % id} if compile_ and not h.foma_installed(): response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} foma_worker_q.put({ 'id': h.generate_salt(), 'func': 'generate_and_compile_parser', 'args': { 'morphological_parser_id': morphological_parser.id, 'compile': compile_, 'user_id': session['user'].id, 'timeout': h.morphological_parser_compile_timeout } }) return morphological_parser
def parse(self, id): """Parse the input word transcriptions using the morphological parser with id=``id``. :param str id: the ``id`` value of the morphological parser that will be used. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphological parser exists and foma is installed, a JSON object of the form ``{t1: p1, t2: p2, ...}`` where ``t1`` and ``t2`` are transcriptions of words from the request body and ``p1`` and ``p2`` are the most probable morphological parsers of t1 and t2. """ parser = Session.query(MorphologicalParser).get(id) if not parser: response.status_int = 404 return { 'error': 'There is no morphological parser with id %s' % id } if not h.foma_installed(): response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} try: inputs = json.loads(unicode(request.body, request.charset)) schema = TranscriptionsSchema inputs = schema.to_python(inputs) inputs = [h.normalize(w) for w in inputs['transcriptions']] parses = parser.parse(inputs) # TODO: allow for a param which causes the candidates to be # returned as well as/instead of only the most probable parse # candidate. return dict( (transcription, parse) for transcription, (parse, candidates) in parses.iteritems()) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()}
def servecompiled(self, id): """Serve the compiled foma script of the phonology. :URL: ``PUT /phonologies/servecompiled/id`` :param str id: the ``id`` value of a phonology. :returns: a stream of bytes -- the compiled phonology script. """ phonology = Session.query(Phonology).get(id) if phonology: if h.foma_installed(): compiled_path = phonology.get_file_path('binary') if os.path.isfile(compiled_path): return forward(FileApp(compiled_path)) else: response.status_int = 400 return json.dumps({'error': 'Phonology %d has not been compiled yet.' % phonology.id}) else: response.status_int = 400 return json.dumps({'error': 'Foma and flookup are not installed.'}) else: response.status_int = 404 return json.dumps({'error': 'There is no phonology with id %s' % id})
def runtests(self, id): """Run the tests defined in the phonology's script against the phonology. A line in a phonology's script that begins with "#test" signifies a test. After "#test" there should be a string of characters followed by "->" followed by another string of characters. The first string is the underlying representation and the second is the anticipated surface representation. Requests to ``GET /phonologies/runtests/id`` will cause the OLD to run a phonology script against its tests and return a dictionary detailing the expected and actual outputs of each input in the transcription. :URL: ``GET /phonologies/runtests/id`` :param str id: the ``id`` value of the phonology that will be tested. :returns: if the phonology exists and foma is installed, a JSON object representing the results of the test. """ phonology = Session.query(Phonology).get(id) if phonology: if h.foma_installed(): try: test_results = phonology.run_tests() if test_results: return test_results else: response.status_int = 400 return {'error': 'The script of phonology %d contains no tests.' % phonology.id} except AttributeError: response.status_int = 400 return {'error': 'Phonology %d has not been compiled yet.' % phonology.id} else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'} else: response.status_int = 404 return {'error': 'There is no phonology with id %s' % id}
def apply(self, id, direction): """Call foma apply in the direction of ``direction`` on the input in the request body using a morphological parser. :param str id: the ``id`` value of the morphological parser that will be used. :param str direction: the direction of foma application. :Request body: JSON object of the form ``{'transcriptions': [t1, t2, ...]}``. :returns: if the morphological parser exists and foma is installed, a JSON object of the form ``{t1: [p1t1, p2t1, ...], ...}`` where ``t1`` is a transcription from the request body and ``p1t1``, ``p2t1``, etc. are outputs of ``t1`` after apply up/down. """ parser = Session.query(MorphologicalParser).get(id) if parser: if h.foma_installed(): binary_path = parser.get_file_path('binary') if os.path.isfile(binary_path): try: inputs = json.loads(unicode(request.body, request.charset)) schema, key = {'up': (TranscriptionsSchema, 'transcriptions'), 'down': (MorphemeSequencesSchema, 'morpheme_sequences')}.\ get(direction, (MorphemeSequencesSchema, 'morpheme_sequences')) inputs = schema.to_python(inputs) return parser.apply(direction, inputs[key]) except h.JSONDecodeError: response.status_int = 400 return h.JSONDecodeErrorResponse except Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status_int = 400 return json.dumps({'error': 'The morphophonology foma script of ' 'MorphologicalParser %d has not been compiled yet.' % parser.id}) else: response.status_int = 400 return {'error': 'Foma and flookup are not installed.'}
def servecompiled(self, id): """Serve the compiled foma script of the morphophonology FST of the morphological parser. :URL: ``PUT /morphologicalparsers/servecompiled/id`` :param str id: the ``id`` value of a morphological parser. :returns: a stream of bytes -- the compiled morphological parser script. """ parser = Session.query(MorphologicalParser).get(id) if parser: if h.foma_installed(): binary_path = parser.get_file_path('binary') if os.path.isfile(binary_path): return forward(FileApp(binary_path)) else: response.status_int = 400 return json.dumps({'error': 'The morphophonology foma script of ' 'MorphologicalParser %d has not been compiled yet.' % parser.id}) else: response.status_int = 400 return json.dumps({'error': 'Foma and flookup are not installed.'}) else: response.status_int = 404 return json.dumps({'error': 'There is no morphological parser with id %s' % id})