browserfetch 0.15.0__tar.gz → 0.16.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.3
2
2
  Name: browserfetch
3
- Version: 0.15.0
3
+ Version: 0.16.0
4
4
  Summary: fetch in Python using your browser!
5
5
  Keywords: browser,fetch,python,cookies
6
6
  License: GNU General Public License v3 (GPLv3)
@@ -26,14 +26,14 @@ Usage
26
26
 
27
27
  from asyncio import gather, new_event_loop
28
28
 
29
- from browserfetch import fetch, get, post, run_server
29
+ from browserfetch import fetch, run_server
30
30
 
31
31
 
32
32
  async def main():
33
33
  response1, response2, reponse3 = await gather(
34
- get('https://example.com/path1', params={'a': 1}),
34
+ fetch('https://example.com/path1', params={'a': 1}),
35
35
  fetch('https://example.com/image.png'),
36
- post('https://example.com/path2', data={'a': 1}),
36
+ fetch('https://example.com/path2', data={'a': 1}, method='post'),
37
37
  )
38
38
  # do stuff with retrieved responses
39
39
 
@@ -12,14 +12,14 @@ Usage
12
12
 
13
13
  from asyncio import gather, new_event_loop
14
14
 
15
- from browserfetch import fetch, get, post, run_server
15
+ from browserfetch import fetch, run_server
16
16
 
17
17
 
18
18
  async def main():
19
19
  response1, response2, reponse3 = await gather(
20
- get('https://example.com/path1', params={'a': 1}),
20
+ fetch('https://example.com/path1', params={'a': 1}),
21
21
  fetch('https://example.com/image.png'),
22
- post('https://example.com/path2', data={'a': 1}),
22
+ fetch('https://example.com/path2', data={'a': 1}, method='post'),
23
23
  )
24
24
  # do stuff with retrieved responses
25
25
 
@@ -1,4 +1,4 @@
1
- __version__ = '0.15.0'
1
+ __version__ = '0.16.0'
2
2
  __all__ = [
3
3
  'BrowserError',
4
4
  'Response',
@@ -6,12 +6,10 @@ __all__ = [
6
6
  'fetch',
7
7
  'start_server',
8
8
  ]
9
- import atexit
10
9
  from asyncio import (
11
- AbstractEventLoop,
10
+ CancelledError,
12
11
  Event,
13
- Task,
14
- get_running_loop,
12
+ Future,
15
13
  wait_for,
16
14
  )
17
15
  from collections import defaultdict
@@ -134,7 +132,7 @@ async def receive_responses(ws: WebSocketResponse | ClientWebSocketResponse):
134
132
 
135
133
 
136
134
  routes = RouteTableDef()
137
- PROTOCOL = '3'
135
+ PROTOCOL = '4'
138
136
 
139
137
 
140
138
  @routes.get('/ws')
@@ -325,12 +323,6 @@ async def fetch(
325
323
 
326
324
  app = Application()
327
325
  app.add_routes(routes)
328
- app_runner = AppRunner(app)
329
-
330
-
331
- def _cancel_relay_task(loop: AbstractEventLoop, task: Task):
332
- logger.info('cancelling relay task')
333
- task.cancel()
334
326
 
335
327
 
336
328
  _server = False
@@ -341,9 +333,9 @@ _port = 9404
341
333
  async def start_server(*, host=_host, port=_port):
342
334
  global _server, _host, _port
343
335
  _host, _port = host, port
344
- loop = get_running_loop()
345
- await app_runner.setup()
346
- site = TCPSite(app_runner, host, port)
336
+ runner = AppRunner(app)
337
+ await runner.setup()
338
+ site = TCPSite(runner, host, port)
347
339
  try:
348
340
  await site.start() # does not block
349
341
  except OSError as e:
@@ -352,8 +344,19 @@ async def start_server(*, host=_host, port=_port):
352
344
  port,
353
345
  e,
354
346
  )
355
- relay_task = loop.create_task(relay_client(host, port))
356
- atexit.register(_cancel_relay_task, loop, relay_task)
357
- else:
358
- _server = True
359
- logger.info('server started at http://%s:%s', host, port)
347
+ try:
348
+ await relay_client(host, port) # blocks
349
+ finally:
350
+ logger.error('relay failed: %s', e)
351
+ return
352
+
353
+ _server = True
354
+ logger.info('server started at http://%s:%s', host, port)
355
+ try:
356
+ await Future()
357
+ except CancelledError:
358
+ pass # python raises CancelledError on KeyboardInterrupt
359
+ finally:
360
+ await runner.shutdown()
361
+ await runner.cleanup()
362
+ logger.info('server shutdown')
@@ -75,7 +75,7 @@
75
75
  /**
76
76
  *
77
77
  * @param {any} req
78
- * @returns {Promise<Uint8Array>}
78
+ * @returns {Promise<Blob>}
79
79
  */
80
80
  async function doEval(req) {
81
81
  var evalled, resp;
@@ -96,9 +96,10 @@
96
96
  } catch (/**@type {any} */err) {
97
97
  resp = { 'result': err.toString(), 'event_id': req['event_id'] };
98
98
  }
99
- return new TextEncoder().encode(JSON.stringify(resp));
99
+ return new Blob([JSON.stringify(resp)]);
100
100
  }
101
101
 
102
+
102
103
  /**
103
104
  *
104
105
  * @param {ArrayBuffer} d
@@ -126,7 +127,7 @@
126
127
  var hostName;
127
128
 
128
129
  function connect() {
129
- var protocol = '3'
130
+ var protocol = '4'
130
131
  var ws = new WebSocket("ws://127.0.0.1:9404/ws");
131
132
  ws.binaryType = "arraybuffer";
132
133
 
@@ -143,7 +144,7 @@
143
144
  };
144
145
 
145
146
  ws.onmessage = async (evt) => {
146
- var /**@type {Uint8Array | Blob} */ result, /**@type {any} */ j, b;
147
+ var /**@type {Blob} */ result, /**@type {any} */ j, b;
147
148
  [b, j] = parseData(evt.data);
148
149
  switch (j['action']) {
149
150
  case 'close_ws':
@@ -158,10 +159,11 @@
158
159
  result = await doEval(j);
159
160
  break;
160
161
  default:
161
- result = new TextEncoder().encode(JSON.stringify({
162
+ result = new Blob([JSON.stringify({
162
163
  'event_id': j['event_id'],
163
164
  'error': `Action ${j['action']} is not defined.`
164
- }));
165
+ })]);
166
+
165
167
  break;
166
168
  }
167
169
  ws.send(result);
@@ -10,12 +10,8 @@ classifiers = [
10
10
  "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
11
11
  ]
12
12
  requires-python = ">=3.13"
13
- dependencies = [
14
- "aiohttp",
15
- "pyperclip",
16
- "cyclopts",
17
- ]
18
- version = "0.15.0"
13
+ dependencies = ["aiohttp", "pyperclip", "cyclopts"]
14
+ version = "0.16.0"
19
15
 
20
16
  [[authors]]
21
17
  name = "5j9"
@@ -37,17 +33,18 @@ format.quote-style = 'single'
37
33
  lint.isort.combine-as-imports = true
38
34
  lint.extend-select = [
39
35
  'W605', # invalid-escape-sequence
40
- 'FA', # flake8-future-annotations
41
- 'I', # isort
42
- 'UP', # pyupgrade
43
- 'RUF', # Ruff-specific rules (RUF)
36
+ 'FA', # flake8-future-annotations
37
+ 'I', # isort
38
+ 'UP', # pyupgrade
39
+ 'RUF', # Ruff-specific rules (RUF)
44
40
  ]
45
41
  lint.ignore = [
46
- 'E721', # Do not compare types, use `isinstance()`
47
- 'RUF001', # ambiguous-unicode-character-string
48
- 'RUF002', # ambiguous-unicode-character-docstring
49
- 'RUF003', # ambiguous-unicode-character-comment
50
- 'RUF012', # mutable-class-default
42
+ 'E721', # Do not compare types, use `isinstance()`
43
+ 'RUF001', # ambiguous-unicode-character-string
44
+ 'RUF002', # ambiguous-unicode-character-docstring
45
+ 'RUF003', # ambiguous-unicode-character-comment
46
+ 'RUF012', # mutable-class-default
47
+ 'RUF059', # Unpacked variable never used
51
48
  ]
52
49
 
53
50
  [tool.pytest.ini_options]
@@ -68,6 +65,8 @@ reportInvalidStringEscapeSequence = false
68
65
  reportConstantRedefinition = 'error'
69
66
  reportTypeCommentUsage = 'warning'
70
67
  reportUnnecessaryComparison = 'warning'
68
+ venvPath = "."
69
+ venv = ".venv"
71
70
 
72
71
  [tool.uv.build-backend]
73
72
  module-root = ""