Archived
添加了api接口需要key的规则
This commit is contained in:
9 files changed
+151
-40
No files matched your search
+26
-3
@@ -6,6 +6,8 @@
|
|||||||
# @File Name: __init__.py
|
# @File Name: __init__.py
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import random
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_sslify import SSLify
|
from flask_sslify import SSLify
|
||||||
from .main import main as main_blueprint
|
from .main import main as main_blueprint
|
||||||
@@ -13,17 +15,38 @@ from .api import api as api_blueprint
|
|||||||
from app.config import config
|
from app.config import config
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_string(length):
|
||||||
|
"""
|
||||||
|
生成随机密码
|
||||||
|
:param length:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
return ''.join(random.choice(letters) for _ in range(length))
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_name):
|
def create_app(config_name):
|
||||||
"""创建主app"""
|
"""
|
||||||
|
创建 app
|
||||||
|
:param config_name:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(config[config_name])
|
app.config.from_object(config[config_name])
|
||||||
config[config_name].init_app(app)
|
config[config_name].init_app(app)
|
||||||
if config[config_name].SSL_REDIRECT:
|
if os.environ.get('SSL_REDIRECT'):
|
||||||
sslify = SSLify(app)
|
SSLify(app)
|
||||||
|
|
||||||
app.register_blueprint(main_blueprint)
|
app.register_blueprint(main_blueprint)
|
||||||
app.register_blueprint(api_blueprint, url_prefix='/api/v1/')
|
app.register_blueprint(api_blueprint, url_prefix='/api/v1/')
|
||||||
|
|
||||||
|
if not os.getenv('ACCESS_KEY'):
|
||||||
|
access_key = generate_random_string(32)
|
||||||
|
os.environ['ACCESS_KEY'] = access_key
|
||||||
|
else:
|
||||||
|
access_key = os.getenv('ACCESS_KEY')
|
||||||
|
print('==========Access Key: {}=========='.format(access_key))
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+13
-2
@@ -9,12 +9,23 @@ from . import api
|
|||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
|
|
||||||
|
@api.errorhandler(403)
|
||||||
|
def forbidden(e):
|
||||||
|
return jsonify(
|
||||||
|
{
|
||||||
|
'code': 403,
|
||||||
|
'msg': 'API: 没有权限',
|
||||||
|
'data': None
|
||||||
|
}
|
||||||
|
), 403
|
||||||
|
|
||||||
|
|
||||||
@api.errorhandler(404)
|
@api.errorhandler(404)
|
||||||
def page_not_found(e):
|
def page_not_found(e):
|
||||||
return jsonify(
|
return jsonify(
|
||||||
{
|
{
|
||||||
'code': 404,
|
'code': 404,
|
||||||
'msg': '页面未找到',
|
'msg': 'API: 页面未找到',
|
||||||
'data': None
|
'data': None
|
||||||
}
|
}
|
||||||
), 404
|
), 404
|
||||||
@@ -25,7 +36,7 @@ def internal_server_error(e):
|
|||||||
return jsonify(
|
return jsonify(
|
||||||
{
|
{
|
||||||
'code': 500,
|
'code': 500,
|
||||||
'msg': '服务器内部错误',
|
'msg': 'API: 服务器内部错误',
|
||||||
'data': None
|
'data': None
|
||||||
}
|
}
|
||||||
), 500
|
), 500
|
||||||
@@ -6,14 +6,33 @@
|
|||||||
# @File Name: views.py
|
# @File Name: views.py
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from functools import wraps
|
||||||
|
from flask import abort
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from flask import send_file
|
||||||
from ..db.db import SQLite as db
|
from ..db.db import SQLite as db
|
||||||
from . import api
|
from . import api
|
||||||
|
|
||||||
|
|
||||||
|
def permission_required(func):
|
||||||
|
@wraps(func)
|
||||||
|
def decorated_func(*args, **kwargs):
|
||||||
|
if request.args.get('key') != os.getenv('ACCESS_KEY'):
|
||||||
|
abort(403)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return decorated_func
|
||||||
|
|
||||||
|
|
||||||
@api.route('/overall/', methods=['GET', 'POST'])
|
@api.route('/overall/', methods=['GET', 'POST'])
|
||||||
|
@permission_required
|
||||||
def overall():
|
def overall():
|
||||||
|
"""
|
||||||
|
查询ReqCount表内所有的源数据
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
limit = request.args.get('limit', type=int)
|
limit = request.args.get('limit', type=int)
|
||||||
try:
|
try:
|
||||||
data = db().exec('select * from reqcount;')
|
data = db().exec('select * from reqcount;')
|
||||||
@@ -38,7 +57,12 @@ def overall():
|
|||||||
|
|
||||||
|
|
||||||
@api.route('/query/', methods=['GET', 'POST'])
|
@api.route('/query/', methods=['GET', 'POST'])
|
||||||
|
@permission_required
|
||||||
def query():
|
def query():
|
||||||
|
"""
|
||||||
|
查询指定名称的计数数据
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
name = request.args.get('name', type=str)
|
name = request.args.get('name', type=str)
|
||||||
nochange = request.args.get('nochange', type=bool)
|
nochange = request.args.get('nochange', type=bool)
|
||||||
if nochange:
|
if nochange:
|
||||||
@@ -63,7 +87,12 @@ def query():
|
|||||||
|
|
||||||
|
|
||||||
@api.route('/theme/', methods=['GET', 'POST'])
|
@api.route('/theme/', methods=['GET', 'POST'])
|
||||||
|
@permission_required
|
||||||
def theme():
|
def theme():
|
||||||
|
"""
|
||||||
|
查询数据库内主题的源数据
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
_theme = request.args.get('name', type=str)
|
_theme = request.args.get('name', type=str)
|
||||||
if not db().exists_table(_theme):
|
if not db().exists_table(_theme):
|
||||||
return jsonify(
|
return jsonify(
|
||||||
@@ -85,7 +114,12 @@ def theme():
|
|||||||
|
|
||||||
|
|
||||||
@api.route('/alltables/', methods=['GET', 'POST'])
|
@api.route('/alltables/', methods=['GET', 'POST'])
|
||||||
|
@permission_required
|
||||||
def all_tables():
|
def all_tables():
|
||||||
|
"""
|
||||||
|
查询所有已有表
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
data = db().show_tables
|
data = db().show_tables
|
||||||
return jsonify(
|
return jsonify(
|
||||||
{
|
{
|
||||||
@@ -94,3 +128,14 @@ def all_tables():
|
|||||||
'data': data
|
'data': data
|
||||||
}
|
}
|
||||||
), 200
|
), 200
|
||||||
|
|
||||||
|
|
||||||
|
@api.route('/export/', methods=['GET', 'POST'])
|
||||||
|
@api.route('/export/<key>', methods=['GET', 'POST'])
|
||||||
|
@permission_required
|
||||||
|
def export(key: str = None):
|
||||||
|
"""
|
||||||
|
导出数据库文件
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return send_file('./db/data.sqlite', as_attachment=True)
|
||||||
+1
-1
@@ -31,5 +31,5 @@ config = {
|
|||||||
'development': DevelopmentConfig,
|
'development': DevelopmentConfig,
|
||||||
'production': ProductionConfig,
|
'production': ProductionConfig,
|
||||||
|
|
||||||
'default': ProductionConfig
|
'default': DevelopmentConfig
|
||||||
}
|
}
|
||||||
+15
-1
@@ -7,9 +7,23 @@
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import sys
|
import sys
|
||||||
import requests
|
import requests
|
||||||
from ..decorators import time_it
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def time_it(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
print('I: 数据库文件开始下载')
|
||||||
|
start = time.time()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
end = time.time()
|
||||||
|
print('I: 下载结束, 耗时 {} 秒'.format(round(end - start, 2)))
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
@time_it
|
@time_it
|
||||||
|
|||||||
Binary file not shown.
@@ -1,25 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -- coding:utf-8 --
|
|
||||||
# @Author: markushammered@gmail.com
|
|
||||||
# @Development Tool: PyCharm
|
|
||||||
# @Create Time: 2022/4/5
|
|
||||||
# @File Name: decorators.py
|
|
||||||
|
|
||||||
import time
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
|
|
||||||
def time_it(func):
|
|
||||||
@wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
print('I: 数据库文件开始下载')
|
|
||||||
start = time.time()
|
|
||||||
result = func(*args, **kwargs)
|
|
||||||
end = time.time()
|
|
||||||
print('I: 下载结束, 耗时 {} 秒'.format(round(end - start, 2)))
|
|
||||||
return result
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -- coding:utf-8 --
|
||||||
|
# @Author: markushammered@gmail.com
|
||||||
|
# @Development Tool: PyCharm
|
||||||
|
# @Create Time: 2022/4/10
|
||||||
|
# @File Name: test_decorator.py
|
||||||
|
|
||||||
|
|
||||||
|
def check(func):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
print(kwargs)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@check()
|
||||||
|
def test(name: str):
|
||||||
|
print(name)
|
||||||
|
|
||||||
|
|
||||||
|
test('Markus')
|
||||||
+27
-5
@@ -32,7 +32,12 @@
|
|||||||
- 可选参数: `theme` `length`
|
- 可选参数: `theme` `length`
|
||||||
|
|
||||||
# API
|
# API
|
||||||
> 注意事项: ***调用接口必须在路径末尾加入 `/` (不是参数末尾)***
|
|
||||||
|
* 注意事项
|
||||||
|
|
||||||
|
1. `/api/v1/`内的所有接口都是需要`key`来访问
|
||||||
|
2. `key`是从环境变量中获取或自动生成, 这取决与你部署到`Heroku`时是否设置了`ACCESS_KEY`环境变量
|
||||||
|
3. `key`的长度为`32`位的随机英文字母大小写字符串
|
||||||
|
|
||||||
> 地址前缀: `/api/v1/`
|
> 地址前缀: `/api/v1/`
|
||||||
|
|
||||||
@@ -42,12 +47,13 @@
|
|||||||
## `/overall/` 接口
|
## `/overall/` 接口
|
||||||
|
|
||||||
> 使用此接口获取数据库中所有的数据
|
> 使用此接口获取数据库中所有的数据
|
||||||
|
|
||||||
> 必选参数: `limit: int` > 自定义查询数量, 输入的数字大于等于最大值时, 将返回最大值
|
> 必选参数: `limit: int` > 自定义查询数量, 输入的数字大于等于最大值时, 将返回最大值
|
||||||
|
|
||||||
### 调用示例
|
### 调用示例
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/overall/?limit=20
|
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/overall/?limit=20&key=<key>
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -74,13 +80,15 @@ $ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/overall/?limit=20
|
|||||||
***使用此接口查询的名称计数数值会加一***
|
***使用此接口查询的名称计数数值会加一***
|
||||||
|
|
||||||
> 必选参数: `name: str` > 查询指定名称的计数数据
|
> 必选参数: `name: str` > 查询指定名称的计数数据
|
||||||
|
|
||||||
> 可选参数: `nochange: Any`
|
> 可选参数: `nochange: Any`
|
||||||
|
|
||||||
> `nochange`: 'Any` > 将参数值设置为任意值则仅查询不增加
|
> `nochange`: 'Any` > 将参数值设置为任意值则仅查询不增加
|
||||||
|
|
||||||
### 调用示例
|
### 调用示例
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/query/?name=main&nochange=1
|
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/query/?name=main&nochange=1&key=<key>
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -97,12 +105,13 @@ $ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/query/?name=main&no
|
|||||||
## `/theme/` 接口
|
## `/theme/` 接口
|
||||||
|
|
||||||
> 使用此接口获取数据库内原始的base64编码的主题图片
|
> 使用此接口获取数据库内原始的base64编码的主题图片
|
||||||
|
|
||||||
> 必选参数: `theme: str`
|
> 必选参数: `theme: str`
|
||||||
|
|
||||||
### 调用示例
|
### 调用示例
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/theme/?name=lewd
|
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/theme/?name=lewd&key=<key>
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -125,10 +134,11 @@ $ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/theme/?name=lewd
|
|||||||
## `/alltables/` 接口
|
## `/alltables/` 接口
|
||||||
|
|
||||||
> 此接口可以获取数据库内所有的表名 > 返回的数据中不包含`ReqCount`
|
> 此接口可以获取数据库内所有的表名 > 返回的数据中不包含`ReqCount`
|
||||||
|
|
||||||
> 无参数
|
> 无参数
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/alltables/
|
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/alltables/&key=<key>
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -141,6 +151,18 @@ $ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/alltables/
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `/export/` 接口
|
||||||
|
|
||||||
|
> 此接口可以导出应用的数据库文件
|
||||||
|
|
||||||
|
> 无参数
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ curl -L -X GET https://requestcounter.herokuapp.com/api/v1/export/&key=<key>
|
||||||
|
```
|
||||||
|
|
||||||
|
> 该接口请求成功后返回文件
|
||||||
|
|
||||||
# 关于
|
# 关于
|
||||||
|
|
||||||
## 开源
|
## 开源
|
||||||
|
|||||||
Reference in New Issue
Block a user