🦋
Butterfly 用户手册
  • Introduction
  • 一 前言
  • 二 开始
    • 安装部署
    • 五分钟体验指南
    • 单机使用手册
    • 应用规范
      • handler specs
      • middleware specs
      • xingqiao_plugin specs
      • yiqiu_program specs
  • 三 客户端功能
    • MySQL 原生协议
    • MySQL ORM
    • Redis 原生协议
      • redis_config
      • redis_tls
    • Redis ORM
    • Redis mcpack
    • Localcache
    • Kazoo
  • 四 应用(通用服务)
    • API JSON 规范
    • 异步任务 BaiChuan(百川)
    • 任务调度 RuQi(如期)
    • 任务编排 XingQiao(星桥)
    • 配置管理 WuXing(五行)
    • 运筹决策 BaiCe(百策)
  • 五 部署运维
    • 单机容器化部署
    • 监控
    • 异常排查
      • CPU Load spike every 7 hours
    • 升级
    • 安全
    • 其他
  • 六 前端
    • butterfly_template
    • butterfly_fe
    • butterfly-admin(json2web)
      • amis
      • sso
      • pangu
    • NoahV
    • PyWebIO
  • 七 潘多拉魔盒
    • 装饰器
      • localcache_decorator
      • retry_decorator
      • custom_decorator
      • command2http_decorator
    • 算法
      • 算法-分位数
      • 算法-变异系数
    • 实用工具
      • host_util
      • shell_util
      • http_util
      • time_util
      • random_util
      • concurrent
      • jsonschema
      • blinker
      • toml
      • command_util
      • config_util
      • picobox
      • 对称加密
        • des
        • aes
      • ascii_art
        • ttable
        • chart
      • business_rules
      • python-mysql-replication
      • dict_util
    • 中间件
      • middleware_status
      • middleware_whitelist
    • test_handler.py
  • 八 最佳实践
    • 分布式架构
    • Code practice
    • Log practice
    • Daemon process
  • 附录
Powered by GitBook
On this page
  • http_util
  • 1 使用
  • 1.1 常规使用
  • 1.2 替换 requests 使用
  • 2 常见问题
  • 2.1 Unicode 解码错误
  1. 七 潘多拉魔盒
  2. 实用工具

http_util

Previousshell_utilNexttime_util

Last updated 12 months ago

http_util

1 使用

1.1 常规使用

GET 请求,无参数

from xlib.util import http_util

res = http_util.get("http://127.0.0.1:8585/x/ping")
if res.success():
    print(res.output())

GET 请求,校验结果,校验失败时会记录日志

from xlib.util import http_util

res = http_util.get("http://127.0.0.1:8585/x/ping", check_key="stat", check_value=0)
assert res.success() == False

res = http_util.get("http://127.0.0.1:8585/x/ping", check_key="stat", check_value="OK")
assert res.success() == True
print res.output()

GET 请求, 有参数

http_util.get("http://127.0.0.1:8585/x/hello", params={"str_info": "meetbill"})

post 请求,使用 JSON 方式

http_util.post_json("http://127.0.0.1:8585/x/hello", data={"str_info": "meetbill"}, debug=True)

post 请求,使用 FORM 方式(butterfly 服务端不支持此方式)

print("[POST], post form---------------------------------[exe error]")
post_form("http://127.0.0.1:8585/x/hello", data={"str_info": "meetbill"}, debug=True)

GET 请求, 有 header

# GET,have headers
headers = {"X_USERNAME": "meetbill"}
res = get("http://127.0.0.1:8585/demo_api/ping", headers=headers, debug=True)
if res.success():
    print(res.output())

1.2 替换 requests 使用

1.2.1 requests

依赖包

requests-2.22.0.tar.gz
urllib3_1_26_2-1.26.2.0.tar.gz
idna-2.8.tar.gz
chardet-3.0.4.tar.gz
certifi-2019.6.16.tar.gz

代码

import requests

def main():
    ...
    r = requests.request(method, url, headers=headers, params=params, data=data, json=json, timeout=timeout)
    curl_cmd = http_util.to_curl_for_requests(r.request)
    logger.info(("cmd={cmd}\t"
                 "status_code={status_code}\t"
                 "response={response}".format(cmd=curl_cmd, status_code=r.status_code, response=r.text)))
    return res

-----
r.status_code : 响应状态码
r.json()      : JSON 响应内容

1.2.2 http_util

from xlib.util import http_util

def main():
    ...
    rsp = http_util.request(method, url, headers=headers, params=params, data=data, json=json, timeout=timeout)
    return rsp

-----
rsp.status_code : 响应状态码
rsp.json()      : JSON 响应内容

1.2.3 SDK 装饰器

from xlib.util import wrapt
from xlib.util import funcsigs
from xlib.util import http_util
from xlib.util import config_util

def requested(method, uri):
    """
    添加 endpoint
    """
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        """
        wrapper
        """
        # 提取原 func 中的 req, 不论使用位置参数还是关键字参数
        sig = funcsigs.signature(wrapped)
        kargs = dict(zip([k for k in sig.parameters if k not in kwargs], args))
        req = kargs.get("req", kwargs.get("req"))

        _service_name = "vm_manager"
        host = config_util.get_config(req, _service_name, "host")
        port = config_util.get_config(req, _service_name, "port")
        url = "http://{}:{}{}".format(host, port, uri)

        kwargs["method"] = method
        kwargs["url"] = url
        return wrapped(*args, **kwargs)
    return wrapper
    
------------------------------------------------------example
@requested(method="POST",
           uri="/v1/x1Resouce/instance/delete"
           )
def resource_delete(req, resource_id, **kwargs):
    """
    resource delete
    """
    data = {
        "instanceIds": [
            resource_id
        ],
        "userId": ""
    }
    headers = {"x_username": "x1_cli"}
    r = http_util.request(headers=headers, json=data, **kwargs)
    return r

2 常见问题

2.1 Unicode 解码错误

错误信息

File "py_menu.py", line 46, in main
    self.first_menu()
  File "py_menu.py", line 102, in first_menu
    self.secondary_menu()
  File "py_menu.py", line 132, in secondary_menu
    fun[1](self.screen, **func_kargs)
  File "/home/work/chunfeng/sinan_cli_bak/three_page.py", line 65, in select_node
    return _exe_command(screen, service, offsets, action)
  File "/home/work/chunfeng/sinan_cli_bak/three_page.py", line 31, in _exe_command
    res = http_util.post_json("http://{ip}:5000/sinan/operation".format(ip=nodes[int(offset)]["ip"]), data=data)
  File "/home/work/chunfeng/sinan_cli_bak/w_lib/http_util.py", line 99, in post_json
    return RequestTool(url, **kwargs)
  File "/home/work/chunfeng/sinan_cli_bak/w_lib/http_util.py", line 297, in __init__
    res_attr=json.dumps(self.header)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 12: ordinal not in range(128)

程序中添加如下配置

import sys
reload(sys)
sys.setdefaultencoding('utf8')

异常原因

ERROR: 12-20 13:43:40: http_util.py:303 * 140336365434624 [file=/home/work/chunfeng/sinan_cli/three_page.py:_exe_command:31 type=http_POST req_path=http://xx.xx.xx.xx:5000/sinan/operation req_data={'action': 'status', 'service': 'redis_proxy', 'offset': 2} cost=0.000272 is_success=False err_no=-1 err_msg=[Errno 111] 拒绝连接 res_len=0 res_data= res_attr={}]

err_msg 中含有中文
1 使用
1.1 常规使用
1.2 替换 requests 使用
1.2.1 requests
1.2.2 http_util
2 常见问题
2.1 Unicode 解码错误