asana-api-cli 3.1.2__tar.gz → 3.2.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 (36) hide show
  1. {asana_api_cli-3.1.2/src/asana_api_cli.egg-info → asana_api_cli-3.2.0}/PKG-INFO +44 -6
  2. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/README.md +43 -5
  3. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/pyproject.toml +5 -1
  4. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/cli.py +307 -122
  5. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/click_ext.py +25 -68
  6. asana_api_cli-3.2.0/src/asana_api_cli/codegen.py +721 -0
  7. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/formatter.py +96 -24
  8. asana_api_cli-3.2.0/src/asana_api_cli/multibyte_filename.py +68 -0
  9. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/redactor.py +22 -9
  10. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/session.py +6 -64
  11. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/version.py +1 -1
  12. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0/src/asana_api_cli.egg-info}/PKG-INFO +44 -6
  13. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli.egg-info/SOURCES.txt +6 -0
  14. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_cli_invocation.py +26 -0
  15. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_click_ext.py +9 -7
  16. asana_api_cli-3.2.0/tests/test_codegen.py +992 -0
  17. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_formatter.py +42 -30
  18. asana_api_cli-3.2.0/tests/test_generate_python.py +155 -0
  19. asana_api_cli-3.2.0/tests/test_generate_python_snapshots.py +179 -0
  20. asana_api_cli-3.2.0/tests/test_multibyte_filename.py +117 -0
  21. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_redactor.py +105 -10
  22. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_sdk_boilerplate.py +166 -0
  23. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_session.py +1 -109
  24. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/LICENSE +0 -0
  25. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/setup.cfg +0 -0
  26. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/__init__.py +0 -0
  27. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli/structured_arg.py +0 -0
  28. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli.egg-info/dependency_links.txt +0 -0
  29. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli.egg-info/entry_points.txt +0 -0
  30. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli.egg-info/requires.txt +0 -0
  31. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/src/asana_api_cli.egg-info/top_level.txt +0 -0
  32. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_cli.py +0 -0
  33. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_cli_surface.py +0 -0
  34. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_py310_compat.py +0 -0
  35. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_structured_arg.py +0 -0
  36. {asana_api_cli-3.1.2 → asana_api_cli-3.2.0}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: asana-api-cli
3
- Version: 3.1.2
3
+ Version: 3.2.0
4
4
  Summary: Command-line wrapper around the official Asana Python SDK
5
5
  Author: Masanao Izumo
6
6
  License-Expression: MIT
@@ -46,6 +46,9 @@ asana-api tasks get-tasks --project 123 --opt-fields name,assignee.name
46
46
  asana.TasksApi(client).get_tasks({"project": "123", "opt_fields": "name,assignee.name"})
47
47
  ```
48
48
 
49
+ Or skip the translation entirely: `asana-api --generate-python …` writes that
50
+ Python for you (see [Usage](#usage)).
51
+
49
52
  ## Why asana-api-cli
50
53
 
51
54
  - **Explore the whole API from the shell.** Every method of every `*Api`
@@ -176,7 +179,7 @@ asana-api tasks get-tasks --help
176
179
  # List workspaces
177
180
  asana-api workspaces get-workspaces
178
181
 
179
- # List up to 50 projects
182
+ # List up to 50 projects (workspace comes from $ASANA_DEFAULT_WORKSPACE)
180
183
  asana-api projects get-projects-for-workspace --item-limit 50
181
184
  asana-api projects get-projects --workspace <WORKSPACE_GID> --item-limit 50
182
185
 
@@ -195,10 +198,11 @@ asana-api tasks get-task --task <TASK_GID>
195
198
  # Create a task (body is a JSON string)
196
199
  asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PROJECT_GID>"]}}'
197
200
 
198
- # Output formats — pair non-JSON formats with `--query '.data'` to unwrap the
199
- # `{"data": [...]}` envelope into one row per item.
200
- asana-api tasks get-tasks --project <PROJECT_GID> --query '.data' --output table
201
- asana-api tasks get-tasks --project <PROJECT_GID> --query '.data' --output csv
201
+ # Output formats — non-JSON formats render one row per item. The default
202
+ # auto-paginating output is a flat list, so it is directly rowable; under
203
+ # --full-payload, unwrap the `{"data": [...]}` envelope first with `--query '.data'`.
204
+ asana-api tasks get-tasks --project <PROJECT_GID> --output table
205
+ asana-api tasks get-tasks --project <PROJECT_GID> --full-payload --query '.data' --output csv
202
206
 
203
207
  # CSV output is UTF-8 without a BOM by default. Pass --csv-bom for Excel on
204
208
  # Windows, which otherwise displays non-ASCII characters as garbled text.
@@ -210,6 +214,40 @@ asana-api tasks get-tasks --project <PROJECT_GID> --output csv --csv-bom > tasks
210
214
  asana-api tasks delete-task --task <TASK_GID> --output none
211
215
  ```
212
216
 
217
+ Don't hand-translate the call yourself — `--generate-python` does it for you. It
218
+ prints a standalone `python-asana` script equivalent to the command instead of
219
+ running it (no token, no network), turning a working shell call into
220
+ ready-to-paste SDK code:
221
+
222
+ ```bash
223
+ asana-api --generate-python tasks get-task --task <TASK_GID>
224
+ ```
225
+
226
+ ```python
227
+ # Generated equivalent (header and stdio-setup boilerplate trimmed):
228
+ import json
229
+ import os
230
+
231
+ import asana
232
+
233
+ configuration = asana.Configuration()
234
+ configuration.access_token = os.environ['ASANA_ACCESS_TOKEN']
235
+ api_client = asana.ApiClient(configuration)
236
+
237
+ api_instance = asana.TasksApi(api_client)
238
+ opts = {}
239
+
240
+ result = api_instance.get_task('<TASK_GID>', opts)
241
+
242
+ print(json.dumps(result, indent=2, ensure_ascii=False))
243
+ ```
244
+
245
+ Redirect it to a file (`asana-api … --generate-python > fetch_task.py`) to keep
246
+ the script. It reproduces your configuration, output format, `--query`, `--debug`
247
+ (with the auth token masked), and uploads — see
248
+ [Generating Python code](https://github.com/izumo-m/asana-api-cli/blob/main/docs/usage.md#generating-python-code)
249
+ for the full behavior.
250
+
213
251
  For the complete option reference — global options, pagination, output formats,
214
252
  workspace resolution, error handling, and exit codes — see
215
253
  [`docs/usage.md`](https://github.com/izumo-m/asana-api-cli/blob/main/docs/usage.md).
@@ -18,6 +18,9 @@ asana-api tasks get-tasks --project 123 --opt-fields name,assignee.name
18
18
  asana.TasksApi(client).get_tasks({"project": "123", "opt_fields": "name,assignee.name"})
19
19
  ```
20
20
 
21
+ Or skip the translation entirely: `asana-api --generate-python …` writes that
22
+ Python for you (see [Usage](#usage)).
23
+
21
24
  ## Why asana-api-cli
22
25
 
23
26
  - **Explore the whole API from the shell.** Every method of every `*Api`
@@ -148,7 +151,7 @@ asana-api tasks get-tasks --help
148
151
  # List workspaces
149
152
  asana-api workspaces get-workspaces
150
153
 
151
- # List up to 50 projects
154
+ # List up to 50 projects (workspace comes from $ASANA_DEFAULT_WORKSPACE)
152
155
  asana-api projects get-projects-for-workspace --item-limit 50
153
156
  asana-api projects get-projects --workspace <WORKSPACE_GID> --item-limit 50
154
157
 
@@ -167,10 +170,11 @@ asana-api tasks get-task --task <TASK_GID>
167
170
  # Create a task (body is a JSON string)
168
171
  asana-api tasks create-task --body '{"data":{"name":"new task","projects":["<PROJECT_GID>"]}}'
169
172
 
170
- # Output formats — pair non-JSON formats with `--query '.data'` to unwrap the
171
- # `{"data": [...]}` envelope into one row per item.
172
- asana-api tasks get-tasks --project <PROJECT_GID> --query '.data' --output table
173
- asana-api tasks get-tasks --project <PROJECT_GID> --query '.data' --output csv
173
+ # Output formats — non-JSON formats render one row per item. The default
174
+ # auto-paginating output is a flat list, so it is directly rowable; under
175
+ # --full-payload, unwrap the `{"data": [...]}` envelope first with `--query '.data'`.
176
+ asana-api tasks get-tasks --project <PROJECT_GID> --output table
177
+ asana-api tasks get-tasks --project <PROJECT_GID> --full-payload --query '.data' --output csv
174
178
 
175
179
  # CSV output is UTF-8 without a BOM by default. Pass --csv-bom for Excel on
176
180
  # Windows, which otherwise displays non-ASCII characters as garbled text.
@@ -182,6 +186,40 @@ asana-api tasks get-tasks --project <PROJECT_GID> --output csv --csv-bom > tasks
182
186
  asana-api tasks delete-task --task <TASK_GID> --output none
183
187
  ```
184
188
 
189
+ Don't hand-translate the call yourself — `--generate-python` does it for you. It
190
+ prints a standalone `python-asana` script equivalent to the command instead of
191
+ running it (no token, no network), turning a working shell call into
192
+ ready-to-paste SDK code:
193
+
194
+ ```bash
195
+ asana-api --generate-python tasks get-task --task <TASK_GID>
196
+ ```
197
+
198
+ ```python
199
+ # Generated equivalent (header and stdio-setup boilerplate trimmed):
200
+ import json
201
+ import os
202
+
203
+ import asana
204
+
205
+ configuration = asana.Configuration()
206
+ configuration.access_token = os.environ['ASANA_ACCESS_TOKEN']
207
+ api_client = asana.ApiClient(configuration)
208
+
209
+ api_instance = asana.TasksApi(api_client)
210
+ opts = {}
211
+
212
+ result = api_instance.get_task('<TASK_GID>', opts)
213
+
214
+ print(json.dumps(result, indent=2, ensure_ascii=False))
215
+ ```
216
+
217
+ Redirect it to a file (`asana-api … --generate-python > fetch_task.py`) to keep
218
+ the script. It reproduces your configuration, output format, `--query`, `--debug`
219
+ (with the auth token masked), and uploads — see
220
+ [Generating Python code](https://github.com/izumo-m/asana-api-cli/blob/main/docs/usage.md#generating-python-code)
221
+ for the full behavior.
222
+
185
223
  For the complete option reference — global options, pagination, output formats,
186
224
  workspace resolution, error handling, and exit codes — see
187
225
  [`docs/usage.md`](https://github.com/izumo-m/asana-api-cli/blob/main/docs/usage.md).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "asana-api-cli"
3
- version = "3.1.2"
3
+ version = "3.2.0"
4
4
  description = "Command-line wrapper around the official Asana Python SDK"
5
5
  authors = [{name = "Masanao Izumo"}]
6
6
  readme = "README.md"
@@ -55,6 +55,10 @@ where = ["src"]
55
55
  [tool.ruff]
56
56
  target-version = "py310"
57
57
  line-length = 100
58
+ # Generated python-asana scripts pinned as golden snapshots; they use repr/pprint
59
+ # literal style and are validated by ``compile()`` in the snapshot test, not by
60
+ # this project's lint config.
61
+ extend-exclude = ["tests/fixtures/generate_python"]
58
62
 
59
63
  [tool.ruff.format]
60
64
  docstring-code-format = true