diff --git a/nc_http/__init__.py b/nc_http/__init__.py index b3c06d4..ee0f28a 100644 --- a/nc_http/__init__.py +++ b/nc_http/__init__.py @@ -1 +1 @@ -__version__ = "0.0.1" \ No newline at end of file +__version__ = "0.0.1.1" \ No newline at end of file diff --git a/nc_http/core/__init__.py b/nc_http/core/__init__.py index e7bc240..f57e6fc 100644 --- a/nc_http/core/__init__.py +++ b/nc_http/core/__init__.py @@ -1,3 +1,20 @@ """ core: 依赖于第三方类库的工具函数、类 """ +from nc_http.core.excel.excel_reader import ExcelReader +from nc_http.core.excel.excel_writer import ExcelWriter +from nc_http.core.response.response import Response +from nc_http.core.response.response_meta import ResponseMeta +from nc_http.core.response.meta import Meta +from nc_http.core.verification.image import SimpleImageCaptcha +from nc_http.core.verification.storage import BaseCaptchaStorage + +__all__ = [ + 'ExcelReader', + 'ExcelWriter', + 'Response', + 'ResponseMeta', + 'Meta', + 'SimpleImageCaptcha', + 'BaseCaptchaStorage', +] diff --git a/nc_http/core/response/__init__.py b/nc_http/core/response/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nc_http/core/response/meta.py b/nc_http/core/response/meta.py new file mode 100644 index 0000000..cba41fe --- /dev/null +++ b/nc_http/core/response/meta.py @@ -0,0 +1,34 @@ +from nc_http.core import ResponseMeta + + +class Meta: + """ + 预设响应描述信息 + """ + OK = ResponseMeta(code=200, http_code=200, description='') + # 请求已经被实现,而且有一个新的资源已经依据请求的需要而创建。 + CREATED = ResponseMeta(code=201, http_code=201, description='') + # 资源已经删除。 + NO_CONTENT = ResponseMeta(code=204, http_code=204, description='') + # 由于包含语法错误,当前请求无法被服务器理解。 + BAD_REQUEST = ResponseMeta(code=400, http_code=400, description='请求数据错误!') + # 当前请求需要用户验证。 + UNAUTHORIZED = ResponseMeta(code=401, http_code=401, description='授权无效!') + # 服务器已经理解请求,但是拒绝执行它。 + FORBIDDEN = ResponseMeta(code=403, http_code=403, description='无访问权限,请退出重新登录!') + # 无权限操作 + OPERATE_FORBIDDEN = ResponseMeta(code=407, http_code=403, description='无操作权限') + # 请求失败,请求所希望得到的资源未被在服务器上发现。 + NOT_FOUND = ResponseMeta(code=404, http_code=404, description='资源不存在!') + # 请求行中指定的请求方法不能被用于请求相应的资源。 + METHOD_NOT_ALLOWED = ResponseMeta(code=405, http_code=405, description='方法不存在!') + # 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。 + NOT_ACCEPTABLE = ResponseMeta(code=406, http_code=406, description='客户端无效!') + # 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。 + INTERNAL_SERVER_ERROR = ResponseMeta(code=500, http_code=500, description='服务器内部错误!') + # 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。 + BAD_GATEWAY = ResponseMeta(code=502, http_code=502, description='接口错误!') + # 由于临时的服务器维护或者过载,服务器当前无法处理请求。 + SERVICE_UNAVAILABLE = ResponseMeta(code=503, http_code=503, description='服务暂时不可用!') + # 未能及时从上游服务器收到响应。 + GATEWAY_TIMEOUT = ResponseMeta(code=504, http_code=504, description='接口超时!') diff --git a/nc_http/core/response/response.py b/nc_http/core/response/response.py new file mode 100644 index 0000000..e9a4368 --- /dev/null +++ b/nc_http/core/response/response.py @@ -0,0 +1,75 @@ +from flask import g, request +from flask import json +from flask import make_response + + +class Response(object): + """ + 业务响应类 + """ + def __init__(self, data=None, meta=None, pagination=None, headers=None, code=200): + result = {} + + pagination = pagination or getattr(g, 'pagination', None) + if hasattr(pagination, 'present'): + result['pagination'] = pagination.present() + elif pagination: + result['pagination'] = pagination + + if hasattr(meta, 'present'): + result['meta'] = meta.present() + elif meta: + result['meta'] = meta + else: + # 默认 meta + result['meta'] = { + 'code': code, + 'message': '', + } + + if hasattr(data, 'present'): + result['data'] = data.present() + else: + result['data'] = data + + head = {'Content-Type': 'application/json'} + if headers: + head.update(headers) + + if head.get('Content-Type') == 'application/json': + result = json.dumps(result) + + head.update(cross_domain_headers()) + + response = make_response(result) + response.headers = head + + self.response = response + + def __call__(self, environ, start_response): + return self.response(environ, start_response) + + +def cross_domain_headers(is_list=False): + """ + 跨域 headers + :param is_list: + :return: + """ + origin = request.headers.get('Origin') + headers = {} + if origin: + headers['Access-Control-Allow-Origin'] = origin + headers['Access-Control-Allow-Credentials'] = 'true' + headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS' + headers['Access-Control-Allow-Headers'] = ', '.join(( + 'Origin', 'No-Cache', 'X-Requested-With', 'If-Modified-Since', 'Pragma', + 'Last-Modified', 'Cache-Control', 'Expires', 'Content-Type', + )) + else: + headers['Access-Control-Allow-Origin'] = '*' + + if is_list: + return [(key, value) for key, value in headers.items()] + else: + return headers diff --git a/nc_http/core/response/response_meta.py b/nc_http/core/response/response_meta.py new file mode 100644 index 0000000..ec26693 --- /dev/null +++ b/nc_http/core/response/response_meta.py @@ -0,0 +1,46 @@ +from werkzeug.wrappers import Response +from flask import json + +from nc_http.core.response.response import cross_domain_headers + + +class ResponseMeta(Exception): + """ + 响应描述信息 + """ + def __init__(self, code=None, description=None, http_code=400, **kwargs): + Exception.__init__(self) + self.http_code = http_code + self.code = code + self.description = description + self.extra = kwargs + + def update(self, **kwargs): + self.extra.update(kwargs) + + def present(self): + data = {} + if self.code: + data['code'] = self.code + if self.description: + data['message'] = self.description + + data.update(self.extra) + + return data + + def get_response(self): + meta = self.present() + if meta: + body = json.dumps({'meta': self.present()}) + else: + body = None + + headers = [('Content-Type', 'application/json')] + headers += cross_domain_headers(is_list=True) + + return Response(body, self.http_code, headers) + + def __call__(self, environ, start_response): + response = self.get_response() + return response(environ, start_response) diff --git a/nc_http/core/verification/storage.py b/nc_http/core/verification/storage.py index 7109b15..2f54f14 100644 --- a/nc_http/core/verification/storage.py +++ b/nc_http/core/verification/storage.py @@ -1,9 +1,9 @@ -from abc import abstractmethod, ABC +from abc import abstractmethod from nc_http.core.verification.image import SimpleImageCaptcha -class BaseCaptchaStorage(ABC): +class BaseCaptchaStorage: """ 验证码信息池 """ diff --git a/nc_http/utils/__init__.py b/nc_http/utils/__init__.py index 7497b68..5a078fd 100644 --- a/nc_http/utils/__init__.py +++ b/nc_http/utils/__init__.py @@ -1,3 +1,8 @@ """ utils: 依赖于 core 的类库 """ +from nc_http.utils.sheet.sheet import Sheet + +__all__ = [ + 'Sheet' +]