python-httpfile 0.0.4.4__tar.gz → 0.0.5.1__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-httpfile
3
- Version: 0.0.4.4
3
+ Version: 0.0.5.1
4
4
  Summary: Python httpfile.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-httpfile
6
6
  License: MIT
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3.10
18
18
  Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
20
21
  Classifier: Programming Language :: Python :: 3 :: Only
21
22
  Classifier: Topic :: Software Development
22
23
  Classifier: Topic :: Software Development :: Libraries
@@ -4,7 +4,7 @@
4
4
  from __future__ import annotations
5
5
 
6
6
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
7
- __version__ = (0, 0, 4)
7
+ __version__ = (0, 0, 5)
8
8
  __all__ = ["HTTPFileReader", "AsyncHTTPFileReader"]
9
9
 
10
10
  import errno
@@ -106,13 +106,13 @@ class HTTPFileReader(RawIOBase, BinaryIO):
106
106
  urlopen = urlopen,
107
107
  ):
108
108
  if headers:
109
- headers = {**headers, "Accept-Encoding": "identity"}
109
+ headers = {**headers, "accept-encoding": "identity"}
110
110
  else:
111
- headers = {"Accept-Encoding": "identity"}
111
+ headers = {"accept-encoding": "identity"}
112
112
  if start > 0:
113
- headers["Range"] = f"bytes={start}-"
113
+ headers["range"] = f"bytes={start}-"
114
114
  elif start < 0:
115
- headers["Range"] = f"bytes={start}"
115
+ headers["range"] = f"bytes={start}"
116
116
  if urlopen is None:
117
117
  urlopen = globals()["urlopen"]
118
118
  if callable(url):
@@ -316,7 +316,7 @@ class HTTPFileReader(RawIOBase, BinaryIO):
316
316
  url = self.url
317
317
  response = self.urlopen(
318
318
  url() if callable(url) else url,
319
- headers={**self.headers, "Range": f"bytes={start}-"}
319
+ headers={**self.headers, "range": f"bytes={start}-"}
320
320
  )
321
321
  length_new = get_total_length(response)
322
322
  if self.length != length_new:
@@ -572,13 +572,13 @@ class AsyncHTTPFileReader(HTTPFileReader):
572
572
  urlopen = None,
573
573
  ):
574
574
  if headers:
575
- headers = {**headers, "Accept-Encoding": "identity"}
575
+ headers = {**headers, "accept-encoding": "identity"}
576
576
  else:
577
- headers = {"Accept-Encoding": "identity"}
577
+ headers = {"accept-encoding": "identity"}
578
578
  if start > 0:
579
- headers["Range"] = f"bytes={start}-"
579
+ headers["range"] = f"bytes={start}-"
580
580
  elif start < 0:
581
- headers["Range"] = f"bytes={start}"
581
+ headers["range"] = f"bytes={start}"
582
582
  if urlopen is None:
583
583
  urlopen = globals()["urlopen"]
584
584
  if callable(url):
@@ -751,7 +751,7 @@ class AsyncHTTPFileReader(HTTPFileReader):
751
751
  url = self.url
752
752
  response = await self.urlopen(
753
753
  (await url()) if callable(url) else url,
754
- headers={**self.headers, "Range": f"bytes={start}-"}
754
+ headers={**self.headers, "range": f"bytes={start}-"}
755
755
  )
756
756
  length_new = get_total_length(response)
757
757
  if self.length != length_new:
@@ -1119,8 +1119,55 @@ if find_spec("aiohttp"):
1119
1119
  if find_spec("httpx"):
1120
1120
  from filewrap import bytes_iter_to_reader, bytes_iter_to_async_reader
1121
1121
 
1122
- _httpx_urlopen = None
1123
- _httpx_urlopen_async = None
1122
+ def httpx_request(
1123
+ url,
1124
+ method: str = "GET",
1125
+ auth = None,
1126
+ follow_redirects: bool = True,
1127
+ stream: bool = True,
1128
+ session = None,
1129
+ **request_kwargs,
1130
+ ):
1131
+ if session is None:
1132
+ from httpx import Client
1133
+ if "__del__" not in Client.__dict__:
1134
+ setattr(Client, "__del__", lambda self: self.close())
1135
+ session = Client()
1136
+ return session.send(
1137
+ request=session.build_request(
1138
+ method=method,
1139
+ url=url,
1140
+ **request_kwargs,
1141
+ ),
1142
+ auth=auth,
1143
+ follow_redirects=follow_redirects,
1144
+ stream=stream,
1145
+ )
1146
+
1147
+ async def httpx_request_async(
1148
+ url,
1149
+ method: str = "GET",
1150
+ auth = None,
1151
+ follow_redirects: bool = True,
1152
+ stream: bool = True,
1153
+ session = None,
1154
+ **request_kwargs,
1155
+ ):
1156
+ if session is None:
1157
+ from httpx import AsyncClient
1158
+ if "__del__" not in AsyncClient.__dict__:
1159
+ setattr(AsyncClient, "__del__", lambda self: run_async(self.aclose()))
1160
+ session = AsyncClient()
1161
+ return await session.send(
1162
+ request=session.build_request(
1163
+ method=method,
1164
+ url=url,
1165
+ **request_kwargs,
1166
+ ),
1167
+ auth=auth,
1168
+ follow_redirects=follow_redirects,
1169
+ stream=stream,
1170
+ )
1124
1171
 
1125
1172
  class HttpxFileReader(HTTPFileReader):
1126
1173
 
@@ -1133,24 +1180,14 @@ if find_spec("httpx"):
1133
1180
  seek_threshold: int = 1 << 20,
1134
1181
  urlopen = None,
1135
1182
  ):
1136
- global _httpx_urlopen
1137
- from httpx import stream, Client
1183
+ from httpx import Client
1138
1184
 
1139
- if isinstance(urlopen, Client):
1140
- urlopen = partial(urlopen.stream, "GET")
1141
- elif urlopen is None:
1142
- if _httpx_urlopen is None:
1143
- if "__del__" not in Client.__dict__:
1144
- setattr(Client, "__del__", lambda self: self.close())
1145
- urlopen = _httpx_urlopen = partial(stream, "GET")
1146
- else:
1147
- urlopen = _httpx_urlopen
1185
+ if urlopen is None or isinstance(urlopen, Client):
1186
+ urlopen = partial(httpx_request, session=urlopen)
1148
1187
 
1149
1188
  def urlopen_wrapper(url: str, headers: None | Mapping = headers):
1150
- context = urlopen(url, headers=headers)
1151
- resp = context.__enter__()
1189
+ resp = urlopen(url, headers=headers)
1152
1190
  resp.raise_for_status()
1153
- resp.context = context
1154
1191
  file = bytes_iter_to_reader(resp.iter_raw())
1155
1192
  self.__dict__["file"] = file
1156
1193
  return resp
@@ -1178,64 +1215,14 @@ if find_spec("httpx"):
1178
1215
  seek_threshold: int = 1 << 20,
1179
1216
  urlopen = None,
1180
1217
  ):
1181
- global _httpx_urlopen_async
1182
1218
  from httpx import AsyncClient
1183
1219
 
1184
- if isinstance(urlopen, AsyncClient):
1185
- urlopen = partial(urlopen.stream, "GET")
1186
- elif urlopen is None:
1187
- if _httpx_urlopen_async is None:
1188
- if "__del__" not in AsyncClient.__dict__:
1189
- setattr(AsyncClient, "__del__", lambda self: run_async(self.aclose()))
1190
- def async_stream(
1191
- method,
1192
- url,
1193
- params = None,
1194
- content = None,
1195
- data = None,
1196
- files = None,
1197
- json = None,
1198
- headers = None,
1199
- cookies = None,
1200
- auth = None,
1201
- proxy = None,
1202
- proxies = None,
1203
- timeout = 5.0,
1204
- follow_redirects = False,
1205
- verify = True,
1206
- cert = None,
1207
- trust_env = True,
1208
- ):
1209
- client = AsyncClient(
1210
- cookies=cookies,
1211
- proxy=proxy,
1212
- proxies=proxies,
1213
- cert=cert,
1214
- verify=verify,
1215
- timeout=timeout,
1216
- trust_env=trust_env,
1217
- )
1218
- return client.stream(
1219
- method=method,
1220
- url=url,
1221
- content=content,
1222
- data=data,
1223
- files=files,
1224
- json=json,
1225
- params=params,
1226
- headers=headers,
1227
- auth=auth,
1228
- follow_redirects=follow_redirects,
1229
- )
1230
- urlopen = _httpx_urlopen_async = partial(async_stream, "GET")
1231
- else:
1232
- urlopen = _httpx_urlopen_async
1220
+ if urlopen is None or isinstance(urlopen, AsyncClient):
1221
+ urlopen = partial(httpx_request_async, session=urlopen)
1233
1222
 
1234
1223
  async def urlopen_wrapper(url: str, headers: None | Mapping = headers):
1235
- context = urlopen(url, headers=headers)
1236
- resp = await context.__aenter__()
1224
+ resp = await urlopen(url, headers=headers)
1237
1225
  resp.raise_for_status()
1238
- resp.context = context
1239
1226
  file = bytes_iter_to_async_reader(resp.aiter_raw())
1240
1227
  self.__dict__["file"] = file
1241
1228
  return resp
@@ -1257,3 +1244,4 @@ if find_spec("httpx"):
1257
1244
 
1258
1245
  # TODO: 增加 blacksheep 的 HTTPFileReader
1259
1246
  # TODO: 设计实现一个 HTTPFileWriter,用于实现上传,关闭后视为上传完成
1247
+ # TODO: httpx 重新实现 stream 和 async_stream 方法,确保不需要用上下文管理器,如此才能真的简化
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-httpfile"
3
- version = "0.0.4.4"
3
+ version = "0.0.5.1"
4
4
  description = "Python httpfile."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"