def token_auth_error(status): '''用于在 Token Auth 认证失败的情况下返回错误响应''' print('错误状态吗', status) # return error_response(401) if status == 401: return restfulResponse(data="", msg="认证失败,token非法或过期", code=status) elif status == 403: return restfulResponse(data="", msg=f"权限不足,当前角色为{g.current_user.role}", code=status)
def get_user(): '''返回一个用户''' id = request.args.get('id', None, type=int) if id: user = User.query.get_or_404(id) if id is None: user = g.current_user return restfulResponse(user.to_dict(include_email=True)) data = user.to_dict() return restfulResponse(data)
def get_token(): token = g.current_user.get_jwt() # 每次用户登录(即成功获取 JWT 后),更新 last_seen 时间 g.current_user.ping() db.session.commit() print(token) return restfulResponse({'token': token})
def update_post(): '''修改病人信息''' data = request.get_json() print('sa', data) if not data: return bad_request('You must post JSON data.') id = data.get('id', 0) post = PatientBasicInformation.query.get_or_404(id) # if g.current_user != post.author and not g.current_user.is_administrator(): # return error_response(403) message = {} if 'name' not in data or not data.get('name').strip(): message['name'] = 'name is required.' # if 'date' not in data or not data.get('date').strip(): # message['date'] = 'date is required.' if 'sex' not in data or not data.get('sex').strip(): message['sex'] = 'sex is required.' if len(data.get('address')) > 255: message['address'] = 'address must less than 255 characters.' if message: return bad_request(message) post.from_dict(data) db.session.commit() return restfulResponse(post.to_dict())
def get_disease(id): '''返回当前患病详情''' post = DiseaseInformation.query.get_or_404(id) data = post.to_dict() # 下一个病人信息 next_basequery = DiseaseInformation.query.order_by( DiseaseInformation.timestamp.desc()).filter( DiseaseInformation.timestamp > post.timestamp) if next_basequery.all(): data['next_id'] = next_basequery[-1].id data['next_title'] = next_basequery[-1].name data['_links']['next'] = url_for('api.get_disease', id=next_basequery[-1].id) else: data['_links']['next'] = None # 上一个病人信息 prev_basequery = DiseaseInformation.query.order_by( DiseaseInformation.timestamp.desc()).filter( DiseaseInformation.timestamp < post.timestamp) if prev_basequery.first(): data['prev_id'] = prev_basequery.first().id data['prev_title'] = prev_basequery.first().name data['_links']['prev'] = url_for('api.get_disease', id=prev_basequery.first().id) else: data['_links']['prev'] = None return restfulResponse(data)
def create_post(): '''添加新的病人基础信息''' data = request.get_json() print(data) if not data: return bad_request('You must post JSON data.') message = {} if 'name' not in data or not data.get('name').strip(): message['name'] = 'name is required.' if 'date' not in data or not data.get('date').strip(): message['date'] = 'date is required.' if 'sex' not in data or not data.get('sex').strip(): message['sex'] = 'sex is required.' if len(data.get('address')) > 255: message['address'] = 'address must less than 255 characters.' if message: return bad_request(message) patient = PatientBasicInformation() patient.from_dict(data) db.session.add(patient) db.session.commit() response = restfulResponse(patient.to_dict()) response.status_code = 201 # HTTP协议要求201响应包含一个值为新资源URL的Location头部 response.headers['Location'] = url_for('api.get_patients', id=patient.id) return response
def get_patients(): '''返回病人集合,分页''' page = request.args.get('page', 1, type=int) per_page = min( request.args.get('limit', current_app.config['POSTS_PER_PAGE'], type=int), 100) queryMap = [] queryMap.append(PatientBasicInformation.deleted == False) # 非删除 name = request.args.get('name', None) sex = request.args.get('sex', None) if name: queryMap.append(PatientBasicInformation.name == name) if sex: queryMap.append(PatientBasicInformation.sex == sex) querySort = [] sort = request.args.get('sort', '+id') if sort == "+id": querySort.append(PatientBasicInformation.id.asc()) else: querySort.append(PatientBasicInformation.id.desc()) data = PatientBasicInformation.to_collection_dict( PatientBasicInformation.query.filter(*queryMap).order_by(*querySort), page, per_page, 'api.get_patients') return restfulResponse(data)
def error_response(status_code, message=None): # payload = {'error': HTTP_STATUS_CODES.get(status_code, 'Unknown error')} # if message: # payload['message'] = message # response = jsonify(payload) # response.status_code = status_code # return response return restfulResponse(data="", msg=message, code=status_code)
def delete_post(id): '''删除一位病人信息''' post = PatientBasicInformation.query.get_or_404(id) # if g.current_user != post.author and not g.current_user.is_administrator(): # return error_response(403) if post.diseases_history is not None: return restfulResponse({'msg': '此病人还有关联信息尚未清除,不能删除'}) db.session.delete(post) db.session.commit() return '', 204
def delete_disease(id): '''删除一条疾病信息''' post = DiseaseInformation.query.get_or_404(id) # if g.current_user != post.author and not g.current_user.is_administrator(): # return error_response(403) # if post.sequences is not None: # return restfulResponse({'msg':'此疾病还有关联测序信息尚未清除,不能删除'}) post.deleted = True db.session.commit() return restfulResponse({})
def export_posts(): '''导出当前用户的所有文章,RQ 后台任务''' if g.current_user.get_task_in_progress( 'export_posts'): # 如果用户已经有同名的后台任务在运行中时 return bad_request('上一个导出文章的后台任务尚未结束') else: # 将 app.utils.tasks.export_posts 放入任务队列中 g.current_user.launch_task('export_posts', '正在导出文章...', kwargs={'user_id': g.current_user.id}) return restfulResponse(message='正在运行导出文章后台任务')
def update_user(): '''修改一个用户''' print('dsddsd', g.current_user.id) user = User.query.get_or_404(g.current_user.id) print(user) data = request.get_json() if not data: return bad_request(_('You must post JSON data.')) email = data.get('email', None) name = data.get('name', None) pattern = '^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$' if not email or not re.match(pattern, email): return restfulResponse(data={}, msg="请提供正确的邮箱地址.", code=403) if not name: return restfulResponse(data={}, msg="用户名不能为空.", code=403) user.from_dict(data, new_user=False) db.session.commit() return restfulResponse(user.to_dict())
def update_disease(): '''修改疾病信息''' # if g.current_user != post.author and not g.current_user.is_administrator(): # return error_response(403) data = request.get_json() post = DiseaseInformation.query.get_or_404(data['id']) if not data: return bad_request('You must post JSON data.') post.from_dict(data) db.session.commit() return restfulResponse(post.to_dict())
def get_patient_diseases(): '''获取所有疾病信息''' page = request.args.get('page', 1, type=int) per_page = min( request.args.get('limit', current_app.config['POSTS_PER_PAGE'], type=int), 100) data = DiseaseInformation.to_collection_dict( DiseaseInformation.query.filter( DiseaseInformation.deleted == False).order_by( DiseaseInformation.timestamp.desc()), page, per_page, 'api.get_sequences') print('疾病', data) print(type(data)) return restfulResponse(data)
def excel_create_disease(): '''excel导入样本疾病信息''' data = request.get_json() if not data: return bad_request('excel表内容为空') sample_data = data['data'] # print(sample_data) sample_header = data['header'] # print(sample_header) n = 1 with db.session.no_autoflush: for data in sample_data: n += 1 name = data.get('姓名', None) origin = data.get('样品来源', None) if not name or not origin or name == '姓名': continue patient = PatientBasicInformation.query.filter( PatientBasicInformation.name == name).filter( PatientBasicInformation.name == data['样品来源']).first() or PatientBasicInformation() patient.from_dict(data, trans=True) sequence_id = data.get('Sequence ID', None) sequence = SampleSequence.query.get( sequence_id) or SampleSequence() sequence.from_dict(data, trans=True) disease = DiseaseInformation.query.filter( sequence.disease_info.patient_id == patient.id).first( ) if sequence.disease_info else DiseaseInformation() disease.from_dict(data, trans=True) disease.patient_id = patient.id sequence.disease_id = disease.id db.session.add(disease) db.session.add(patient) db.session.add(sequence) if sequence.sequence_id == 'Sequence ID': print('id:', sequence.sequence_id) print(n, data) db.session.commit() return restfulResponse({})
def search(): '''Elasticsearch全文检索博客文章''' q = request.args.get('q') if not q: return bad_request(message='keyword is required.') page = request.args.get('page', 1, type=int) per_page = min( request.args.get('per_page', current_app.config['POSTS_PER_PAGE'], type=int), 100) total, hits_basequery = PatientBasicInformation.search(q, page, per_page) # 总页数 total_pages, div = divmod(total, per_page) if div > 0: total_pages += 1 # 不能使用 PatientBasicInformation.to_collection_dict(),因为查询结果已经分页过了 data = { 'items': [item.to_dict() for item in hits_basequery], '_meta': { 'page': page, 'per_page': per_page, 'total_pages': total_pages, 'total_items': total }, '_links': { 'self': url_for('api.search', q=q, page=page, per_page=per_page), 'next': url_for('api.search', q=q, page=page + 1, per_page=per_page) if page < total_pages else None, 'prev': url_for('api.search', q=q, page=page - 1, per_page=per_page) if page > 1 else None } } return restfulResponse(data=data, message='Total items: {}, current page: {}'.format( total, page))
def create_disease(): '''添加新的病人患病信息''' data = request.get_json() print(data) if not data: return bad_request('You must post JSON data.') # patient = PatientBasicInformation.query.get_or_404(id) # if not patient: # return bad_request('该病人信息不存在') disease_info = DiseaseInformation() disease_info.from_dict(data) # disease_info.patient_id = id db.session.add(disease_info) db.session.commit() response = restfulResponse(disease_info.to_dict()) response.status_code = 201 # HTTP协议要求201响应包含一个值为新资源URL的Location头部 # response.headers['Location'] = url_for('api.get_patient_diseases', id=data.id) return response
def get_search_post(id): '''从搜索结果列表页跳转到文章详情''' q = request.args.get('q') page = request.args.get('page', type=int) per_page = request.args.get('per_page', type=int) if q and page and per_page: # 说明是从搜索结果页中过来查看文章详情的,所以要高亮关键字 total, hits_basequery = PatientBasicInformation.search( q, page, per_page) post = hits_basequery.first() # 只会有唯一的一篇文章 data = post.to_dict() # 会高亮关键字 else: post = PatientBasicInformation.query.get_or_404(id) data = post.to_dict() # 不会高亮关键字 # 下一篇文章 next_basequery = PatientBasicInformation.query.order_by( PatientBasicInformation.timestamp.desc()).filter( PatientBasicInformation.timestamp > post.timestamp) if next_basequery.all(): data['next_id'] = next_basequery[-1].id data['next_title'] = next_basequery[-1].title data['_links']['next'] = url_for('api.get_post', id=next_basequery[-1].id) else: data['_links']['next'] = None # 上一篇文章 prev_basequery = PatientBasicInformation.query.order_by( PatientBasicInformation.timestamp.desc()).filter( PatientBasicInformation.timestamp < post.timestamp) if prev_basequery.first(): data['prev_id'] = prev_basequery.first().id data['prev_title'] = prev_basequery.first().title data['_links']['prev'] = url_for('api.get_post', id=prev_basequery.first().id) else: data['_links']['prev'] = None return restfulResponse(data)
def logout(): """用户退出""" return restfulResponse({})
def create_user(api=True): '''注册一个新用户''' data = request.get_json() if not data and api: return bad_request(_('You must post JSON data.')) message = {} if 'username' not in data or not data.get('username', None).strip(): message['username'] = _('Please provide a valid username.') pattern = '^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$' if 'email' not in data or not re.match(pattern, data.get('email', None)): message['email'] = _('Please provide a valid email address.') if 'password' not in data or not data.get('password', None).strip(): message['password'] = _('Please provide a valid password.') if User.query.filter_by(username=data.get('username', None)).first(): message['username'] = _('Please use a different username.') if User.query.filter_by(email=data.get('email', None)).first(): message['email'] = _('Please use a different email address.') if message: return bad_request(message) user = User() user.from_dict(data, new_user=True) user.confirmed = True db.session.add(user) db.session.commit() # 发送确认账户的邮件 token = user.generate_confirm_jwt() if not data.get('confirm_email_base_url'): confirm_url = 'http://127.0.0.1:5000/api/confirm/' + token else: confirm_url = data.get('confirm_email_base_url') + token text_body = ''' Dear {}, Welcome to Madblog! To confirm your account please click on the following link: {} Sincerely, The Madblog Team Note: replies to this email address are not monitored. '''.format(user.username, confirm_url) html_body = ''' <p>Dear {0},</p> <p>Welcome to <b>Madblog</b>!</p> <p>To confirm your account please <a href="{1}">click here</a>.</p> <p>Alternatively, you can paste the following link in your browser's address bar:</p> <p><b>{1}</b></p> <p>Sincerely,</p> <p>The Madblog Team</p> <p><small>Note: replies to this email address are not monitored.</small></p> '''.format(user.username, confirm_url) # send_email('[Madblog] Confirm Your Account', # sender=current_app.config['MAIL_SENDER'], # recipients=[user.email], # text_body=text_body, # html_body=html_body) response = restfulResponse(user.to_dict()) response.status_code = 201 # HTTP协议要求201响应包含一个值为新资源URL的Location头部 response.headers['Location'] = url_for('api.get_user', id=user.id) return response
def basic_auth_error(): '''用于在认证失败的情况下返回错误响应''' # return error_response(401) return restfulResponse(data="", msg="用户名或密码错误", code=50000)