atsfill 0.0.3.dev10__tar.gz → 0.0.3.dev11__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.
Files changed (24) hide show
  1. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/PKG-INFO +1 -1
  2. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/pyproject.toml +3 -2
  3. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/pyproject.toml.orig +3 -2
  4. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/browser.py +10 -1
  5. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/LICENSE +0 -0
  6. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/README.md +0 -0
  7. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/__init__.py +0 -0
  8. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/adapters/__init__.py +0 -0
  9. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/adapters/ashby.py +0 -0
  10. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/adapters/greenhouse.py +0 -0
  11. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/adapters/teamtailor.py +0 -0
  12. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/adapters/wttj.py +0 -0
  13. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/cli.py +0 -0
  14. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/__init__.py +0 -0
  15. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/accounts.py +0 -0
  16. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/adapter.py +0 -0
  17. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/attempts.py +0 -0
  18. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/commands.py +0 -0
  19. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/matching.py +0 -0
  20. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/paths.py +0 -0
  21. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/registry.py +0 -0
  22. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/core/results.py +0 -0
  23. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/py.typed +0 -0
  24. {atsfill-0.0.3.dev10 → atsfill-0.0.3.dev11}/src/atsfill/registry.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atsfill
3
- Version: 0.0.3.dev10
3
+ Version: 0.0.3.dev11
4
4
  Summary: Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle.
5
5
  Keywords: job-applications,ats,ashby,greenhouse,teamtailor,ai-agents,cli
6
6
  Author: shbernal
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.3.dev10"
3
+ version = "0.0.3.dev11"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -46,6 +46,7 @@ build-backend = "uv_build"
46
46
  [dependency-groups]
47
47
  dev = [
48
48
  "pytest>=9.1.1",
49
+ "pytest-xdist>=3.8.0",
49
50
  "ruff>=0.17.1",
50
51
  "ty==0.0.89",
51
52
  ]
@@ -67,7 +68,7 @@ select = [
67
68
  [tool.pytest.ini_options]
68
69
  testpaths = ["tests"]
69
70
  markers = ["live: drives a real hiring system page with data from .env and .tmp/; opt-in with -m live"]
70
- addopts = "-m 'not live'"
71
+ addopts = "-m 'not live' -n 8"
71
72
 
72
73
  [[tool.uv.index]]
73
74
  name = "testpypi"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.3.dev10"
3
+ version = "0.0.3.dev11"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -38,6 +38,7 @@ build-backend = "uv_build"
38
38
  [dependency-groups]
39
39
  dev = [
40
40
  "pytest>=9.1.1",
41
+ "pytest-xdist>=3.8.0",
41
42
  "ruff>=0.17.1",
42
43
  "ty==0.0.89",
43
44
  ]
@@ -54,7 +55,7 @@ testpaths = ["tests"]
54
55
  markers = [
55
56
  "live: drives a real hiring system page with data from .env and .tmp/; opt-in with -m live",
56
57
  ]
57
- addopts = "-m 'not live'"
58
+ addopts = "-m 'not live' -n 8"
58
59
 
59
60
  [[tool.uv.index]]
60
61
  name = "testpypi"
@@ -1,5 +1,6 @@
1
1
  """The browser launcher, the only module that imports camoufox and playwright (ADR 0002)."""
2
2
 
3
+ import asyncio
3
4
  import fcntl
4
5
  import json
5
6
  import locale
@@ -9,6 +10,7 @@ import sys
9
10
  import threading
10
11
  import time
11
12
  from collections.abc import Generator
13
+ from concurrent.futures import Future
12
14
  from contextlib import contextmanager
13
15
  from pathlib import Path
14
16
 
@@ -129,11 +131,15 @@ def open_page(
129
131
  deadline = time.monotonic() + seconds
130
132
  with lock(data_dir, deadline), _launch(data_dir, headless=True) as browser:
131
133
  expired = threading.Event()
134
+ closing: list[Future] = []
132
135
 
133
136
  def expire() -> None: # on the timer's thread: hand the close to Playwright's loop
134
137
  expired.set()
135
138
  close = browser._impl_obj.close(reason="time budget ran out")
136
- browser._loop.call_soon_threadsafe(browser._loop.create_task, close)
139
+ closing.append(asyncio.run_coroutine_threadsafe(close, browser._loop))
140
+
141
+ async def closed() -> None:
142
+ await asyncio.wrap_future(closing[0])
137
143
 
138
144
  timer = threading.Timer(max(0.0, deadline - time.monotonic()), expire)
139
145
  timer.start()
@@ -147,6 +153,9 @@ def open_page(
147
153
  raise
148
154
  finally:
149
155
  timer.cancel()
156
+ timer.join()
157
+ if closing: # Playwright stops on exit, so the close ends first
158
+ browser._sync(closed())
150
159
 
151
160
 
152
161
  @contextmanager
File without changes
File without changes