sparrow cloud 组件介绍
Django SDK
- RestClient : 封装了request包和服务发现,正确请求返回解析后json数据, 错误请求返回HTTPException
- RequestsClient : 封装了request包和服务发现, 返回原生的request结果
- Message_Client : 将任务发送到rabbitmq, server端未开源
- Rabbitmq_Consumer : rabbitmq消息消费端,server端未开源
- Table_API : 接收查询条件返回 django model 序列化后的数据
- Api Schema Register : django subcommand, 主动注册API 描述到文档服务, server端未开源
- access_control verify : 访问控制验证,服务端未开源
- get_user_token : 获取用户token
- get_app_token : 获取app token
- ly_msg : 发送app 消息
- distributed_lock : 添加分布式锁或移除锁
Django Middleware
- JWTMiddleware : 解析 JWT Token
- MethodConvertMiddleware : 兼容不支持 put/delete 请求
- ExceptionMiddleware : 异常通知
- TracingMiddleware : 追踪链
- CheckLockMiddleware : 前端防重复提交锁中间件
rest_framework 中间件
- UserID Authentication: 验证 user
sparrow cloud组件
LogFilter
django中间件
rest_framework中间件
installation
pip3.11 install sparrowcloud
测试运行
运行所有测试:
source tests/mock_configmap.sh && python3.11 -m unittest tests/test* access_control/test*
运行单个测试:
source tests/mock_configmap.sh && python3.11 -m unittest tests/test_rest_client.py
运行环境
sparrowcloud 5.x.x 基于django4.2.x, python3.11
sparrowcloud 4.x.x 基于django3.2.x, python3.7
JWTMiddleware
描述:Token 解析 注意:配置SC_JWT_PUBLIC_KEY环境变量,rsa公钥文件数据 配置 JWTMiddleware 中间件需要的参数
# 注册中间件
MIDDLEWARE = (
'sparrow_cloud.middleware.jwt_middleware.JWTMiddleware', # 放最上层
UserIDAuthentication
描述: user_id 解析 配置 UserIDAuthentication 认证需要的参数(仅兼容django2.2以上版本)
SPARROW_AUTHENTICATION = {
"USER_CLASS_PATH": "sparrow_cloud.auth.user.User",
}
# 参数说明: USER_CLASS_PATH: 路径中的User为中间件的User模版, 可以根据自己的需求重新创建User, 并将自己的 User路径按照模版格式放到:USER_CLASS_PATH下
# 注册中间件
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'sparrow_cloud.auth.user_id_authentication.UserIDAuthentication',
),
}
METHOD_MIDDLEWARE
兼容阿里不支持 put/delete 请求 配置METHOD_MIDDLEWARE需要的参数
# 注册 METHOD_MIDDLEWARE
MIDDLEWARE_CLASSES = (
'sparrow_cloud.middleware.methodconvert.MethodConvertMiddleware', #兼容阿里请求方式中间件
)
TracingMiddleware
兼容阿里不支持 put/delete 请求 配置METHOD_MIDDLEWARE需要的参数
MIDDLEWARE_CLASSES = (
'sparrow_cloud.middleware.tracing_middleware.TracingMiddleware', # 追踪链
)
CheckLockMiddleware
防前端重复提交中间件,需要前端配合使用 对请求header中的特定键值判断其状态,来决定是否阻止该次请求
MIDDLEWARE_CLASSES = (
'sparrow_cloud.middleware.lock_middleware.CheckLockMiddleware', # 防前端重复提交
)
restclient
微服务间调用,使用示例
from sparrow_cloud.restclient import rest_client
rest_client.post(service_address, api_path, timeout=30, token=None, json=api_list)
参数说明
service_address = "test-svc:8000"
timeout:
非必传,默认超时时间30秒
传参方式:
timeout=30 # 30秒为connect 和 read 的 timeout
timeout=(5, 5) # 分别定制:connect 和 read 的 timeout
timeout=None # Request 永远等待
token:
内部跨服务调用认证token
from sparrow_cloud.authorization.token import get_app_token, get_user_token
token = get_user_token(user_id="21424kvjbcdjslafds")
或者
token = get_app_token()
其它:
剩余参数与 requests.get/post 等方法保持一致
异常返回
当服务间调用异常时,抛出异常 HTTPException
requestsclient
服务调用(返回结果未封装)
from sparrow_cloud.restclient import requests_client
requests_client.post(service_address, api_path, timeout=30, token=None, json=api_list)
参数说明
service_address = "test-svc:8000"
timeout:
非必传,默认超时时间30秒
传参方式:
timeout=30 # 30秒为connect 和 read 的 timeout
timeout=(5, 5) # 分别定制:connect 和 read 的 timeout
timeout=None # Request 永远等待
token:
内部跨服务调用认证token
from sparrow_cloud.authorization.token import get_app_token, get_user_token
token = get_user_token(user_id="21424kvjbcdjslafds")
或者
token = get_app_token()
其它:
剩余参数与 requests.get/post 等方法保持一致
message_client
麻雀任务发送
- 注册消息 2. 发送消息
# 调用方式
from sparrow_cloud.message_service.sender import send_task_v3
# 发送消息
data = send_task_v3(message_code=message_code,
*args,
**kwargs)
# 发送延时消息
data = send_task_v3(
message_code=message_code, # message_code: 消息码
delay_time=200, # delay_time: 延时时间,单位为秒
*args,
**kwargs)
=====================以下为旧版调用方式,不建议继续使用,会逐步弃用===========================
# 调用方式
from sparrow_cloud.message_service.sender import send_task
# 发送消息
data = send_task(
exchange=exchange, # 交换机
routing_key=routing_key, # 路由
message_code=message_code, # 消息码
retry_times=3, # 重试次数,非必填,默认重试次数为3次(每次间隔1秒)
*args,
**kwargs)
# 发送延时消息
data = send_task(
exchange=exchange, # 交换机
routing_key=routing_key, # 路由
message_code=message_code, # 消息码
retry_times=3, # 重试次数,非必填,默认重试次数为3次(每次间隔1秒)
delay=True, # 发送延时消息,默认为False,表示立即发送。如果设为True,则根据delay_time来设定延时时间
delay_time=200, # 延时时间,单位为秒
*args,
**kwargs)
rabbitmq_consumer
麻雀任务消费
- 获取队列 2. 消费任务
# 1. settings 注册服务
INSTALLED_APPS = [
"sparrow_cloud.apps.message_service",
]
# 2. settings 配置消费者对列
QUEUE_CONF_1 = { # 队列的配置,QUEUE_CONF_1可自定义名称
"QUEUE": "", # 队列名称
"TARGET_FUNC_MAP": { # 队列消费任务(字典中的键为message code,对应的值为执行该消息的任务函数路径字符串)
"message_code": "path", # message_code: 消息代码。path: 消费消息的函数路径,如: django模块名称.文件名.函数方法名
},
}
# 消费者启动命令:
python3.11 manage.py rabbitmq_consumer --queue QUEUE_CONF_1 # --queue: 指定发送队列配置名称,settings QUEUE_CONF_1的名称
table_api
接受查询条件返回django model 序列化后的数据 分为server端和client端
# server 端配置
# settings注册服务
INSTALLED_APPS = [
"sparrow_cloud.apps.table_api",
]
# url配置
urlpatterns = [
path('table/api/', include("sparrow_cloud.apps.table_api.urls")),
]
# client端调用
from sparrow_cloud.restclient import rest_client
service_address = "sparrow-demo:8000"
payload = {
"app_lable_model":"app_lable.model",
"filter_condition":{"product_id":"74101"}
}
response = rest_client.get(service_address, api_path='/table/api/', json=payload)
# 返回的数据结构:{'code': 0, 'message': 'ok', 'data': [{}]}
# ps:
# app_lable_model: app_name.model(app_name:INSTALLED_APPS里面注册的服务的名字, model:app_lable下的model名字,不区分大小写)
# filter_condition: 过滤数据, kwargs
# server端使用orm filter查询数据,当前版本不支持order_by
API SCHEMA REGISTER
描述:主动注册API 描述到文档服务 配置schema_command 需要的参数
# settings 配置:
INSTALLED_APPS = [
"sparrow_cloud.apps.schema_command", # 注册schema_command到INSTALLED_APPS中
]
# schema_command依赖配置
SERVICE_CONF = {
"NAME": "", # 使用sparrowcloud的服务名称
"SECRET": ""
}
# 调用方式:
python3 manage.py register_api_schema
# 使用说明:
# 1、view支持@api_view注解方式,view_class支持GenericApiView,GenericViewSet及其子类
# 2、接口描述书写在view函数或者view_class的__doc__上,建议使用markdown格式,展示更美观
接口描述代码示例
from rest_framework.decorators import api_view
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from rest_framework import generics
from rest_framework.viewsets import ModelViewSet
@api_view(('GET',))
def get_user(request):
"""
### 获取用户信息 ####
请求参数 id, 用户id
返回
{
"user_id":"1", # 用户ID
"user_name":"Tom" # 用户名称
}
"""
class UserApiView(RetrieveUpdateDestroyAPIView, generics.GenericAPIView):
"""
get:
### 查询用户信息 ###
请求参数 id, 用户id
返回
{
"id":"1", # 用户ID
"user_name":"Tom" # 用户名称
}
delete:
### 删除用户 ###
路径参数
id 用户id
返回
404 用户id不存在
204 删除成功
"""
def put(self, request, *args, **kwargs):
"""
### 覆盖修改用户 ###
请求参数
{
"id":"1", # 用户ID
"user_name":"Tom" # 用户名称
}
返回 200 修改成功
"""
return super(UserApiView, self).put(self, request, *args, **kwargs)
class CarViewSet(ModelViewSet):
"""
list: 分页查询车辆
retrieve:获取车辆信息
update: 覆盖修改车辆
partial_update: 部分修改车辆
create: 创建车辆
destroy: 删除车辆
"""
ExceptionMiddleware
中间件 说明: 可自动捕获程序异常,并将详细错误信息发送到飞书
# settings 配置
MIDDLEWARE = [
"sparrow_cloud.middleware.exception.ExceptionMiddleware"
]
LogMiddleware
日志中间件 日志中自动打印请求的request_id。日志的request_id与链路追踪中的request_id一致,可结合链路追踪中搜索快速定位异常请求信息。 此中间件需要配合log_filter 使用,才能在每条业务逻辑日志中插入request_id, 如单独使用只能透request_id
# settings 配置
MIDDLEWARE = [
"sparrow_cloud.middleware.log_middleware.RequestIDMiddleware"
]
log_filter
log_filter(自定义logfilter,从线程中获取request_id,从每条日志中打印出来) 需要与LogMiddleware 中间件配合使用,否则不生效
# log_settings 配置
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
# 新增的配置
'request_id': {
'()': 'sparrow_cloud.filter.log_filters.RequestIDFilter'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'standard', # 需要修改的的配置
'filters': ['request_id'], # 增加的 log_filter 的配置
},
# 修改后的业务日志配置示例
'access_control': {
'class': 'logging.handlers.RotatingFileHandler',
'filters': ['request_id'], # 增加的配置
'level': 'DEBUG',
'formatter': 'standard', # 修改为新增的formatters 配置
'filename': os.path.join(os.path.sep, BASE_DIR_LOG, 'access_control.log'),
'mode': 'a',
'maxBytes': 1024 * 1024 * 5,
'backupCount': 1, # 修改
},
},
'formatters': {
# 增加的配置
'standard': {
'format': '%(levelname)s %(asctime)s %(request_id)s %(lineno)d %(name)s %(module)s %(funcName)s %(process)d %(thread)d %(message)s'
},
},
# sparrow_cloud 的日志
'sparrow_cloud': {
'handlers': ['console', 'sparrow_cloud'],
'level': 'DEBUG',
'propagate': False,
},
# 业务日志配置
'access_control': {
'handlers': ['console', 'access_control'],
'level': 'DEBUG',
'propagate': False,
}
}
}
ACCESS_CONTROL_VERIFY
access_control_verify decorators (访问控制验证)
# settings 配置
SERVICE_CONF = {
"NAME": "", # value为本服务的注册名称
"SECRET": "",
}
# 访问控制client端settings配置
# SC_SKIP_ACCESS_CONTROL: 是否跳过访问控制, True:跳过, false:不跳过
# 使用方式
# 函数视图使用方式示例
from sparrow_cloud.access_control.decorators import access_control_fbv
@api_view(('POST', 'GET', 'PUT', 'DELETE'))
@access_control_fbv("permission_example1") # 位置放到最下层
def test(request, *args, **kwargs):
return Response({"message": "ok"}, status=status.HTTP_200_OK)
# 类视图使用方式(全部方法都验证)
from sparrow_cloud.access_control.decorators import access_control_cbv_all
@access_control_cbv_all("permission_example1")
class ProductOperationList(generics.ListCreateAPIView):
"""请求方法:GET/POST"""
pass
# 类视图使用方式(根据method验证)
from sparrow_cloud.access_control.decorators import access_control_cbv_method
RESOURCE = {
"post": "permission_example1",
"get": "permission_example2"
}
@access_control_cbv_method(RESOURCE)
class ProductOperationList(generics.ListCreateAPIView):
"""请求方法:GET/POST"""
pass
get_user_token
get_user_token (获取用户token)
# 获取用户token
from sparrow_cloud.authorization.token import get_user_token
user_token = get_user_token(user_id="21424kvjbcdjslafds")
get_app_token
get_app_token (获取服务token)
# 获取app token
from sparrow_cloud.authorization.token import get_app_token
app_token = get_app_token()
app_message
app_message (发送消息到揽月app, 服务端未开源)
#目前支持的消息类型有:纯文本、图片,Markdown、文字card和图片card
# 发送图片消息到app
from sparrow_cloud.app_message.sender import send_message
msg_data = "http://www.test.com/image.png"
res = send_message(msg_data=msg_data, code_type="test", content_type="image", msg_sender="麻雀")
# 发送文本消息到app
from sparrow_cloud.app_message.sender import send_message
msg_data = "文本消息"
res = send_message(msg_data=msg_data, code_type="test", nickname="文本消息携带字段")
# 发送文本card消息到app
from sparrow_cloud.app_message.sender import send_message
msg_data = "卡片消息内容"
res = send_message(msg_data=msg_data, code_type="test", content_type="card_text", title="通知")
## 参数说明
## msg_data: 消息主体。填充待发送的消息格式msg中的data数据
## code_type: 申请的code
## content_type: 发送消息的类型,非必传,默认是text文本类型。目前支持"text","image","markdown","card_text","card_image".
## msg_sender: app中展示的发送消息服务的名称, 非必传,如不传取 service_name
## shop_id: 非必传,默认为None,根据自己的需求
## user_id_list: 非必传,默认为空列表,根据自己的需求
## nickname: 非必传,根据发送的消息类型content_type决定是否传递
## title: 非必传,根据发送的消息类型content_type决定是否传递
distributed_lock
add_lock (添加锁) remove_lock (移除锁)
from sparrow_cloud.distributed_lock.lock_op import add_lock, remove_lock
#添加锁
res = add_lock("lock_key", 100)
if res.get("code") != 0:
#加锁失败
##添加锁参数说明
## key: 加锁的key值
## exexpire_time: 必须是int型,表示超时时间。如果在超过这个时间没有调用移除锁,则会自动释放锁。所以该时间需要根据业务层处理时间尽可能准确
## 返回字典结构为{"code":0/-1, "message":"xxxx"}或者{"message":"xxx"}
## 如果没有code字段表示出错,需要查看message。
## code为0表示加锁成功。其他数值表示加锁失败,停止执行之后的业务逻辑。
## message表示具体的信息
# 移除锁
res = remove_lock("lock_key")
if res.get("code") != 0:
#移除锁失败
##移除锁参数说明
## key: 移除锁的key值
## 返回字典结构为{"code":0/-1, "message":"xxxx"}或者{"message":"xxx"}
## 如果没有code字段表示出错,需要查看message。
## code为0表示移除锁成功。其他数值表示移除锁失败
## message表示具体的信息,“1”表示移除成功,“0”表示没有该key值。
Stargazers over time
Metadata
Release files for sparrowcloud 5.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sparrowcloud-5.0.1.tar.gz | 86.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sparrowcloud-5.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 184.4 kB
Release files / sparrowcloud-5.0.1.tar.gz
| Download URL | sparrowcloud-5.0.1.tar.gz |
|---|---|
| Size | 86.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
869aa2889a888d954236a941e3c584a49cb43f859b0d652e585237f1e55b9caf
|
|
BLAKE2b-256 checksum How to use checksums |
8050e224c6bfbf7019c6c0e2bb2ddd6f0706d0f57f308a14b51b141b4a2bb263
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.11.9
|
Release files / sparrowcloud-5.0.1-py3-none-any.whl
| Download URL | sparrowcloud-5.0.1-py3-none-any.whl |
|---|---|
| Size | 98.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aff73b620dfdee33cf76a019c98a04e65799934858a2a39d487f893f7cb1b3c0
|
|
BLAKE2b-256 checksum How to use checksums |
69d09302a78fd0395720ffd308e71c49b2725813aad22bb1914eeffbbc864546
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.11.9
|