def handle_request(content, server): start = time.time() ensure_required_params(["action"], "All actions", content) session_id = "<unknown>" if content.get("session-id", None): session_id = content["session-id"] action = content["action"] logger.info("Received action %s for session %s" % (action, session_id)) nav_mode = content.get("nav", "prompt") try: # Formplayer routes if action == xformplayer.Actions.NEW_FORM: form_fields = {"form-name": "uid", "form-content": "raw", "form-url": "url"} form_spec = None for k, v in form_fields.iteritems(): try: form_spec = (v, content[k]) break except KeyError: pass if not form_spec: return {"error": "form specification required (form-name, form-content, or form-url)"} if "instance-content" in content: inst_spec = ("raw", content["instance-content"]) else: inst_spec = None session_data = content.get("session-data", {}) return xformplayer.open_form( form_spec, inst_spec, **{ "init_lang": content.get("lang"), "extensions": server.extensions, "session_data": session_data, "nav_mode": nav_mode, "api_auth": content.get("hq_auth"), "form_context": content.get("form_context", {}), "staleness_window": content.get("staleness_window", server.default_stale_window), } ) elif action == xformplayer.Actions.ANSWER: ensure_required_params(["session-id", "answer"], action, content) return xformplayer.answer_question(content["session-id"], content["answer"], content.get("ix")) # sequential (old-style) repeats only elif action == xformplayer.Actions.ADD_REPEAT: ensure_required_params(["session-id"], action, content) return xformplayer.new_repetition(content["session-id"]) elif action == xformplayer.Actions.NEXT: ensure_required_params(["session-id"], action, content) return xformplayer.skip_next(content["session-id"]) elif action == xformplayer.Actions.BACK: ensure_required_params(["session-id"], action, content) return xformplayer.go_back(content["session-id"]) elif action == xformplayer.Actions.CURRENT: ensure_required_params(["session-id"], action, content) override_state = None # override api_auth with the current auth to avoid issues with expired django sessions # when editing saved forms hq_auth = content.get("hq_auth") if hq_auth: override_state = {"api_auth": hq_auth} return xformplayer.current_question(content["session-id"], override_state=override_state) elif action == xformplayer.Actions.HEARTBEAT: return {} elif action == xformplayer.Actions.EDIT_REPEAT: ensure_required_params(["session-id", "ix"], action, content) return xformplayer.edit_repeat(content["session-id"], content["ix"]) elif action == xformplayer.Actions.NEW_REPEAT: ensure_required_params(["session-id"], action, content) return xformplayer.new_repeat(content["session-id"], content.get("ix")) elif action == xformplayer.Actions.DELETE_REPEAT: ensure_required_params(["session-id", "ix"], action, content) return xformplayer.delete_repeat(content["session-id"], content["ix"], content.get("form_ix")) elif action == xformplayer.Actions.SUBMIT_ALL: ensure_required_params(["session-id"], action, content) return xformplayer.submit_form( content["session-id"], content.get("answers", []), content.get("prevalidated", False) ) elif action == xformplayer.Actions.SET_LANG: ensure_required_params(["session-id", "lang"], action, content) return xformplayer.set_locale(content["session-id"], content["lang"]) elif action == xformplayer.Actions.PURGE_STALE: ensure_required_params(["window"], action, content) return xformplayer.purge(content["window"]) elif action == xformplayer.Actions.GET_INSTANCE: ensure_required_params(["session-id"], action, content) xfsess = xformplayer.global_state.get_session(content["session-id"]) return {"output": xfsess.output(), "xmlns": xfsess.get_xmlns()} elif action == xformplayer.Actions.EVALUATE_XPATH: ensure_required_params(["session-id"], action, content) xfsess = xformplayer.global_state.get_session(content["session-id"]) result = xfsess.evaluate_xpath(content["xpath"]) return {"output": result["output"], "status": result["status"]} # Touchcare routes elif action == touchcare.Actions.FILTER_CASES: ensure_required_params(["hq_auth", "filter_expr"], action, content) result = touchcare.filter_cases( content.get("filter_expr"), content.get("hq_auth"), content.get("session_data", {}), content.get("form_context", {}), ) return result else: raise InvalidRequestException("Unrecognized action: %s" % action) except xformplayer.NoSuchSession: return {"error": "invalid session id"} except xformplayer.SequencingException: return {"error": "session is locked by another request"} finally: delta = (time.time() - start) * 1000 domain = "<unknown>" if content.get("session-id", None) and xformplayer.global_state: xfsess = xformplayer.global_state.get_session(session_id) domain = xfsess.orig_params["session_data"].get("domain", "<unknown>") elif content.get("session-data", None): domain = content["session-data"].get("domain", "<unknown>") elif content.get("session_data", None): domain = content["session_data"].get("domain", "<unknown>") logger.info( "Finished processing action %s in %s ms for session %s in domain '%s'" % (action, delta, session_id, domain) )
def handle_request (content, **kwargs): if 'action' not in content: return {'error': 'action required'} action = content['action'] nav_mode = content.get('nav', 'prompt') try: if action == 'new-form': if 'form-name' not in content: return {'error': 'form identifier required'} preload_data = content.get("preloader-data", {}) return xformplayer.open_form(content['form-name'], content.get('instance-content'), content.get('lang'), kwargs.get('extensions', []), preload_data, nav_mode) elif action == 'edit-form': return {'error': 'unsupported'} elif action == 'answer': if 'session-id' not in content: return {'error': 'session id required'} if 'answer' not in content: return {'error': 'answer required'} return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix')) #sequential (old-style) repeats only elif action == 'add-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repetition(content['session-id']) elif action == 'next': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.skip_next(content['session-id']) elif action == 'back': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.go_back(content['session-id']) elif action == 'edit-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.edit_repeat(content['session-id'], content['ix']) elif action == 'new-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repeat(content['session-id'], content.get('ix')) elif action == 'delete-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix')) elif action == 'submit-all': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False)) elif action == 'set-lang': if 'session-id' not in content: return {'error': 'session id required'} if 'lang' not in content: return {'error': 'language required'} return xformplayer.set_locale(content['session-id'], content['lang']) elif action == 'purge-stale': if 'window' not in content: return {'error': 'staleness window required'} return xformplayer.purge(content['window']) else: return {'error': 'unrecognized action'} except xformplayer.NoSuchSession: return {'error': 'invalid session id'} except xformplayer.SequencingException: return {'error': 'session is locked by another request'}
def handle_request(content, server): start = time.time() ensure_required_params(['action'], 'All actions', content) session_id = '<unknown>' if content.get('session-id', None): session_id = content['session-id'] action = content['action'] logger.info('Received action %s for session %s' % (action, session_id)) datadog_logger.info( 'event=received action=%s unit=request' % (action), extra={'value': 1, 'metric_type': 'counter', 'timestamp': int(time.time()), 'metric': 'actions'} ) nav_mode = content.get('nav', 'prompt') try: # Formplayer routes if action == xformplayer.Actions.NEW_FORM: form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'} form_spec = None for k, v in form_fields.iteritems(): try: form_spec = (v, content[k]) break except KeyError: pass if not form_spec: return {'error': 'form specification required (form-name, form-content, or form-url)'} if 'instance-content' in content: inst_spec = ('raw', content['instance-content']) else: inst_spec = None session_data = content.get("session-data", {}) return xformplayer.open_form(form_spec, inst_spec, **{ 'init_lang': content.get('lang'), 'extensions': server.extensions, 'session_data': session_data, 'nav_mode': nav_mode, 'api_auth': content.get('hq_auth'), 'form_context': content.get('form_context', {}), 'staleness_window': content.get('staleness_window', server.default_stale_window), 'uses_sql_backend': content.get('uses_sql_backend'), }) elif action == xformplayer.Actions.ANSWER: ensure_required_params(['session-id', 'answer'], action, content) return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix')) #sequential (old-style) repeats only elif action == xformplayer.Actions.ADD_REPEAT: ensure_required_params(['session-id'], action, content) return xformplayer.new_repetition(content['session-id']) elif action == xformplayer.Actions.NEXT: ensure_required_params(['session-id'], action, content) return xformplayer.skip_next(content['session-id']) elif action == xformplayer.Actions.BACK: ensure_required_params(['session-id'], action, content) return xformplayer.go_back(content['session-id']) elif action == xformplayer.Actions.CURRENT: ensure_required_params(['session-id'], action, content) override_state = _get_override_state(content) return xformplayer.current_question(content['session-id'], override_state=override_state) elif action == xformplayer.Actions.HEARTBEAT: return {} elif action == xformplayer.Actions.EDIT_REPEAT: ensure_required_params(['session-id', 'ix'], action, content) return xformplayer.edit_repeat(content['session-id'], content['ix']) elif action == xformplayer.Actions.NEW_REPEAT: ensure_required_params(['session-id'], action, content) return xformplayer.new_repeat(content['session-id'], content.get('ix')) elif action == xformplayer.Actions.DELETE_REPEAT: ensure_required_params(['session-id', 'ix'], action, content) return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix')) elif action == xformplayer.Actions.SUBMIT_ALL: ensure_required_params(['session-id'], action, content) return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False)) elif action == xformplayer.Actions.SET_LANG: ensure_required_params(['session-id', 'lang'], action, content) return xformplayer.set_locale(content['session-id'], content['lang']) elif action == xformplayer.Actions.PURGE_STALE: ensure_required_params(['window'], action, content) return xformplayer.purge(content['window']) elif action == xformplayer.Actions.GET_INSTANCE: ensure_required_params(['session-id'], action, content) xfsess = xformplayer.global_state.get_session(content['session-id']) return {"output": xfsess.output(), "xmlns": xfsess.get_xmlns()} elif action == xformplayer.Actions.EVALUATE_XPATH: ensure_required_params(['session-id'], action, content) xfsess = xformplayer.global_state.get_session(content['session-id']) result = xfsess.evaluate_xpath(content['xpath']) return {"output": result['output'], "status": result['status']} elif action == xformplayer.Actions.SYNC_USER_DB: ensure_required_params(['username', 'domain', 'hq_auth'], action, content) username = content['username'] domain = content['domain'] # if a mobile user, we only want the username up to the @{domain}.{host} portion if username.endswith('commcarehq.org'): username = content['username'][:content['username'].index('@')] result = touchcare.force_ota_restore(username, domain, auth=content['hq_auth']) return result # Touchcare routes elif action == touchcare.Actions.FILTER_CASES: ensure_required_params(['hq_auth', 'filter_expr'], action, content) result = touchcare.filter_cases( content.get('filter_expr'), content.get('hq_auth'), content.get('session_data', {}), content.get('form_context', {}), uses_sqlite=content.get('uses_sql_backend', False) ) return result else: raise InvalidRequestException("Unrecognized action: %s" % action) except xformplayer.NoSuchSession: return {'error': 'invalid session id'} except xformplayer.SequencingException: return {'error': 'session is locked by another request'} finally: delta = (time.time() - start) * 1000 _log_action(action, content, delta, session_id)
def handle_request (content, **kwargs): if 'action' not in content: return {'error': 'action required'} action = content['action'] nav_mode = content.get('nav', 'prompt') try: if action == 'new-form': if 'form-name' not in content: return {'error': 'form identifier required'} preload_data = content["preloader-data"] if "preloader-data" in content else {} return xformplayer.open_form(content['form-name'], content.get('instance-content'), kwargs.get('extensions', []), preload_data, nav_mode) elif action == 'edit-form': return {'error': 'unsupported'} elif action == 'answer': if 'session-id' not in content: return {'error': 'session id required'} if 'answer' not in content: return {'error': 'answer required'} return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix')) #sequential (old-style) repeats only elif action == 'add-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repetition(content['session-id']) elif action == 'next': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.skip_next(content['session-id']) elif action == 'back': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.go_back(content['session-id']) elif action == 'edit-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.edit_repeat(content['session-id'], content['ix']) elif action == 'new-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repeat(content['session-id'], content.get('ix')) elif action == 'delete-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix')) elif action == 'submit-all': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False)) elif action == 'purge-stale': if 'window' not in content: return {'error': 'staleness window required'} return xformplayer.purge(content['window']) else: return {'error': 'unrecognized action'} except xformplayer.NoSuchSession: return {'error': 'invalid session id'} except xformplayer.SequencingException: return {'error': 'session is locked by another request'}
def handle_request (content, server): if 'action' not in content: return {'error': 'action required'} action = content['action'] nav_mode = content.get('nav', 'prompt') try: if action == 'new-form': form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'} form_spec = None for k, v in form_fields.iteritems(): try: form_spec = (v, content[k]) break except KeyError: pass if not form_spec: return {'error': 'form specification required (form-name, form-content, or form-url)'} inst_fields = {'instance-content': 'raw'} inst_spec = None for k, v in inst_fields.iteritems(): try: inst_spec = (v, content[k]) break except KeyError: pass session_data = content.get("session-data", {}) return xformplayer.open_form(form_spec, inst_spec, **{ 'init_lang': content.get('lang'), 'extensions': server.extensions, 'session_data': session_data, 'nav_mode': nav_mode, 'api_auth': content.get('hq_auth'), 'staleness_window': content.get('staleness_window', server.default_stale_window), }) elif action == 'edit-form': return {'error': 'unsupported'} elif action == 'answer': if 'session-id' not in content: return {'error': 'session id required'} if 'answer' not in content: return {'error': 'answer required'} return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix')) #sequential (old-style) repeats only elif action == 'add-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repetition(content['session-id']) elif action == 'next': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.skip_next(content['session-id']) elif action == 'back': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.go_back(content['session-id']) elif action == 'current': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.current_question(content['session-id']) elif action == 'heartbeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.heartbeat(content['session-id']) elif action == 'edit-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.edit_repeat(content['session-id'], content['ix']) elif action == 'new-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repeat(content['session-id'], content.get('ix')) elif action == 'delete-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix')) elif action == 'submit-all': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False)) elif action == 'set-lang': if 'session-id' not in content: return {'error': 'session id required'} if 'lang' not in content: return {'error': 'language required'} return xformplayer.set_locale(content['session-id'], content['lang']) elif action == 'purge-stale': if 'window' not in content: return {'error': 'staleness window required'} return xformplayer.purge(content['window']) elif action in touchcare.SUPPORTED_ACTIONS: return touchcare.handle_request(content, server) elif action == 'get-instance': if 'session-id' not in content: return {'error': 'session id required'} xfsess = xformplayer.global_state.get_session(content['session-id']) return {"output": xfsess.output()} else: return {'error': 'unrecognized action'} except xformplayer.NoSuchSession: return {'error': 'invalid session id'} except xformplayer.SequencingException: return {'error': 'session is locked by another request'}
def handle_request (content, **kwargs): if 'action' not in content: return {'error': 'action required'} action = content['action'] nav_mode = content.get('nav', 'prompt') try: if action == 'new-form': form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'} form_spec = None for k, v in form_fields.iteritems(): try: form_spec = (v, content[k]) break except KeyError: pass if not form_spec: return {'error': 'form specification required (form-name, form-content, or form-url)'} inst_fields = {'instance-content': 'raw'} inst_spec = None for k, v in inst_fields.iteritems(): try: inst_spec = (v, content[k]) break except KeyError: pass session_data = content.get("session-data", {}) return xformplayer.open_form(form_spec, inst_spec, content.get('lang'), kwargs.get('extensions', []), session_data, nav_mode, content.get('hq_auth')) elif action == 'edit-form': return {'error': 'unsupported'} elif action == 'answer': if 'session-id' not in content: return {'error': 'session id required'} if 'answer' not in content: return {'error': 'answer required'} return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix')) #sequential (old-style) repeats only elif action == 'add-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repetition(content['session-id']) elif action == 'next': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.skip_next(content['session-id']) elif action == 'back': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.go_back(content['session-id']) elif action == 'current': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.current_question(content['session-id']) elif action == 'edit-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.edit_repeat(content['session-id'], content['ix']) elif action == 'new-repeat': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.new_repeat(content['session-id'], content.get('ix')) elif action == 'delete-repeat': if 'session-id' not in content: return {'error': 'session id required'} if 'ix' not in content: return {'error': 'repeat index required'} return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix')) elif action == 'submit-all': if 'session-id' not in content: return {'error': 'session id required'} return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False)) elif action == 'set-lang': if 'session-id' not in content: return {'error': 'session id required'} if 'lang' not in content: return {'error': 'language required'} return xformplayer.set_locale(content['session-id'], content['lang']) elif action == 'purge-stale': if 'window' not in content: return {'error': 'staleness window required'} return xformplayer.purge(content['window']) elif action in touchcare.SUPPORTED_ACTIONS: return touchcare.handle_request(content, **kwargs) elif action == 'get-instance': if 'session-id' not in content: return {'error': 'session id required'} xfsess = xformplayer.global_state.get_session(content['session-id']) return {"output": xfsess.output()} else: return {'error': 'unrecognized action'} except xformplayer.NoSuchSession: return {'error': 'invalid session id'} except xformplayer.SequencingException: return {'error': 'session is locked by another request'}