【实现curl请求与python脚本的转化】

成果

什么都不用说,先上效果截图
在这里插入图片描述
上图是实现的最终效果,是不是觉得很cool

实现思路

	1.实现一个可视化页面来接收用户输入curl请求
	2.将curl请求传给后端进行数据处理
	3.将处理好的数据再返回给前端页面

使用的技术

	pywebio
	yapf

后端处理逻辑

1.通过浏览器F12复制curl请求
2.拿到curl请求内容,针对curl请求去做关键数据的转化
3.自定义一套python脚本模板
4.动态替换python脚本模板中的动态参数

主运行函数

def run():
    with use_scope("index", clear=True):
        put_row([put_text("测试常用调试工具").style(title_style)])
        show_curl_2_python()

工具相关函数

def clear_case(file_name):
    if os.path.exists(file_name):
        os.remove(file_name)


def write_to_file(file_name, data):
    with open(file_name, mode="w", encoding="utf-8") as f:
        f.write(data)


def read_file(file_name):
    if os.path.exists(file_name):
        with open(file_name, mode="r", encoding="utf-8") as f:
            data_str = f.read()
            # print(data_str)
        return data_str
    else:
        return "请输入数据,再进行操作"

核心业务函数

@use_scope("request", clear=True)
def show_curl_2_python():
    put_row(
        [
            None,
            put_column([
                put_html("<br>"),
                put_text("复制curl请求: 打开浏览器  -->  F12-->  选中请求  -->  copy  -->  Copy as cURL(bash)").style(title_style),
                put_text("请输入curl请求:"),
                put_button("转化", onclick=show_curl_to_python_result),
                put_textarea(name="curl_data", rows=40, value="", code={
                    'mode': "curl",
                    'theme': 'darcula'
                })
            ], size="50px 50px 50px 50px 100%")
            ,
            None,
            put_column([
                put_html("<br>"),
                None,
                None,
                put_text("转化为python脚本后:"),
                put_textarea(name="python_data", rows=40, value="", code={
                    'mode': "python",
                    'theme': 'darcula'
                })
            ], size="50px 50px 50px 50px 100%")
            ,
            None
        ],
        size="20px 48% 4% 48% 20px"
    )


@use_scope("request", clear=False)
def show_curl_to_python_result():
    curl_to_python()
    pin.pin_update("python_data", value=read_file(files["py_template"]))


def curl_to_python():
    try:
        curl_data = pin.pin.curl_data
        # print(curl_data)
        curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S)
        curl_result_list = re.findall(curl_re_expression, curl_data)
        # print(curl_result_list)
        if not curl_result_list:
            for file_name in files.values():
                clear_case(file_name)
        if curl_result_list:
            curl_result = curl_result_list[0]
            url_re_expression = re.compile("(http.*?)'", re.S)
            url_result_list = re.findall(url_re_expression, curl_result)
            url = url_result_list[0]
            headers_re_expression = re.compile("-H '(.*?)'", re.S)
            headers_result_list = re.findall(headers_re_expression, curl_result)
            # print(headers_result_list)
            headers = {}
            for header_str in headers_result_list:
                if ":" in header_str:
                    key = header_str.replace(" ", "").split(":")[0]
                    value = header_str.replace(" ", "").split(":")[1]
                    headers[key] = value
            # print(headers)
            method_re_expression = re.compile("-X '(.*?)'", re.S)
            # print(method_re_expression)
            method_result_list = re.findall(method_re_expression, curl_result)
            # print(method_result_list)

            content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S)
            content_type_result_list = re.findall(content_type_re_expression, curl_result)
            # print(content_type_result_list)
            data = None
            method = None
            if not method_result_list and not content_type_result_list:
                method = "get"
            if method_result_list:
                method = str(method_result_list[0]).lower()
            if content_type_result_list:
                # print(method)
                if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]:
                    if not method:
                        method = "post"
                # print(method)
                if "application" in content_type_result_list[0]:
                    data_re_expression = re.compile("--data-raw '(.*?)'", re.S)
                    data_result_list = re.findall(data_re_expression, curl_result)
                    # print(data_result_list)
                    if data_result_list:
                        data = json.loads(data_result_list[0])
                if "multipart" in content_type_result_list[0]:
                    data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S)
                    data_result_list = re.findall(data_re_expression, curl_result)
                    if data_result_list:
                        data = data_result_list[0]
            py_json_template = """import requests
        
headers = {{headers}}
    
json_data = {{data}}
    
response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False)
    
print(response.text)
        
            """
            py_template = """import requests
        
headers = {{headers}}
    
data = '{{data}}'
response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False)
    
print(response.text)
        
            """
            if data and (isinstance(data, dict) or isinstance(data, list)):
                py_template = py_json_template.replace("{{headers}}", str(headers)).replace(
                    "{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url)
            elif data and isinstance(data, str):
                py_template = py_template.replace("{{headers}}", str(headers)).replace(
                    "{{data}}", data).replace("{{method}}", method).replace("{{url}}", url)
            else:
                # print("我执行了吗")
                py_template = str(py_template).replace("{{headers}}", str(headers)).replace(
                    "data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace(
                    'data=str(data).encode("utf-8"), ', "")
            py_template = str(FormatCode(py_template)[0])
            space_re_expression = re.compile("(:\n\s*?)'", re.S)
            space_result_list = re.findall(space_re_expression, py_template)
            # print(space_result_list)
            for space in space_result_list:
                # print(space)
                py_template = py_template.replace(space, ": ")
            # print(py_template)
            write_to_file("py_template.py", py_template)
            # print("我执行到底了")
    except:
        write_to_file("py_template.py", "curl请求格式错误,请重新复制")

效果呈现

使用的接口地址
http://httpbin.org/

转化get请求

curl

curl 'http://httpbin.org/get' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.get('http://httpbin.org/get',
                        headers=headers,
                        verify=False)

print(response.text)

在这里插入图片描述

post请求

curl

curl 'http://httpbin.org/post' \
  -X 'POST' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Origin: http://httpbin.org' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '0',
    'Origin': 'http',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.post('http://httpbin.org/post',
                         headers=headers,
                         verify=False)

print(response.text)

在这里插入图片描述

put请求

curl

curl 'http://httpbin.org/put' \
  -X 'PUT' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Origin: http://httpbin.org' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '0',
    'Origin': 'http',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.put('http://httpbin.org/put',
                        headers=headers,
                        verify=False)

print(response.text)

在这里插入图片描述

完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Copyright ©  版权所有
# @Time    : 2022/11/16 12:01
# @Author  : 胡浩浩
# @Email   : hu_haohao@venusgroup.com.cn
# @File    : curl2python.py
# @IDE     : PyCharm
# @description :
import json
import os
import re

from pywebio import *
from pywebio.output import *
from screeninfo import get_monitors
from pywebio.pin import put_textarea
from pywebio.platform.tornado_http import start_server
from ruamel import yaml
from yapf.yapflib.yapf_api import FormatCode

css = """
.container {
    margin-top: 0;
    max-width: 100%;
}
.CodeMirror {
    font-size: 13px;
    width: {{width}};
    overflow: scroll;
}
"""

title_style = """
color: red;
"""
code_mirror_width = str(get_monitors()[0].width / 2)

css = css.replace("{{width}}", code_mirror_width + "px")
config(title="curl2python", theme="minty", css_style=css)
files = {
    "py_template": "py_template.py",
}


def clear_case(file_name):
    if os.path.exists(file_name):
        os.remove(file_name)


def write_to_file(file_name, data):
    with open(file_name, mode="w", encoding="utf-8") as f:
        f.write(data)


def read_file(file_name):
    if os.path.exists(file_name):
        with open(file_name, mode="r", encoding="utf-8") as f:
            data_str = f.read()
            # print(data_str)
        return data_str
    else:
        return "请输入数据,再进行操作"


@use_scope("request", clear=True)
def show_curl_2_python():
    put_row(
        [
            put_column([
                put_html("<br>"),
                put_text("复制curl请求: 打开浏览器  -->  F12-->  选中请求  -->  copy  -->  Copy as cURL(bash)").style(title_style),
                put_text("请输入curl请求:"),
                put_button("转化", onclick=show_curl_to_python_result),
                put_textarea(name="curl_data", rows=40, value="", code={
                    'mode': "curl",
                    'theme': 'darcula'
                })
            ], size="50px 50px 50px 50px 100%"),
            None,
            put_column([
                put_html("<br>"),
                None,
                None,
                put_text("转化为python脚本后:"),
                put_textarea(name="python_data", rows=40, value="", code={
                    'mode': "python",
                    'theme': 'darcula'
                })
            ], size="50px 50px 50px 50px 100%")
            ,
            None
        ],
        size="48% 4% 48% 20px"
    )


@use_scope("request", clear=False)
def show_curl_to_python_result():
    curl_to_python()
    pin.pin_update("python_data", value=read_file(files["py_template"]))


def curl_to_python():
    try:
        curl_data = pin.pin.curl_data
        # print(curl_data)
        curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S)
        curl_result_list = re.findall(curl_re_expression, curl_data)
        # print(curl_result_list)
        if not curl_result_list:
            for file_name in files.values():
                clear_case(file_name)
        if curl_result_list:
            curl_result = curl_result_list[0]
            url_re_expression = re.compile("(http.*?)'", re.S)
            url_result_list = re.findall(url_re_expression, curl_result)
            url = url_result_list[0]
            headers_re_expression = re.compile("-H '(.*?)'", re.S)
            headers_result_list = re.findall(headers_re_expression, curl_result)
            # print(headers_result_list)
            headers = {}
            for header_str in headers_result_list:
                if ":" in header_str:
                    key = header_str.replace(" ", "").split(":")[0]
                    value = header_str.replace(" ", "").split(":")[1]
                    headers[key] = value
            # print(headers)
            method_re_expression = re.compile("-X '(.*?)'", re.S)
            # print(method_re_expression)
            method_result_list = re.findall(method_re_expression, curl_result)
            # print(method_result_list)

            content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S)
            content_type_result_list = re.findall(content_type_re_expression, curl_result)
            # print(content_type_result_list)
            data = None
            method = None
            if not method_result_list and not content_type_result_list:
                method = "get"
            if method_result_list:
                method = str(method_result_list[0]).lower()
            if content_type_result_list:
                # print(method)
                if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]:
                    if not method:
                        method = "post"
                # print(method)
                if "application" in content_type_result_list[0]:
                    data_re_expression = re.compile("--data-raw '(.*?)'", re.S)
                    data_result_list = re.findall(data_re_expression, curl_result)
                    # print(data_result_list)
                    if data_result_list:
                        data = json.loads(data_result_list[0])
                if "multipart" in content_type_result_list[0]:
                    data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S)
                    data_result_list = re.findall(data_re_expression, curl_result)
                    if data_result_list:
                        data = data_result_list[0]
            py_json_template = """import requests

headers = {{headers}}

json_data = {{data}}

response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False)

print(response.text)

            """
            py_template = """import requests

headers = {{headers}}

data = '{{data}}'
response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False)

print(response.text)

            """
            if data and (isinstance(data, dict) or isinstance(data, list)):
                py_template = py_json_template.replace("{{headers}}", str(headers)).replace(
                    "{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url)
            elif data and isinstance(data, str):
                py_template = py_template.replace("{{headers}}", str(headers)).replace(
                    "{{data}}", data).replace("{{method}}", method).replace("{{url}}", url)
            else:
                # print("我执行了吗")
                py_template = str(py_template).replace("{{headers}}", str(headers)).replace(
                    "data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace(
                    'data=str(data).encode("utf-8"), ', "")
            py_template = str(FormatCode(py_template)[0])
            space_re_expression = re.compile("(:\n\s*?)'", re.S)
            space_result_list = re.findall(space_re_expression, py_template)
            # print(space_result_list)
            for space in space_result_list:
                # print(space)
                py_template = py_template.replace(space, ": ")
            # print(py_template)
            write_to_file("py_template.py", py_template)
            # print("我执行到底了")
    except:
        write_to_file("py_template.py", "curl请求格式错误,请重新复制")


def run():
    with use_scope("index", clear=True):
        put_row([put_text("测试常用调试工具").style(title_style)])
        show_curl_2_python()


if __name__ == '__main__':
    for file_name in files.values():
        clear_case(file_name)
    start_server(run, port=8897)
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要将自己的Python算法发布为一个服务,以便其他人能够通过POST请求使用它,可以按照以下步骤进行操作: 1. 创建一个Python脚本,将算法封装在其中。确保你的算法接受POST请求并返回相应的结果。你可以使用Pythonweb框架(如Flask、Django等)来实现这一功能。 2. 安装并配置一个Web服务器,比如Nginx或Apache。这样可以将HTTP请求路由到你的Python脚本上。 3. 将你的Python脚本部署到Web服务器上。具体的部署方式可能因你选择的Web服务器而异。你可以根据相关文档了解如何将Python应用程序部署到你选定的Web服务器上。 4. 配置路由和端口。确保你的Web服务器监听一个合适的端口,并将POST请求路由到正确的Python脚本上。 5. 在你的Python脚本中,处理POST请求并执行相应的算法。你可以使用Flask等Web框架提供的API,获取请求的数据,执行算法,并将结果返回给请求方。 6. 测试服务的可用性和正确性。你可以使用curl或Postman等工具,向你的URL发送POST请求,并检查返回的结果是否与预期一致。 7. 发布你的服务和API文档。提供详细的使用说明,包括如何构造POST请求,以及所需的参数和格式。 8. 提供对服务的保护和安全措施。确保你的服务仅对授权用户开放,并采取必要的安全措施(如身份验证、数据加密等),防止恶意请求和数据泄露。 9. 监控和优化你的服务。定期检查服务性能,并进行必要的优化和扩展,以确保服务的稳定性和可用性。 总之,通过以上步骤,你可以将自己的Python算法发布为一个能够通过POST请求访问的服务,以方便其他人使用和调用。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值