Python で Asana から未完了タスクの一覧を出す方法を紹介します。
ここでは、 Python で、スプレッドシートに貼り付けるためのデータを取得します。
作りたい表の形
Asanaのタスクから、次のようなスプレドシートの表を作ることにします。
Section | Task | Status |
---|---|---|
セクション1 | タスク1 | ステータス1 |
セクション1 | タスク2 | ステータス1 |
セクション1 | タスク3 | ステータス2 |
セクション1 | タスク4 | ステータス2 |
セクション2 | タスク5 | ステータス1 |
セクション2 | タスク6 | ステータス1 |
セクション2 | タスク7 | ステータス2 |
セクション2 | タスク8 | ステータス2 |
セクション3 | タスク9 | ステータス2 |
セクション3 | タスク10 | ステータス3 |
環境
- Python 3.9.0
- pyperclip
- asana
コード
一連のコードです。
PERSONAL_ACCESS_TOKEN='XXXXXXXX'
PROJECT_ID='XXXXXXXX'
import asana
client = asana.Client.access_token(PERSONAL_ACCESS_TOKEN)
def find_sections(project_id):
result = client.sections.get_sections_for_project(project_id, {}, opt_pretty=True)
return result
def find_tasks(project_id):
result = client.tasks.get_tasks(
{
'completed_since': 'now',
'opt_fields' : [
'this.name', 'this.due_on',
'this.custom_fields',
'this.assignee',
'this.assignee.name',
'this.memberships.section',
'this.memberships.section.name'
],
'project': project_id
},
opt_pretty=False
)
return result
section_ids = [section['gid'] for section in find_sections(PROJECT_ID)]
text = 'Section\tTask\tStatus\n'
# i = 1
for task in find_tasks(PROJECT_ID):
sections = list(
filter(
lambda x: x['section']['gid'] in section_ids,
filter(lambda x: 'section' in x, task['memberships'])
)
)
section = sections[0]['section'] if len(sections) > 0 else None
statuses = list(filter(lambda x: x['gid'] == '1234567890123456', task['custom_fields']))
status = statuses[0]['enum_value'] if len(statuses) > 0 else None
# if i == 1:
# print(task['custom_fields'])
# i += 1
text += f'{section["name"] if section is not None else None}\t' + \
f'{task["name"]}\t' + \
f'{status["name"] if status is not None else None}'
text += "\n"
import pyperclip
pyperclip.copy(text)
説明
まずアクセストークンとプロジェクトIDを格納します。
PERSONAL_ACCESS_TOKEN='XXXXXXXX'
PROJECT_ID='XXXXXXXX'
Asana のクライアントを作ります。
import asana
client = asana.Client.access_token(PERSONAL_ACCESS_TOKEN)
クライアントを利用して、あるプロジェクト内のセクションの一覧と、あるプロジェクト内のタスクの一覧を取得する関数を作ります。
タスクの一覧を取得するときに、セクション名も取れるのですが、そのときにタスクが複数のセクションに所属していると、それらがすべて取得できてしまいます。
そういった場合に、表示するべきセクションを絞り込むために、あるプロジェクトないのセクションを一度取得しています。
find_tasks
では、 完了日の条件のみを指定しています。
タスクの基本情報と一緒に取得したいデータを、 opt_fields
に設定しています。 どんなフィールドが使えるのかは、 get_task
の レスポンスの構造を見るとわかります。
def find_sections(project_id):
result = client.sections.get_sections_for_project(project_id, {}, opt_pretty=True)
return result
def find_tasks(project_id):
result = client.tasks.get_tasks(
{
'completed_since': 'now',
'opt_fields' : [
'this.name', 'this.due_on',
'this.custom_fields',
'this.assignee',
'this.assignee.name',
'this.memberships.section',
'this.memberships.section.name'
],
'project': project_id
},
opt_pretty=False
)
return result
セクションをすべて取得して、そのIDをリストにしておきます。
その後、プロジェクト内の未完了タスクをすべて取得して、表示する項目を整理して、 text
にタブ区切りの文字列を生成します。
section_ids = [section['gid'] for section in find_sections(PROJECT_ID)]
text = 'Section\tTask\tStatus\n'
# i = 1
for task in find_tasks(PROJECT_ID):
sections = list(
filter(
lambda x: x['section']['gid'] in section_ids,
filter(lambda x: 'section' in x, task['memberships'])
)
)
section = sections[0]['section'] if len(sections) > 0 else None
statuses = list(filter(lambda x: x['gid'] == '1234567890123456', task['custom_fields']))
status = statuses[0]['enum_value'] if len(statuses) > 0 else None
# if i == 1:
# print(task['custom_fields'])
# i += 1
text += f'{section["name"] if section is not None else None}\t' + \
f'{task["name"]}\t' + \
f'{status["name"] if status is not None else None}'
text += "\n"
ここで status
は、カスタマイズとして追加されたフィールドです。
カスタマイズされたフィールドは、 task
の custom_fields
に含まれて返ってきます。
そこで、表示したいカスタムフィールドの gid
で値をフィルタ・表示しています。
コメントアウトされている箇所をコメントインすると、 カスタムフィールドの一覧が表示されるので、gid
を調べることができるようになります。
最後に、組み立てた文字列をクリップボードにコピーします。
import pyperclip
pyperclip.copy(text)
コピーした文字列を Excel などに貼り付けると、 表として表示されます。