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.
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/PKG-INFO +1 -1
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/pyproject.toml +1 -1
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl/api.py +55 -16
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/PKG-INFO +1 -1
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/LICENSE +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/README.md +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/setup.cfg +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/setup.py +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/tests/test_api.py +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/tests/test_bin.py +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl/__init__.py +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl/bin.py +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/SOURCES.txt +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/dependency_links.txt +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/entry_points.txt +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/requires.txt +0 -0
- {uncurl_httpx-0.1.2 → uncurl_httpx-0.1.3}/uncurl_httpx.egg-info/top_level.txt +0 -0
|
@@ -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[
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|