atsfill 0.0.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.
- atsfill-0.0.1/LICENSE +21 -0
- atsfill-0.0.1/PKG-INFO +157 -0
- atsfill-0.0.1/README.md +133 -0
- atsfill-0.0.1/pyproject.toml +76 -0
- atsfill-0.0.1/pyproject.toml.orig +63 -0
- atsfill-0.0.1/src/atsfill/__init__.py +0 -0
- atsfill-0.0.1/src/atsfill/adapters/__init__.py +7 -0
- atsfill-0.0.1/src/atsfill/adapters/ashby.py +262 -0
- atsfill-0.0.1/src/atsfill/adapters/greenhouse.py +356 -0
- atsfill-0.0.1/src/atsfill/adapters/teamtailor.py +269 -0
- atsfill-0.0.1/src/atsfill/adapters/wttj.py +180 -0
- atsfill-0.0.1/src/atsfill/cli.py +126 -0
- atsfill-0.0.1/src/atsfill/core/__init__.py +13 -0
- atsfill-0.0.1/src/atsfill/core/accounts.py +42 -0
- atsfill-0.0.1/src/atsfill/core/adapter.py +58 -0
- atsfill-0.0.1/src/atsfill/core/attempts.py +32 -0
- atsfill-0.0.1/src/atsfill/core/browser.py +218 -0
- atsfill-0.0.1/src/atsfill/core/commands.py +243 -0
- atsfill-0.0.1/src/atsfill/core/matching.py +101 -0
- atsfill-0.0.1/src/atsfill/core/paths.py +40 -0
- atsfill-0.0.1/src/atsfill/core/results.py +89 -0
- atsfill-0.0.1/src/atsfill/py.typed +0 -0
atsfill-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shbernal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
atsfill-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: atsfill
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle.
|
|
5
|
+
Keywords: job-applications,ats,ashby,greenhouse,teamtailor,ai-agents,cli
|
|
6
|
+
Author: shbernal
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Office/Business
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Dist: camoufox==0.5.8
|
|
19
|
+
Requires-Python: >=3.14
|
|
20
|
+
Project-URL: Homepage, https://github.com/shbernal/atsfill
|
|
21
|
+
Project-URL: Repository, https://github.com/shbernal/atsfill
|
|
22
|
+
Project-URL: Issues, https://github.com/shbernal/atsfill/issues
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
<div align="center">
|
|
26
|
+
|
|
27
|
+
# atsfill
|
|
28
|
+
|
|
29
|
+
Fill job application forms from the command line: read, dry-run, then submit.
|
|
30
|
+
|
|
31
|
+
[![PyPI][pypi-badge]][pypi]
|
|
32
|
+
[![Python][python-badge]][pypi]
|
|
33
|
+
[![CI][ci-badge]][ci]
|
|
34
|
+
[![License][license-badge]][license]
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
[Install](#install) • [Quickstart](#quickstart) • [How it works](#how-it-works) • [Docs](docs/adr/README.md)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
atsfill reads the application form behind a job posting, fills it with your answers, and checks what the hiring system will receive before anything is sent.
|
|
45
|
+
It is built for agents with a shell: every command prints one JSON document and exits with a code a script can branch on.
|
|
46
|
+
|
|
47
|
+
- `read` lists a form's fields with their ids, types, options and whether they are required.
|
|
48
|
+
- `fill` is a dry run: it fills the form, reads it back field by field, and never submits.
|
|
49
|
+
- `send` fills again and submits only when every answer reads back as given.
|
|
50
|
+
- Submitting is off until you enable it per hiring system, in a config file the agent does not write.
|
|
51
|
+
- A posting already sent is refused unless you pass `--resend`.
|
|
52
|
+
|
|
53
|
+
## Supported hiring systems
|
|
54
|
+
|
|
55
|
+
| System | Account needed | `read` without a browser |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| Ashby | no | yes |
|
|
58
|
+
| Greenhouse | no | yes |
|
|
59
|
+
| Teamtailor | no | no |
|
|
60
|
+
| Welcome to the Jungle | yes, `atsfill login wttj` | no |
|
|
61
|
+
|
|
62
|
+
Any other system returns `unsupported`, so the caller can fall back to driving a browser itself.
|
|
63
|
+
|
|
64
|
+
## Why atsfill?
|
|
65
|
+
|
|
66
|
+
An agent applying through a generic browser carries each system's quirks as prose, rereads it every run, and checks the form before submitting only because an instruction says so.
|
|
67
|
+
atsfill moves the quirks into one adapter per system and makes the check code: a `send` whose read-back differs from the answers is refused.
|
|
68
|
+
|
|
69
|
+
| | Generic browser agent | atsfill |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| System quirks | prose in the prompt | an adapter per system |
|
|
72
|
+
| Check before submit | an instruction | the read-back must match |
|
|
73
|
+
| Permission to submit | whatever the agent decides | a config file, per system |
|
|
74
|
+
| Double send | possible | refused without `--resend` |
|
|
75
|
+
| Output | page snapshots | one JSON result |
|
|
76
|
+
|
|
77
|
+
## Install
|
|
78
|
+
|
|
79
|
+
atsfill runs on Linux and macOS with Python 3.14, which `uvx` fetches if needed.
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
uvx atsfill install-browser
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This downloads the Camoufox browser build atsfill is pinned to: 1.3 GB, about 2.5 GB once unpacked.
|
|
86
|
+
|
|
87
|
+
## Quickstart
|
|
88
|
+
|
|
89
|
+
1. List the form's fields:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
uvx atsfill read https://job-boards.greenhouse.io/acme/jobs/1234
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
2. Write your answers to `answers.json`, keyed by field id. Files take an absolute path:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"first_name": "Ada",
|
|
100
|
+
"last_name": "Lovelace",
|
|
101
|
+
"email": "ada@example.com",
|
|
102
|
+
"resume": "/home/ada/resume.pdf"
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
3. Dry-run the fill. It ends `ready` when every answer reads back as given:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
uvx atsfill fill https://job-boards.greenhouse.io/acme/jobs/1234 --answers answers.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
4. Allow the system to submit in `~/.config/atsfill/config.toml`:
|
|
113
|
+
|
|
114
|
+
```toml
|
|
115
|
+
submit = ["greenhouse"]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
5. Send. A `submitted` result carries the evidence of the send:
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
uvx atsfill send https://job-boards.greenhouse.io/acme/jobs/1234 --answers answers.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
A dry run is not invisible: some systems save answers or the resume as they are typed.
|
|
125
|
+
`atsfill status` lists each system's side effects and whether it is allowed to submit.
|
|
126
|
+
|
|
127
|
+
## How it works
|
|
128
|
+
|
|
129
|
+
```mermaid
|
|
130
|
+
flowchart LR
|
|
131
|
+
CLI[atsfill CLI] --> Core
|
|
132
|
+
Core -->|detect, read, fill, read back, submit| Adapter[adapter for the system]
|
|
133
|
+
Adapter --> Browser[headless Camoufox]
|
|
134
|
+
Core --> Gate{read-back matches,<br>submit enabled,<br>not already sent}
|
|
135
|
+
Gate -->|yes| Submit[submit]
|
|
136
|
+
Gate -->|no| Refused[refused]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Each command launches its own headless Camoufox, a Firefox build patched to hide automation, with a fresh context and one saved device identity.
|
|
140
|
+
The core owns every rule about when a send is allowed; an adapter only knows its system's page.
|
|
141
|
+
|
|
142
|
+
Every result has a `status` (`ready`, `refused`, `submitted`, `blocked`, `unknown`, `unsupported`) and, when it is not clean, a `reason` code.
|
|
143
|
+
The exit code is 0 for `ready` and `submitted`, 1 otherwise, 2 for a usage error.
|
|
144
|
+
|
|
145
|
+
## More
|
|
146
|
+
|
|
147
|
+
- [Architecture decisions](docs/adr/README.md): the contract, the submit gate, the browser, sessions.
|
|
148
|
+
- [Hiring systems](docs/adapters/): each system's form as observed.
|
|
149
|
+
- `atsfill --help` for every command and option.
|
|
150
|
+
|
|
151
|
+
[pypi]: https://pypi.org/project/atsfill/
|
|
152
|
+
[pypi-badge]: https://img.shields.io/pypi/v/atsfill?style=for-the-badge&color=7aa2f7&logo=pypi&logoColor=white
|
|
153
|
+
[python-badge]: https://img.shields.io/pypi/pyversions/atsfill?style=for-the-badge&color=9ece6a&logo=python&logoColor=white
|
|
154
|
+
[ci]: https://github.com/shbernal/atsfill/actions/workflows/ci.yml
|
|
155
|
+
[ci-badge]: https://img.shields.io/github/actions/workflow/status/shbernal/atsfill/ci.yml?branch=main&style=for-the-badge&color=bb9af7&logo=githubactions&logoColor=white
|
|
156
|
+
[license]: LICENSE
|
|
157
|
+
[license-badge]: https://img.shields.io/github/license/shbernal/atsfill?style=for-the-badge&color=e0af68
|
atsfill-0.0.1/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# atsfill
|
|
4
|
+
|
|
5
|
+
Fill job application forms from the command line: read, dry-run, then submit.
|
|
6
|
+
|
|
7
|
+
[![PyPI][pypi-badge]][pypi]
|
|
8
|
+
[![Python][python-badge]][pypi]
|
|
9
|
+
[![CI][ci-badge]][ci]
|
|
10
|
+
[![License][license-badge]][license]
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
[Install](#install) • [Quickstart](#quickstart) • [How it works](#how-it-works) • [Docs](docs/adr/README.md)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
atsfill reads the application form behind a job posting, fills it with your answers, and checks what the hiring system will receive before anything is sent.
|
|
21
|
+
It is built for agents with a shell: every command prints one JSON document and exits with a code a script can branch on.
|
|
22
|
+
|
|
23
|
+
- `read` lists a form's fields with their ids, types, options and whether they are required.
|
|
24
|
+
- `fill` is a dry run: it fills the form, reads it back field by field, and never submits.
|
|
25
|
+
- `send` fills again and submits only when every answer reads back as given.
|
|
26
|
+
- Submitting is off until you enable it per hiring system, in a config file the agent does not write.
|
|
27
|
+
- A posting already sent is refused unless you pass `--resend`.
|
|
28
|
+
|
|
29
|
+
## Supported hiring systems
|
|
30
|
+
|
|
31
|
+
| System | Account needed | `read` without a browser |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Ashby | no | yes |
|
|
34
|
+
| Greenhouse | no | yes |
|
|
35
|
+
| Teamtailor | no | no |
|
|
36
|
+
| Welcome to the Jungle | yes, `atsfill login wttj` | no |
|
|
37
|
+
|
|
38
|
+
Any other system returns `unsupported`, so the caller can fall back to driving a browser itself.
|
|
39
|
+
|
|
40
|
+
## Why atsfill?
|
|
41
|
+
|
|
42
|
+
An agent applying through a generic browser carries each system's quirks as prose, rereads it every run, and checks the form before submitting only because an instruction says so.
|
|
43
|
+
atsfill moves the quirks into one adapter per system and makes the check code: a `send` whose read-back differs from the answers is refused.
|
|
44
|
+
|
|
45
|
+
| | Generic browser agent | atsfill |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| System quirks | prose in the prompt | an adapter per system |
|
|
48
|
+
| Check before submit | an instruction | the read-back must match |
|
|
49
|
+
| Permission to submit | whatever the agent decides | a config file, per system |
|
|
50
|
+
| Double send | possible | refused without `--resend` |
|
|
51
|
+
| Output | page snapshots | one JSON result |
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
atsfill runs on Linux and macOS with Python 3.14, which `uvx` fetches if needed.
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
uvx atsfill install-browser
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This downloads the Camoufox browser build atsfill is pinned to: 1.3 GB, about 2.5 GB once unpacked.
|
|
62
|
+
|
|
63
|
+
## Quickstart
|
|
64
|
+
|
|
65
|
+
1. List the form's fields:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
uvx atsfill read https://job-boards.greenhouse.io/acme/jobs/1234
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. Write your answers to `answers.json`, keyed by field id. Files take an absolute path:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"first_name": "Ada",
|
|
76
|
+
"last_name": "Lovelace",
|
|
77
|
+
"email": "ada@example.com",
|
|
78
|
+
"resume": "/home/ada/resume.pdf"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
3. Dry-run the fill. It ends `ready` when every answer reads back as given:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
uvx atsfill fill https://job-boards.greenhouse.io/acme/jobs/1234 --answers answers.json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
4. Allow the system to submit in `~/.config/atsfill/config.toml`:
|
|
89
|
+
|
|
90
|
+
```toml
|
|
91
|
+
submit = ["greenhouse"]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
5. Send. A `submitted` result carries the evidence of the send:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
uvx atsfill send https://job-boards.greenhouse.io/acme/jobs/1234 --answers answers.json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
A dry run is not invisible: some systems save answers or the resume as they are typed.
|
|
101
|
+
`atsfill status` lists each system's side effects and whether it is allowed to submit.
|
|
102
|
+
|
|
103
|
+
## How it works
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
flowchart LR
|
|
107
|
+
CLI[atsfill CLI] --> Core
|
|
108
|
+
Core -->|detect, read, fill, read back, submit| Adapter[adapter for the system]
|
|
109
|
+
Adapter --> Browser[headless Camoufox]
|
|
110
|
+
Core --> Gate{read-back matches,<br>submit enabled,<br>not already sent}
|
|
111
|
+
Gate -->|yes| Submit[submit]
|
|
112
|
+
Gate -->|no| Refused[refused]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Each command launches its own headless Camoufox, a Firefox build patched to hide automation, with a fresh context and one saved device identity.
|
|
116
|
+
The core owns every rule about when a send is allowed; an adapter only knows its system's page.
|
|
117
|
+
|
|
118
|
+
Every result has a `status` (`ready`, `refused`, `submitted`, `blocked`, `unknown`, `unsupported`) and, when it is not clean, a `reason` code.
|
|
119
|
+
The exit code is 0 for `ready` and `submitted`, 1 otherwise, 2 for a usage error.
|
|
120
|
+
|
|
121
|
+
## More
|
|
122
|
+
|
|
123
|
+
- [Architecture decisions](docs/adr/README.md): the contract, the submit gate, the browser, sessions.
|
|
124
|
+
- [Hiring systems](docs/adapters/): each system's form as observed.
|
|
125
|
+
- `atsfill --help` for every command and option.
|
|
126
|
+
|
|
127
|
+
[pypi]: https://pypi.org/project/atsfill/
|
|
128
|
+
[pypi-badge]: https://img.shields.io/pypi/v/atsfill?style=for-the-badge&color=7aa2f7&logo=pypi&logoColor=white
|
|
129
|
+
[python-badge]: https://img.shields.io/pypi/pyversions/atsfill?style=for-the-badge&color=9ece6a&logo=python&logoColor=white
|
|
130
|
+
[ci]: https://github.com/shbernal/atsfill/actions/workflows/ci.yml
|
|
131
|
+
[ci-badge]: https://img.shields.io/github/actions/workflow/status/shbernal/atsfill/ci.yml?branch=main&style=for-the-badge&color=bb9af7&logo=githubactions&logoColor=white
|
|
132
|
+
[license]: LICENSE
|
|
133
|
+
[license-badge]: https://img.shields.io/github/license/shbernal/atsfill?style=for-the-badge&color=e0af68
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "atsfill"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.14"
|
|
9
|
+
keywords = [
|
|
10
|
+
"job-applications",
|
|
11
|
+
"ats",
|
|
12
|
+
"ashby",
|
|
13
|
+
"greenhouse",
|
|
14
|
+
"teamtailor",
|
|
15
|
+
"ai-agents",
|
|
16
|
+
"cli",
|
|
17
|
+
]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Environment :: Console",
|
|
21
|
+
"Intended Audience :: End Users/Desktop",
|
|
22
|
+
"Operating System :: MacOS",
|
|
23
|
+
"Operating System :: POSIX :: Linux",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
26
|
+
"Topic :: Office/Business",
|
|
27
|
+
"Typing :: Typed",
|
|
28
|
+
]
|
|
29
|
+
dependencies = ["camoufox==0.5.8"]
|
|
30
|
+
|
|
31
|
+
[[project.authors]]
|
|
32
|
+
name = "shbernal"
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/shbernal/atsfill"
|
|
36
|
+
Repository = "https://github.com/shbernal/atsfill"
|
|
37
|
+
Issues = "https://github.com/shbernal/atsfill/issues"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
atsfill = "atsfill.cli:main"
|
|
41
|
+
|
|
42
|
+
[build-system]
|
|
43
|
+
requires = ["uv_build>=0.13.0,<0.14.0"]
|
|
44
|
+
build-backend = "uv_build"
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
dev = [
|
|
48
|
+
"pytest>=9.1.1",
|
|
49
|
+
"ruff>=0.17.1",
|
|
50
|
+
"ty==0.0.89",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.ruff]
|
|
54
|
+
target-version = "py314"
|
|
55
|
+
line-length = 100
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint]
|
|
58
|
+
select = [
|
|
59
|
+
"E",
|
|
60
|
+
"F",
|
|
61
|
+
"I",
|
|
62
|
+
"UP",
|
|
63
|
+
"B",
|
|
64
|
+
"SIM",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[tool.pytest.ini_options]
|
|
68
|
+
testpaths = ["tests"]
|
|
69
|
+
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
|
+
|
|
72
|
+
[[tool.uv.index]]
|
|
73
|
+
name = "testpypi"
|
|
74
|
+
url = "https://test.pypi.org/simple/"
|
|
75
|
+
publish-url = "https://test.pypi.org/legacy/"
|
|
76
|
+
explicit = true
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "atsfill"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "shbernal" }]
|
|
9
|
+
requires-python = ">=3.14"
|
|
10
|
+
keywords = ["job-applications", "ats", "ashby", "greenhouse", "teamtailor", "ai-agents", "cli"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: End Users/Desktop",
|
|
15
|
+
"Operating System :: MacOS",
|
|
16
|
+
"Operating System :: POSIX :: Linux",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.14",
|
|
19
|
+
"Topic :: Office/Business",
|
|
20
|
+
"Typing :: Typed",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"camoufox==0.5.8",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/shbernal/atsfill"
|
|
28
|
+
Repository = "https://github.com/shbernal/atsfill"
|
|
29
|
+
Issues = "https://github.com/shbernal/atsfill/issues"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
atsfill = "atsfill.cli:main"
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["uv_build>=0.13.0,<0.14.0"]
|
|
36
|
+
build-backend = "uv_build"
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"pytest>=9.1.1",
|
|
41
|
+
"ruff>=0.17.1",
|
|
42
|
+
"ty==0.0.89",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[tool.ruff]
|
|
46
|
+
target-version = "py314"
|
|
47
|
+
line-length = 100
|
|
48
|
+
|
|
49
|
+
[tool.ruff.lint]
|
|
50
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
markers = [
|
|
55
|
+
"live: drives a real hiring system page with data from .env and .tmp/; opt-in with -m live",
|
|
56
|
+
]
|
|
57
|
+
addopts = "-m 'not live'"
|
|
58
|
+
|
|
59
|
+
[[tool.uv.index]]
|
|
60
|
+
name = "testpypi"
|
|
61
|
+
url = "https://test.pypi.org/simple/"
|
|
62
|
+
publish-url = "https://test.pypi.org/legacy/"
|
|
63
|
+
explicit = true
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from atsfill.adapters.ashby import Ashby
|
|
2
|
+
from atsfill.adapters.greenhouse import Greenhouse
|
|
3
|
+
from atsfill.adapters.teamtailor import Teamtailor
|
|
4
|
+
from atsfill.adapters.wttj import WelcomeToTheJungle
|
|
5
|
+
from atsfill.core.adapter import Adapter
|
|
6
|
+
|
|
7
|
+
ADAPTERS: list[Adapter] = [Ashby(), Teamtailor(), Greenhouse(), WelcomeToTheJungle()]
|