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.
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/PKG-INFO +2 -1
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/httpfile/__init__.py +68 -80
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/pyproject.toml +1 -1
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/LICENSE +0 -0
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/httpfile/py.typed +0 -0
- {python_httpfile-0.0.4.4 → python_httpfile-0.0.5.1}/readme.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-httpfile
|
|
3
|
-
Version: 0.0.
|
|
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,
|
|
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, "
|
|
109
|
+
headers = {**headers, "accept-encoding": "identity"}
|
|
110
110
|
else:
|
|
111
|
-
headers = {"
|
|
111
|
+
headers = {"accept-encoding": "identity"}
|
|
112
112
|
if start > 0:
|
|
113
|
-
headers["
|
|
113
|
+
headers["range"] = f"bytes={start}-"
|
|
114
114
|
elif start < 0:
|
|
115
|
-
headers["
|
|
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, "
|
|
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, "
|
|
575
|
+
headers = {**headers, "accept-encoding": "identity"}
|
|
576
576
|
else:
|
|
577
|
-
headers = {"
|
|
577
|
+
headers = {"accept-encoding": "identity"}
|
|
578
578
|
if start > 0:
|
|
579
|
-
headers["
|
|
579
|
+
headers["range"] = f"bytes={start}-"
|
|
580
580
|
elif start < 0:
|
|
581
|
-
headers["
|
|
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, "
|
|
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
|
-
|
|
1123
|
-
|
|
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
|
-
|
|
1137
|
-
from httpx import stream, Client
|
|
1183
|
+
from httpx import Client
|
|
1138
1184
|
|
|
1139
|
-
if isinstance(urlopen, Client):
|
|
1140
|
-
urlopen = partial(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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 方法,确保不需要用上下文管理器,如此才能真的简化
|
|
File without changes
|
|
File without changes
|
|
File without changes
|