asana-api-cli 1.4.0__tar.gz → 2.0.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.
Files changed (78) hide show
  1. asana_api_cli-2.0.0/PKG-INFO +246 -0
  2. asana_api_cli-2.0.0/README.md +227 -0
  3. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/pyproject.toml +6 -6
  4. asana_api_cli-2.0.0/src/asana_api_cli/cli.py +622 -0
  5. asana_api_cli-2.0.0/src/asana_api_cli/click_ext.py +276 -0
  6. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli/session.py +53 -6
  7. asana_api_cli-2.0.0/src/asana_api_cli.egg-info/PKG-INFO +246 -0
  8. asana_api_cli-2.0.0/src/asana_api_cli.egg-info/SOURCES.txt +22 -0
  9. asana_api_cli-2.0.0/src/asana_api_cli.egg-info/requires.txt +4 -0
  10. asana_api_cli-2.0.0/tests/test_cli.py +251 -0
  11. asana_api_cli-2.0.0/tests/test_cli_surface.py +81 -0
  12. asana_api_cli-2.0.0/tests/test_click_ext.py +176 -0
  13. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/tests/test_formatter.py +0 -1
  14. asana_api_cli-2.0.0/tests/test_py310_compat.py +41 -0
  15. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/tests/test_session.py +0 -2
  16. asana_api_cli-1.4.0/PKG-INFO +0 -121
  17. asana_api_cli-1.4.0/README.md +0 -102
  18. asana_api_cli-1.4.0/src/asana_api_cli/cli/__init__.py +0 -96
  19. asana_api_cli-1.4.0/src/asana_api_cli/cli/access_requests.py +0 -67
  20. asana_api_cli-1.4.0/src/asana_api_cli/cli/allocations.py +0 -102
  21. asana_api_cli-1.4.0/src/asana_api_cli/cli/attachments.py +0 -93
  22. asana_api_cli-1.4.0/src/asana_api_cli/cli/audit_log_api.py +0 -53
  23. asana_api_cli-1.4.0/src/asana_api_cli/cli/batch_api.py +0 -31
  24. asana_api_cli-1.4.0/src/asana_api_cli/cli/budgets.py +0 -80
  25. asana_api_cli-1.4.0/src/asana_api_cli/cli/custom_field_settings.py +0 -93
  26. asana_api_cli-1.4.0/src/asana_api_cli/cli/custom_fields.py +0 -134
  27. asana_api_cli-1.4.0/src/asana_api_cli/cli/custom_types.py +0 -51
  28. asana_api_cli-1.4.0/src/asana_api_cli/cli/events.py +0 -33
  29. asana_api_cli-1.4.0/src/asana_api_cli/cli/exports.py +0 -40
  30. asana_api_cli-1.4.0/src/asana_api_cli/cli/goal_relationships.py +0 -99
  31. asana_api_cli-1.4.0/src/asana_api_cli/cli/goals.py +0 -218
  32. asana_api_cli-1.4.0/src/asana_api_cli/cli/jobs.py +0 -30
  33. asana_api_cli-1.4.0/src/asana_api_cli/cli/memberships.py +0 -90
  34. asana_api_cli-1.4.0/src/asana_api_cli/cli/organization_exports.py +0 -45
  35. asana_api_cli-1.4.0/src/asana_api_cli/cli/portfolio_memberships.py +0 -84
  36. asana_api_cli-1.4.0/src/asana_api_cli/cli/portfolios.py +0 -216
  37. asana_api_cli-1.4.0/src/asana_api_cli/cli/project_briefs.py +0 -73
  38. asana_api_cli-1.4.0/src/asana_api_cli/cli/project_memberships.py +0 -54
  39. asana_api_cli-1.4.0/src/asana_api_cli/cli/project_portfolio_settings.py +0 -88
  40. asana_api_cli-1.4.0/src/asana_api_cli/cli/project_statuses.py +0 -78
  41. asana_api_cli-1.4.0/src/asana_api_cli/cli/project_templates.py +0 -103
  42. asana_api_cli-1.4.0/src/asana_api_cli/cli/projects.py +0 -381
  43. asana_api_cli-1.4.0/src/asana_api_cli/cli/rates.py +0 -98
  44. asana_api_cli-1.4.0/src/asana_api_cli/cli/reactions.py +0 -35
  45. asana_api_cli-1.4.0/src/asana_api_cli/cli/roles.py +0 -99
  46. asana_api_cli-1.4.0/src/asana_api_cli/cli/rules.py +0 -29
  47. asana_api_cli-1.4.0/src/asana_api_cli/cli/sections.py +0 -112
  48. asana_api_cli-1.4.0/src/asana_api_cli/cli/status_updates.py +0 -87
  49. asana_api_cli-1.4.0/src/asana_api_cli/cli/stories.py +0 -131
  50. asana_api_cli-1.4.0/src/asana_api_cli/cli/tags.py +0 -156
  51. asana_api_cli-1.4.0/src/asana_api_cli/cli/task_templates.py +0 -78
  52. asana_api_cli-1.4.0/src/asana_api_cli/cli/tasks.py +0 -521
  53. asana_api_cli-1.4.0/src/asana_api_cli/cli/team_memberships.py +0 -104
  54. asana_api_cli-1.4.0/src/asana_api_cli/cli/teams.py +0 -134
  55. asana_api_cli-1.4.0/src/asana_api_cli/cli/time_periods.py +0 -58
  56. asana_api_cli-1.4.0/src/asana_api_cli/cli/time_tracking_categories.py +0 -124
  57. asana_api_cli-1.4.0/src/asana_api_cli/cli/time_tracking_entries.py +0 -139
  58. asana_api_cli-1.4.0/src/asana_api_cli/cli/timesheet_approval_statuses.py +0 -95
  59. asana_api_cli-1.4.0/src/asana_api_cli/cli/typeahead.py +0 -41
  60. asana_api_cli-1.4.0/src/asana_api_cli/cli/user_task_lists.py +0 -46
  61. asana_api_cli-1.4.0/src/asana_api_cli/cli/users.py +0 -174
  62. asana_api_cli-1.4.0/src/asana_api_cli/cli/webhooks.py +0 -97
  63. asana_api_cli-1.4.0/src/asana_api_cli/cli/workspace_memberships.py +0 -76
  64. asana_api_cli-1.4.0/src/asana_api_cli/cli/workspaces.py +0 -114
  65. asana_api_cli-1.4.0/src/asana_api_cli/click_ext.py +0 -109
  66. asana_api_cli-1.4.0/src/asana_api_cli.egg-info/PKG-INFO +0 -121
  67. asana_api_cli-1.4.0/src/asana_api_cli.egg-info/SOURCES.txt +0 -65
  68. asana_api_cli-1.4.0/src/asana_api_cli.egg-info/requires.txt +0 -4
  69. asana_api_cli-1.4.0/tests/test_codegen.py +0 -258
  70. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/LICENSE +0 -0
  71. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/setup.cfg +0 -0
  72. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli/__init__.py +0 -0
  73. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli/formatter.py +0 -0
  74. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli/version.py +0 -0
  75. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli.egg-info/dependency_links.txt +0 -0
  76. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli.egg-info/entry_points.txt +0 -0
  77. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/src/asana_api_cli.egg-info/top_level.txt +0 -0
  78. {asana_api_cli-1.4.0 → asana_api_cli-2.0.0}/tests/test_version.py +0 -0
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: asana-api-cli
3
+ Version: 2.0.0
4
+ Summary: Command-line wrapper around the official Asana Python SDK
5
+ Author-email: Masanao Izumo <asana@masanao.site>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/izumo-m/asana-api-cli
8
+ Project-URL: Repository, https://github.com/izumo-m/asana-api-cli
9
+ Project-URL: Issues, https://github.com/izumo-m/asana-api-cli/issues
10
+ Project-URL: Changelog, https://github.com/izumo-m/asana-api-cli/blob/main/CHANGELOG.md
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: click>=8.0
15
+ Requires-Dist: jq>=1.5
16
+ Requires-Dist: tabulate>=0.9
17
+ Requires-Dist: asana<6,>=5.2
18
+ Dynamic: license-file
19
+
20
+ # asana-api-cli
21
+
22
+ A CLI for the Asana API. It thinly wraps the official
23
+ [python-asana](https://github.com/Asana/python-asana) SDK with click, exposing
24
+ every endpoint as `asana-api <group> <command>`.
25
+
26
+ ## Why asana-api-cli
27
+
28
+ - **Near-complete SDK coverage.** Almost every method on every `*Api` class in
29
+ python-asana is available as a CLI command. The command tree is built at
30
+ runtime from the installed `asana` package, so new APIs surface as the
31
+ upstream library evolves — no asana-api-cli release required.
32
+ - **Tracks the SDK version you actually use.** Because commands are
33
+ introspected from whatever `asana` is installed alongside, the CLI surface
34
+ matches the SDK version pinned in your project. When using asana-api-cli
35
+ as a dev-dependency, `pip install -U asana` updates the CLI's available
36
+ endpoints in lockstep with your application code.
37
+ - **SDK-compatible arguments and output.** Command arguments map to
38
+ python-asana method parameters (with minor naming adjustments — hyphens
39
+ become underscores, group names become PascalCase API classes), and JSON
40
+ output matches the SDK's response shape. The CLI makes it easy to iterate:
41
+ try different arguments, inspect the response, and refine until you
42
+ understand the endpoint's behavior. Once verified, port the call into your
43
+ Python app — far fewer surprises on the first integration.
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install asana-api-cli
49
+ ```
50
+
51
+ For best results, install asana-api-cli into the same Python environment
52
+ that holds your project's `python-asana` so the CLI surface tracks the
53
+ exact SDK version your application uses (see [As a
54
+ dev-dependency](#as-a-dev-dependency) below).
55
+
56
+ ### As a dev-dependency
57
+
58
+ If your project already uses `python-asana`, add asana-api-cli to your dev
59
+ group so the CLI tracks the same SDK version your application code uses:
60
+
61
+ ```toml
62
+ # pyproject.toml
63
+ [project]
64
+ dependencies = ["asana>=5.2,<6"]
65
+
66
+ [dependency-groups] # uv
67
+ dev = ["asana-api-cli"]
68
+ ```
69
+
70
+ ```toml
71
+ # Poetry
72
+ [tool.poetry.group.dev.dependencies]
73
+ asana-api-cli = "*"
74
+ ```
75
+
76
+ After `uv sync` (or equivalent), `asana-api` resolves to the project's
77
+ `.venv` and introspects whatever `asana` version is locked there. Tests
78
+ prototyped with `asana-api tasks ...` will exactly match the SDK calls in
79
+ your app.
80
+
81
+ ### Installing globally with pipx
82
+
83
+ If you would rather isolate asana-api-cli from any project's dependencies
84
+ — for example, when you administer Asana from the shell without writing
85
+ Python — install it with [pipx](https://pipx.pypa.io/):
86
+
87
+ ```bash
88
+ pipx install asana-api-cli
89
+ ```
90
+
91
+ In this setup the CLI uses the `python-asana` version that shipped with
92
+ the asana-api-cli release; `pipx upgrade asana-api-cli` updates only
93
+ asana-api-cli itself, not the bundled `python-asana`. To pull a newer
94
+ `python-asana` into the existing pipx install without reinstalling the
95
+ CLI:
96
+
97
+ ```bash
98
+ pipx runpip asana-api-cli install -U asana
99
+ ```
100
+
101
+ The next `asana-api` run sees the new SDK and any newly added endpoints
102
+ automatically.
103
+
104
+ ## Environment variables
105
+
106
+ | Name | Required | Description |
107
+ |------|----------|-------------|
108
+ | `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana Personal Access Token |
109
+ | `ASANA_DEFAULT_WORKSPACE` | No | Default workspace GID for endpoints that require it |
110
+
111
+ The token can be issued from the
112
+ [Asana Developer Console](https://app.asana.com/0/developer-console).
113
+ No token is needed for `--help` or argument-error output.
114
+
115
+ ```bash
116
+ export ASANA_ACCESS_TOKEN="1/12345..."
117
+ export ASANA_DEFAULT_WORKSPACE="12345678" # optional
118
+ ```
119
+
120
+ ## Shell completion
121
+
122
+ `asana-api` is built with Click, which supports dynamic shell completion.
123
+ To enable bash completion, add the following line to your `~/.bashrc`:
124
+
125
+ ```bash
126
+ eval "$(_ASANA_API_COMPLETE=bash_source asana-api)"
127
+ ```
128
+
129
+ Then reload the shell (`source ~/.bashrc` or open a new terminal). Pressing
130
+ `<TAB>` after `asana-api` will now complete subcommands and options.
131
+
132
+ For `zsh` or `fish`, replace `bash_source` with `zsh_source` or `fish_source`
133
+ and add the line to `~/.zshrc` or `~/.config/fish/config.fish` respectively.
134
+
135
+ ## Usage
136
+
137
+ ```bash
138
+ # Version and help
139
+ asana-api --version
140
+ asana-api --help
141
+ asana-api tasks --help
142
+ asana-api tasks get-tasks --help
143
+
144
+ # List workspaces and projects
145
+ asana-api workspaces get-workspaces
146
+ asana-api projects get-projects-for-workspace
147
+ asana-api projects get-projects --workspace <WORKSPACE_GID>
148
+
149
+ # List tasks (first page only by default)
150
+ asana-api tasks get-tasks --project <PROJECT_GID>
151
+
152
+ # Preview the first few items
153
+ asana-api tasks get-tasks --project <PROJECT_GID> --max-items 5
154
+
155
+ # Fetch every item across pages
156
+ asana-api tasks get-tasks --project <PROJECT_GID> --all-items
157
+
158
+ # Single task
159
+ asana-api tasks get-task --task <TASK_GID>
160
+
161
+ # Create a task (body is a JSON string)
162
+ asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PID>"]}}'
163
+
164
+ # Output formats
165
+ asana-api tasks get-tasks --project <PID> --output table
166
+ asana-api tasks get-tasks --project <PID> --query '.data' --output csv
167
+ ```
168
+
169
+ See [Pagination](#pagination) for fetching across pages and
170
+ [Global options](#global-options) for `--debug`, `--access-token`, etc.
171
+
172
+ ### Workspace resolution
173
+
174
+ Many API endpoints require a workspace. For those endpoints (e.g.
175
+ `get-projects-for-workspace`), the CLI resolves it in this order:
176
+
177
+ 1. `--workspace <GID>` on the command
178
+ 2. `ASANA_DEFAULT_WORKSPACE` environment variable
179
+
180
+ For endpoints where workspace is optional (e.g. `get-tasks`), the env-var
181
+ fallback is **not** used — pass `--workspace` explicitly if needed. This
182
+ prevents conflicts with other scope parameters like `--project` that are
183
+ mutually exclusive with workspace in the Asana API.
184
+
185
+ ## Pagination
186
+
187
+ Listing endpoints (e.g. `tasks get-tasks`) return paginated results. The CLI
188
+ provides four ways to control how much is fetched:
189
+
190
+ | Option | Behavior |
191
+ |--------|----------|
192
+ | (none) | Fetch a single page (Asana default: 100 items) |
193
+ | `--max-items N` | Fetch up to N items, auto-paginating across pages. The last request is automatically capped to the remaining count. |
194
+ | `--all-items` | Fetch every page until the server reports no more |
195
+ | `--offset <TOKEN>` | Manual pagination: pass the `next_page.offset` token from the previous response |
196
+
197
+ `--max-items` and `--all-items` are mutually exclusive.
198
+
199
+ `--page-size N` tunes the per-page request size (Asana API requires 1-100,
200
+ default 100). Rarely needed — combine with `--all-items` or `--max-items` only
201
+ when the default doesn't suit (e.g. very large rows or rate-limit tuning).
202
+
203
+ ```bash
204
+ # Auto-paginate up to 250 items
205
+ asana-api tasks get-tasks --project <PID> --max-items 250
206
+
207
+ # Fetch everything
208
+ asana-api tasks get-tasks --project <PID> --all-items
209
+
210
+ # Manual pagination using the offset token
211
+ asana-api tasks get-tasks --project <PID> --offset <TOKEN>
212
+ ```
213
+
214
+ ## Global options
215
+
216
+ These options work at any level of the command tree, so the following are
217
+ equivalent:
218
+
219
+ ```bash
220
+ asana-api --debug tasks get-tasks --project <PID>
221
+ asana-api tasks get-tasks --project <PID> --debug
222
+ ```
223
+
224
+ When the same option is given at multiple levels, the more specific (later)
225
+ one wins.
226
+
227
+ | Option | Description |
228
+ |--------|-------------|
229
+ | `--access-token TOKEN` | Asana personal access token (default: `$ASANA_ACCESS_TOKEN`) |
230
+ | `--host URL` | Override API base URL (default: `https://app.asana.com/api/1.0`) |
231
+ | `--proxy URL` | HTTP/HTTPS proxy URL |
232
+ | `--no-verify-ssl` | Disable TLS certificate verification (insecure) |
233
+ | `--ca-cert PATH` | Path to a PEM bundle of trusted CA certificates |
234
+ | `--retries N` | Number of retries on 429/5xx responses (default: 5) |
235
+ | `--timeout SECONDS` | Per-request timeout in seconds |
236
+ | `--temp-dir PATH` | Directory for temporary downloads |
237
+ | `--debug` | Print HTTP request/response to stderr for troubleshooting |
238
+
239
+ ## Development
240
+
241
+ See [docs/development.md](https://github.com/izumo-m/asana-api-cli/blob/main/docs/development.md)
242
+ for building from source, project layout, and library usage.
243
+
244
+ ## License
245
+
246
+ [MIT License](https://github.com/izumo-m/asana-api-cli/blob/main/LICENSE)
@@ -0,0 +1,227 @@
1
+ # asana-api-cli
2
+
3
+ A CLI for the Asana API. It thinly wraps the official
4
+ [python-asana](https://github.com/Asana/python-asana) SDK with click, exposing
5
+ every endpoint as `asana-api <group> <command>`.
6
+
7
+ ## Why asana-api-cli
8
+
9
+ - **Near-complete SDK coverage.** Almost every method on every `*Api` class in
10
+ python-asana is available as a CLI command. The command tree is built at
11
+ runtime from the installed `asana` package, so new APIs surface as the
12
+ upstream library evolves — no asana-api-cli release required.
13
+ - **Tracks the SDK version you actually use.** Because commands are
14
+ introspected from whatever `asana` is installed alongside, the CLI surface
15
+ matches the SDK version pinned in your project. When using asana-api-cli
16
+ as a dev-dependency, `pip install -U asana` updates the CLI's available
17
+ endpoints in lockstep with your application code.
18
+ - **SDK-compatible arguments and output.** Command arguments map to
19
+ python-asana method parameters (with minor naming adjustments — hyphens
20
+ become underscores, group names become PascalCase API classes), and JSON
21
+ output matches the SDK's response shape. The CLI makes it easy to iterate:
22
+ try different arguments, inspect the response, and refine until you
23
+ understand the endpoint's behavior. Once verified, port the call into your
24
+ Python app — far fewer surprises on the first integration.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install asana-api-cli
30
+ ```
31
+
32
+ For best results, install asana-api-cli into the same Python environment
33
+ that holds your project's `python-asana` so the CLI surface tracks the
34
+ exact SDK version your application uses (see [As a
35
+ dev-dependency](#as-a-dev-dependency) below).
36
+
37
+ ### As a dev-dependency
38
+
39
+ If your project already uses `python-asana`, add asana-api-cli to your dev
40
+ group so the CLI tracks the same SDK version your application code uses:
41
+
42
+ ```toml
43
+ # pyproject.toml
44
+ [project]
45
+ dependencies = ["asana>=5.2,<6"]
46
+
47
+ [dependency-groups] # uv
48
+ dev = ["asana-api-cli"]
49
+ ```
50
+
51
+ ```toml
52
+ # Poetry
53
+ [tool.poetry.group.dev.dependencies]
54
+ asana-api-cli = "*"
55
+ ```
56
+
57
+ After `uv sync` (or equivalent), `asana-api` resolves to the project's
58
+ `.venv` and introspects whatever `asana` version is locked there. Tests
59
+ prototyped with `asana-api tasks ...` will exactly match the SDK calls in
60
+ your app.
61
+
62
+ ### Installing globally with pipx
63
+
64
+ If you would rather isolate asana-api-cli from any project's dependencies
65
+ — for example, when you administer Asana from the shell without writing
66
+ Python — install it with [pipx](https://pipx.pypa.io/):
67
+
68
+ ```bash
69
+ pipx install asana-api-cli
70
+ ```
71
+
72
+ In this setup the CLI uses the `python-asana` version that shipped with
73
+ the asana-api-cli release; `pipx upgrade asana-api-cli` updates only
74
+ asana-api-cli itself, not the bundled `python-asana`. To pull a newer
75
+ `python-asana` into the existing pipx install without reinstalling the
76
+ CLI:
77
+
78
+ ```bash
79
+ pipx runpip asana-api-cli install -U asana
80
+ ```
81
+
82
+ The next `asana-api` run sees the new SDK and any newly added endpoints
83
+ automatically.
84
+
85
+ ## Environment variables
86
+
87
+ | Name | Required | Description |
88
+ |------|----------|-------------|
89
+ | `ASANA_ACCESS_TOKEN` | Yes (at runtime only) | Asana Personal Access Token |
90
+ | `ASANA_DEFAULT_WORKSPACE` | No | Default workspace GID for endpoints that require it |
91
+
92
+ The token can be issued from the
93
+ [Asana Developer Console](https://app.asana.com/0/developer-console).
94
+ No token is needed for `--help` or argument-error output.
95
+
96
+ ```bash
97
+ export ASANA_ACCESS_TOKEN="1/12345..."
98
+ export ASANA_DEFAULT_WORKSPACE="12345678" # optional
99
+ ```
100
+
101
+ ## Shell completion
102
+
103
+ `asana-api` is built with Click, which supports dynamic shell completion.
104
+ To enable bash completion, add the following line to your `~/.bashrc`:
105
+
106
+ ```bash
107
+ eval "$(_ASANA_API_COMPLETE=bash_source asana-api)"
108
+ ```
109
+
110
+ Then reload the shell (`source ~/.bashrc` or open a new terminal). Pressing
111
+ `<TAB>` after `asana-api` will now complete subcommands and options.
112
+
113
+ For `zsh` or `fish`, replace `bash_source` with `zsh_source` or `fish_source`
114
+ and add the line to `~/.zshrc` or `~/.config/fish/config.fish` respectively.
115
+
116
+ ## Usage
117
+
118
+ ```bash
119
+ # Version and help
120
+ asana-api --version
121
+ asana-api --help
122
+ asana-api tasks --help
123
+ asana-api tasks get-tasks --help
124
+
125
+ # List workspaces and projects
126
+ asana-api workspaces get-workspaces
127
+ asana-api projects get-projects-for-workspace
128
+ asana-api projects get-projects --workspace <WORKSPACE_GID>
129
+
130
+ # List tasks (first page only by default)
131
+ asana-api tasks get-tasks --project <PROJECT_GID>
132
+
133
+ # Preview the first few items
134
+ asana-api tasks get-tasks --project <PROJECT_GID> --max-items 5
135
+
136
+ # Fetch every item across pages
137
+ asana-api tasks get-tasks --project <PROJECT_GID> --all-items
138
+
139
+ # Single task
140
+ asana-api tasks get-task --task <TASK_GID>
141
+
142
+ # Create a task (body is a JSON string)
143
+ asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PID>"]}}'
144
+
145
+ # Output formats
146
+ asana-api tasks get-tasks --project <PID> --output table
147
+ asana-api tasks get-tasks --project <PID> --query '.data' --output csv
148
+ ```
149
+
150
+ See [Pagination](#pagination) for fetching across pages and
151
+ [Global options](#global-options) for `--debug`, `--access-token`, etc.
152
+
153
+ ### Workspace resolution
154
+
155
+ Many API endpoints require a workspace. For those endpoints (e.g.
156
+ `get-projects-for-workspace`), the CLI resolves it in this order:
157
+
158
+ 1. `--workspace <GID>` on the command
159
+ 2. `ASANA_DEFAULT_WORKSPACE` environment variable
160
+
161
+ For endpoints where workspace is optional (e.g. `get-tasks`), the env-var
162
+ fallback is **not** used — pass `--workspace` explicitly if needed. This
163
+ prevents conflicts with other scope parameters like `--project` that are
164
+ mutually exclusive with workspace in the Asana API.
165
+
166
+ ## Pagination
167
+
168
+ Listing endpoints (e.g. `tasks get-tasks`) return paginated results. The CLI
169
+ provides four ways to control how much is fetched:
170
+
171
+ | Option | Behavior |
172
+ |--------|----------|
173
+ | (none) | Fetch a single page (Asana default: 100 items) |
174
+ | `--max-items N` | Fetch up to N items, auto-paginating across pages. The last request is automatically capped to the remaining count. |
175
+ | `--all-items` | Fetch every page until the server reports no more |
176
+ | `--offset <TOKEN>` | Manual pagination: pass the `next_page.offset` token from the previous response |
177
+
178
+ `--max-items` and `--all-items` are mutually exclusive.
179
+
180
+ `--page-size N` tunes the per-page request size (Asana API requires 1-100,
181
+ default 100). Rarely needed — combine with `--all-items` or `--max-items` only
182
+ when the default doesn't suit (e.g. very large rows or rate-limit tuning).
183
+
184
+ ```bash
185
+ # Auto-paginate up to 250 items
186
+ asana-api tasks get-tasks --project <PID> --max-items 250
187
+
188
+ # Fetch everything
189
+ asana-api tasks get-tasks --project <PID> --all-items
190
+
191
+ # Manual pagination using the offset token
192
+ asana-api tasks get-tasks --project <PID> --offset <TOKEN>
193
+ ```
194
+
195
+ ## Global options
196
+
197
+ These options work at any level of the command tree, so the following are
198
+ equivalent:
199
+
200
+ ```bash
201
+ asana-api --debug tasks get-tasks --project <PID>
202
+ asana-api tasks get-tasks --project <PID> --debug
203
+ ```
204
+
205
+ When the same option is given at multiple levels, the more specific (later)
206
+ one wins.
207
+
208
+ | Option | Description |
209
+ |--------|-------------|
210
+ | `--access-token TOKEN` | Asana personal access token (default: `$ASANA_ACCESS_TOKEN`) |
211
+ | `--host URL` | Override API base URL (default: `https://app.asana.com/api/1.0`) |
212
+ | `--proxy URL` | HTTP/HTTPS proxy URL |
213
+ | `--no-verify-ssl` | Disable TLS certificate verification (insecure) |
214
+ | `--ca-cert PATH` | Path to a PEM bundle of trusted CA certificates |
215
+ | `--retries N` | Number of retries on 429/5xx responses (default: 5) |
216
+ | `--timeout SECONDS` | Per-request timeout in seconds |
217
+ | `--temp-dir PATH` | Directory for temporary downloads |
218
+ | `--debug` | Print HTTP request/response to stderr for troubleshooting |
219
+
220
+ ## Development
221
+
222
+ See [docs/development.md](https://github.com/izumo-m/asana-api-cli/blob/main/docs/development.md)
223
+ for building from source, project layout, and library usage.
224
+
225
+ ## License
226
+
227
+ [MIT License](https://github.com/izumo-m/asana-api-cli/blob/main/LICENSE)
@@ -1,16 +1,16 @@
1
1
  [project]
2
2
  name = "asana-api-cli"
3
- version = "1.4.0"
3
+ version = "2.0.0"
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"
7
7
  license = "MIT"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
- "click>=8.1,<9",
11
- "jq>=1.8,<2",
12
- "tabulate>=0.9,<1",
13
- "asana>=5.2.4,<6",
10
+ "click>=8.0",
11
+ "jq>=1.5",
12
+ "tabulate>=0.9",
13
+ "asana>=5.2,<6",
14
14
  ]
15
15
 
16
16
  [project.urls]
@@ -28,6 +28,7 @@ dev = [
28
28
  "pytest>=9,<10",
29
29
  "build>=1,<2",
30
30
  "twine>=6,<7",
31
+ "vermin>=1.6,<2",
31
32
  ]
32
33
 
33
34
  [build-system]
@@ -40,7 +41,6 @@ where = ["src"]
40
41
  [tool.ruff]
41
42
  target-version = "py310"
42
43
  line-length = 100
43
- extend-exclude = ["src/asana_api_cli/cli"] # auto-generated (tools/codegen.py)
44
44
 
45
45
  [tool.ruff.format]
46
46
  docstring-code-format = true