Skip to content

Instantly share code, notes, and snippets.

@BKDaugherty
Created October 20, 2022 18:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BKDaugherty/a1b689ac118f42c48f6c5f4edfc10b9b to your computer and use it in GitHub Desktop.
Save BKDaugherty/a1b689ac118f42c48f6c5f4edfc10b9b to your computer and use it in GitHub Desktop.
A quick click CLI tool to generate a DOT file from an asana project
import asana
import click
import logging
import graphviz
import os
def get_client():
access_token = os.environ["ASANA_ACCESS_TOKEN"]
client = asana.Client.access_token(access_token)
return client
@click.command()
@click.option("--project-id", help="find this in the URL of the asana project")
@click.option(
"--output-filename", type=click.Path(exists=False), default="./asana-project.gv"
)
def build_diagram(project_id, output_filename):
asana_client = get_client()
logging.info("Getting the tasks in the project")
all_tasks_in_project = list(asana_client.tasks.get_tasks({"project": project_id}))
task_info = {}
task_parent_map = {}
task_children_map = {}
logging.info("Gathering info on tasks in the project")
for task in all_tasks_in_project:
task_id = task["gid"]
full_task = asana_client.tasks.get_task(
task_id,
opt_field=["dependencies", "dependents", "completed", "assignee", "name"],
)
task_info[task_id] = {
"completed": full_task["completed"],
"name": full_task["name"],
}
parents = [
x["gid"] for x in asana_client.tasks.get_dependencies_for_task(task_id)
]
children = [
x["gid"] for x in asana_client.tasks.get_dependents_for_task(task_id)
]
task_parent_map[task_id] = parents
task_children_map[task_id] = children
# Iterate through dependencies and dependents to get full task info
logging.info("Gathering info on dependencies")
for task, dep_task_ids in task_parent_map.items():
for task_id in dep_task_ids:
if task_id in task_info:
continue
full_task = asana_client.tasks.get_task(
task_id,
opt_field=[
"dependencies",
"dependents",
"completed",
"assignee",
"name",
],
)
task_info[task_id] = {
"completed": full_task["completed"],
"name": full_task["name"],
}
for task, dep_task_ids in task_children_map.items():
for task_id in dep_task_ids:
if task_id in task_info:
continue
full_task = asana_client.tasks.get_task(
task_id,
opt_field=[
"dependencies",
"dependents",
"completed",
"assignee",
"name",
],
)
task_info[task_id] = {
"completed": full_task["completed"],
"name": full_task["name"],
}
# Create graphviz
logging.info("Building a visualization")
edge_existence = set()
dot = graphviz.Digraph(comment="my project")
for task_id, task in task_info.items():
dot.node(task_id, task["name"])
for source, dests in task_children_map.items():
for dest in dests:
if (source, dest) not in edge_existence:
dot.edge(source, dest)
edge_existence.add((source, dest))
for source, dests in task_parent_map.items():
for dest in dests:
if (dest, source) not in edge_existence:
dot.edge(dest, source)
edge_existence.add((dest, source))
file_path = dot.render(output_filename).replace("\\", "/")
logging.info(f"Find your diagram at {file_path}!")
if __name__ == "__main__":
build_diagram()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment