fastls 0.1.3__py3-none-win_amd64.whl
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.
- fastls/__init__.py +11 -0
- fastls/_lib/build-info.json +21 -0
- fastls/_lib/fastls.dll +0 -0
- fastls/_lib/native-audit.json +14 -0
- fastls/_native.py +145 -0
- fastls/client.py +675 -0
- fastls/cookies.py +43 -0
- fastls/duplex.py +54 -0
- fastls/headers.py +28 -0
- fastls/notifications.py +170 -0
- fastls/request_options.py +139 -0
- fastls/sse.py +208 -0
- fastls/timeout.py +27 -0
- fastls/upload.py +59 -0
- fastls/websocket.py +391 -0
- fastls-0.1.3.dist-info/METADATA +223 -0
- fastls-0.1.3.dist-info/RECORD +21 -0
- fastls-0.1.3.dist-info/WHEEL +5 -0
- fastls-0.1.3.dist-info/licenses/LICENSE +203 -0
- fastls-0.1.3.dist-info/licenses/THIRD_PARTY_LICENSES.txt +1428 -0
- fastls-0.1.3.dist-info/top_level.txt +1 -0
fastls/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from ._native import FastlsError, FastlsTimeoutError, FastlsDecodeError
|
|
2
|
+
from .client import Session, AsyncSession, Response, AsyncResponse, FastlsHTTPError
|
|
3
|
+
from .headers import Headers
|
|
4
|
+
from .cookies import Cookies
|
|
5
|
+
from .timeout import Timeout
|
|
6
|
+
from .sse import ServerSentEvent, SSEStream, AsyncSSEStream
|
|
7
|
+
|
|
8
|
+
__all__ = ["Session", "AsyncSession", "Response", "AsyncResponse", "FastlsError", "Headers", "Cookies", "Timeout", "FastlsTimeoutError", "FastlsDecodeError", "ServerSentEvent", "SSEStream", "AsyncSSEStream"]
|
|
9
|
+
__all__.append("FastlsHTTPError")
|
|
10
|
+
from .websocket import WebSocket, AsyncWebSocket, WebSocketClosed
|
|
11
|
+
__all__ += ["WebSocket", "AsyncWebSocket", "WebSocketClosed"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "Windows-10-10.0.20348-SP0",
|
|
3
|
+
"machine": "AMD64",
|
|
4
|
+
"local_dependencies": true,
|
|
5
|
+
"package_version": "0.1.3",
|
|
6
|
+
"go": "go version go1.26.10 windows/amd64",
|
|
7
|
+
"cc": "gcc",
|
|
8
|
+
"abi": 1,
|
|
9
|
+
"workspace_source": {
|
|
10
|
+
"sha256": "36962eb4a11e9bd292ef4fc30f3901e6d863d10aecec9b61fe54265881eb8bbd",
|
|
11
|
+
"input_count": 126
|
|
12
|
+
},
|
|
13
|
+
"sources": {
|
|
14
|
+
"fastls-ffi": "f87f44148b79c7f60d92d0d3bf98ab7a29800f90",
|
|
15
|
+
"fastls": "a57a7c51852b80976a07d7ce50ab758c22d44434",
|
|
16
|
+
"ftransport": "2e1d66a7983b4fe730d18c3b8b90831ae6e93db5",
|
|
17
|
+
"imitate": "1ef806aec3fca9607c083e375a72e84ae542d6bd"
|
|
18
|
+
},
|
|
19
|
+
"library_sha256": "058562dfecad02a58bfdd02517322af304efdb676ac89741947ab8730feb019b",
|
|
20
|
+
"note": "Native build metadata. Consult the release manifest for publication and certification status."
|
|
21
|
+
}
|
fastls/_lib/fastls.dll
ADDED
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "PE",
|
|
3
|
+
"machine": "0x8664",
|
|
4
|
+
"imports": [
|
|
5
|
+
"KERNEL32.dll",
|
|
6
|
+
"api-ms-win-crt-environment-l1-1-0.dll",
|
|
7
|
+
"api-ms-win-crt-heap-l1-1-0.dll",
|
|
8
|
+
"api-ms-win-crt-runtime-l1-1-0.dll",
|
|
9
|
+
"api-ms-win-crt-stdio-l1-1-0.dll",
|
|
10
|
+
"api-ms-win-crt-string-l1-1-0.dll",
|
|
11
|
+
"api-ms-win-crt-time-l1-1-0.dll"
|
|
12
|
+
],
|
|
13
|
+
"note": "Static import table only; does not enumerate runtime LoadLibrary calls."
|
|
14
|
+
}
|
fastls/_native.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""ctypes binding to C ABI v1. No native callbacks or Python worker threads."""
|
|
2
|
+
import ctypes as C
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import sys
|
|
7
|
+
import threading
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FastlsError(Exception):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FastlsTimeoutError(FastlsError):
|
|
15
|
+
def __init__(self, message, phase):
|
|
16
|
+
super().__init__(message)
|
|
17
|
+
self.phase = phase
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class FastlsDecodeError(FastlsError):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def raise_response_error(info):
|
|
25
|
+
message = info.get("error") or "native request failed"
|
|
26
|
+
if info.get("error_code") == "timeout":
|
|
27
|
+
raise FastlsTimeoutError(message, info.get("timeout_phase", "total"))
|
|
28
|
+
if info.get("error_code") == "decode_error":
|
|
29
|
+
raise FastlsDecodeError(message)
|
|
30
|
+
raise FastlsError(message)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
_libraries = {}
|
|
34
|
+
_load_lock = threading.Lock()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Native:
|
|
38
|
+
def __init__(self, library=None):
|
|
39
|
+
name = "fastls.dll" if sys.platform == "win32" else "libfastls.dylib" if sys.platform == "darwin" else "libfastls.so"
|
|
40
|
+
selected = library if library is not None else os.environ.get("FASTLS_LIBRARY")
|
|
41
|
+
if selected is None:
|
|
42
|
+
bundled = Path(__file__).resolve().parent / "_lib" / name
|
|
43
|
+
development = Path(__file__).resolve().parents[2]
|
|
44
|
+
if bundled.is_file():
|
|
45
|
+
selected = bundled
|
|
46
|
+
elif (development / "python" / "pyproject.toml").is_file():
|
|
47
|
+
selected = development / "dist" / name
|
|
48
|
+
else:
|
|
49
|
+
raise FastlsError("Fastls native library is missing; install a platform wheel or set FASTLS_LIBRARY")
|
|
50
|
+
path = Path(selected).resolve()
|
|
51
|
+
with _load_lock:
|
|
52
|
+
if path not in _libraries:
|
|
53
|
+
try:
|
|
54
|
+
_libraries[path] = C.CDLL(str(path))
|
|
55
|
+
except OSError as error:
|
|
56
|
+
raise FastlsError(f"Cannot load Fastls native library at {path}; check its architecture and system dependencies") from error
|
|
57
|
+
self.lib = _libraries[path] # Retain the library for the process lifetime.
|
|
58
|
+
if not hasattr(self.lib, "fastls_abi_version"):
|
|
59
|
+
raise FastlsError("Selected library does not provide the Fastls C ABI")
|
|
60
|
+
self.lib.fastls_abi_version.argtypes = []
|
|
61
|
+
self.lib.fastls_abi_version.restype = C.c_uint32
|
|
62
|
+
if self.lib.fastls_abi_version() != 1:
|
|
63
|
+
raise FastlsError("unsupported Fastls ABI version")
|
|
64
|
+
signatures = {
|
|
65
|
+
"fastls_profiles": [],
|
|
66
|
+
"fastls_start": [C.c_char_p, C.c_size_t],
|
|
67
|
+
"fastls_info": [C.c_uint64],
|
|
68
|
+
"fastls_cancel": [C.c_uint64],
|
|
69
|
+
"fastls_close": [C.c_uint64],
|
|
70
|
+
}
|
|
71
|
+
if hasattr(self.lib, "fastls_stats"):
|
|
72
|
+
signatures["fastls_stats"] = []
|
|
73
|
+
if hasattr(self.lib, "fastls_features"):
|
|
74
|
+
signatures["fastls_features"] = []
|
|
75
|
+
if hasattr(self.lib, "fastls_ws_start"):
|
|
76
|
+
signatures["fastls_ws_start"] = [C.c_char_p, C.c_size_t]
|
|
77
|
+
self.lib.fastls_ws_send.argtypes = [C.c_uint64, C.c_int, C.c_void_p, C.c_size_t]
|
|
78
|
+
self.lib.fastls_ws_send.restype = C.c_int
|
|
79
|
+
self.lib.fastls_ws_read.argtypes = [C.c_uint64, C.c_void_p, C.c_size_t, C.POINTER(C.c_size_t), C.POINTER(C.c_int), C.POINTER(C.c_int)]
|
|
80
|
+
self.lib.fastls_ws_read.restype = C.c_int
|
|
81
|
+
for name, args in {"fastls_session_create": [], "fastls_session_close": [C.c_uint64], "fastls_session_close_idle": [C.c_uint64]}.items():
|
|
82
|
+
if hasattr(self.lib, name):
|
|
83
|
+
signatures[name] = args
|
|
84
|
+
if hasattr(self.lib, "fastls_session_cookies"):
|
|
85
|
+
signatures["fastls_session_cookies"] = [C.c_uint64, C.c_char_p, C.c_size_t]
|
|
86
|
+
for name, args in {"fastls_session_watch": [C.c_uint64, C.c_uint16, C.c_void_p, C.c_size_t],
|
|
87
|
+
"fastls_session_events": [C.c_uint64], "fastls_session_unwatch": [C.c_uint64]}.items():
|
|
88
|
+
if hasattr(self.lib, name):
|
|
89
|
+
signatures[name] = args
|
|
90
|
+
for name, args in signatures.items():
|
|
91
|
+
fn = getattr(self.lib, name)
|
|
92
|
+
fn.argtypes, fn.restype = args, C.c_void_p
|
|
93
|
+
self.lib.fastls_free.argtypes = [C.c_void_p]
|
|
94
|
+
self.lib.fastls_free.restype = None
|
|
95
|
+
self.lib.fastls_read.argtypes = [C.c_uint64, C.c_void_p, C.c_size_t, C.POINTER(C.c_size_t)]
|
|
96
|
+
self.lib.fastls_read.restype = C.c_int
|
|
97
|
+
|
|
98
|
+
if hasattr(self.lib, "fastls_write"):
|
|
99
|
+
self.lib.fastls_write.argtypes = [C.c_uint64, C.c_void_p, C.c_size_t, C.c_int]
|
|
100
|
+
self.lib.fastls_write.restype = C.c_int
|
|
101
|
+
|
|
102
|
+
if hasattr(self.lib, "fastls_wait"):
|
|
103
|
+
self.lib.fastls_wait.argtypes = [C.c_uint64, C.c_uint32, C.c_uint32]
|
|
104
|
+
self.lib.fastls_wait.restype = C.c_int
|
|
105
|
+
|
|
106
|
+
def wait(self, handle, events, timeout_ms=1000):
|
|
107
|
+
code = self.lib.fastls_wait(handle, events, timeout_ms)
|
|
108
|
+
if code < 0:
|
|
109
|
+
raise FastlsError("native wait failed or request is closed")
|
|
110
|
+
return code
|
|
111
|
+
|
|
112
|
+
def write(self, handle, data, end=False):
|
|
113
|
+
code = self.lib.fastls_write(handle, data, len(data), int(end))
|
|
114
|
+
if code < 0:
|
|
115
|
+
info = self.call("fastls_info", handle)
|
|
116
|
+
if info["state"] == "error":
|
|
117
|
+
raise_response_error(info)
|
|
118
|
+
if info["state"] in ("headers", "eof"):
|
|
119
|
+
return 2 # Server finished the upload early.
|
|
120
|
+
raise FastlsError("upload is closed or invalid")
|
|
121
|
+
return code
|
|
122
|
+
|
|
123
|
+
def call(self, name, *args):
|
|
124
|
+
ptr = getattr(self.lib, name)(*args)
|
|
125
|
+
if not ptr:
|
|
126
|
+
raise FastlsError("native library returned a null result")
|
|
127
|
+
try:
|
|
128
|
+
envelope = json.loads(C.string_at(ptr).decode("utf-8"))
|
|
129
|
+
finally:
|
|
130
|
+
self.lib.fastls_free(ptr)
|
|
131
|
+
if not envelope["ok"]:
|
|
132
|
+
raise FastlsError(envelope["error"])
|
|
133
|
+
return envelope["result"]
|
|
134
|
+
|
|
135
|
+
def start(self, request):
|
|
136
|
+
raw = json.dumps(request, ensure_ascii=False).encode("utf-8")
|
|
137
|
+
return self.call("fastls_start", raw, len(raw))
|
|
138
|
+
|
|
139
|
+
def read(self, handle, buffer):
|
|
140
|
+
length = C.c_size_t()
|
|
141
|
+
code = self.lib.fastls_read(handle, buffer, len(buffer), C.byref(length))
|
|
142
|
+
if code < 0:
|
|
143
|
+
info = self.call("fastls_info", handle)
|
|
144
|
+
raise_response_error(info)
|
|
145
|
+
return code, buffer.raw[:length.value]
|