uncurl-httpx 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uncurl-httpx
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: uncurl for httpx, fork from uncurl-requests
5
5
  Author-email: cyliu <liucy1983@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/liucy1983/uncurl-httpx
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "uncurl-httpx"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "uncurl for httpx, fork from uncurl-requests"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -3,6 +3,7 @@ import argparse
3
3
  import json
4
4
  import re
5
5
  import shlex
6
+ import warnings
6
7
  from collections import OrderedDict
7
8
  from dataclasses import dataclass, field
8
9
  from http.cookies import SimpleCookie
@@ -19,10 +20,10 @@ parser.add_argument('--data-binary', '--data-raw', default=None)
19
20
  parser.add_argument('-X', default='')
20
21
  parser.add_argument('-H', '--header', action='append', default=[])
21
22
  parser.add_argument('--compressed', action='store_true')
22
- parser.add_argument('-k','--insecure', action='store_true')
23
+ parser.add_argument('-k', '--insecure', action='store_true')
23
24
  parser.add_argument('--user', '-u', default=())
24
- parser.add_argument('-i','--include', action='store_true')
25
- parser.add_argument('-s','--silent', action='store_true')
25
+ parser.add_argument('-i', '--include', action='store_true')
26
+ parser.add_argument('-s', '--silent', action='store_true')
26
27
  parser.add_argument('-x', '--proxy', default={})
27
28
  parser.add_argument('-U', '--proxy-user', default='')
28
29
 
@@ -33,12 +34,13 @@ BASE_INDENT = " " * 4
33
34
  class ParsedContext:
34
35
  method: str
35
36
  url: str
36
- data: Optional[str] = None
37
+ data: Optional[Any] = None
37
38
  headers: OrderedDict = field(default_factory=OrderedDict)
38
39
  cookies: OrderedDict = field(default_factory=OrderedDict)
39
40
  verify: bool = False
40
41
  auth: Tuple[str, ...] = ()
41
42
  proxy: Any = field(default_factory=dict)
43
+ is_json_data: bool = field(default=True)
42
44
 
43
45
  def build_request_kwargs(self, **kwargs):
44
46
  request_kwargs = dict(kwargs)
@@ -46,7 +48,10 @@ class ParsedContext:
46
48
  request_kwargs['follow_redirects'] = request_kwargs.pop('allow_redirects')
47
49
 
48
50
  if self.data:
49
- request_kwargs['data'] = self.data
51
+ if self.is_json_data:
52
+ request_kwargs['data'] = json.dumps(self.data)
53
+ else:
54
+ request_kwargs['data'] = self.data
50
55
 
51
56
  if self.headers:
52
57
  request_kwargs['headers'] = dict(self.headers)
@@ -74,7 +79,11 @@ class ParsedContext:
74
79
  request_kwargs.append(format_request_arg(key, value))
75
80
 
76
81
  if self.data:
77
- request_kwargs.append(format_request_arg('data', self.data))
82
+ data_value = self.data
83
+ if self.is_json_data and not isinstance(self.data, str):
84
+ # Keep generated code stable with curl-like JSON string payloads.
85
+ data_value = json.dumps(self.data, separators=(",", ":"))
86
+ request_kwargs.append(format_request_arg('data', data_value))
78
87
 
79
88
  if self.headers:
80
89
  request_kwargs.append(format_dict_arg('headers', self.headers))
@@ -105,14 +114,38 @@ class ParsedContext:
105
114
  request_kwargs='\n'.join(request_kwargs),
106
115
  )
107
116
 
117
+ def set_header(self, header_name, header_value):
118
+ self.headers[header_name] = header_value
119
+ return self
120
+
121
+ def set_cookie(self, cookie_name, cookie_value):
122
+ self.cookies[cookie_name] = cookie_value
123
+ return self
124
+
125
+ def set_proxy(self, proxy):
126
+ self.proxy = proxy
127
+ return self
128
+
129
+ def set_data(self, data: Optional[Any] = None, data_key: Optional[str] = None,
130
+ data_value: Optional[Any] = None):
131
+ if data:
132
+ self.data = data
133
+ elif data_key:
134
+ if self.is_json_data:
135
+ if isinstance(self.data, dict):
136
+ self.data[data_key] = data_value
137
+ else:
138
+ warnings.warn("Current request data is not Dict, skipping set_data()", RuntimeWarning)
139
+ else:
140
+ warnings.warn("Current request data is not JSON, skipping set_data().", UserWarning)
141
+ else:
142
+ warnings.warn("data or data_key must be provided.", UserWarning)
143
+ return self
144
+
108
145
  def request(self, **kwargs):
109
146
  return httpx.request(self.method, self.url, **self.build_request_kwargs(**kwargs))
110
147
 
111
148
 
112
- def normalize_newlines(multiline_text):
113
- return multiline_text.replace(" \\\n", " ")
114
-
115
-
116
149
  def parse_cookies(cookie_string):
117
150
  if not cookie_string:
118
151
  return OrderedDict()
@@ -121,10 +154,10 @@ def parse_cookies(cookie_string):
121
154
  return OrderedDict((key, morsel.value) for key, morsel in sorted(cookie.items()))
122
155
 
123
156
 
124
- def parse_context(curl_command):
157
+ def parse_context(curl_command, is_json_data: bool = True):
125
158
  method = "get"
126
159
 
127
- tokens = shlex.split(normalize_newlines(curl_command))
160
+ tokens = shlex.split(curl_command.replace(" \\\n", " "))
128
161
  parsed_args = parser.parse_args(tokens)
129
162
 
130
163
  post_data = parsed_args.data or parsed_args.data_binary
@@ -135,7 +168,7 @@ def parse_context(curl_command):
135
168
  method = parsed_args.X.lower()
136
169
 
137
170
  cookie_dict = parse_cookies(parsed_args.cookie)
138
-
171
+
139
172
  quoted_headers = OrderedDict()
140
173
 
141
174
  for curl_header in parsed_args.header:
@@ -163,6 +196,12 @@ def parse_context(curl_command):
163
196
  elif parsed_args.proxy:
164
197
  proxy = "http://{}/".format(parsed_args.proxy)
165
198
 
199
+ if post_data and is_json_data:
200
+ try:
201
+ post_data = json.loads(post_data)
202
+ except (TypeError, json.JSONDecodeError):
203
+ # Fallback to plain text payload when request body is not valid JSON.
204
+ is_json_data = False
166
205
  return ParsedContext(
167
206
  method=method,
168
207
  url=parsed_args.url,
@@ -172,11 +211,12 @@ def parse_context(curl_command):
172
211
  verify=parsed_args.insecure,
173
212
  auth=user,
174
213
  proxy=proxy,
214
+ is_json_data=is_json_data,
175
215
  )
176
216
 
177
217
 
178
- def parse(curl_command, as_object=True, **kwargs):
179
- parsed_context = parse_context(curl_command)
218
+ def parse(curl_command, as_object=True, is_json_data: bool = True, **kwargs):
219
+ parsed_context = parse_context(curl_command, is_json_data)
180
220
 
181
221
  if as_object:
182
222
  return parsed_context
@@ -204,4 +244,3 @@ def dict_to_pretty_string(the_dict, indent=4):
204
244
 
205
245
  return ("\n" + " " * indent).join(
206
246
  json.dumps(the_dict, sort_keys=True, indent=indent, separators=(',', ': ')).splitlines())
207
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uncurl-httpx
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: uncurl for httpx, fork from uncurl-requests
5
5
  Author-email: cyliu <liucy1983@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/liucy1983/uncurl-httpx
File without changes
File without changes
File without changes
File without changes
File without changes