python-http_request 0.0.9__tar.gz → 0.1.0__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.1
2
2
  Name: python-http_request
3
- Version: 0.0.9
3
+ Version: 0.1.0
4
4
  Summary: Python http response utils.
5
5
  Home-page: https://github.com/ChenyangGao/python-modules/tree/main/python-http_request
6
6
  License: MIT
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 0, 9)
5
+ __version__ = (0, 1, 0)
6
6
  __all__ = [
7
7
  "SupportsGeturl", "url_origin", "complete_url", "ensure_ascii_url",
8
8
  "urlencode", "cookies_str_to_dict", "headers_str_to_dict_by_lines",
@@ -25,7 +25,10 @@ from os import PathLike
25
25
  from os.path import basename
26
26
  from re import compile as re_compile, Pattern
27
27
  from string import punctuation
28
- from typing import runtime_checkable, Any, Final, Protocol, TypedDict
28
+ from typing import (
29
+ cast, overload, runtime_checkable, Any, Final, Literal, Protocol,
30
+ TypedDict,
31
+ )
29
32
  from urllib.parse import quote, urlparse, urlunparse
30
33
  from uuid import uuid4
31
34
  from yarl import URL
@@ -57,15 +60,17 @@ class SupportsGeturl[AnyStr: (bytes, str)](Protocol):
57
60
  def geturl(self) -> AnyStr: ...
58
61
 
59
62
 
60
- def url_origin(url: str, /, default_port: int = 0) -> str:
63
+ def url_origin(
64
+ url: str,
65
+ /,
66
+ default_port: int = 0,
67
+ ) -> str:
61
68
  if url.startswith("/"):
62
69
  url = "http://localhost" + url
63
70
  elif url.startswith("//"):
64
71
  url = "http:" + url
65
72
  elif url.startswith("://"):
66
73
  url = "http" + url
67
- elif not CRE_URL_SCHEME_match(url):
68
- url = "http://" + url
69
74
  urlp = urlparse(url)
70
75
  scheme, netloc = urlp.scheme or "http", urlp.netloc or "localhost"
71
76
  if default_port and not urlp.port:
@@ -73,17 +78,27 @@ def url_origin(url: str, /, default_port: int = 0) -> str:
73
78
  return f"{scheme}://{netloc}"
74
79
 
75
80
 
76
- def complete_url(url: str, /, default_port: int = 0) -> str:
81
+ def complete_url(
82
+ url: str,
83
+ /,
84
+ default_port: int = 0,
85
+ clean: bool = False,
86
+ ) -> str:
77
87
  if url.startswith("/"):
78
88
  url = "http://localhost" + url
79
89
  elif url.startswith("//"):
80
90
  url = "http:" + url
81
91
  elif url.startswith("://"):
82
92
  url = "http" + url
83
- elif not CRE_URL_SCHEME_match(url):
84
- url = "http://" + url
93
+ if not (clean or default_port):
94
+ if not CRE_URL_SCHEME_match(url):
95
+ url = "http://" + url
96
+ return url
85
97
  urlp = urlparse(url)
86
- repl = {"query": "", "fragment": ""}
98
+ if clean:
99
+ repl = {"params": "", "query": "", "fragment": ""}
100
+ else:
101
+ repl = {}
87
102
  if not urlp.scheme:
88
103
  repl["scheme"] = "http"
89
104
  netloc = urlp.netloc
@@ -91,7 +106,10 @@ def complete_url(url: str, /, default_port: int = 0) -> str:
91
106
  netloc = "localhost"
92
107
  if default_port and not urlp.port:
93
108
  netloc = netloc.removesuffix(":") + f":{default_port}"
94
- repl["netloc"] = netloc
109
+ if netloc != urlp.netloc:
110
+ repl["netloc"] = netloc
111
+ if not repl:
112
+ return url
95
113
  return urlunparse(urlp._replace(**repl)).rstrip("/")
96
114
 
97
115
 
@@ -166,12 +184,37 @@ def headers_str_to_dict_by_lines(headers: str, /, ) -> dict[str, str]:
166
184
  return dict(batched(lines, 2)) # type: ignore
167
185
 
168
186
 
187
+ @overload
169
188
  def encode_multipart_data(
170
- data: None | Mapping[Buffer | str, Any] = None,
171
- files: None | Mapping[Buffer | str, Any] = None,
189
+ data: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
190
+ files: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
172
191
  boundary: None | str = None,
173
192
  file_suffix: str = "",
193
+ *,
194
+ async_: Literal[False] = False,
174
195
  ) -> tuple[dict, Iterator[Buffer]]:
196
+ ...
197
+ @overload
198
+ def encode_multipart_data(
199
+ data: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
200
+ files: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
201
+ boundary: None | str = None,
202
+ file_suffix: str = "",
203
+ *,
204
+ async_: Literal[True],
205
+ ) -> tuple[dict, AsyncIterator[Buffer]]:
206
+ ...
207
+ def encode_multipart_data(
208
+ data: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
209
+ files: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
210
+ boundary: None | str = None,
211
+ file_suffix: str = "",
212
+ *,
213
+ async_: bool = False,
214
+ ) -> tuple[dict, Iterator[Buffer]] | tuple[dict, AsyncIterator[Buffer]]:
215
+ if async_:
216
+ return encode_multipart_data_async(data, files, boundary)
217
+
175
218
  if not boundary:
176
219
  boundary = uuid4().hex
177
220
  boundary_bytes = bytes(boundary, "ascii")
@@ -258,8 +301,8 @@ def encode_multipart_data(
258
301
 
259
302
 
260
303
  def encode_multipart_data_async(
261
- data: None | Mapping[Buffer | str, Any] = None,
262
- files: None | Mapping[Buffer | str, Any] = None,
304
+ data: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
305
+ files: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
263
306
  boundary: None | str = None,
264
307
  file_suffix: str = "",
265
308
  ) -> tuple[dict, AsyncIterator[Buffer]]:
@@ -380,8 +423,11 @@ def normalize_request_args(
380
423
  params: Any = None,
381
424
  data: Any = None,
382
425
  json: Any = None,
426
+ files: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
383
427
  headers: None | Mapping[string, Any] | Iterable[tuple[string, Any]] = None,
384
428
  ensure_ascii: bool = False,
429
+ *,
430
+ async_: bool = False,
385
431
  ) -> RequestArgs:
386
432
  method = ensure_str(method).upper()
387
433
  if isinstance(url, SupportsGeturl):
@@ -404,7 +450,14 @@ def normalize_request_args(
404
450
  content_type = headers_.get("content-type", "")
405
451
  charset = get_charset(content_type)
406
452
  mimetype = get_mimetype(charset).lower()
407
- if data is not None:
453
+ if files is not None:
454
+ headers2, data = encode_multipart_data(
455
+ cast(None | Mapping[string, Any] | Iterable[tuple[string, Any]], data),
456
+ files,
457
+ async_=async_, # type: ignore
458
+ )
459
+ headers_.update(headers2)
460
+ elif data is not None:
408
461
  if isinstance(data, Buffer):
409
462
  pass
410
463
  elif isinstance(data, (str, UserString)):
@@ -412,7 +465,10 @@ def normalize_request_args(
412
465
  elif isinstance(data, AsyncIterable):
413
466
  data = async_map(ensure_buffer, data)
414
467
  elif isinstance(data, Iterator):
415
- data = map(ensure_buffer, data)
468
+ if async_:
469
+ data = async_map(ensure_buffer, data)
470
+ else:
471
+ data = map(ensure_buffer, data)
416
472
  elif mimetype == "application/json":
417
473
  if charset == "utf-8":
418
474
  data = json_dumps(data, default=json_default)
@@ -429,13 +485,18 @@ def normalize_request_args(
429
485
  elif json is not None:
430
486
  if isinstance(json, Buffer):
431
487
  data = json
432
- elif isinstance(data, AsyncIterable):
433
- data = async_map(ensure_buffer, data)
434
- if charset == "utf-8":
435
- data = json_dumps(data, default=json_default)
488
+ elif isinstance(json, AsyncIterable):
489
+ data = async_map(ensure_buffer, json)
490
+ elif isinstance(json, Iterator):
491
+ if async_:
492
+ data = async_map(ensure_buffer, json)
493
+ else:
494
+ data = map(ensure_buffer, json)
495
+ elif charset == "utf-8":
496
+ data = json_dumps(json, default=json_default)
436
497
  else:
437
498
  from json import dumps
438
- data = dumps(data, default=json_default).encode(charset)
499
+ data = dumps(json, default=json_default).encode(charset)
439
500
  if mimetype != "application/json":
440
501
  headers_["content-type"] = "application/json; charset=" + charset
441
502
  elif mimetype == "application/json":
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-http_request"
3
- version = "0.0.9"
3
+ version = "0.1.0"
4
4
  description = "Python http response utils."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"