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解决的问题
<!-- Please include the GitHub issue this fixes or resolves, if applicable, please also explain any extra purpose of this PR -->
<!-- 请在下方附上本PR解决或实现的Issue编号, 例如 `#1`. 此外如果有, 请尽可能阐述本PR除issue所描述之外的目的 -->
- Closes #
### Changes | 本PR的更改
<!-- Please list out what major changes were made in this PR to address the issue: -->
<!-- 请尽可能详细的列出本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

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

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

[](https://app.slack.com/client/TT5U1VCPQ/CT3V5CDKJ)
[](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square&logo=love)

[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

[](https://app.slack.com/client/TT5U1VCPQ/CT3V5CDKJ)
[](https://img.shields.io/badge/BUILT%20WITH-LOVE-orange?style=flat-square&logo=love)

[中文文档](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.

## 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
================================================
<data>
<code>0</code>
<msg>success</msg>
<data>
</data>
</data>
================================================
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)
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
SYMBOL INDEX (32 symbols across 7 files) FILE: config/settings.py function get_cache_path (line 6) | def get_cache_path(): class Config (line 19) | class Config(object): class CacheCfg (line 27) | class CacheCfg(Config): FILE: src/api/accommodations.py function get_all (line 1) | def get_all(): function get_by_name (line 6) | def get_by_name(): FILE: src/api/hospitals.py function get_all (line 1) | def get_all(): function add (line 6) | def add(): FILE: src/main.py function aggregate_specs (line 20) | def aggregate_specs(main_file: Path) -> Dict[str, Any]: function handler (line 45) | def handler(environ, start_response) -> flask.Flask: FILE: src/tests/test_nothing.py function test_nothing (line 1) | def test_nothing(): FILE: tools.py function auth_token_wrapper (line 20) | def auth_token_wrapper(token): function csv_helper (line 26) | def csv_helper(fpath, headers): function csv_with_medical_supplier (line 36) | def csv_with_medical_supplier(fpath, headers): function yaml_helper (line 52) | def yaml_helper(fpath): function xml_helper (line 59) | def xml_helper(xml_path): function json_helper (line 66) | def json_helper(json_path): FILE: utils.py function json_test (line 21) | def json_test(): function xml_test (line 27) | def xml_test(): function hospital_list (line 33) | def hospital_list(): function hotel_list (line 62) | def hotel_list(): function logistical_list (line 79) | def logistical_list(): function news_list (line 96) | def news_list(): function donation_list (line 113) | def donation_list(): function factory_list (line 130) | def factory_list(): function clinic_list (line 147) | def clinic_list(): function hospital_list_json (line 162) | def hospital_list_json(): function hotel_list_json (line 180) | def hotel_list_json(): function logstics_list_json (line 196) | def logstics_list_json(): function news_list_json (line 212) | def news_list_json(): function donation_list_json (line 228) | def donation_list_json(): function factory_list_json (line 244) | def factory_list_json(): function clinic_list_json (line 260) | def clinic_list_json():
Condensed preview — 46 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (82K chars).
[
{
"path": ".dockerignore",
"chars": 39,
"preview": "README.md\nREADME-en.md\nCONTRIBUTING.md\n"
},
{
"path": ".github/hypertrons.json",
"chars": 1808,
"preview": "{\n \"label_setup\": {\n \"version\": 1,\n \"labels\": [\n {\n \"__merge__\": true\n },\n {\n \"name\""
},
{
"path": ".github/pull_request_template.md",
"chars": 389,
"preview": "### Purpose | 本PR解决的问题\n<!-- Please include the GitHub issue this fixes or resolves, if applicable, please also explain a"
},
{
"path": ".github/workflows/pythonapp.yml",
"chars": 949,
"preview": "name: Tests on Pull Requests and Master\n\non:\n push:\n branches:\n - master\n pull_request:\n\njobs:\n build:\n ru"
},
{
"path": ".gitignore",
"chars": 145,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n*.pyc\n__pycache__/\n.vscode/\n.idea/"
},
{
"path": ".gitmodules",
"chars": 88,
"preview": "[submodule \"wuhan2020\"]\n\tpath = wuhan2020\n\turl = git@github.com:wuhan2020/wuhan2020.git\n"
},
{
"path": ".python-version",
"chars": 7,
"preview": "3.6.10\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 2670,
"preview": "# Contributing Guide\n\n## Structure\n\n 2020 援助武汉\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof th"
},
{
"path": "README-cn.md",
"chars": 1936,
"preview": "# API Server\n\n\n"
},
{
"path": "README.md",
"chars": 3013,
"preview": "# API Server\n\n\n"
},
{
"path": "bootstrap",
"chars": 34,
"preview": "#!/bin/bash\npython3 -m \"src.main\"\n"
},
{
"path": "config/dev.py",
"chars": 0,
"preview": ""
},
{
"path": "config/product.py",
"chars": 0,
"preview": ""
},
{
"path": "config/settings.py",
"chars": 1578,
"preview": "import os, sys\n\nDEBUG_FLAG = True\n\n\ndef get_cache_path():\n path_home = './'\n if DEBUG_FLAG:\n path_home = os"
},
{
"path": "const.py",
"chars": 2095,
"preview": "\"\"\"\nSUB HEADERS\nTODO: change to en\n\"\"\"\nfactory_medical_supplies = [\n # 口罩\n ('普通医用口罩', 'YY/T 0969-2013'),\n ('医用外"
},
{
"path": "requirements.txt",
"chars": 131,
"preview": "Flask==1.1.1\nPyYAML==5.3\nflask-swagger==0.2.14\nxmltodict==0.12.0\nFlask-HTTPAuth==3.3.0\nconnexion[swagger-ui]==2.6.0\npran"
},
{
"path": "src/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "src/api/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "src/api/accommodations.py",
"chars": 138,
"preview": "def get_all():\n \"\"\"List all available accomodations.\"\"\"\n return {}\n\n\ndef get_by_name():\n \"\"\"Search for accomoda"
},
{
"path": "src/api/hospitals.py",
"chars": 125,
"preview": "def get_all():\n \"\"\"List all available hospitals.\"\"\"\n return {}\n\n\ndef add():\n \"\"\"Add new hospitals.\"\"\"\n retur"
},
{
"path": "src/core/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "src/main.py",
"chars": 1739,
"preview": "import argparse\nimport flask\nfrom flask import Flask\nfrom flask import Response as ResponseBase\nimport connexion\nfrom sw"
},
{
"path": "src/swagger/accommodations.yml",
"chars": 3728,
"preview": "paths:\n /accommodation/all:\n get:\n tags:\n - Wuhan2020 Data\n summary: Search for all available accom"
},
{
"path": "src/swagger/api.yml",
"chars": 983,
"preview": "openapi: 3.0.2\ninfo:\n title: Wuhan2020 API service\n description: This is the API service of the Wuhan2020 project, whi"
},
{
"path": "src/swagger/archived/accomodation.yaml",
"chars": 5037,
"preview": "openapi: 3.0.2\ninfo:\n description: This API provides Hotel/motel/ Accomodation list\n version: 0.1.0\n title: Accomodat"
},
{
"path": "src/swagger/archived/donation.yaml",
"chars": 3639,
"preview": "openapi: 3.0.2\ninfo:\n description: This API provides Donation list\n version: 0.2.0\n title: Donation List API\n contac"
},
{
"path": "src/swagger/archived/hospitaldemands.yaml",
"chars": 4478,
"preview": "openapi: 3.0.2\ninfo:\n description: This is Hostpital Demands API\n\n version: 0.2.0\n\n title: Hostpital Demands API\n # "
},
{
"path": "src/swagger/archived/supplies.yaml",
"chars": 2986,
"preview": "openapi: 3.0.2\ninfo:\n description: This API provides Supplies list\n version: 0.2.0\n title: Supplies List API\n contac"
},
{
"path": "src/swagger/archived/suppliesunits.yaml",
"chars": 4521,
"preview": "openapi: 3.0.2\ninfo:\n description: This API provides Supplies list\n version: 0.2.0\n title: Supplies Units List API\n "
},
{
"path": "src/swagger/errors.yml",
"chars": 1023,
"preview": "# This YML defines the Error Response\n# for most of the errors\ncomponents:\n # 500\n InternalServerError:\n descriptio"
},
{
"path": "src/swagger/hospitals.yml",
"chars": 2058,
"preview": "paths:\n /hospital/all:\n get:\n tags:\n - Wuhan2020 Data\n summary: Search for all available hospitals\n"
},
{
"path": "src/swagger/validations.yaml",
"chars": 5907,
"preview": "openapi: 3.0.2\ninfo:\n description: This API provides Base Validation Item list and validation feature\n version: 0.1.0\n"
},
{
"path": "src/tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "src/tests/data/csv/DONATION.csv",
"chars": 437,
"preview": "¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷ϢȷԣעϢԴӣȻΪЧд,,,,,,\n,տʽ,ٷ,տ˻,ǰ״̬,״̬,\nƱУѻ,пת,https://mp.weixin.qq.com/s/dXed5MIYgBisrV_pfQmV0w,\"˻\nxx\nУй"
},
{
"path": "src/tests/data/csv/FACTORY.csv",
"chars": 2413,
"preview": "¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷ϢȷԣעϢԴӣȻΪЧд,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\nʾд,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,沿,,Ʒ,,,,,Ȳ,,,IJ,,,,,"
},
{
"path": "src/tests/data/csv/HOSPITAL.csv",
"chars": 2690,
"preview": "ҪֱдûҪֱ1ûдκϢ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,沿,,Ʒ,,,,,Ȳ,,,IJ,,,,,IJ,,豸,,,ٷ,ҽԺַ,ϵʽ,ע,״̬,,,\n,,ͨҽÿ,ҽƿ,ҽ÷ | N95,/Ŀ/۾,,ñ/ҽñ"
},
{
"path": "src/tests/data/csv/HOTEL.csv",
"chars": 329,
"preview": "¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷ϢȷԣעϢԴӣȻΪЧд,,,,,,,,,,\nƵ,ƵϽ,Ƶַ,?Ƶṩ,ƵɽӴ,ϵ,ϵʽ,ע,ϢԴ,״̬,\nƵƸѨ,Ѩ,·,,,,,,https://m.traveldaily.cn/article/135"
},
{
"path": "src/tests/data/csv/LOGISTICAL.csv",
"chars": 6505,
"preview": "¼ʱرŶ̬ȣһҪ¼ȷϢȻǵĺķ鷳Ϊ˷ϢȷԣעϢԴӣȻΪЧд,,,,,,,,,,,,,,,,,,\n,,ϵʽ,,ע,״̬,,Ԯ,,,,,,,,,,,\n˳Ἧ,人ij,95338,https://mp.weixin.qq.com/s/42UEPYl"
},
{
"path": "src/tests/data/test.json",
"chars": 37,
"preview": "{\"code\":0,\"data\":{},\"msg\":\"success\"}\n"
},
{
"path": "src/tests/data/test.xml",
"chars": 82,
"preview": "<data>\n <code>0</code>\n <msg>success</msg>\n <data>\n\n </data>\n\n</data>\n"
},
{
"path": "src/tests/test_nothing.py",
"chars": 88,
"preview": "def test_nothing():\n \"\"\"Placeholder for Pytest on Github Actions.\"\"\"\n assert True\n"
},
{
"path": "src/utils/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tools.py",
"chars": 1747,
"preview": "import os\nimport yaml\nimport xmltodict\nimport json\nimport functools\nimport logging\nfrom flask import abort\nfrom flask_ht"
},
{
"path": "utils.py",
"chars": 6901,
"preview": "# -*- coding: utf-8 -*-\nfrom flask import Blueprint, current_app, request\nimport os\nimport json\nimport datetime\nimport p"
}
]
About this extraction
This page contains the full source code of the wuhan2020/api-server GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 46 files (72.1 KB), approximately 22.8k tokens, and a symbol index with 32 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.