asana-api-cli 2.0.0__tar.gz → 2.1.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.
- {asana_api_cli-2.0.0/src/asana_api_cli.egg-info → asana_api_cli-2.1.1}/PKG-INFO +62 -44
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/README.md +60 -42
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/pyproject.toml +4 -3
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli/cli.py +112 -75
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli/click_ext.py +1 -12
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli/formatter.py +71 -19
- asana_api_cli-2.1.1/src/asana_api_cli/session.py +413 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1/src/asana_api_cli.egg-info}/PKG-INFO +62 -44
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli.egg-info/SOURCES.txt +1 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli.egg-info/requires.txt +1 -1
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_cli.py +10 -2
- asana_api_cli-2.1.1/tests/test_cli_invocation.py +489 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_click_ext.py +1 -1
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_formatter.py +149 -0
- asana_api_cli-2.1.1/tests/test_session.py +455 -0
- asana_api_cli-2.0.0/src/asana_api_cli/session.py +0 -222
- asana_api_cli-2.0.0/tests/test_session.py +0 -103
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/LICENSE +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/setup.cfg +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli/__init__.py +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli/version.py +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli.egg-info/dependency_links.txt +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli.egg-info/entry_points.txt +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/src/asana_api_cli.egg-info/top_level.txt +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_cli_surface.py +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_py310_compat.py +0 -0
- {asana_api_cli-2.0.0 → asana_api_cli-2.1.1}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: asana-api-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: Command-line wrapper around the official Asana Python SDK
|
|
5
5
|
Author-email: Masanao Izumo <asana@masanao.site>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -12,35 +12,38 @@ Requires-Python: >=3.10
|
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: click>=8.0
|
|
15
|
-
Requires-Dist: jq>=1.
|
|
15
|
+
Requires-Dist: jq>=1.6
|
|
16
16
|
Requires-Dist: tabulate>=0.9
|
|
17
17
|
Requires-Dist: asana<6,>=5.2
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
20
|
# asana-api-cli
|
|
21
21
|
|
|
22
|
-
A CLI
|
|
23
|
-
[python-asana](https://github.com/Asana/python-asana) SDK
|
|
24
|
-
|
|
22
|
+
A CLI that exposes **every method of the official
|
|
23
|
+
[`python-asana`](https://github.com/Asana/python-asana) SDK** as
|
|
24
|
+
`asana-api <group> <command>`. The command tree is generated at runtime
|
|
25
|
+
from the installed `asana` package, automatically tracking whatever
|
|
26
|
+
SDK version is installed in the same environment.
|
|
25
27
|
|
|
26
28
|
## Why asana-api-cli
|
|
27
29
|
|
|
28
|
-
- **
|
|
29
|
-
python-asana
|
|
30
|
-
|
|
31
|
-
upstream
|
|
30
|
+
- **Complete SDK coverage.** Every method of every `*Api` class in
|
|
31
|
+
`python-asana` becomes a CLI command. Because the tree is introspected
|
|
32
|
+
from the installed `asana` package, new methods surface the moment
|
|
33
|
+
upstream ships them — no `asana-api-cli` release required.
|
|
32
34
|
- **Tracks the SDK version you actually use.** Because commands are
|
|
33
|
-
introspected from whatever `asana` is installed
|
|
34
|
-
matches the SDK version pinned in your project. When using
|
|
35
|
-
as a dev-dependency, `pip install -U asana` updates the
|
|
36
|
-
|
|
35
|
+
introspected from whatever `asana` is installed in the same environment,
|
|
36
|
+
the CLI surface matches the SDK version pinned in your project. When using
|
|
37
|
+
`asana-api-cli` as a dev-dependency, `pip install -U asana` updates the
|
|
38
|
+
CLI's available commands in lockstep with your application code.
|
|
37
39
|
- **SDK-compatible arguments and output.** Command arguments map to
|
|
38
|
-
python-asana method parameters (with minor naming adjustments — hyphens
|
|
39
|
-
become underscores, group names
|
|
40
|
-
output matches the SDK's response shape. The CLI makes
|
|
41
|
-
try different arguments, inspect the response, and
|
|
42
|
-
understand the endpoint's behavior. Once verified,
|
|
43
|
-
|
|
40
|
+
`python-asana` method parameters (with minor naming adjustments — hyphens
|
|
41
|
+
become underscores, group names map back to PascalCase `*Api` class
|
|
42
|
+
names), and JSON output matches the SDK's response shape. The CLI makes
|
|
43
|
+
it easy to iterate: try different arguments, inspect the response, and
|
|
44
|
+
refine until you understand the endpoint's behavior. Once verified,
|
|
45
|
+
translate the call into the equivalent `python-asana` invocation in your
|
|
46
|
+
app — far fewer surprises on the first integration.
|
|
44
47
|
|
|
45
48
|
## Installation
|
|
46
49
|
|
|
@@ -48,14 +51,14 @@ every endpoint as `asana-api <group> <command>`.
|
|
|
48
51
|
pip install asana-api-cli
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
For best results, install asana-api-cli into the same Python environment
|
|
54
|
+
For best results, install `asana-api-cli` into the same Python environment
|
|
52
55
|
that holds your project's `python-asana` so the CLI surface tracks the
|
|
53
56
|
exact SDK version your application uses (see [As a
|
|
54
57
|
dev-dependency](#as-a-dev-dependency) below).
|
|
55
58
|
|
|
56
59
|
### As a dev-dependency
|
|
57
60
|
|
|
58
|
-
If your project already uses `python-asana`, add asana-api-cli to your dev
|
|
61
|
+
If your project already uses `python-asana`, add `asana-api-cli` to your dev
|
|
59
62
|
group so the CLI tracks the same SDK version your application code uses:
|
|
60
63
|
|
|
61
64
|
```toml
|
|
@@ -74,13 +77,13 @@ asana-api-cli = "*"
|
|
|
74
77
|
```
|
|
75
78
|
|
|
76
79
|
After `uv sync` (or equivalent), `asana-api` resolves to the project's
|
|
77
|
-
`.venv` and introspects whatever `asana` version is locked there.
|
|
78
|
-
prototyped with `asana-api tasks ...`
|
|
79
|
-
your app.
|
|
80
|
+
`.venv` and introspects whatever `asana` version is locked there. Calls
|
|
81
|
+
prototyped with `asana-api tasks ...` translate directly to the SDK calls
|
|
82
|
+
you'll write in your app.
|
|
80
83
|
|
|
81
84
|
### Installing globally with pipx
|
|
82
85
|
|
|
83
|
-
If you would rather isolate asana-api-cli from any project's dependencies
|
|
86
|
+
If you would rather isolate `asana-api-cli` from any project's dependencies
|
|
84
87
|
— for example, when you administer Asana from the shell without writing
|
|
85
88
|
Python — install it with [pipx](https://pipx.pypa.io/):
|
|
86
89
|
|
|
@@ -88,9 +91,9 @@ Python — install it with [pipx](https://pipx.pypa.io/):
|
|
|
88
91
|
pipx install asana-api-cli
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
In this setup the CLI uses the `python-asana` version
|
|
92
|
-
|
|
93
|
-
asana-api-cli itself, not the bundled `python-asana`. To pull a newer
|
|
94
|
+
In this setup the CLI uses the `python-asana` version pipx resolved when
|
|
95
|
+
installing `asana-api-cli`; `pipx upgrade asana-api-cli` updates only
|
|
96
|
+
`asana-api-cli` itself, not the bundled `python-asana`. To pull a newer
|
|
94
97
|
`python-asana` into the existing pipx install without reinstalling the
|
|
95
98
|
CLI:
|
|
96
99
|
|
|
@@ -98,25 +101,32 @@ CLI:
|
|
|
98
101
|
pipx runpip asana-api-cli install -U asana
|
|
99
102
|
```
|
|
100
103
|
|
|
101
|
-
The next `asana-api` run sees the new SDK and any newly added
|
|
104
|
+
The next `asana-api` run sees the new SDK and any newly added methods
|
|
102
105
|
automatically.
|
|
103
106
|
|
|
104
107
|
## Environment variables
|
|
105
108
|
|
|
106
109
|
| Name | Required | Description |
|
|
107
110
|
|------|----------|-------------|
|
|
108
|
-
| `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana
|
|
111
|
+
| `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana personal access token |
|
|
109
112
|
| `ASANA_DEFAULT_WORKSPACE` | No | Default workspace GID for endpoints that require it |
|
|
110
113
|
|
|
111
114
|
The token can be issued from the
|
|
112
115
|
[Asana Developer Console](https://app.asana.com/0/developer-console).
|
|
113
|
-
No token is needed for `--help` or argument
|
|
116
|
+
No token is needed for `--help` or argument validation errors.
|
|
114
117
|
|
|
115
118
|
```bash
|
|
116
119
|
export ASANA_ACCESS_TOKEN="1/12345..."
|
|
117
120
|
export ASANA_DEFAULT_WORKSPACE="12345678" # optional
|
|
118
121
|
```
|
|
119
122
|
|
|
123
|
+
On Windows PowerShell:
|
|
124
|
+
|
|
125
|
+
```powershell
|
|
126
|
+
$env:ASANA_ACCESS_TOKEN = "1/12345..."
|
|
127
|
+
$env:ASANA_DEFAULT_WORKSPACE = "12345678" # optional
|
|
128
|
+
```
|
|
129
|
+
|
|
120
130
|
## Shell completion
|
|
121
131
|
|
|
122
132
|
`asana-api` is built with Click, which supports dynamic shell completion.
|
|
@@ -132,6 +142,9 @@ Then reload the shell (`source ~/.bashrc` or open a new terminal). Pressing
|
|
|
132
142
|
For `zsh` or `fish`, replace `bash_source` with `zsh_source` or `fish_source`
|
|
133
143
|
and add the line to `~/.zshrc` or `~/.config/fish/config.fish` respectively.
|
|
134
144
|
|
|
145
|
+
Click does not generate PowerShell completion. Windows users can install
|
|
146
|
+
completion under WSL or Git Bash using the `bash_source` line above.
|
|
147
|
+
|
|
135
148
|
## Usage
|
|
136
149
|
|
|
137
150
|
```bash
|
|
@@ -161,9 +174,14 @@ asana-api tasks get-task --task <TASK_GID>
|
|
|
161
174
|
# Create a task (body is a JSON string)
|
|
162
175
|
asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PID>"]}}'
|
|
163
176
|
|
|
164
|
-
# Output formats
|
|
165
|
-
|
|
177
|
+
# Output formats — pair non-JSON formats with `--query '.data'` to unwrap the
|
|
178
|
+
# `{"data": [...]}` envelope into one row per item.
|
|
179
|
+
asana-api tasks get-tasks --project <PID> --query '.data' --output table
|
|
166
180
|
asana-api tasks get-tasks --project <PID> --query '.data' --output csv
|
|
181
|
+
|
|
182
|
+
# CSV output is UTF-8 without a BOM by default. Pass --csv-bom for Excel on
|
|
183
|
+
# Windows, which otherwise displays non-ASCII characters as garbled text.
|
|
184
|
+
asana-api tasks get-tasks --project <PID> --output csv --csv-bom > tasks.csv
|
|
167
185
|
```
|
|
168
186
|
|
|
169
187
|
See [Pagination](#pagination) for fetching across pages and
|
|
@@ -171,20 +189,21 @@ See [Pagination](#pagination) for fetching across pages and
|
|
|
171
189
|
|
|
172
190
|
### Workspace resolution
|
|
173
191
|
|
|
174
|
-
Many API endpoints require a workspace. For
|
|
175
|
-
`get-projects-for-workspace`), the CLI resolves it in
|
|
192
|
+
Many API endpoints require a workspace. For commands wrapping such
|
|
193
|
+
endpoints (e.g. `get-projects-for-workspace`), the CLI resolves it in
|
|
194
|
+
this order:
|
|
176
195
|
|
|
177
196
|
1. `--workspace <GID>` on the command
|
|
178
197
|
2. `ASANA_DEFAULT_WORKSPACE` environment variable
|
|
179
198
|
|
|
180
|
-
For
|
|
199
|
+
For commands where workspace is optional (e.g. `get-tasks`), the env-var
|
|
181
200
|
fallback is **not** used — pass `--workspace` explicitly if needed. This
|
|
182
|
-
|
|
183
|
-
|
|
201
|
+
avoids ambiguity with alternative scope parameters like `--project` that
|
|
202
|
+
the Asana API accepts in place of workspace.
|
|
184
203
|
|
|
185
204
|
## Pagination
|
|
186
205
|
|
|
187
|
-
|
|
206
|
+
List commands (e.g. `tasks get-tasks`) return paginated results. The CLI
|
|
188
207
|
provides four ways to control how much is fetched:
|
|
189
208
|
|
|
190
209
|
| Option | Behavior |
|
|
@@ -198,7 +217,7 @@ provides four ways to control how much is fetched:
|
|
|
198
217
|
|
|
199
218
|
`--page-size N` tunes the per-page request size (Asana API requires 1-100,
|
|
200
219
|
default 100). Rarely needed — combine with `--all-items` or `--max-items` only
|
|
201
|
-
when the default doesn't suit (e.g. very large
|
|
220
|
+
when the default doesn't suit (e.g. very large response items).
|
|
202
221
|
|
|
203
222
|
```bash
|
|
204
223
|
# Auto-paginate up to 250 items
|
|
@@ -221,8 +240,7 @@ asana-api --debug tasks get-tasks --project <PID>
|
|
|
221
240
|
asana-api tasks get-tasks --project <PID> --debug
|
|
222
241
|
```
|
|
223
242
|
|
|
224
|
-
When the same option is given at multiple levels, the
|
|
225
|
-
one wins.
|
|
243
|
+
When the same option is given at multiple levels, the later one wins.
|
|
226
244
|
|
|
227
245
|
| Option | Description |
|
|
228
246
|
|--------|-------------|
|
|
@@ -234,12 +252,12 @@ one wins.
|
|
|
234
252
|
| `--retries N` | Number of retries on 429/5xx responses (default: 5) |
|
|
235
253
|
| `--timeout SECONDS` | Per-request timeout in seconds |
|
|
236
254
|
| `--temp-dir PATH` | Directory for temporary downloads |
|
|
237
|
-
| `--debug` | Print HTTP request/response
|
|
255
|
+
| `--debug` | Print HTTP request/response traces for troubleshooting (Authorization values are masked). |
|
|
238
256
|
|
|
239
257
|
## Development
|
|
240
258
|
|
|
241
259
|
See [docs/development.md](https://github.com/izumo-m/asana-api-cli/blob/main/docs/development.md)
|
|
242
|
-
for building from source
|
|
260
|
+
for building from source and project layout.
|
|
243
261
|
|
|
244
262
|
## License
|
|
245
263
|
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
# asana-api-cli
|
|
2
2
|
|
|
3
|
-
A CLI
|
|
4
|
-
[python-asana](https://github.com/Asana/python-asana) SDK
|
|
5
|
-
|
|
3
|
+
A CLI that exposes **every method of the official
|
|
4
|
+
[`python-asana`](https://github.com/Asana/python-asana) SDK** as
|
|
5
|
+
`asana-api <group> <command>`. The command tree is generated at runtime
|
|
6
|
+
from the installed `asana` package, automatically tracking whatever
|
|
7
|
+
SDK version is installed in the same environment.
|
|
6
8
|
|
|
7
9
|
## Why asana-api-cli
|
|
8
10
|
|
|
9
|
-
- **
|
|
10
|
-
python-asana
|
|
11
|
-
|
|
12
|
-
upstream
|
|
11
|
+
- **Complete SDK coverage.** Every method of every `*Api` class in
|
|
12
|
+
`python-asana` becomes a CLI command. Because the tree is introspected
|
|
13
|
+
from the installed `asana` package, new methods surface the moment
|
|
14
|
+
upstream ships them — no `asana-api-cli` release required.
|
|
13
15
|
- **Tracks the SDK version you actually use.** Because commands are
|
|
14
|
-
introspected from whatever `asana` is installed
|
|
15
|
-
matches the SDK version pinned in your project. When using
|
|
16
|
-
as a dev-dependency, `pip install -U asana` updates the
|
|
17
|
-
|
|
16
|
+
introspected from whatever `asana` is installed in the same environment,
|
|
17
|
+
the CLI surface matches the SDK version pinned in your project. When using
|
|
18
|
+
`asana-api-cli` as a dev-dependency, `pip install -U asana` updates the
|
|
19
|
+
CLI's available commands in lockstep with your application code.
|
|
18
20
|
- **SDK-compatible arguments and output.** Command arguments map to
|
|
19
|
-
python-asana method parameters (with minor naming adjustments — hyphens
|
|
20
|
-
become underscores, group names
|
|
21
|
-
output matches the SDK's response shape. The CLI makes
|
|
22
|
-
try different arguments, inspect the response, and
|
|
23
|
-
understand the endpoint's behavior. Once verified,
|
|
24
|
-
|
|
21
|
+
`python-asana` method parameters (with minor naming adjustments — hyphens
|
|
22
|
+
become underscores, group names map back to PascalCase `*Api` class
|
|
23
|
+
names), and JSON output matches the SDK's response shape. The CLI makes
|
|
24
|
+
it easy to iterate: try different arguments, inspect the response, and
|
|
25
|
+
refine until you understand the endpoint's behavior. Once verified,
|
|
26
|
+
translate the call into the equivalent `python-asana` invocation in your
|
|
27
|
+
app — far fewer surprises on the first integration.
|
|
25
28
|
|
|
26
29
|
## Installation
|
|
27
30
|
|
|
@@ -29,14 +32,14 @@ every endpoint as `asana-api <group> <command>`.
|
|
|
29
32
|
pip install asana-api-cli
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
For best results, install asana-api-cli into the same Python environment
|
|
35
|
+
For best results, install `asana-api-cli` into the same Python environment
|
|
33
36
|
that holds your project's `python-asana` so the CLI surface tracks the
|
|
34
37
|
exact SDK version your application uses (see [As a
|
|
35
38
|
dev-dependency](#as-a-dev-dependency) below).
|
|
36
39
|
|
|
37
40
|
### As a dev-dependency
|
|
38
41
|
|
|
39
|
-
If your project already uses `python-asana`, add asana-api-cli to your dev
|
|
42
|
+
If your project already uses `python-asana`, add `asana-api-cli` to your dev
|
|
40
43
|
group so the CLI tracks the same SDK version your application code uses:
|
|
41
44
|
|
|
42
45
|
```toml
|
|
@@ -55,13 +58,13 @@ asana-api-cli = "*"
|
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
After `uv sync` (or equivalent), `asana-api` resolves to the project's
|
|
58
|
-
`.venv` and introspects whatever `asana` version is locked there.
|
|
59
|
-
prototyped with `asana-api tasks ...`
|
|
60
|
-
your app.
|
|
61
|
+
`.venv` and introspects whatever `asana` version is locked there. Calls
|
|
62
|
+
prototyped with `asana-api tasks ...` translate directly to the SDK calls
|
|
63
|
+
you'll write in your app.
|
|
61
64
|
|
|
62
65
|
### Installing globally with pipx
|
|
63
66
|
|
|
64
|
-
If you would rather isolate asana-api-cli from any project's dependencies
|
|
67
|
+
If you would rather isolate `asana-api-cli` from any project's dependencies
|
|
65
68
|
— for example, when you administer Asana from the shell without writing
|
|
66
69
|
Python — install it with [pipx](https://pipx.pypa.io/):
|
|
67
70
|
|
|
@@ -69,9 +72,9 @@ Python — install it with [pipx](https://pipx.pypa.io/):
|
|
|
69
72
|
pipx install asana-api-cli
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
In this setup the CLI uses the `python-asana` version
|
|
73
|
-
|
|
74
|
-
asana-api-cli itself, not the bundled `python-asana`. To pull a newer
|
|
75
|
+
In this setup the CLI uses the `python-asana` version pipx resolved when
|
|
76
|
+
installing `asana-api-cli`; `pipx upgrade asana-api-cli` updates only
|
|
77
|
+
`asana-api-cli` itself, not the bundled `python-asana`. To pull a newer
|
|
75
78
|
`python-asana` into the existing pipx install without reinstalling the
|
|
76
79
|
CLI:
|
|
77
80
|
|
|
@@ -79,25 +82,32 @@ CLI:
|
|
|
79
82
|
pipx runpip asana-api-cli install -U asana
|
|
80
83
|
```
|
|
81
84
|
|
|
82
|
-
The next `asana-api` run sees the new SDK and any newly added
|
|
85
|
+
The next `asana-api` run sees the new SDK and any newly added methods
|
|
83
86
|
automatically.
|
|
84
87
|
|
|
85
88
|
## Environment variables
|
|
86
89
|
|
|
87
90
|
| Name | Required | Description |
|
|
88
91
|
|------|----------|-------------|
|
|
89
|
-
| `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana
|
|
92
|
+
| `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana personal access token |
|
|
90
93
|
| `ASANA_DEFAULT_WORKSPACE` | No | Default workspace GID for endpoints that require it |
|
|
91
94
|
|
|
92
95
|
The token can be issued from the
|
|
93
96
|
[Asana Developer Console](https://app.asana.com/0/developer-console).
|
|
94
|
-
No token is needed for `--help` or argument
|
|
97
|
+
No token is needed for `--help` or argument validation errors.
|
|
95
98
|
|
|
96
99
|
```bash
|
|
97
100
|
export ASANA_ACCESS_TOKEN="1/12345..."
|
|
98
101
|
export ASANA_DEFAULT_WORKSPACE="12345678" # optional
|
|
99
102
|
```
|
|
100
103
|
|
|
104
|
+
On Windows PowerShell:
|
|
105
|
+
|
|
106
|
+
```powershell
|
|
107
|
+
$env:ASANA_ACCESS_TOKEN = "1/12345..."
|
|
108
|
+
$env:ASANA_DEFAULT_WORKSPACE = "12345678" # optional
|
|
109
|
+
```
|
|
110
|
+
|
|
101
111
|
## Shell completion
|
|
102
112
|
|
|
103
113
|
`asana-api` is built with Click, which supports dynamic shell completion.
|
|
@@ -113,6 +123,9 @@ Then reload the shell (`source ~/.bashrc` or open a new terminal). Pressing
|
|
|
113
123
|
For `zsh` or `fish`, replace `bash_source` with `zsh_source` or `fish_source`
|
|
114
124
|
and add the line to `~/.zshrc` or `~/.config/fish/config.fish` respectively.
|
|
115
125
|
|
|
126
|
+
Click does not generate PowerShell completion. Windows users can install
|
|
127
|
+
completion under WSL or Git Bash using the `bash_source` line above.
|
|
128
|
+
|
|
116
129
|
## Usage
|
|
117
130
|
|
|
118
131
|
```bash
|
|
@@ -142,9 +155,14 @@ asana-api tasks get-task --task <TASK_GID>
|
|
|
142
155
|
# Create a task (body is a JSON string)
|
|
143
156
|
asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PID>"]}}'
|
|
144
157
|
|
|
145
|
-
# Output formats
|
|
146
|
-
|
|
158
|
+
# Output formats — pair non-JSON formats with `--query '.data'` to unwrap the
|
|
159
|
+
# `{"data": [...]}` envelope into one row per item.
|
|
160
|
+
asana-api tasks get-tasks --project <PID> --query '.data' --output table
|
|
147
161
|
asana-api tasks get-tasks --project <PID> --query '.data' --output csv
|
|
162
|
+
|
|
163
|
+
# CSV output is UTF-8 without a BOM by default. Pass --csv-bom for Excel on
|
|
164
|
+
# Windows, which otherwise displays non-ASCII characters as garbled text.
|
|
165
|
+
asana-api tasks get-tasks --project <PID> --output csv --csv-bom > tasks.csv
|
|
148
166
|
```
|
|
149
167
|
|
|
150
168
|
See [Pagination](#pagination) for fetching across pages and
|
|
@@ -152,20 +170,21 @@ See [Pagination](#pagination) for fetching across pages and
|
|
|
152
170
|
|
|
153
171
|
### Workspace resolution
|
|
154
172
|
|
|
155
|
-
Many API endpoints require a workspace. For
|
|
156
|
-
`get-projects-for-workspace`), the CLI resolves it in
|
|
173
|
+
Many API endpoints require a workspace. For commands wrapping such
|
|
174
|
+
endpoints (e.g. `get-projects-for-workspace`), the CLI resolves it in
|
|
175
|
+
this order:
|
|
157
176
|
|
|
158
177
|
1. `--workspace <GID>` on the command
|
|
159
178
|
2. `ASANA_DEFAULT_WORKSPACE` environment variable
|
|
160
179
|
|
|
161
|
-
For
|
|
180
|
+
For commands where workspace is optional (e.g. `get-tasks`), the env-var
|
|
162
181
|
fallback is **not** used — pass `--workspace` explicitly if needed. This
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
avoids ambiguity with alternative scope parameters like `--project` that
|
|
183
|
+
the Asana API accepts in place of workspace.
|
|
165
184
|
|
|
166
185
|
## Pagination
|
|
167
186
|
|
|
168
|
-
|
|
187
|
+
List commands (e.g. `tasks get-tasks`) return paginated results. The CLI
|
|
169
188
|
provides four ways to control how much is fetched:
|
|
170
189
|
|
|
171
190
|
| Option | Behavior |
|
|
@@ -179,7 +198,7 @@ provides four ways to control how much is fetched:
|
|
|
179
198
|
|
|
180
199
|
`--page-size N` tunes the per-page request size (Asana API requires 1-100,
|
|
181
200
|
default 100). Rarely needed — combine with `--all-items` or `--max-items` only
|
|
182
|
-
when the default doesn't suit (e.g. very large
|
|
201
|
+
when the default doesn't suit (e.g. very large response items).
|
|
183
202
|
|
|
184
203
|
```bash
|
|
185
204
|
# Auto-paginate up to 250 items
|
|
@@ -202,8 +221,7 @@ asana-api --debug tasks get-tasks --project <PID>
|
|
|
202
221
|
asana-api tasks get-tasks --project <PID> --debug
|
|
203
222
|
```
|
|
204
223
|
|
|
205
|
-
When the same option is given at multiple levels, the
|
|
206
|
-
one wins.
|
|
224
|
+
When the same option is given at multiple levels, the later one wins.
|
|
207
225
|
|
|
208
226
|
| Option | Description |
|
|
209
227
|
|--------|-------------|
|
|
@@ -215,12 +233,12 @@ one wins.
|
|
|
215
233
|
| `--retries N` | Number of retries on 429/5xx responses (default: 5) |
|
|
216
234
|
| `--timeout SECONDS` | Per-request timeout in seconds |
|
|
217
235
|
| `--temp-dir PATH` | Directory for temporary downloads |
|
|
218
|
-
| `--debug` | Print HTTP request/response
|
|
236
|
+
| `--debug` | Print HTTP request/response traces for troubleshooting (Authorization values are masked). |
|
|
219
237
|
|
|
220
238
|
## Development
|
|
221
239
|
|
|
222
240
|
See [docs/development.md](https://github.com/izumo-m/asana-api-cli/blob/main/docs/development.md)
|
|
223
|
-
for building from source
|
|
241
|
+
for building from source and project layout.
|
|
224
242
|
|
|
225
243
|
## License
|
|
226
244
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "asana-api-cli"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.1.1"
|
|
4
4
|
description = "Command-line wrapper around the official Asana Python SDK"
|
|
5
5
|
authors = [{name = "Masanao Izumo", email = "asana@masanao.site"}]
|
|
6
6
|
readme = "README.md"
|
|
@@ -8,7 +8,7 @@ license = "MIT"
|
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
dependencies = [
|
|
10
10
|
"click>=8.0",
|
|
11
|
-
"jq>=1.
|
|
11
|
+
"jq>=1.6",
|
|
12
12
|
"tabulate>=0.9",
|
|
13
13
|
"asana>=5.2,<6",
|
|
14
14
|
]
|
|
@@ -24,7 +24,8 @@ asana-api = "asana_api_cli.cli:main"
|
|
|
24
24
|
|
|
25
25
|
[dependency-groups]
|
|
26
26
|
dev = [
|
|
27
|
-
"ruff
|
|
27
|
+
"ruff>=0.6",
|
|
28
|
+
"basedpyright>=1.13",
|
|
28
29
|
"pytest>=9,<10",
|
|
29
30
|
"build>=1,<2",
|
|
30
31
|
"twine>=6,<7",
|