Repository: wuhan2020/api-server Branch: master Commit: 19b784d5e8f1 Files: 46 Total size: 72.1 KB Directory structure: gitextract_rth757f3/ ├── .dockerignore ├── .github/ │ ├── hypertrons.json │ ├── pull_request_template.md │ └── workflows/ │ └── pythonapp.yml ├── .gitignore ├── .gitmodules ├── .python-version ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README-cn.md ├── README.md ├── bootstrap ├── config/ │ ├── dev.py │ ├── product.py │ └── settings.py ├── const.py ├── requirements.txt ├── src/ │ ├── __init__.py │ ├── api/ │ │ ├── __init__.py │ │ ├── accommodations.py │ │ └── hospitals.py │ ├── core/ │ │ └── __init__.py │ ├── main.py │ ├── swagger/ │ │ ├── accommodations.yml │ │ ├── api.yml │ │ ├── archived/ │ │ │ ├── accomodation.yaml │ │ │ ├── donation.yaml │ │ │ ├── hospitaldemands.yaml │ │ │ ├── supplies.yaml │ │ │ └── suppliesunits.yaml │ │ ├── errors.yml │ │ ├── hospitals.yml │ │ └── validations.yaml │ ├── tests/ │ │ ├── __init__.py │ │ ├── data/ │ │ │ ├── csv/ │ │ │ │ ├── DONATION.csv │ │ │ │ ├── FACTORY.csv │ │ │ │ ├── HOSPITAL.csv │ │ │ │ ├── HOTEL.csv │ │ │ │ └── LOGISTICAL.csv │ │ │ ├── test.json │ │ │ └── test.xml │ │ └── test_nothing.py │ └── utils/ │ └── __init__.py ├── tools.py └── utils.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ README.md README-en.md CONTRIBUTING.md ================================================ FILE: .github/hypertrons.json ================================================ { "label_setup": { "version": 1, "labels": [ { "__merge__": true }, { "name": "pull/approved", "description": "If a pull is approved, it will be automatically merged", "color": "008672" } ] }, "role": { "version": 1, "roles": [ { "name": "replier", "description": "Replier is responsible for reply issues in time", "users": [ "LiuChangFreeman", "JamesBonddu" ], "commands": [] }, { "name": "approver", "description": "After approvers' approve, pulls should be merged automatically", "users": [ "LiuChangFreeman", "JamesBonddu" ], "commands": [ "/approve" ] }, { "name": "author", "description": "Author of the issue or pull", "users": [], "commands": [] }, { "name": "notauthor", "description": "Not author of the issue or pull", "users": [], "commands": [ "/approve" ] }, { "name": "anyone", "description": "Anyone", "users": [], "commands": [ "/self-assign" ] } ] }, "command": { "version": 1, "commands": [ { "name": "/approve", "scopes": [ "review", "review_comment", "pull_comment" ] } ] }, "approve": { "version": 1 }, "auto_merge": { "version": 1, "sched": "0 */5 * * * *" }, "issue_reminder": { "version": 1 }, "auto_label": { "version": 1 }, "self_assign": { "version": 1 }, "weekly_report": { "version": 1, "generateTime": "0 0 12 * * 1" } } ================================================ FILE: .github/pull_request_template.md ================================================ ### Purpose | 本PR解决的问题 - Closes # ### Changes | 本PR的更改 - No changes. ================================================ FILE: .github/workflows/pythonapp.yml ================================================ name: Tests on Pull Requests and Master on: push: branches: - master pull_request: jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v2 - name: Set up Python 3.6 uses: actions/setup-python@v1 with: python-version: 3.6 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Lint with flake8 run: | pip install flake8 # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Test with pytest run: | pip install pytest pytest -v src/tests ================================================ FILE: .gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. *.pyc __pycache__/ .vscode/ .idea/ .venv/ .env *.swp auth/ ================================================ FILE: .gitmodules ================================================ [submodule "wuhan2020"] path = wuhan2020 url = git@github.com:wuhan2020/wuhan2020.git ================================================ FILE: .python-version ================================================ 3.6.10 ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing Guide ## Structure ![Tech Arch Diagram](https://www.lucidchart.com/publicSegments/view/6ab27659-257a-44ce-a478-46dad3328b9c/image.png) As the above Tech Arch diagram shows (dot-line entities mean they are not there yet), this project is purely data-driven and the core layout looks like the following: ``` src ├── __init__.py ├── api/ ├── core/ ├── main.py ├── swagger/ ├── tests/ └── utils/ ``` `main.py` is the entry point of the services and it helps: - glue all sub API YML files together to an aggregated YML - send the YML to connection which renders the Swagger UI and applies the API resolvers. - load required service-level connfigurations (such as debug, logging, path to the data sources, etc.). ### To add new or edit on existing API endpoint(s) In general you need to edit the `src/swagger/api.yml` and probably its dependencies (such as `donation.yml`). **Be aware that any changes to the YML files can change the data model and breaks the system and the API consumers.** If you are using a local Python3.6 environment, setting `debug=True` in `main.py` will help you see the changes you made in the Swagger UI in real time. Be aware that the `operationId` field in the YML files works as automatic routers that map your endpoint to your Python views functions. To make the endpoints functional, you also have to add/edit the functions in `src/api`. The results of the functions need to be consistent with the data model defined in the API YML file(s). ## Development ![DevOps Pipeline](https://www.lucidchart.com/publicSegments/view/b853bf49-31fa-46ba-b732-2eb9de8a2cf8/image.png) The above diagram shows how to work on this repo: ### Development Process The development process of this project requires every contributor to fork the repo and only make PRs from the fork to `master` branch. #### Setup upstream From within your fork, use: ``` git remote add upstream git@github.com:wuhan2020/api-server.git ``` to setup this repo as the `upstream`. #### Keep up-to-date with the upstream Everytime before you want to make new changes to the repo, use: ``` git fetch upstream git rebase upstream/master ``` to update your fork with latest changes that have merged to `upstream`'s `master` branch. #### Address comments Once you have finished committing and pushing your changes to your remote fork, please create a PR from your remote repo following the PR template. One of the maintainers of the repo will review and merge your PR. Please note PR that fails the tests cannot be reviewed or merged. ## Deployment The current deployment is under construction and subjects to change. New documentation is coming soon... ================================================ FILE: Dockerfile ================================================ # Align with the CI/CD YML # We cannot use alpine since # we need to call bash in entrypoint FROM python:3.6 # Setup workdir WORKDIR /api-server # Copy src files COPY . . # Install deps RUN pip install -r requirements.txt # Expose port 5000 EXPOSE 9000 # Start the server ENTRYPOINT [ "bash", "bootstrap"] ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 援助武汉 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README-cn.md ================================================ # API Server ![Python3.6](https://img.shields.io/badge/python-3.6-green.svg?style=flat-square&logo=python&colorB=blue) [![Slack Channel](https://img.shields.io/badge/Slack%20Channel-%23api--server-green.svg?style=flat-square&colorB=blue)](https://app.slack.com/client/TT5U1VCPQ/CT3V5CDKJ) [![Built with love](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square)](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square&logo=love) ![Build Status](https://github.com/wuhan2020/api-server/workflows/Tests%20on%20Pull%20Requests%20and%20Master/badge.svg?branch=master&event=push) [English Version](README.md) 这是一个为了抗击在武汉乃至全球爆发的新型冠状病毒而建设的志愿信息收集和分享平台的后端API服务。 此API使用Python 和 Flask 编写,意在轻量化和无状态,通过标准的RESTFul接口传输依靠从其他子项目收集并验证的数据。 ## 快速上手 克隆此仓库及子模块仓库: ``` git clone https://github.com/wuhan2020/api-server cd api-server git clone https://github.com/wuhan2020/wuhan2020 ``` ### 在本地 Docker 容器运行(推荐) 首先,你需要安装[Docker客户端](https://www.docker.com/products/docker-desktop). #### 构建 Docker 镜像 在克隆的本仓库根目录下运行: ``` docker build -t api-server:default . ``` * 注意:这一步耗时取决于所在国家或地区 #### 运行已构建的 Docker 镜像 运行: ``` docker run --name api-server --publish 9000:9000 api-server:default ``` 然后在浏览器中打开 `http://localhost:9000` 。(使用 `-d` 来以后台模式(Detached mode)运行 Docker 容器) 在这一步后你应该可以看到记录了可用的端点的Swagger页面。 如果出现 `The container name "/api-server" is already in use` 报错可先执行 `docker rm api-server` 删除残留的同名容器. #### 停止运行中的 Docker 容器 运行: ``` docker stop api-server ``` 停止运行中的容器. ### 在Python环境中运行 确保你已经安装 **Python3.6** (一般来讲你应该会使用 [VirtualEnv](https://docs.python.org/3.6/tutorial/venv.html) 或是 [PyEnv](https://github.com/pyenv/pyenv)). 然后在克隆仓库的根目录运行: ``` pip install -U -r requirements.txt ``` 启动服务器: ``` bash bootstrap ``` 在浏览器中打开`http://localhost:9000`,你应该可以看到记录了可用的端点的Swagger页面。. ## 开发 待更新... ## 部署 待更新... ## 贡献 参照[贡献指南](CONTRIBUTING.md) ## 前端issues 请查阅[这里](https://github.com/wuhan2020/front-pages/issues) ================================================ FILE: README.md ================================================ # API Server ![Python3.6](https://img.shields.io/badge/python-3.6-green.svg?style=flat-square&logo=python&colorB=blue) [![Slack Channel](https://img.shields.io/badge/Slack%20Channel-%23api--server-green.svg?style=flat-square&colorB=blue)](https://app.slack.com/client/TT5U1VCPQ/CT3V5CDKJ) [![Built with love](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square)](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square&logo=love) ![Build Status](https://github.com/wuhan2020/api-server/workflows/Tests%20on%20Pull%20Requests%20and%20Master/badge.svg?branch=master&event=push) [中文文档](README-cn.md) This a backend API service of the voluntary information collection and sharing platform to fight against the 2019-nCoV outbreak in Wuhan and the world. The API is designed to be thin and stateless. It relies on the data collected and validated by other sub-projects, transform and expose them through standard RESTful APIs. The service is written in Python and Flask. ![Tech Arch Diagram](https://www.lucidchart.com/publicSegments/view/6ab27659-257a-44ce-a478-46dad3328b9c/image.png) ## Get Started Please first clone this repository and the sub-module-repo by: ``` git clone https://github.com/wuhan2020/api-server cd api-server git clone https://github.com/wuhan2020/wuhan2020 ``` ### Running locally with Docker (Recommended) **Pre-requisite: You have to have [Docker client](https://www.docker.com/products/docker-desktop) installed on your machine.** #### Build the Docker image Run: ``` docker build -t api-server:default . ``` from the root directory of the clone of this repo. Note this step could take a long time depends on where you are located in. #### Run built Docker image Run: ``` docker run --name api-server --publish 9000:9000 api-server:default ``` and then open `http://localhost:9000` in your browser. _(Add `-d` to run the Docker container in detach/background mode)_ You should see a Swagger page documents the available endpoints now. _If you ran into error `The container name "/api-server" is already in use`, please run `docker rm api-server` to delete previous container which has the same name._ #### Stop running Docker container Run: ``` docker stop api-server ``` to stop the running container. ### Running with your own Python environment Please make sure you have **Python3.6** installed, (ideally you should be using a [VirtualEnv](https://docs.python.org/3.6/tutorial/venv.html) or something like [PyEnv](https://github.com/pyenv/pyenv)). Then from the root directory of the cloned repo, run: ``` pip install -U -r requirements.txt ``` and then start the server by: ``` bash bootstrap ``` now if you open `http://localhost:9000` in your browser, you should see a Swagger page documents the available endpoints. ## Contributing Guide Please see [Conntributing Guide](CONTRIBUTING.md) for more information about this project. ## Front-end issues Please check [here](https://github.com/wuhan2020/front-pages/issues) ================================================ FILE: bootstrap ================================================ #!/bin/bash python3 -m "src.main" ================================================ FILE: config/dev.py ================================================ ================================================ FILE: config/product.py ================================================ ================================================ FILE: config/settings.py ================================================ import os, sys DEBUG_FLAG = True def get_cache_path(): path_home = './' if DEBUG_FLAG: path_home = os.path.join(path_home, 'test/data/') else: path_home = os.path.join(path_home, 'wuhan2020/data/') # wuhan2020文件夹为https://github.com/wuhan2020/wuhan2020项目文件的本地clone # 阿里云serverless使用挂载nas远程目录来存放缓存文件;在本机调试时,缓存文件夹将存放在项目根目录 if not os.path.exists(path_home): os.mkdirs(path_home) return path_home class Config(object): DEBUG = DEBUG_FLAG # 使用aliyun默认端口9000 ENV = { "FC_SERVER_PORT": 9000, } class CacheCfg(Config): CACHE_DIR = get_cache_path() # csv CSV_CACHE = CACHE_DIR + 'csv/' HOSPITAL_PATH = os.path.join(CSV_CACHE, "HOSPITAL.csv") HOTEL_PATH = os.path.join(CSV_CACHE, "HOTEL.csv") LOGISITICAL_PATH = os.path.join(CSV_CACHE, "LOGISTICAL.csv") NEWS_PATH = os.path.join(CSV_CACHE, "NEWS.csv") DONATION_PATH = os.path.join(CSV_CACHE, "DONATION.csv") FACTORY_PATH = os.path.join(CSV_CACHE, "FACTORY.csv") CLINIC_PATH = os.path.join(CSV_CACHE, "CLINIC.csv") # json JSON_CACHE = CACHE_DIR + 'json/' JSON_HOSPITAL_PATH = os.path.join(JSON_CACHE, "HOSPITAL.json") JSON_HOTEL_PATH = os.path.join(JSON_CACHE, "HOTEL.json") JSON_LOGISITICAL_PATH = os.path.join(JSON_CACHE, "LOGISTICAL.json") JSON_NEWS_PATH = os.path.join(JSON_CACHE, "NEWS.json") JSON_DONATION_PATH = os.path.join(JSON_CACHE, "DONATION.json") JSON_FACTORY_PATH = os.path.join(JSON_CACHE, "FACTORY.json") JSON_CLINIC_PATH = os.path.join(JSON_CACHE, "CLINIC.json") ================================================ FILE: const.py ================================================ """ SUB HEADERS TODO: change to en """ factory_medical_supplies = [ # 口罩 ('普通医用口罩', 'YY/T 0969-2013'), ('医用外科口罩', 'YY 0469-2010'), ('医用防护口罩 | N95口罩', 'GB 19083-2010, 建议3M 1860/1870/9123,防飞沫血液体液款'), # 面罩 ('防冲击眼罩/护目镜/防护眼镜', 'GB 19083-2010, 建议3M 1860/1870/9123,防飞沫血液体液款'), ('防护面罩', 'GB 19083-2010, 建议3M 1860/1870/9123,防飞沫血液体液款'), ('防护帽/医用帽/圆帽', 'GB 19083-2010, 建议3M 1860/1870/9123,防飞沫血液体液款'), # 衣物 ('隔离衣', ''), ('防护服', 'GB 19082-2003'), ('手术衣', ''), # 手套 ('乳胶手套', '灭菌,GB 10213-2006'), # 鞋 ('长筒胶鞋/防污染靴', ), ('防污染鞋套', ), ('防污染靴套', ), # 消毒耗材 ('84消毒液', ), ('过氧乙酸', ), ('75%酒精', ), ('手部皮肤消毒液', ), ('活力碘', ), # 其它耗材 ('床罩', ), ('医用面罩式雾化器', ), ('测体温设备', ), ('空气消毒设备', ), ('医用紫外线消毒车', ), ] """ CSV HEADERS """ DONATION_HEADERS = [ 'donate_sorce', 'donate_way', 'donate_link', 'donate_account_info', 'donate_cur_status', 'donate_audit_status', 'donate_audit_person', ] FACTORY_HEADERS = [ 'factory_prov', 'factory_name', factory_medical_supplies, 'factory_qualification', 'factory_addr', 'factory_contact', 'factory_note', 'factory_link', 'factory_audit_status', 'factory_reviewer', ] CLINIC_HEADERS = [ 'clinic_unit', 'clinic_contact', 'clinic_note' ] HOTEL_HEADERS = [ 'hotel_name', 'hotel_prov', 'hotel_addr', 'hotel_room_num', 'hotel_acceptable_num', 'hotel_supplier', 'hotel_concat_person', 'hotel_concat_phone', 'hotel_note', 'hotel_link', 'hotel_audit_status', 'hotel_audit_person', ] LOGISTICS_HEADERS = [ 'logistics_name', 'logistics_area', 'logistics_power', 'logistics_link', 'logistics_contact' ] NEWS_HEADERS = [ 'news_title', 'news_summary', 'news_time', 'news_link' ] HOSPITAL_HEADERS = [ 'hospital_prov', 'hospital_name', factory_medical_supplies, 'hospital_link', 'hospital_addr', 'hospital_contact', 'hospital_note', 'hospital_audit_status', 'hospital_audit_person', ] ================================================ FILE: requirements.txt ================================================ Flask==1.1.1 PyYAML==5.3 flask-swagger==0.2.14 xmltodict==0.12.0 Flask-HTTPAuth==3.3.0 connexion[swagger-ui]==2.6.0 prance==0.18.1 ================================================ FILE: src/__init__.py ================================================ ================================================ FILE: src/api/__init__.py ================================================ ================================================ FILE: src/api/accommodations.py ================================================ def get_all(): """List all available accomodations.""" return {} def get_by_name(): """Search for accomodations by name.""" ================================================ FILE: src/api/hospitals.py ================================================ def get_all(): """List all available hospitals.""" return {} def add(): """Add new hospitals.""" return {} ================================================ FILE: src/core/__init__.py ================================================ ================================================ FILE: src/main.py ================================================ import argparse import flask from flask import Flask from flask import Response as ResponseBase import connexion from swagger_ui_bundle import swagger_ui_3_path import os from connexion.resolver import RestyResolver import prance from pathlib import Path from typing import Dict, Any parser = argparse.ArgumentParser() parser.add_argument('--host', default='0.0.0.0') parser.add_argument('--port', type=int, default=9000) args, _ = parser.parse_known_args() def aggregate_specs(main_file: Path) -> Dict[str, Any]: """This function glues all seperate API Spec YML files together. This enales we keep a set of small YML files while being able to use something like $ref: 'another.yaml#/components/schemas/Foo' in the YML files. """ parser = prance.ResolvingParser(str(main_file.absolute()), lazy=True, strict=True) parser.parse() return parser.specification # Use OpenAPI Swagger page, and redirct SwaggerUI to root options = {'swagger_path': swagger_ui_3_path, "swagger_url": ""} # Note this app is a wrapper around FlaskAPP, use app.app to access # the actual Flask app app = connexion.App(__name__, options=options) app.add_api( aggregate_specs(Path(__file__).parent / "swagger/api.yml"), validate_responses=True, resolver=RestyResolver('src.api'), ) def handler(environ, start_response) -> flask.Flask: """This function is required by the deployment. For more information, check here: https://www.alibabacloud.com/help/doc-detail/74756.htm?spm=a2c63.l28256.a3.18.a2543c943bYfKr """ # do something here return app(environ, start_response) if __name__ == "__main__": app.run(host=args.host, port=os.environ.get("FC_SERVER_PORT", args.port), debug=False) ================================================ FILE: src/swagger/accommodations.yml ================================================ paths: /accommodation/all: get: tags: - Wuhan2020 Data summary: Search for all available accommodations operationId: src.api.accommodations.get_all description: | By passing in the appropriate options, you can get all of the available accommodations or query for specific accommodations in the system parameters: - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 default: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 default: 50 responses: "200": description: OK content: application/json: schema: type: array items: $ref: "#/components/schemas/AccommodationItem" "400": $ref: "errors.yml#/components/BadRequest" "500": $ref: "errors.yml#/components/InternalServerError" # Definition of all other error statuses default: description: Unexpected error content: application/json: schema: $ref: "errors.yml#/components/schemas/Error" components: schemas: AccommodationItem: type: object required: - id - name - address - volume - supportType - contact - validation properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: 第一大酒店 address: type: string example: 湖北省武汉市靖江大街12号 第一大酒店 supportType: type: string enum: [ "医护人员", "运输司机", "需隔离观察人员", "支援人员", "外出滞留人员", ] contact: $ref: "validations.yaml#/components/schemas/Contact" validation: $ref: "validations.yaml#/components/schemas/ValidationItem" volume: type: object required: - totalPeople properties: maxCapacity: type: integer format: int32 example: 55 description: 最多可接纳55人 rooms: type: array items: type: object required: - number - room properties: number: type: integer format: int32 example: 5 description: 5间 room: $ref: "#/components/schemas/AccomodationRoom" releaseDate: type: string format: date-time example: "2020-01-01T09:12:33.001Z" availableState: oneOf: - type: boolean default: true - $ref: "validations.yaml#/components/schemas/SuspendItem" AccomodationRoom: type: object required: - capacity properties: capacity: type: integer format: int32 example: 2 description: 做多可接纳2个人 space: type: number format: float example: 5.2 description: 5.2 平方米 roomtype: type: string enum: ["单人间", "双人间", "多人间", "标准间", "套房", "豪华套房", "总统套房", "钟点房", "其他"] ================================================ FILE: src/swagger/api.yml ================================================ openapi: 3.0.2 info: title: Wuhan2020 API service description: This is the API service of the Wuhan2020 project, which aims at collecting all useful information to help people fight against the 2019-nCoV outbreak, check the developer website for more info version: 0.1.0 contact: name: "Github Repo" url: https://github.com/wuhan2020/api-server # Let's version the APIs a bit later # servers: # - url: /api/v1 tags: - name: Wuhan2020 Data description: Get data that's collected and validated by Wuhan2020 volunteers # Refer to https://swagger.io/docs/specification/using-ref/ for Escape Characters e.g. ~1 paths: /accommodation/all: $ref: "accommodations.yml#/paths/~1accommodation~1all" /hospital/all: $ref: "hospitals.yml#/paths/~1hospital~1all" components: schemas: AccommodationItem: $ref: "accommodations.yml#/components/schemas/AccommodationItem" HospitalItem: $ref: "hospitals.yml#/components/schemas/HospitalItem" ================================================ FILE: src/swagger/archived/accomodation.yaml ================================================ openapi: 3.0.2 info: description: This API provides Hotel/motel/ Accomodation list version: 0.1.0 title: Accomodation List API contact: email: wuhan2020@your-company.com license: name: Apache 2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' tags: - name: contributors description: Secured write permission calls - name: developers description: Operations available to regular developers paths: /acomodations: get: tags: - developers summary: searches accomodations operationId: searchAccomodations description: | By passing in the appropriate options, you can search for available accomodations in the system parameters: - in: query name: searchString description: pass an optional search string for looking up accomodations required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/AccomodationItem' '400': description: bad input parameter post: tags: - contributors summary: adds am accomodation item operationId: addAccomodation description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/AccomodationItem' description: Accomodation item to add put: tags: - contributors summary: suspend am accomodation item operationId: suspendAccomodation description: suspend an item to the system responses: '201': description: item suspended '400': description: 'invalid input, object invalid' '403': description: 'forbidden' '404': description: 'not found' requestBody: content: application/json: schema: $ref: 'validations.yaml#/components/schemas/SuspendItem' servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/accomodations/0.1.0' components: schemas: AccomodationItem: type: object required: - id - name - address - volume - supporttype - contact - validation properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: 第一大酒店 address: type: string example: 湖北省武汉市靖江大街12号 第一大酒店 supporttype: type: string enum: ['医护人员','运输司机','需隔离观察人员','支援人员','外出滞留人员'] contact: $ref: 'validations.yaml#/components/schemas/Contact' validation: $ref: 'validations.yaml#/components/schemas/ValidationItem' volume: type: object required: - totalPpl properties: totalPpl: type: integer format: int32 example: 55 description: 共可接纳55人 rooms: type: array items: type: object required: - number - room properties: number: type: integer format: int32 example: 5 description: 5间 room: $ref: '#/components/schemas/AccomodationRoom' releaseDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' availableState: oneOf: - type: boolean default: true - $ref: 'validations.yaml#/components/schemas/SuspendItem' AccomodationRoom: type: object required: - ppl properties: ppl: type: integer format: int32 example: 2 description: 2个人 space: type: number format: float example: 5.2 description: 5.2 平方米 roomtype: type: string enum: ['双人间','多人间','标准间','套房','豪华套房','总统套房'] ================================================ FILE: src/swagger/archived/donation.yaml ================================================ openapi: 3.0.2 info: description: This API provides Donation list version: 0.2.0 title: Donation List API contact: email: wuhan2020@your-company.com license: name: Apache 2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' tags: - name: contributors description: Secured write permission calls - name: developers description: Operations available to regular developers paths: /donation: get: tags: - developers summary: searches donation operationId: searchDonation description: | By passing in the appropriate options, you can search for available inventory in the system parameters: - in: query name: searchString description: pass an optional search string for looking up inventory required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/DonationItem' '400': description: bad input parameter post: tags: - contributors summary: adds a donation item operationId: addDonation description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/DonationItem' description: Donation item to add servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/donation/0.2.0' components: schemas: DonationItem: type: object required: - id - source - donate_way - offical_link - contact - cur_status - source_link - audit_status - update_time properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 source: type: string example: 红十字会 donate_way: type: string example: 支付宝 offical_link: type: string format: uri example: https://mp.weixin.qq.com/s/qGAsMA4hsduP99CaabdQDg contact: type: array items: $ref: '#/components/schemas/ContactItem' cur_status: type: string example: 已捐赠; 筹款中; source_link: type: string format: uri example: https://mp.weixin.qq.com/s/qGAsMA4hsduP99CaabdQDg audit_status: type: string example: 已审计; 审计中; update_time: type: string format: date-time example: '2020-01-23T09:12:33.001Z' ContactItem: type: object required: - name - phone properties: name: type: string example: xxx phone: type: string example: 12315 ================================================ FILE: src/swagger/archived/hospitaldemands.yaml ================================================ openapi: 3.0.2 info: description: This is Hostpital Demands API version: 0.2.0 title: Hostpital Demands API # put the contact info for your development or API team contact: email: wuhan2020@inrganizing operations tags: - name: contributors description: Secured write permission calls - name: developers description: Operations available to regular developers paths: /hospitaldemands: get: tags: - developers summary: searches hospital demands operationId: searchHospitalDemands description: | By passing in the appropriate options, you can search for recorded hospital demands in the system parameters: - in: query name: searchString description: pass an optional search string for looking up hospital demands required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/HospitalDemandItem' '400': description: bad input parameter post: tags: - contributors summary: adds an hospital demands item operationId: addHospitalDemands description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/HospitalDemandItem' description: Hospital Demands item to add put: tags: - contributors summary: suspend an hospital demands item operationId: suspendHospitalDemands description: suspend an item to the system responses: '201': description: item suspended '400': description: 'invalid input, object invalid' '403': description: 'forbidden' '404': description: 'not found' requestBody: content: application/json: schema: $ref: 'validations.yaml#/components/schemas/SuspendItem' description: Hospital Demands item to suspend 取消医院需求item servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/hospitaldemands/0.2.0' components: schemas: HospitalDemandItem: type: object required: - hospitDevelopal - demands - contact - releaseDate - validation properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 hospital: $ref: 'hospitals.yaml#/components/schemas/HospitalItem' validation: $ref: 'validations.yaml#/components/schemas/ValidationItem' releaseDate: type: string format: date-time example: 2016-08-29T09:12:33.001Z contact: $ref: 'validations.yaml#/components/schemas/Contact' demands: type: array items: type: object required: - supply properties: supply: $ref: 'supplies.yaml#/components/schemas/SupplyItem' amount: oneOf: - type: integer format: int32 description: 个 - $ref: 'suppliesunits.yaml#/components/schemas/SupplyItemUnit' - $ref: 'suppliesunits.yaml#/components/schemas/Unit' remark: type: string example: 需符合或高于下列国家标准,医用一次性防护服技术要求 availableState: oneOf: - type: boolean default: true - $ref: 'validations.yaml#/components/schemas/SuspendItem' ================================================ FILE: src/swagger/archived/supplies.yaml ================================================ openapi: 3.0.2 info: description: This API provides Supplies list version: 0.2.0 title: Supplies List API contact: email: wuhan2020@your-company.com license: name: Apache 2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' tags: - name: contributors description: Secured write permission calls - name: developers description: Operations available to regular developers paths: /supplies: get: tags: - developers summary: searches supplies operationId: searchSupplies description: | By passing in the appropriate options, you can search for available supplies in the system parameters: - in: query name: searchString description: pass an optional search string for looking up supplies required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/SupplyItem' '400': description: bad input parameter post: tags: - contributors summary: adds a supply item operationId: addSupply description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/SupplyItem' description: Supply item to add servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/supplies/0.2.0' components: schemas: SupplyItem: type: object required: - id - name - std properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: 医用口罩 std: type: array items: $ref: '#/components/schemas/Standard' releaseDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' Standard: type: object required: - name properties: name: type: string example: GB 19083-2010 desc: type: string example: 国家标医用标准 ================================================ FILE: src/swagger/archived/suppliesunits.yaml ================================================ openapi: 3.0.2 info: description: This API provides Supplies list version: 0.2.0 title: Supplies Units List API contact: email: wuhan2020@your-company.com license: name: Apache 2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' tags: - name: contributors description: Secured write permission calls - name: developers description: Operations available to regular developers paths: /suppliesunits: get: tags: - developers summary: searches supplies units operationId: searchSuppliesUnits description: | By passing in the appropriate options, you can search for available supplies units in the system parameters: - in: query name: searchString description: pass an optional search string for looking up inventory required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/SupplyItemUnit' '400': description: bad input parameter post: tags: - contributors summary: adds a supply item operationId: addSupply description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/SupplyItemUnit' description: Supply item to add servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/suppliesunits/0.2.0' components: schemas: SupplyItemUnit: type: object required: - id - name - unitamount - volume properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: 箱 unitamount: type: integer format: int32 example: 250 desc: type: string example: 1箱口罩250个 volume: type: object required: - length - height - width properties: length: $ref: '#/components/schemas/Length' height: $ref: '#/components/schemas/Length' width: $ref: '#/components/schemas/Length' weight: $ref: '#/components/schemas/Weight' releaseDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' Unit: oneOf: - $ref: '#/components/schemas/Length' - $ref: '#/components/schemas/Size' - $ref: '#/components/schemas/Weight' - $ref: '#/components/schemas/Volume' Size: type: object required: - amount - unit properties: amount: type: integer format: int32 unit: type: string enum: ['#'] description: 号 Length: type: object required: - amount - unit properties: amount: type: number format: float unit: type: string enum: [CM, M] description: 米, 厘米 Weight: type: object required: - amount - unit properties: amount: type: number format: float unit: type: string enum: [g, kg, ton] description: 克, 千克, 吨 Volume: type: object required: - amount - unit properties: amount: type: number format: float unit: type: string enum: [ml, L] description: 毫升,升 ================================================ FILE: src/swagger/errors.yml ================================================ # This YML defines the Error Response # for most of the errors components: # 500 InternalServerError: description: The server cannot process the request for an unknown reason content: application/json: schema: $ref: "#/components/schemas/Error" # 400 BadRequest: description: The HTTP request that was sent to the server has invalid syntax content: application/json: schema: $ref: "#/components/schemas/Error" # 404 NotFound: description: The specified resource was not found content: application/json: schema: $ref: "#/components/schemas/Error" # 401 Unauthorized: description: Unauthorized content: application/json: schema: $ref: "#/components/schemas/Error" schemas: Error: type: object properties: code: type: string message: type: string example: "Error message shows here." required: - message ================================================ FILE: src/swagger/hospitals.yml ================================================ paths: /hospital/all: get: tags: - Wuhan2020 Data summary: Search for all available hospitals operationId: src.api.hospitals.get_all description: | By passing in the appropriate options, you can get all of the available hospitals or query for specific hospitals in the system parameters: - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 default: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 default: 50 responses: "200": description: OK content: application/json: schema: type: array items: $ref: "#/components/schemas/HospitalItem" "400": $ref: "errors.yml#/components/BadRequest" "500": $ref: "errors.yml#/components/InternalServerError" # Definition of all other error statuses default: description: Unexpected error content: application/json: schema: $ref: "errors.yml#/components/schemas/Error" components: schemas: HospitalItem: type: object required: - id - name - city - address - releaseDate properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 name: type: string example: 武汉第一人民医院 city: type: string example: 武汉市 address: type: string example: 湖北省武汉市东湖路169号 武汉大学中南医院 releaseDate: type: string format: date-time example: "2016-08-29T09:12:33.001Z" ================================================ FILE: src/swagger/validations.yaml ================================================ openapi: 3.0.2 info: description: This API provides Base Validation Item list and validation feature version: 0.1.0 title: Validation API contact: email: wuhan2020@your-company.com license: name: Apache 2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' tags: - name: contributors description: Secured write permission calls - name: reviewers description: Secured write 'reviewState' field permission update calls - name: developers description: Operations available to regular developers paths: /validations: get: tags: - developers summary: searches validations operationId: searchValidations description: | By passing in the appropriate options, you can search for existing validations in the system parameters: - in: query name: searchString description: pass an optional search string for looking up validations required: false schema: type: string - in: query name: skip description: number of records to skip for pagination schema: type: integer format: int32 minimum: 0 - in: query name: limit description: maximum number of records to return schema: type: integer format: int32 minimum: 0 maximum: 50 responses: '200': description: search results matching criteria content: application/json: schema: type: array items: $ref: '#/components/schemas/ValidationItem' '400': description: bad input parameter post: tags: - contributors summary: adds a accomodation item operationId: addValidation description: Adds an item to the system responses: '201': description: item created '400': description: 'invalid input, object invalid' '409': description: an existing item already exists requestBody: content: application/json: schema: $ref: '#/components/schemas/ValidationItem' description: Validation item to add put: tags: - reviewers summary: adds a accomodation item operationId: updateValidation description: Update an item with 'approved' status the system responses: '201': description: 'item updated' '400': description: 'invalid input, object invalid' '403': description: 'forbidden' '404': description: 'item not found' requestBody: content: application/json: schema: $ref: '#/components/schemas/ValidationItem' description: Validation item to add servers: - url: 'https://virtserver.swaggerhub.com/wuhan2020/validations/0.1.0' components: schemas: ValidationItem: type: object required: - id - url - name - source - sourcetype - releaseDate properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 url: type: string format: uri example: https://paper.people.com.cn name: type: string example: 湖北紧急求援 source: type: string example: 人民日报海外版 sourcetype: type: string enum: ['hospitaldemand','patientreport','logistic','accommodation','supplies','general'] releaseDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' contributor: $ref: '#/components/schemas/Operator' reviewStates: type: array items: $ref: '#/components/schemas/ReviewState' Operator: type: object required: - id - username properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 username: type: string example: 我的网名是柱子 email: type: string format: email ReviewState: type: object required: - status - reviewDate properties: status: type: string enum: ['truth','uncertain','false'] example: 已验证为真实 truth default: 'uncertain' reviewDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' reviewer: $ref: '#/components/schemas/Operator' Contact: type: object required: - name - phone properties: name: type: string example: 王老师,李经理 phone: type: array items: type: string example: 21-221111111 email: type: string example: example@163.com SuspendItem: type: object required: - id - reason - validation - suspendDate properties: id: type: string format: uuid example: d290f1ee-6c54-4b01-90e6-d701748f0851 description: 应取消的项目的id,例如医院需求id reason: oneOf: - type: string enum: ['已过时','判定不真实','已撤销','已完成','已结束'] - type: object properties: desc: type: string example: 外界不可抗力 validation: $ref: '#/components/schemas/ValidationItem' suspendDate: type: string format: date-time example: '2016-08-29T09:12:33.001Z' ================================================ FILE: src/tests/__init__.py ================================================ ================================================ FILE: src/tests/data/csv/DONATION.csv ================================================ ¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷Ϣ׼ȷԣעϢԴӣȻΪЧд,,,,,, ,տʽ,ٷ,տ˻,ǰ״̬,״̬, ƱУѻ,пת,https://mp.weixin.qq.com/s/dXed5MIYgBisrV_pfQmV0w,"˻ xx Уйб山·֧ ˺ţxxxxx ˻ΪУѻ˻",,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ,,,,,, ================================================ FILE: src/tests/data/csv/FACTORY.csv ================================================ ¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷Ϣ׼ȷԣעϢԴӣȻΪЧд,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ʾд,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,沿,,Ʒ,,,,,Ȳ,,,IJ,,,,,IJ,,豸,,,֤,̵ַ,ϵʽ,ע,ϢԴ,״̬, ,,ͨҽÿ,ҽƿ,ҽ÷ | N95,/Ŀ/۾,,ñ/ҽñ/Բñ,,,,齺,ͲЬ/Ⱦѥ,ȾЬ,Ⱦѥ,84Һ,,75%ƾ,ֲƤҺ,,,ҽʽ,豸,豸,ҽ,,,,,,, ׼/ƼƷ,,YY/T 0969-2013,YY 0469-2010,"GB 19083-2010, 3M 1860/1870/9123,ĭѪҺҺ",,,,,GB 19082-2003,,GB 10213-2006,,,,,,,,,,,,ҽеע֤,ҽеע֤,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ɶнţ,ĴƼ޹˾,һҽÿ,,,,,,,,,,,,,,,,,,,,,,,,ĴʡɶйҵӶ·39,,,http://finance.sina.com.cn/wm/2020-01-26/doc-iihnzahk6405080.shtml,,Ǿ ,ҽƷ޹˾,,ҽƷ֣2000ֻ,ҽ÷N95100ֻ,,,,,ҽһԷ10,,,,,,,,,,,,,,,,,й.ɽʡ·153,,ϵˣ꣨,http://finance.sina.com.cn/wm/2020-01-26/doc-iihnzahk6405080.shtml,,Ǿ Ϻ,Ϻ֮ҽҩƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20203400057,Ϻ¿·58826¥1¥107Һ102,,͹״2019-nCoVԼУӫPCR,http://dy.163.com/v2/article/detail/F3GCB07P0530JPJ4.html,, Ϻ,ϺҽƿƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,е20180202,ϺֶƼ·908Ū18¥3¥,,Լ,http://dy.163.com/v2/article/detail/F3GCB07P0530JPJ4.html,, Ϻ,ϺƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,,Ϻмζ·137862279,,Լ,http://huiruibio.com/contact.asp,, ,ȵƼ()޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20163401400,кҵ·36509510,,ʵʱӫⶨPCR,https://baijiahao.baidu.com/s?id=1656405518294494200&wfr=spider&for=pc,, ʡɳ,ʥƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,泤е20150021,ɳ¼ҵ´·680,,Լ,https://baijiahao.baidu.com/s?id=1656405518294494200&wfr=spider&for=pc,, ʡ̩,˶Ƽ޹˾,,,,,,,,,,,,,,,,,,,,,,,,̩е20150182,ʡ̩п︻Ұ,,Լ,https://baijiahao.baidu.com/s?id=1656405518294494200&wfr=spider&for=pc,, Ϻ,ϺŵƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20203400058,Ϻ·466¥,,͹״2019-nCoVԼУӫPCR,https://baijiahao.baidu.com/s?id=1656405518294494200&wfr=spider&for=pc,, 人,Ƽ人޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20203400060,人ж¼´666人ҵĿBCDз¥B2¥B1һ¥,,͹״2019-nCoVԼУӫPCR,https://baijiahao.baidu.com/s?id=1656405518294494200&wfr=spider&for=pc,, ,ݰ˼ҽѧƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20153400667,·320һ,,ʵʱӫⶨPCR,,, ʡ,¡Ƽ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20153400710,оü·389,,ʵʱӫⶨPCR,,, ,̩ѧй޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20183401609,ͬ·2041101201301Ԫ2045101201501Ԫ,,ʵʱӫⶨPCR,,, ,ݰԴ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20183400126,ݸƼǽ·81¥41815¥103220311,,ʵʱӫⶨPCR,,, ,ɽѧﰲɷ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20183401526,и¼ҵɽ·19,,ʵʱӫⶨPCR,,, ʡկ,ͬƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20183400129,ʡկִҵ԰ͩҵ԰A7¥1¥2¥,,ʵʱӫⶨPCR,,, ,\޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20173401410,ݹҵ԰Ǻ218׿Ƽ԰C7¥101201,,ʵʱӫⶨPCR,,, ,ŵ\޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20153400948,бü·192405407408,,ʵʱӫⶨPCR,,, ,ݵϰ\޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20193220321,㽭ʡຼǰֵ·115㡢1¥4423,,ʵʱӫⶨPCR,,, ,ݲտƼ޹˾,,,,,,,,,,,,,,,,,,,,,,,,еע׼20193220680,и¼ҵ·1192,,ʵʱӫⶨPCR,,, ================================================ FILE: src/tests/data/csv/HOSPITAL.csv ================================================ ҪֱдûҪֱ1ûдκϢ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,沿,,Ʒ,,,,,Ȳ,,,IJ,,,,,IJ,,豸,,,ٷ,ҽԺַ,ϵʽ,ע,״̬,,, ,,ͨҽÿ,ҽƿ,ҽ÷ | N95,/Ŀ/۾,,ñ/ҽñ/Բñ,,,,齺,ͲЬ/Ⱦѥ,ȾЬ,Ⱦѥ,84Һ,,75%ƾ,ֲƤҺ,,,ҽʽ,豸,豸,ҽ,,,,,,,, ׼/ƼƷ,,YY/T 0969-2013,YY 0469-2010,"GB 19083-2010, 3M 1860/1870/9123,ĭѪҺҺ",,,,,GB 19082-2003,,GB 10213-2006,,,,,,,,,,,,ҽеע֤,ҽеע֤,,,,,,,, ,ҽԺ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,еڶҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,https://mp.weixin.qq.com/s/EmDnJVak0MQ0W0N9aRbfHw,ɳ·241,,,,,"ǵλٷϢ, Ϊ԰, Ӧɿ",2020.01.27 ,еһҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,http://www.jzyy1949.com/user_queryArticleById?article.aid=9726,ɳ·8 еһҽԺе,,,,,"ǵλٷϢ, Ϊ԰, Ӧɿ",2020.01.27 ,ҽԺ,1,YY 0469-2011,1,1,1,1,,1,,,,,,,,,,,,,,,,https://mp.weixin.qq.com/s/EmDnJVak0MQ0W0N9aRbfHw,о·60 ҽԺĿ,,,,,"ǵλٷϢ, Ϊ԰, Ӧɿ",2020.01.27 ,ؿҽԺ,,,,,,,,,,,,,,,,,,,,,,,,https://mp.weixin.qq.com/s/EmDnJVak0MQ0W0N9aRbfHw,ʡо·6,,,,,"ǵλٷϢ, Ϊ԰, Ӧɿ",2020.01.27 ,еҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,https://mp.weixin.qq.com/s/EmDnJVak0MQ0W0N9aRbfHw,б·196,,,,,"ǵλٷϢ, Ϊ԰, Ӧɿ",2020.01.27 ,кʮֻ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,http://www.jingzhou.gov.cn/zfwxw/jzyq/202001/t20200125_451837.shtml,غʮֻ/ܻͳһ,,,,,, ,ҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,,нغѨ29,,ݲ޹صʺ;,,,https://weibo.com/u/6989496719?refer_flag=1005055013_&is_all=1, ,ؿҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,,о6,,,,,, ,иױԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,,ʡо·233,,,,,, ,мҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,,ʡݳ344,,,,,, ,ҽԺ,,,,,,,,,,,,,,,,,,,,,,,,,½152,,,,,, ,ҽҽԺ,,,,,,,,,,,,,,,,,,,,,,,,,кִ·㴦,,޹棬ž http://news.jznews.com.cn/system/2020/01/26/011980374.shtml,,,, ,ҽҽԺ,,,,,,,,,,,,,,,,,,,,,,,,,ʡкȪ·6,,޹棬ž http://news.jznews.com.cn/system/2020/01/26/011980374.shtml,,,, ʯ,ʯкʮֻ,1,1,1,1,1,1,1,1,1,1,,1,,1,1,1,,,,,,,,,,,ݲ޹صʺ;޹棬ž http://news.jznews.com.cn/system/2020/01/26/011980374.shtml,,,, ,ҽҽԺ,1,1,1,1,1,1,,1,1,,,,,1,,,,,,,,,,http://www.jzszyyy.com/z/yiyuandongtai/yiyuanxinwen/2020-01-25/1777.html,ʡҽҽԺ 豸ҽԺַн·172,,,,,, ,йҽԺ,,,,,,,,,,,,,,,,,,,,,,,,,й119,,2020-1-27,,,, ʯ,ʯҽԺ,1,"YY 0469-2011 5000",2000,3000,1,3000,1000,2000,1,5000,,1000,,1,1,1,,,,,,,,https://mp.weixin.qq.com/s?__biz=MzU2Mzg1MzE5NA==&mid=2247486061&idx=1&sn=b92e03436c18c9ad12a6649a65ead2c3&chksm=fc52a888cb25219e93199201443fc69cd1e736afaa0cba932c12d73925a61c8dcb77a8be3bb7&mpshare=1&scene=1&srcid=&sharer_sharetime=1580280881992&sharer_shareid=5358617ddd2b35735212b40f5eac5301&key=3e858514d2c9d9aa83685104fbf96d3d0d178a06b862aa2a2c3bdecda704ff1ec2d68a213ec57fd19ec19ac168baf5abab36a561d40268957da0f45694a3d7c2de1f69dc6842433bb1ea4ad5caf980a3&ascene=1&uin=MTA5Nzg3NjQ4Mw%3D%3D&devicetype=Windows+10&version=6208006f?=zh_CN&exportkey=AdBnr5Dtk0s1m7%2FPWI3GaKE%3D&pass_ticket=YBuiHNZN%2Fqi2HS0PznCVi0YbW4jODt18BrmF3xRXH8jk2IXOe03FrxoDnP2j%2Bf3Y,ʡʯŶ·㴦,,2020-1-27,,,ٷϢѾ绰ȷ, ================================================ FILE: src/tests/data/csv/HOTEL.csv ================================================ ¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷Ϣ׼ȷԣעϢԴӣȻΪЧд,,,,,,,,,, Ƶ,ƵϽ,Ƶַ,?Ƶṩ,ƵɽӴ,ϵ,ϵʽ,ע,ϢԴ,״̬, ƵƸѨ,Ѩ,·,,,,,,https://m.traveldaily.cn/article/135333?scene=1&clicktime=1580130420&enterid=1580130420&from=singlemessage&isappinstalled=0,, бѨվ,Ѩ,188,,,,,,https://mp.weixin.qq.com/s/VuCa0DdBtw8vqgxb6P1xGA,, бѨ㳡,,ڴ99,,,,,,,, бϵ,,ɽǴ2,,,,,,,, бݺ찲㳡,찲,ʹ㳡Ա,,,,,,,, ================================================ FILE: src/tests/data/csv/LOGISTICAL.csv ================================================ ¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷Ϣ׼ȷԣעϢԴӣȻΪЧд,,,,,,,,,,,,,,,,,, ,,ϵʽ,,ע,״̬,,Ԯ,,,,,,,,,,, ˳Ἧ,人ij,95338,https://mp.weixin.qq.com/s/42UEPYlYR1EDCM8JKZQyqw,,,,,,,,,,,,,,, ,人,950616,https://mp.weixin.qq.com/s/5ZYvBOFSDdh3-AYFU7wzAQ,ܸ˾,,,,,,,,,,,,,, °,人,13917258981;18043320078,https://mp.weixin.qq.com/s/xCGmBHEOrgwfFDobjigHKQ,ܸ˾,,,,,,,,,,,,,, ,人,400-900-5656,https://tech.sina.com.cn/i/2020-01-25/doc-iihnzahk6300507.shtml,,,,,,,,,,,,,,, Բͨٵ޹˾,人,95554,http://www.yto.net.cn/about/news/ytonews/detail.html/?id=7c257cc4-1291-4eba-9aeb-10414f389e88,ܸ˾,,,,,,,,,,,,,, ͨݼ,人,95311,https://www.zto.com/companyIntroduce/newsListDetail.html?id=1267040,ܸ˾,,,,,,,,,,,,,, ӿ,人,4000565666,https://mp.weixin.qq.com/s/D9orpDHGp2xJT1V8pIbSYw,ܸ˾,,,,,,,,,,,,,, ˳,人,4008009999,https://weibo.com/2780826007/IrfwsAo3m?type=repost#_rnd1580099824814,,,,人ѧҽԺҽԺвսҽԺɽСɽҽԺ人ܱ,ɽɶϡ人,,,,,,,,,, غ,人,15915803827,https://weibo.com/2780826007/IrffCjDCa?from=page_1002062780826007_profile&wvr=6&mod=weibotime&type=comment#_rnd1580114854609,,,,,,,,,,,,,,, ,人,10103636/appͷ,https://weibo.com/2780826007/IreEZaTrw?from=page_1002062780826007_profile&wvr=6&mod=weibotime&type=comment#_rnd1580114913374,,,,,,,,,,,,,,, й,人,11183,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,,,,,,,,,,,,,,, ϴٵ,人,95546,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ,人,051-56267288ֻ83424,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ,人,95344,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ,人,95315,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,˾󣬽뵱Ż֯ϵ,,,,,,,,,,,,,, ,人,95006,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ,人,400-866-5566,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾Խӣվֻ19906791226 2ִתȷ񣺴13967130612 18601625459,,,,,,,,,,,,,, Խ,人,95324/18923876321,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, լ,人,01053265090/ 13501275106,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ػ,,400-808-6666,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, ,人," 17379175656/ 18784733363/ 18010017622/ 18629291855/ 18863932588/ 13801500174",https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ܸ˾,,,,,,,,,,,,,, Ҽ׵δ,人,95058,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,˾󣬽뵱Ż֯ϵ,,,,,,,,,,,,,, ٿ,人,95349,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,˾󣬽뵱Ż֯ϵ,,,,,,,,,,,,,, 칷,人,"4008909009ͷʱ125-27Ϊ9:00-18:00,128պΪ8:00-20:00)",https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ϵ人ؽշϵ칷,,,,,,,,,,,,,, ,人,⽭֣ 18017713330/? 13916478826򱱳֣? 18911773800ɶ֣? 15208319985,https://weibo.com/ttarticle/p/show?id=2309404464719346925765,ҽƷʿɼ뷢⽭֡򱱳֡ϳɶ֣ڼв⼰ڲѡ,,,,,,,,,,,,,, ׼ʱ﹩Ӧ,ī硢ձԽϡĴǡ̩ǡӡǡ¼¡ɱӡȡ̨ۡ,׼ʱɫͨߣ400 189 8868 䣺jusda-callcenter@jusdascm.com,https://weibo.com/2780826007/IrrjhFjaE,ݲΪṩɫ֧ͨ,,ӱ,,,,,,,,,,,, GOOD,ɼLos Angelesֿ/ŦԼNew Yorkֿ/˰Oregonֿ,"ϵˣBryan ϵ绰6262976863ɼֿ 17421 East Gale Ave Unit C,City of Industry CA91748 / ŦԼֿ⣺75 Glendale Ave Edison NJ08817 / ˰ݲֿ 7021 NE 79th Court Portland OR97218",https://mp.weixin.qq.com/s/PB_-X4HxjTKHbdVcIEwksw,עһ1.װ豸ע2. 豸עҪջϢ 3. 豸עڼƷƷ,,ӱ,,,,http://www.goodkuaidi.com/NewsDetail?GID=da62467c-102e-4b8d-b73d-0916c0df7489,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,, ================================================ FILE: src/tests/data/test.json ================================================ {"code":0,"data":{},"msg":"success"} ================================================ FILE: src/tests/data/test.xml ================================================ 0 success ================================================ FILE: src/tests/test_nothing.py ================================================ def test_nothing(): """Placeholder for Pytest on Github Actions.""" assert True ================================================ FILE: src/utils/__init__.py ================================================ ================================================ FILE: tools.py ================================================ import os import yaml import xmltodict import json import functools import logging from flask import abort from flask_httpauth import HTTPTokenAuth from config.settings import DEBUG_FLAG # TODO: use .gitignore hide token; i don't know how to use this auth in blueprint auth = HTTPTokenAuth(scheme='Bearer') test_token = 'test-safe-wuhan' auth_file = os.path.join(os.path.abspath(__file__), 'auth/auth_info.json') auth_token = test_token if DEBUG_FLAG else json.load(auth_file)['token'] @auth.verify_token def auth_token_wrapper(token): if token == auth_token: return True return False def csv_helper(fpath, headers): header_st = 2 result = [] with open(fpath) as f: for line in f.readlines()[2:]: csv_data = line.strip().split(",") result.append(dict(zip(headers, csv_data))) return result def csv_with_medical_supplier(fpath, headers): header_st, spliter = 5, '#' result, total_header = [], [] for h in headers: if isinstance(h, list): for sub_h in h: total_header.append(spliter.join(sub_h)) else: total_header.append(h) with open(fpath) as f: for line in f.readlines()[header_st:]: csv_data = line.strip().split(",") result.append(dict(zip(total_header, csv_data))) return result def yaml_helper(fpath): result = [] with open(fpath, 'r') as f: result = yaml.load(f) return result def xml_helper(xml_path): with open(xml_path, 'r') as f: xml_str = f.read() json = xmltodict.parse(xml_str) return json def json_helper(json_path): with open(json_path, 'r', encoding='UTF-8') as f: return json.loads(f.read()) ================================================ FILE: utils.py ================================================ # -*- coding: utf-8 -*- from flask import Blueprint, current_app, request import os import json import datetime import platform import csv import os import traceback import yaml import xmltodict import json from const import * from tools import * data = Blueprint('register', __name__) @data.route('/json_test') def json_test(): path = os.path.join("/root/api-server/", "test.json") return json_helper(path) @data.route('/xml_test') def xml_test(): path = os.path.join("/root/api-server/", "test.xml") return xml_helper(path) @data.route('/hospital_list') def hospital_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: hosptials_data = csv_with_medical_supplier(current_app.config['HOSPITAL_PATH'], HOSPITAL_HEADERS) if 'limit' in request.args or 'skip' in request.args: skip = request.args.get('skip', type=int) limit = request.args.get('limit', type=int) hosptials_data_len = len(hosptials_data) if skip < 0 or limit < 0 or limit > 50: raise Exception('Bad input parameter.') if skip > hosptials_data_len: raise Exception("Index out of range.") if skip + limit > hosptials_data_len: limit = hosptials_data_len - skip resp['data'] = hosptials_data[skip:skip+limit] else: resp['data'] = hosptials_data resp['success'] = True except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False),(400 if not resp['success'] else 200) @data.route('/hotel_list') @auth.login_required def hotel_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_helper(current_app.config['HOTEL_PATH'], HOTEL_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/logistical_list') @auth.login_required def logistical_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_with_medical_supplier(current_app.config['LOGISITICAL_PATH'], LOGISTICS_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/news_list') @auth.login_required def news_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_helper(current_app.config['NEWS_PATH'], NEWS_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/donation_list') @auth.login_required def donation_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_helper(current_app.config['DONATION_PATH'], DONATION_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/factory_list') @auth.login_required def factory_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_with_medical_supplier(current_app.config['FACTORY_PATH'], FACTORY_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/clinic_list') @auth.login_required def clinic_list(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = csv_helper(current_app.config['CLINIC_PATH'], CLINIC_HEADERS) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/hospital_list_json') def hospital_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data= json_helper(current_app.config['JSON_HOSPITAL_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/hotel_list_json') def hotel_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_HOTEL_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/logstics_list_json') def logstics_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_LOGISITICAL_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/news_list_json') def news_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_NEWS_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/donation_list_json') def donation_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_DONATION_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/factory_list_json') def factory_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_FACTORY_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False) @data.route('/clinic_list_json') def clinic_list_json(): resp = { 'success': False, 'data': [], 'msg': '', } try: resp_data = json_helper(current_app.config['JSON_CLINIC_PATH']) resp['success'] = True resp['data'] = resp_data except Exception as e: resp['msg'] = str(e) return json.dumps(resp, ensure_ascii=False)