ajera 0.1.3__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.
- ajera-0.1.3/PKG-INFO +203 -0
- ajera-0.1.3/README.md +191 -0
- ajera-0.1.3/pyproject.toml +31 -0
- ajera-0.1.3/src/ajera/__init__.py +5 -0
- ajera-0.1.3/src/ajera/cli/__init__.py +95 -0
- ajera-0.1.3/src/ajera/cli/__main__.py +4 -0
- ajera-0.1.3/src/ajera/cli/commands/__init__.py +0 -0
- ajera-0.1.3/src/ajera/cli/commands/activities.py +31 -0
- ajera-0.1.3/src/ajera/cli/commands/bank_accounts.py +18 -0
- ajera-0.1.3/src/ajera/cli/commands/clients.py +153 -0
- ajera-0.1.3/src/ajera/cli/commands/companies.py +18 -0
- ajera-0.1.3/src/ajera/cli/commands/contacts.py +153 -0
- ajera-0.1.3/src/ajera/cli/commands/departments.py +18 -0
- ajera-0.1.3/src/ajera/cli/commands/employees.py +212 -0
- ajera-0.1.3/src/ajera/cli/commands/invoice_formats.py +18 -0
- ajera-0.1.3/src/ajera/cli/commands/ledger.py +101 -0
- ajera-0.1.3/src/ajera/cli/commands/projects.py +350 -0
- ajera-0.1.3/src/ajera/cli/commands/rate_tables.py +18 -0
- ajera-0.1.3/src/ajera/cli/commands/vendors.py +407 -0
- ajera-0.1.3/src/ajera/cli/context.py +37 -0
- ajera-0.1.3/src/ajera/cli/group.py +72 -0
- ajera-0.1.3/src/ajera/cli/options.py +27 -0
- ajera-0.1.3/src/ajera/cli/output.py +30 -0
- ajera-0.1.3/src/ajera/client.py +2049 -0
- ajera-0.1.3/src/ajera/schemas/client.py +614 -0
- ajera-0.1.3/src/ajera/schemas/contact.py +568 -0
- ajera-0.1.3/src/ajera/schemas/deduction.py +92 -0
- ajera-0.1.3/src/ajera/schemas/employee.py +858 -0
- ajera-0.1.3/src/ajera/schemas/fringe.py +92 -0
- ajera-0.1.3/src/ajera/schemas/generic.py +82 -0
- ajera-0.1.3/src/ajera/schemas/ledger.py +322 -0
- ajera-0.1.3/src/ajera/schemas/project.py +1416 -0
- ajera-0.1.3/src/ajera/schemas/project_summary.py +825 -0
- ajera-0.1.3/src/ajera/schemas/project_v2.py +1171 -0
- ajera-0.1.3/src/ajera/schemas/reference.py +704 -0
- ajera-0.1.3/src/ajera/schemas/session.py +96 -0
- ajera-0.1.3/src/ajera/schemas/vendor.py +691 -0
- ajera-0.1.3/src/ajera/schemas/vendor_invoice.py +624 -0
ajera-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ajera
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Deltek Ajera Python API Client
|
|
5
|
+
Author: SB&O Inc
|
|
6
|
+
Author-email: SB&O Inc <contact@sboinc.com>
|
|
7
|
+
Requires-Dist: click>=8.0.0
|
|
8
|
+
Requires-Dist: requests>=2.0,<3
|
|
9
|
+
Requires-Dist: pydantic>=2.10.0
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
[](https://github.com/sbo-inc/ajera/actions/workflows/ci.yaml)
|
|
14
|
+
|
|
15
|
+
# Deltek Ajera Python client
|
|
16
|
+
|
|
17
|
+
A typed Python client and command-line interface for the [Deltek Ajera](https://www.deltek.com/en/project-based-erp/ajera) API.
|
|
18
|
+
|
|
19
|
+
Ajera exposes a single JSON-RPC style endpoint; this package wraps it in an ergonomic, fully type-hinted client built on [Pydantic](https://docs.pydantic.dev/) models, plus an `ajera` CLI for quick access from the terminal. Responses are validated and normalized into predictable Python objects so you can work with employees, projects, vendors, invoices, and general-ledger data without hand-rolling request payloads.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **Typed models** - every response is parsed into Pydantic models with descriptive fields.
|
|
24
|
+
- **Python client and CLI** - use it as a library or straight from the shell via `ajera`.
|
|
25
|
+
- **Sensible defaults** - handles session tokens and per-method API versions for you.
|
|
26
|
+
- **Read and write** - list, get, update, and create across the supported APIs.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install ajera
|
|
32
|
+
# or, with uv:
|
|
33
|
+
uv add ajera
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Requires Python 3.12+.
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
Credentials are read from environment variables (or can be passed directly to `AjeraClient`):
|
|
41
|
+
|
|
42
|
+
| Variable | Description |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `AJERA_API_URL` | The Ajera API endpoint URL for your tenant. |
|
|
45
|
+
| `AJERA_API_USERNAME` | API username. |
|
|
46
|
+
| `AJERA_API_PASSWORD` | API password. |
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
export AJERA_API_URL="https://ajera.com/V0000000/AjeraAPI.ashx?..."
|
|
50
|
+
export AJERA_API_USERNAME="your-username"
|
|
51
|
+
export AJERA_API_PASSWORD="your-password"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For setting up an API user and generating credentials, see the [Deltek Ajera Learning Hub API docs](https://learning.deltek.com/bundle/ajera/page/Content/api_setting_up_api_user.htm).
|
|
55
|
+
|
|
56
|
+
## Quick start
|
|
57
|
+
|
|
58
|
+
### Python
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from ajera import AjeraClient
|
|
62
|
+
|
|
63
|
+
# Reads AJERA_API_URL / AJERA_API_USERNAME / AJERA_API_PASSWORD from the
|
|
64
|
+
# environment, or pass url=, username=, password= explicitly.
|
|
65
|
+
client = AjeraClient()
|
|
66
|
+
|
|
67
|
+
for employee in client.list_employees():
|
|
68
|
+
print(employee.employee_key, employee.first_name, employee.last_name)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### CLI
|
|
72
|
+
|
|
73
|
+
```console
|
|
74
|
+
$ ajera employees list
|
|
75
|
+
[
|
|
76
|
+
{
|
|
77
|
+
"employee_key": 42,
|
|
78
|
+
"first_name": "Ada",
|
|
79
|
+
"last_name": "Lovelace",
|
|
80
|
+
...
|
|
81
|
+
},
|
|
82
|
+
...
|
|
83
|
+
]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **Note:** List commands backed by an active/inactive status return only **active** records by
|
|
87
|
+
> default. Pass `--status` to override - e.g. `--status Inactive`, or
|
|
88
|
+
> `--status Active --status Inactive` to include both.
|
|
89
|
+
|
|
90
|
+
## Reference Documentation
|
|
91
|
+
|
|
92
|
+
This client adheres (to the extent possible) to the API documentation provided by Deltek Ajera, which can be found at:
|
|
93
|
+
|
|
94
|
+
https://help.deltek.com/product/Ajera/api/index.html
|
|
95
|
+
|
|
96
|
+
## API reference
|
|
97
|
+
|
|
98
|
+
Each section below maps a CLI command group to the Ajera API(s) it is built on. The Python client
|
|
99
|
+
exposes the same operations as `client.<method>()` (e.g. `client.list_employees()`,
|
|
100
|
+
`client.get_projects(...)`).
|
|
101
|
+
|
|
102
|
+
### Employees
|
|
103
|
+
|
|
104
|
+
Docs: [Employees API](https://help.deltek.com/product/Ajera/api/employees.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
105
|
+
|
|
106
|
+
`pays`, `payroll-taxes`, and `wage-tables` come from the List Methods API; the rest come from the Employees API.
|
|
107
|
+
|
|
108
|
+
| Command | Description |
|
|
109
|
+
| --- | --- |
|
|
110
|
+
| `ajera employees list` | List employees. |
|
|
111
|
+
| `ajera employees get <id>...` | Get one or more employees by ID. |
|
|
112
|
+
| `ajera employees update <key> [options]` | Update simple fields on one employee. |
|
|
113
|
+
| `ajera employees types` | List employee types. |
|
|
114
|
+
| `ajera employees deductions` | List deductions. |
|
|
115
|
+
| `ajera employees fringes` | List fringes. |
|
|
116
|
+
| `ajera employees pays` | List pay types. |
|
|
117
|
+
| `ajera employees payroll-taxes` | List payroll taxes. |
|
|
118
|
+
| `ajera employees wage-tables` | List wage tables. |
|
|
119
|
+
|
|
120
|
+
### Clients
|
|
121
|
+
|
|
122
|
+
Docs: [Clients API](https://help.deltek.com/product/Ajera/api/clients.html)
|
|
123
|
+
|
|
124
|
+
| Command | Description |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| `ajera clients list` | List clients. |
|
|
127
|
+
| `ajera clients get <id>...` | Get one or more clients by ID. |
|
|
128
|
+
| `ajera clients update <key> [options]` | Update simple fields on one client. |
|
|
129
|
+
| `ajera clients types` | List client types. |
|
|
130
|
+
|
|
131
|
+
### Contacts
|
|
132
|
+
|
|
133
|
+
Docs: [Contacts API](https://help.deltek.com/product/Ajera/api/contacts.html)
|
|
134
|
+
|
|
135
|
+
| Command | Description |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `ajera contacts list` | List contacts. |
|
|
138
|
+
| `ajera contacts get <id>...` | Get one or more contacts by ID. |
|
|
139
|
+
| `ajera contacts update <key> [options]` | Update simple fields on one contact. |
|
|
140
|
+
| `ajera contacts types` | List contact types. |
|
|
141
|
+
|
|
142
|
+
### Vendors
|
|
143
|
+
|
|
144
|
+
Docs: [Vendors API](https://help.deltek.com/product/Ajera/api/vendors.html) · [Vendor Invoices API (v2)](https://help.deltek.com/product/Ajera/api/version2/vendor_invoices.html)
|
|
145
|
+
|
|
146
|
+
The `invoices` subcommands come from the Vendor Invoices (v2) API; the rest come from the Vendors API.
|
|
147
|
+
|
|
148
|
+
| Command | Description |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `ajera vendors list` | List vendors. |
|
|
151
|
+
| `ajera vendors get <id>...` | Get one or more vendors by ID. |
|
|
152
|
+
| `ajera vendors update <key> [options]` | Update simple fields on one vendor. |
|
|
153
|
+
| `ajera vendors types` | List vendor types. |
|
|
154
|
+
| `ajera vendors invoices list` | List vendor invoices, optionally filtered. |
|
|
155
|
+
| `ajera vendors invoices get <key>...` | Get one or more vendor invoices, with their line items. |
|
|
156
|
+
| `ajera vendors invoices create [options]` | Create a vendor invoice with a single line item. |
|
|
157
|
+
|
|
158
|
+
### Projects
|
|
159
|
+
|
|
160
|
+
Docs: [Projects API (v2)](https://help.deltek.com/product/Ajera/api/version2/projects.html) · [Projects API (v1)](https://help.deltek.com/product/Ajera/api/projects.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
161
|
+
|
|
162
|
+
`list`, `get`, `update`, and `create` use the v2 Projects API; `totals`, `types`, and `templates`
|
|
163
|
+
use the v1 Projects API; `chargeable-phases` comes from the List Methods API.
|
|
164
|
+
|
|
165
|
+
| Command | Description |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| `ajera projects list` | List projects, optionally filtered. |
|
|
168
|
+
| `ajera projects get <id>...` | Get one or more projects by ID. |
|
|
169
|
+
| `ajera projects create <description> [options]` | Create a new project. |
|
|
170
|
+
| `ajera projects update <key> [options]` | Update simple fields on one project. |
|
|
171
|
+
| `ajera projects totals <id>` | Get a project's financial totals. |
|
|
172
|
+
| `ajera projects types` | List project types. |
|
|
173
|
+
| `ajera projects templates list` | List project templates, optionally filtered. |
|
|
174
|
+
| `ajera projects templates get <id>...` | Get one or more project templates by ID. |
|
|
175
|
+
| `ajera projects chargeable-phases <project-key>` | List the chargeable phases of a project. |
|
|
176
|
+
|
|
177
|
+
### General Ledger
|
|
178
|
+
|
|
179
|
+
Docs: [GL Accounts API](https://help.deltek.com/product/Ajera/api/gl_accounts.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
180
|
+
|
|
181
|
+
`account-groups` comes from the List Methods API; `list` and `get` come from the GL Accounts API.
|
|
182
|
+
|
|
183
|
+
| Command | Description |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| `ajera ledger list` | List general ledger accounts. |
|
|
186
|
+
| `ajera ledger get [id]...` | Get general ledger account details, with calculated amounts. |
|
|
187
|
+
| `ajera ledger account-groups` | List general ledger account groups. |
|
|
188
|
+
|
|
189
|
+
### Reference lists
|
|
190
|
+
|
|
191
|
+
Docs: [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
192
|
+
|
|
193
|
+
Lightweight lookup lists. (Other List Methods endpoints are grouped with their domain - see
|
|
194
|
+
`employees`, `ledger`, and `projects` above.)
|
|
195
|
+
|
|
196
|
+
| Command | Description |
|
|
197
|
+
| --- | --- |
|
|
198
|
+
| `ajera activities` | List activities. |
|
|
199
|
+
| `ajera bank-accounts` | List bank accounts. |
|
|
200
|
+
| `ajera companies` | List companies. |
|
|
201
|
+
| `ajera departments` | List departments. |
|
|
202
|
+
| `ajera invoice-formats` | List invoice formats. |
|
|
203
|
+
| `ajera rate-tables` | List rate tables. |
|
ajera-0.1.3/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
[](https://github.com/sbo-inc/ajera/actions/workflows/ci.yaml)
|
|
2
|
+
|
|
3
|
+
# Deltek Ajera Python client
|
|
4
|
+
|
|
5
|
+
A typed Python client and command-line interface for the [Deltek Ajera](https://www.deltek.com/en/project-based-erp/ajera) API.
|
|
6
|
+
|
|
7
|
+
Ajera exposes a single JSON-RPC style endpoint; this package wraps it in an ergonomic, fully type-hinted client built on [Pydantic](https://docs.pydantic.dev/) models, plus an `ajera` CLI for quick access from the terminal. Responses are validated and normalized into predictable Python objects so you can work with employees, projects, vendors, invoices, and general-ledger data without hand-rolling request payloads.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Typed models** - every response is parsed into Pydantic models with descriptive fields.
|
|
12
|
+
- **Python client and CLI** - use it as a library or straight from the shell via `ajera`.
|
|
13
|
+
- **Sensible defaults** - handles session tokens and per-method API versions for you.
|
|
14
|
+
- **Read and write** - list, get, update, and create across the supported APIs.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install ajera
|
|
20
|
+
# or, with uv:
|
|
21
|
+
uv add ajera
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Requires Python 3.12+.
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
Credentials are read from environment variables (or can be passed directly to `AjeraClient`):
|
|
29
|
+
|
|
30
|
+
| Variable | Description |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `AJERA_API_URL` | The Ajera API endpoint URL for your tenant. |
|
|
33
|
+
| `AJERA_API_USERNAME` | API username. |
|
|
34
|
+
| `AJERA_API_PASSWORD` | API password. |
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
export AJERA_API_URL="https://ajera.com/V0000000/AjeraAPI.ashx?..."
|
|
38
|
+
export AJERA_API_USERNAME="your-username"
|
|
39
|
+
export AJERA_API_PASSWORD="your-password"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For setting up an API user and generating credentials, see the [Deltek Ajera Learning Hub API docs](https://learning.deltek.com/bundle/ajera/page/Content/api_setting_up_api_user.htm).
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
### Python
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from ajera import AjeraClient
|
|
50
|
+
|
|
51
|
+
# Reads AJERA_API_URL / AJERA_API_USERNAME / AJERA_API_PASSWORD from the
|
|
52
|
+
# environment, or pass url=, username=, password= explicitly.
|
|
53
|
+
client = AjeraClient()
|
|
54
|
+
|
|
55
|
+
for employee in client.list_employees():
|
|
56
|
+
print(employee.employee_key, employee.first_name, employee.last_name)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### CLI
|
|
60
|
+
|
|
61
|
+
```console
|
|
62
|
+
$ ajera employees list
|
|
63
|
+
[
|
|
64
|
+
{
|
|
65
|
+
"employee_key": 42,
|
|
66
|
+
"first_name": "Ada",
|
|
67
|
+
"last_name": "Lovelace",
|
|
68
|
+
...
|
|
69
|
+
},
|
|
70
|
+
...
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> **Note:** List commands backed by an active/inactive status return only **active** records by
|
|
75
|
+
> default. Pass `--status` to override - e.g. `--status Inactive`, or
|
|
76
|
+
> `--status Active --status Inactive` to include both.
|
|
77
|
+
|
|
78
|
+
## Reference Documentation
|
|
79
|
+
|
|
80
|
+
This client adheres (to the extent possible) to the API documentation provided by Deltek Ajera, which can be found at:
|
|
81
|
+
|
|
82
|
+
https://help.deltek.com/product/Ajera/api/index.html
|
|
83
|
+
|
|
84
|
+
## API reference
|
|
85
|
+
|
|
86
|
+
Each section below maps a CLI command group to the Ajera API(s) it is built on. The Python client
|
|
87
|
+
exposes the same operations as `client.<method>()` (e.g. `client.list_employees()`,
|
|
88
|
+
`client.get_projects(...)`).
|
|
89
|
+
|
|
90
|
+
### Employees
|
|
91
|
+
|
|
92
|
+
Docs: [Employees API](https://help.deltek.com/product/Ajera/api/employees.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
93
|
+
|
|
94
|
+
`pays`, `payroll-taxes`, and `wage-tables` come from the List Methods API; the rest come from the Employees API.
|
|
95
|
+
|
|
96
|
+
| Command | Description |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `ajera employees list` | List employees. |
|
|
99
|
+
| `ajera employees get <id>...` | Get one or more employees by ID. |
|
|
100
|
+
| `ajera employees update <key> [options]` | Update simple fields on one employee. |
|
|
101
|
+
| `ajera employees types` | List employee types. |
|
|
102
|
+
| `ajera employees deductions` | List deductions. |
|
|
103
|
+
| `ajera employees fringes` | List fringes. |
|
|
104
|
+
| `ajera employees pays` | List pay types. |
|
|
105
|
+
| `ajera employees payroll-taxes` | List payroll taxes. |
|
|
106
|
+
| `ajera employees wage-tables` | List wage tables. |
|
|
107
|
+
|
|
108
|
+
### Clients
|
|
109
|
+
|
|
110
|
+
Docs: [Clients API](https://help.deltek.com/product/Ajera/api/clients.html)
|
|
111
|
+
|
|
112
|
+
| Command | Description |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `ajera clients list` | List clients. |
|
|
115
|
+
| `ajera clients get <id>...` | Get one or more clients by ID. |
|
|
116
|
+
| `ajera clients update <key> [options]` | Update simple fields on one client. |
|
|
117
|
+
| `ajera clients types` | List client types. |
|
|
118
|
+
|
|
119
|
+
### Contacts
|
|
120
|
+
|
|
121
|
+
Docs: [Contacts API](https://help.deltek.com/product/Ajera/api/contacts.html)
|
|
122
|
+
|
|
123
|
+
| Command | Description |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| `ajera contacts list` | List contacts. |
|
|
126
|
+
| `ajera contacts get <id>...` | Get one or more contacts by ID. |
|
|
127
|
+
| `ajera contacts update <key> [options]` | Update simple fields on one contact. |
|
|
128
|
+
| `ajera contacts types` | List contact types. |
|
|
129
|
+
|
|
130
|
+
### Vendors
|
|
131
|
+
|
|
132
|
+
Docs: [Vendors API](https://help.deltek.com/product/Ajera/api/vendors.html) · [Vendor Invoices API (v2)](https://help.deltek.com/product/Ajera/api/version2/vendor_invoices.html)
|
|
133
|
+
|
|
134
|
+
The `invoices` subcommands come from the Vendor Invoices (v2) API; the rest come from the Vendors API.
|
|
135
|
+
|
|
136
|
+
| Command | Description |
|
|
137
|
+
| --- | --- |
|
|
138
|
+
| `ajera vendors list` | List vendors. |
|
|
139
|
+
| `ajera vendors get <id>...` | Get one or more vendors by ID. |
|
|
140
|
+
| `ajera vendors update <key> [options]` | Update simple fields on one vendor. |
|
|
141
|
+
| `ajera vendors types` | List vendor types. |
|
|
142
|
+
| `ajera vendors invoices list` | List vendor invoices, optionally filtered. |
|
|
143
|
+
| `ajera vendors invoices get <key>...` | Get one or more vendor invoices, with their line items. |
|
|
144
|
+
| `ajera vendors invoices create [options]` | Create a vendor invoice with a single line item. |
|
|
145
|
+
|
|
146
|
+
### Projects
|
|
147
|
+
|
|
148
|
+
Docs: [Projects API (v2)](https://help.deltek.com/product/Ajera/api/version2/projects.html) · [Projects API (v1)](https://help.deltek.com/product/Ajera/api/projects.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
149
|
+
|
|
150
|
+
`list`, `get`, `update`, and `create` use the v2 Projects API; `totals`, `types`, and `templates`
|
|
151
|
+
use the v1 Projects API; `chargeable-phases` comes from the List Methods API.
|
|
152
|
+
|
|
153
|
+
| Command | Description |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `ajera projects list` | List projects, optionally filtered. |
|
|
156
|
+
| `ajera projects get <id>...` | Get one or more projects by ID. |
|
|
157
|
+
| `ajera projects create <description> [options]` | Create a new project. |
|
|
158
|
+
| `ajera projects update <key> [options]` | Update simple fields on one project. |
|
|
159
|
+
| `ajera projects totals <id>` | Get a project's financial totals. |
|
|
160
|
+
| `ajera projects types` | List project types. |
|
|
161
|
+
| `ajera projects templates list` | List project templates, optionally filtered. |
|
|
162
|
+
| `ajera projects templates get <id>...` | Get one or more project templates by ID. |
|
|
163
|
+
| `ajera projects chargeable-phases <project-key>` | List the chargeable phases of a project. |
|
|
164
|
+
|
|
165
|
+
### General Ledger
|
|
166
|
+
|
|
167
|
+
Docs: [GL Accounts API](https://help.deltek.com/product/Ajera/api/gl_accounts.html) · [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
168
|
+
|
|
169
|
+
`account-groups` comes from the List Methods API; `list` and `get` come from the GL Accounts API.
|
|
170
|
+
|
|
171
|
+
| Command | Description |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `ajera ledger list` | List general ledger accounts. |
|
|
174
|
+
| `ajera ledger get [id]...` | Get general ledger account details, with calculated amounts. |
|
|
175
|
+
| `ajera ledger account-groups` | List general ledger account groups. |
|
|
176
|
+
|
|
177
|
+
### Reference lists
|
|
178
|
+
|
|
179
|
+
Docs: [List Methods API](https://help.deltek.com/product/Ajera/api/list_methods.html)
|
|
180
|
+
|
|
181
|
+
Lightweight lookup lists. (Other List Methods endpoints are grouped with their domain - see
|
|
182
|
+
`employees`, `ledger`, and `projects` above.)
|
|
183
|
+
|
|
184
|
+
| Command | Description |
|
|
185
|
+
| --- | --- |
|
|
186
|
+
| `ajera activities` | List activities. |
|
|
187
|
+
| `ajera bank-accounts` | List bank accounts. |
|
|
188
|
+
| `ajera companies` | List companies. |
|
|
189
|
+
| `ajera departments` | List departments. |
|
|
190
|
+
| `ajera invoice-formats` | List invoice formats. |
|
|
191
|
+
| `ajera rate-tables` | List rate tables. |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ajera"
|
|
3
|
+
version = "0.1.3"
|
|
4
|
+
description = "Deltek Ajera Python API Client"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [{ name = "SB&O Inc", email = "contact@sboinc.com" }]
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"click >= 8.0.0",
|
|
10
|
+
"requests >=2.0, <3",
|
|
11
|
+
"pydantic >= 2.10.0",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[dependency-groups]
|
|
15
|
+
dev = [
|
|
16
|
+
"mypy",
|
|
17
|
+
"ruff",
|
|
18
|
+
"pytest",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[tool.pytest.ini_options]
|
|
22
|
+
markers = [
|
|
23
|
+
"integration: marks tests that require a live Ajera API instance",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
ajera = "ajera.cli:main"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["uv_build<0.9.0"]
|
|
31
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
from ajera.cli.commands import (
|
|
8
|
+
activities,
|
|
9
|
+
bank_accounts,
|
|
10
|
+
clients,
|
|
11
|
+
companies,
|
|
12
|
+
contacts,
|
|
13
|
+
departments,
|
|
14
|
+
employees,
|
|
15
|
+
invoice_formats,
|
|
16
|
+
ledger,
|
|
17
|
+
projects,
|
|
18
|
+
rate_tables,
|
|
19
|
+
vendors,
|
|
20
|
+
)
|
|
21
|
+
from ajera.cli.context import ClientContext
|
|
22
|
+
from ajera.cli.group import CommonClickGroup
|
|
23
|
+
|
|
24
|
+
CLI_DOCS = """
|
|
25
|
+
Deltek Ajera API command-line interface.
|
|
26
|
+
|
|
27
|
+
Connection settings are read from environment variables:
|
|
28
|
+
|
|
29
|
+
\b
|
|
30
|
+
- AJERA_API_URL to define the API endpoint.
|
|
31
|
+
- AJERA_API_USERNAME / AJERA_API_PASSWORD for authentication.
|
|
32
|
+
- AJERA_API_HEADERS as a JSON object of extra request headers.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@click.group(
|
|
37
|
+
cls=CommonClickGroup,
|
|
38
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
39
|
+
help=CLI_DOCS,
|
|
40
|
+
)
|
|
41
|
+
@click.option(
|
|
42
|
+
"--log",
|
|
43
|
+
is_flag=True,
|
|
44
|
+
default=False,
|
|
45
|
+
help="Enable request logging at INFO level.",
|
|
46
|
+
)
|
|
47
|
+
@click.version_option(package_name="ajera", prog_name="ajera")
|
|
48
|
+
@click.pass_context
|
|
49
|
+
def cli(ctx: click.Context, log: bool) -> None:
|
|
50
|
+
ctx.obj = ClientContext(log=log)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Register all domain-specific command groups.
|
|
54
|
+
# Runtime gating is handled by AJERA_CLI_DISABLE.
|
|
55
|
+
for module in (
|
|
56
|
+
employees,
|
|
57
|
+
clients,
|
|
58
|
+
contacts,
|
|
59
|
+
vendors,
|
|
60
|
+
projects,
|
|
61
|
+
ledger,
|
|
62
|
+
activities,
|
|
63
|
+
companies,
|
|
64
|
+
departments,
|
|
65
|
+
rate_tables,
|
|
66
|
+
bank_accounts,
|
|
67
|
+
invoice_formats,
|
|
68
|
+
):
|
|
69
|
+
cli.add_command(module.group)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main() -> None:
|
|
73
|
+
"""
|
|
74
|
+
Console-script entry point.
|
|
75
|
+
|
|
76
|
+
Translates expected errors into a non-zero exit with a readable message
|
|
77
|
+
instead of a traceback.
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
cli(standalone_mode=False)
|
|
81
|
+
except click.ClickException as exc:
|
|
82
|
+
exc.show()
|
|
83
|
+
sys.exit(exc.exit_code)
|
|
84
|
+
except click.exceptions.Abort:
|
|
85
|
+
sys.exit(1)
|
|
86
|
+
except requests.HTTPError as exc:
|
|
87
|
+
click.echo(f"Error: {exc}", err=True)
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
except Exception as exc: # noqa: BLE001
|
|
90
|
+
logging.getLogger("ajera").debug("CLI error", exc_info=True)
|
|
91
|
+
click.echo(f"Error: {exc}", err=True)
|
|
92
|
+
sys.exit(1)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
__all__ = ["cli", "main"]
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from ajera.cli.context import ClientContext
|
|
4
|
+
from ajera.cli.options import status_option
|
|
5
|
+
from ajera.cli.output import render
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.command(name="activities")
|
|
9
|
+
@status_option
|
|
10
|
+
@click.option(
|
|
11
|
+
"--description-like",
|
|
12
|
+
"filter_by_description_like",
|
|
13
|
+
type=str,
|
|
14
|
+
default=None,
|
|
15
|
+
help="Filter where the description contains this substring.",
|
|
16
|
+
)
|
|
17
|
+
@click.pass_obj
|
|
18
|
+
def group(
|
|
19
|
+
ctx: ClientContext,
|
|
20
|
+
filter_by_status: tuple[str, ...],
|
|
21
|
+
filter_by_description_like: str | None,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""
|
|
24
|
+
List activities (active only by default).
|
|
25
|
+
"""
|
|
26
|
+
render(
|
|
27
|
+
ctx.client.list_activities(
|
|
28
|
+
filter_by_status=list(filter_by_status),
|
|
29
|
+
filter_by_description_like=filter_by_description_like,
|
|
30
|
+
)
|
|
31
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from ajera.cli.context import ClientContext
|
|
4
|
+
from ajera.cli.options import status_option
|
|
5
|
+
from ajera.cli.output import render
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.command(name="bank-accounts")
|
|
9
|
+
@status_option
|
|
10
|
+
@click.pass_obj
|
|
11
|
+
def group(
|
|
12
|
+
ctx: ClientContext,
|
|
13
|
+
filter_by_status: tuple[str, ...],
|
|
14
|
+
) -> None:
|
|
15
|
+
"""
|
|
16
|
+
List bank accounts (active only by default).
|
|
17
|
+
"""
|
|
18
|
+
render(ctx.client.list_bank_accounts(filter_by_status=list(filter_by_status)))
|