bas-http 1.0.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.
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: bas-http
3
+ Version: 1.0.0
4
+ Summary: Copy-paste your browser's request, bas handles the rest. No impersonation needed.
5
+ Author: bas
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourusername/bas
8
+ Project-URL: Repository, https://github.com/yourusername/bas
9
+ Project-URL: Issues, https://github.com/yourusername/bas/issues
10
+ Keywords: http,curl,cookie,scraping,browser,devtools
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
@@ -0,0 +1,244 @@
1
+ # bas
2
+
3
+ Copy-paste your browser's request, bas handles the rest.
4
+
5
+ No impersonation. No fingerprint chasing. No broken cookies.
6
+
7
+ ## Why bas?
8
+
9
+ | Issue | curlcffi | bas |
10
+ |-------|----------|----------|
11
+ | Cookies lost during redirects | **BUG** | **Fixed** |
12
+ | Cookies not accumulating across requests | **BUG** | **Fixed** |
13
+ | Manual Cookie header construction needed | Yes | **Auto-injected** |
14
+ | Requires curl-impersonate | Yes | **No — pure Python** |
15
+ | Browser fingerprint updates needed | Yes | **None — you bring your own headers** |
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install bas
21
+ ```
22
+
23
+ Zero external dependencies. Works with Python's built-in `urllib`.
24
+
25
+ ## Usage
26
+
27
+ ### Method 1: Paste a curl command from DevTools
28
+
29
+ ```
30
+ 1. Open browser DevTools → Network tab
31
+ 2. Right-click any request → "Copy as cURL"
32
+ 3. Paste into bas
33
+ ```
34
+
35
+ ```python
36
+ import bas
37
+
38
+ # Paste your curl command (use raw string r'' to preserve backslashes)
39
+ s = bas.from_curl(r'''curl "https://spaceshooter.net/faucet/ltc" ^
40
+ -H "accept: text/html" ^
41
+ -H "user-agent: Mozilla/5.0 ..." ^
42
+ -b "cf_clearance=abc123; session=xyz"''')
43
+
44
+ # Now make requests — cookies and headers auto-injected
45
+ r = s.get("https://spaceshooter.net/faucet/ltc")
46
+ print(r.status_code, r.text)
47
+
48
+ # Add more cookies manually if needed
49
+ s.set_cookie("new_cookie", "value", domain="spaceshooter.net")
50
+ r = s.get("https://spaceshooter.net/dashboard")
51
+ ```
52
+
53
+ ### Method 2: Build headers manually
54
+
55
+ ```python
56
+ import bas
57
+
58
+ s = bas.Session()
59
+
60
+ # Paste your headers from DevTools
61
+ s.headers = {
62
+ "accept": "text/html,application/xhtml+xml,...",
63
+ "accept-language": "en-US,en;q=0.9",
64
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
65
+ "sec-ch-ua": '"Chromium";v="137", "Not/A)Brand";v="24"',
66
+ "sec-ch-ua-mobile": "?0",
67
+ "sec-ch-ua-platform": '"Windows"',
68
+ "sec-fetch-dest": "document",
69
+ "sec-fetch-mode": "navigate",
70
+ }
71
+
72
+ # Add your cookies
73
+ s.set_cookie("cf_clearance", "abc123", domain="spaceshooter.net")
74
+ s.set_cookie("session", "xyz", domain="spaceshooter.net")
75
+
76
+ # Go!
77
+ r = s.get("https://spaceshooter.net/faucet/ltc")
78
+ ```
79
+
80
+ ### Method 3: Build from headers + cookies dict
81
+
82
+ ```python
83
+ import bas
84
+
85
+ s = bas.from_headers(
86
+ url="https://spaceshooter.net/faucet/ltc",
87
+ headers={
88
+ "user-agent": "Mozilla/5.0 ...",
89
+ "accept": "text/html,...",
90
+ },
91
+ cookies={
92
+ "cf_clearance": "abc123",
93
+ "session": "xyz",
94
+ },
95
+ )
96
+
97
+ r = s.get("https://spaceshooter.net/faucet/ltc")
98
+ ```
99
+
100
+ ### Parse a curl command without making a request
101
+
102
+ ```python
103
+ from bas.curl_parser import parse_curl, print_curl_summary
104
+
105
+ # See what's in a curl command
106
+ print_curl_summary(r'''curl "https://example.com" -H "User-Agent: ..." -b "cookie=value"''')
107
+
108
+ # Or get it as a dict
109
+ parsed = parse_curl(r'''curl "https://example.com" -H "User-Agent: ..." -b "cookie=value"''')
110
+ print(parsed["method"]) # "GET"
111
+ print(parsed["url"]) # "https://example.com"
112
+ print(parsed["headers"]) # {"User-Agent": "..."}
113
+ print(parsed["cookies"]) # {"cookie": "value"}
114
+ ```
115
+
116
+ ### Cookie Management
117
+
118
+ ```python
119
+ import bas
120
+
121
+ with bas.Session() as s:
122
+ # Pre-load cookies
123
+ s.set_cookie("session", "abc123", domain="example.com")
124
+
125
+ # Cookies are auto-injected into every request
126
+ r = s.get("https://example.com")
127
+ print("Cookie header:", r.request.headers.get("Cookie"))
128
+
129
+ # Save cookies to file
130
+ s.save_cookies("cookies.json")
131
+
132
+ # Load cookies from file
133
+ s.load_cookies("cookies.json")
134
+
135
+ # Check what cookies we have for a URL
136
+ print(s.get_cookies("https://example.com"))
137
+ ```
138
+
139
+ ### Cookie Jar (direct access)
140
+
141
+ ```python
142
+ from bas.cookies import Cookie, CookieJar
143
+
144
+ jar = CookieJar()
145
+
146
+ # Parse Set-Cookie headers from responses
147
+ jar.parse_set_cookie(
148
+ "session=abc123; Domain=.example.com; Path=/; Secure; HttpOnly",
149
+ "https://www.example.com/"
150
+ )
151
+
152
+ # Get cookies for a URL (RFC 6265 compliant)
153
+ cookies = jar.match("https://www.example.com/page")
154
+
155
+ # Build Cookie header automatically
156
+ header = jar.to_header("https://www.example.com/")
157
+ print(header) # "session=abc123"
158
+
159
+ # Save/load
160
+ jar.save_json("cookies.json")
161
+ jar.load_json("cookies.json")
162
+ ```
163
+
164
+ ## How bas Fixes curlcffi's Cookie Bugs
165
+
166
+ ### Fix #1: Cookies Accumulate
167
+
168
+ ```python
169
+ # curlcffi (BROKEN):
170
+ r1 = s.get(url)
171
+ r2 = s.get(url) # LOST cookies from r1!
172
+
173
+ # bas (FIXED):
174
+ r1 = s.get(url)
175
+ r2 = s.get(url) # Has ALL cookies from r1 + new ones
176
+ ```
177
+
178
+ ### Fix #2: Redirect Cookie Inheritance
179
+
180
+ ```python
181
+ # curlcffi (BROKEN):
182
+ r = s.get("https://example.com/page") # 302 redirect
183
+ # Cookies LOST during redirect!
184
+
185
+ # bas (FIXED):
186
+ r = s.get("https://example.com/page") # 302 redirect
187
+ # Cookies properly inherited + new Set-Cookie headers captured
188
+ ```
189
+
190
+ ### Fix #3: Auto Cookie Injection
191
+
192
+ ```python
193
+ # curlcffi (manual):
194
+ r = s.get(url, headers={"Cookie": "session=abc123; token=xyz"})
195
+
196
+ # bas (automatic):
197
+ s.set_cookie("session", "abc123")
198
+ s.set_cookie("token", "xyz")
199
+ r = s.get(url) # Cookie header auto-generated!
200
+ ```
201
+
202
+ ## API Reference
203
+
204
+ ### `from_curl(curl_cmd, **kwargs)` → Session
205
+
206
+ Create a Session from a curl command. The main entry point.
207
+
208
+ ### `from_headers(url, headers, cookies, **kwargs)` → Session
209
+
210
+ Create a Session from raw headers and cookies.
211
+
212
+ ### `Session(headers=None, cookies=None, ...)`
213
+
214
+ Simple HTTP session. Pure Python, no curl needed.
215
+
216
+ **Parameters:**
217
+ - `headers` (dict): Default headers
218
+ - `cookies` (dict): Pre-set cookies
219
+ - `verify` (bool): SSL verification (default: True)
220
+ - `timeout` (float): Request timeout (default: 30)
221
+ - `allow_redirects` (bool): Follow redirects (default: True)
222
+ - `max_redirects` (int): Max redirects (default: 20)
223
+
224
+ **Methods:**
225
+ - `get(url, **kwargs)` → Response
226
+ - `post(url, **kwargs)` → Response
227
+ - `put(url, **kwargs)` → Response
228
+ - `delete(url, **kwargs)` → Response
229
+ - `set_cookie(name, value, domain, path)` → None
230
+ - `get_cookies(url)` → dict
231
+ - `save_cookies(filepath, format)` → None
232
+ - `load_cookies(filepath, format)` → None
233
+
234
+ ### `Cookie(name, value, domain, path, ...)`
235
+
236
+ Individual cookie with RFC 6265 compliance.
237
+
238
+ ### `CookieJar`
239
+
240
+ Thread-safe cookie container. Full RFC 6265 domain/path matching.
241
+
242
+ ## License
243
+
244
+ MIT
@@ -0,0 +1,97 @@
1
+ """
2
+ bas — Copy-paste your browser's request, bas handles the rest.
3
+
4
+ No impersonation needed. No fingerprint chasing. Just grab your
5
+ headers + cookies from DevTools and go.
6
+
7
+ Workflow:
8
+ 1. Open browser DevTools -> Network tab
9
+ 2. Right-click request -> "Copy as cURL"
10
+ 3. Paste into bas
11
+
12
+ >>> import bas
13
+ >>> s = bas.from_curl('''curl "https://example.com" -H "User-Agent: ..." -b "cookie=value"''')
14
+ >>> r = s.get("https://example.com/other-page")
15
+ >>> print(r.status_code, r.text)
16
+
17
+ Or manually:
18
+
19
+ >>> s = bas.Session()
20
+ >>> s.headers["User-Agent"] = "Mozilla/5.0 ..."
21
+ >>> s.set_cookie("session", "abc123", domain="example.com")
22
+ >>> r = s.get("https://example.com/page")
23
+ """
24
+
25
+ from typing import Optional
26
+ from .simple_session import Session
27
+ from .curl_parser import parse_curl, curl_to_session, print_curl_summary
28
+ from .cookies import Cookie, CookieJar
29
+ from .models import Headers, PreparedRequest, Response, HTTPError
30
+
31
+ __version__ = "1.0.0"
32
+ __author__ = "bas"
33
+
34
+
35
+ def from_curl(curl_cmd: str, **kwargs) -> Session:
36
+ """
37
+ Create a Session from a curl command.
38
+
39
+ This is the main entry point. Copy a curl command from your browser
40
+ and bas parses all headers, cookies, and settings from it.
41
+
42
+ Usage:
43
+ >>> s = bas.from_curl('''curl "https://example.com" -H "User-Agent: ..." -b "cookie=value"''')
44
+ >>> r = s.get("https://example.com/page")
45
+ """
46
+ return curl_to_session(curl_cmd, **kwargs)
47
+
48
+
49
+ def from_headers(
50
+ url: str,
51
+ headers: dict,
52
+ cookies: Optional[dict] = None,
53
+ **kwargs,
54
+ ) -> Session:
55
+ """
56
+ Create a Session from raw headers and cookies.
57
+
58
+ Use this when you have headers/cookies from browser DevTools
59
+ but not a curl command.
60
+
61
+ Usage:
62
+ >>> s = bas.from_headers(
63
+ ... url="https://example.com",
64
+ ... headers={"User-Agent": "Mozilla/5.0 ...", ...},
65
+ ... cookies={"session": "abc123", ...},
66
+ ... )
67
+ >>> r = s.get("https://example.com/page")
68
+ """
69
+ s = Session(**kwargs)
70
+ s.headers.update(headers)
71
+
72
+ if cookies:
73
+ from urllib.parse import urlparse
74
+ domain = urlparse(url).hostname or ""
75
+ for name, value in cookies.items():
76
+ s.set_cookie(name, value, domain=domain, path="/")
77
+
78
+ return s
79
+
80
+
81
+ __all__ = [
82
+ # Core
83
+ "Session",
84
+ "Cookie",
85
+ "CookieJar",
86
+ "Headers",
87
+ "PreparedRequest",
88
+ "Response",
89
+ "HTTPError",
90
+ # Quick start
91
+ "from_curl",
92
+ "from_headers",
93
+ # Parser
94
+ "parse_curl",
95
+ "curl_to_session",
96
+ "print_curl_summary",
97
+ ]