From 15ecd34a545713c881e9766a748129bcc6ba4bb9 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 22 Mar 2026 10:44:36 +0000 Subject: [PATCH] Initial upload: curl-converter-cli with CI/CD workflow --- curlconverter/generators/python.py | 95 ++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 curlconverter/generators/python.py diff --git a/curlconverter/generators/python.py b/curlconverter/generators/python.py new file mode 100644 index 0000000..b67e9ea --- /dev/null +++ b/curlconverter/generators/python.py @@ -0,0 +1,95 @@ +"""Python code generator.""" + +import json +import base64 +from curlconverter.parser import ParsedCurl +from curlconverter.generators import register_generator + + +def _detect_content_type(headers: dict, data: str) -> str: + """Detect content type from headers or data.""" + if "Content-Type" in headers: + return headers["Content-Type"] + if "content-type" in headers: + return headers["content-type"] + if data: + try: + json.loads(data) + return "application/json" + except (json.JSONDecodeError, TypeError): + pass + return "application/x-www-form-urlencoded" + + +@register_generator("python") +def generate_python(parsed: ParsedCurl) -> str: + """Generate Python requests code from parsed curl data.""" + lines = [] + lines.append("import requests") + lines.append("") + lines.append("url = " + repr(parsed.url)) + lines.append("") + + kwargs = [] + headers = dict(parsed.headers) if parsed.headers else {} + + if parsed.user_agent and "User-Agent" not in headers and "user-agent" not in headers: + headers["User-Agent"] = parsed.user_agent + + if headers: + lines.append("headers = " + _format_dict(headers)) + kwargs.append("headers=headers") + + auth_tuple = None + if parsed.auth: + auth_username, auth_password = parsed.auth + if ":" in parsed.auth[0]: + try: + encoded = base64.b64encode(f"{parsed.auth[0]}:{parsed.auth[1]}".encode()).decode() + if "Authorization" not in headers: + headers["Authorization"] = f"Basic {encoded}" + except Exception: + auth_tuple = parsed.auth + else: + auth_tuple = parsed.auth + + if parsed.data: + content_type = _detect_content_type(headers, parsed.data) + + if content_type == "application/json": + try: + json_data = json.loads(parsed.data) + lines.append("data = " + json.dumps(json_data, indent=4)) + kwargs.append("json=data") + except (json.JSONDecodeError, TypeError): + lines.append("data = " + repr(parsed.data)) + kwargs.append("data=data") + else: + lines.append("data = " + repr(parsed.data)) + kwargs.append("data=data") + + if parsed.cookies: + lines.append("cookies = " + repr(parsed.cookies)) + kwargs.append("cookies=cookies") + + if kwargs: + kwargs_str = ",\n ".join(kwargs) + lines.append(f"response = requests.{parsed.method.lower()}(url, {kwargs_str})") + else: + lines.append(f"response = requests.{parsed.method.lower()}(url)") + + lines.append("") + lines.append("print(response.status_code)") + lines.append("print(response.text)") + + return "\n".join(lines) + + +def _format_dict(d: dict) -> str: + """Format a dictionary for Python code.""" + if not d: + return "{}" + items = [] + for k, v in d.items(): + items.append(f" {repr(k)}: {repr(v)}") + return "{\n" + ",\n".join(items) + "\n}"