Wednesday 16 August 2017

More TD tips - Trello for task management

In any pipeline, communication is key - sharing and passing data back and forth, whether its from application or process to another or from a manager to an artist.  Over the years I've developed plenty of scripts to manage file naming, server logging and automating processes.  I'd also built a SQL feedback and approval system that didn't see the light of day - and after reviewing what I'd done, it was a great learning process but it was fairly limited.

Task and time management...

One thing I had planned with my feedback/approval system was a way to manage artist deadlines in small productions.  These days, a lot of teams and small productions have started to rely on the many online tools such as Slack, Trello and tools provided by Google doc's.  They do what they do best, and that is help manage communication and tasks.

In a bid to leverage off these technologies, I decided that I would investigate how I could build functionality in my existing tools to work alongside and make use of what they offered.  To my surprise, this was actually a lot easier then I had expected...  And that's what this article is about - to share a little about what I've learned so that you can take advantage of leveraging on them yourselves!

"Trello, is it me you're looking for?"

If you are not familiar with Trello, you should take the time to check it out.  Its a great tool you can use to manage tasks in a project - whether its (in my case) for a class room production or for your own personal time management.


Trello works on what could be best described as a virtual 'pin board'.  You create a 'board', you set up lists of things that need to be done and then place 'cards' with tasks on them into these lists.

These cards can include more detailed information - check lists that relate to the task on the card itself, they can be assigned to people in a team and have due dates that have to be met.  Each card contains text, comments and attachments as well.

Its a great way to not just manage task completion, but provide feedback to your team.

Bringing it into the pipeline

First question you might ask is why do anything when all you need to do is just use the web site?  Sure, just having users to flick over to the web to check out their tasks on Trello is easy but it means that your team will be switching between their production tools and a web browser.

Sometimes a user might want a very quick summary of outstanding tasks to pop up in a window within their production tool without the need to visit the web at all.  Perhaps you have a scripted process that relies on information set up on Trello to perform a task.  This is where the benefits of having the ability to communicate with Trello start to become apparent.

Talk the talk...

Lets start with the nerdy layman's explanation first.  As you may (or may not) know, http (HyperText Transfer Protocol) works on a request/response approach.  When you load a website in your browser, you send a request through the website address.  The web server on the other end takes your request and responds by sending back a webpage that your browser downloads and displays.  This is all termed as being stateless - basically neither machine has to physically stay connected together to talk.

Think of it as the difference between a phone call where you stay connected while you talk, and communicating through writing letters and posting them (except on the web its a lot faster then your local postal service).  You don't need to retain a connection to each other with a letter - you write it, its gone.  You simply wait for the response to come back when the other end see's it.

So, how about you tell me what I need to do?

Lets take a peek at how we make use of Trello's REST api (or web api as some people also refer to them) to get communcating.  Essentially, its just a collection of web addresses with query strings and data that is sent to their system, then its processed and the data you asked for is sent back.

Top secret numbers...

However before you begin working with talking to Trello you'll need to authorise (get permission) to do so.  This requires two things - an API key as well as an Authorisation token. (click on that link to go to the right place for these - you will likely need to be signed up to Trello and logged in for this to work).  At the top of the page you can copy the 'secret' API key to use.  You'll notice that there's an option to generate a token in the text below - I did this as I wanted to just toy around with the application for my small pipeline here.

Starting your Python script

Ok.  We're essentially ready to talk to Trello - and this can be taken care of for us by finding one of a few nifty python modules out there to communicate with it.  However rather then google 'Trello python module' or similiar, if this is new to you and you want to see exactly what's going on then avoid the nice abstractions that a module can provide and manage the chatter back and forth ourselves...  It's a good way to get a better understanding of the processes, and also makes the Trello documentation easier to grasp.

A bit of an online chit-chat...

Python does ship with a module called urllib but there is a much more elegant module that has been recommended in many online sources (and even the urllib documentation) called requests.  It provides a 'human friendly' way to deal with web based chatter, and is a real pleasure to work with.  It's relatively easy to install using pip too. Using the windows command line, simply enter python -m pip install requests.

Alongside being able to put and get data using requests, it also have a very useful json() function. We need this to decipher the data being returned by Trello into something easy to process in python.

What exactly are we going to use Trello for?

Lets create something useful, such as retrieving and alerting a user of their allocated tasks and deadlines that may be set on cards within Trello...  This example can then be placed into a script that produced a nicely formatted window in a production tool allowing an artist to see exactly what they have to do for the day.

Note that I'll also import the datetime module here because, as expected, deadlines are usually related to eh, dates and times.

# Import the requests module
import requests

#import the datetime module
from datetime import datetime


Lets start speaking some Trello-nese...

As mentioned, talking online is all about sending data back and forth.  We send it to Trello's web server using this url.

urlBase = "https://api.trello.com/1/"

We also need to pass our api and authorisation codes when we communicate each time, so we will set these up to form the start of a query string that gets added to the end of the url we are communicating with.

While it may be obvious to most, I will make mention that you should REPLACE the words in the below code example APIkey and TOKEN with the authorisation strings you got at the beginning.

I'm not trying to be condescending with making that comment - its just to try and alleviate how many times someones told me a script doesn't work just to discover that they typed in things literally word-for-word without considering what some if it meant.

urlTkKy = "?key=%s&token=%s" % (APIkey, TOKEN)

Tell me about your tasks...

Lets go and retrieve a list of cards for a user, or as Trello refers to users - a member.  We need to build our URL to request this information based on what the api that Trello has set out for retrieving information for a specific member.



I know that some people I've talked to got a little confused with the API doc's but its really as simple as that url shown in the api...  As mentioned before regarding the code examples, don't forget to replace that ourUserName with the actual member name being used on Trello whom you want to query.

tMember = "ourUserName"
tUrl = urlBase+"members/"+tMember+"/cards"+urlTkKy

As shown in the doc's, what we are building is a url that starts with the base address for Trello, followed by the word 'members/', the member name, '/cards' and by adding the key, token to the end, we've created our 'command' to send to Trello.  The complete url would look something like this...

https://api.trello.com/1/members/ourUserName/cards?key=APIkey&token=TOKEN

Our next step is to use the requests module's get function and send this command to request that information from Trello

fromTrello = requests.get(tUrl)

The response will come back as json data.  It's just a data format created for quick passing of information online, but its not easy to read directly in python without first being deciphered.  That's where we ask for the json data to be translated using the json() function.

cardsList = fromTrello.json()

What we now get in cardsList is - well - a list.  This list contains dictionaries, one for each card, containing all data fields. We can then iterate through the list of cards and find out their details fairly quickly.

However in terms of making this tool do what we need it to do, we're interested in just those cards that our user did not yet complete (ie. they are still in the to-do pile).  We'll also look for whether there were any checklists associated with the card too, as those are often used to tick of steps needed to complete the task.

for card in cardsList:
    # Look for anything not closed or marked as Complete
    if not (card['dueComplete'] or card['closed']):
        print "CARD : ",card['name']
        print "DEADLINE : ",card['due']

I want to get the current day and see how much time is left in comparison with the cards due date.  This information is useful for setting up any alert messages, or notifying someone about problems with meeting their production deadlines.

(Note that when I'm explaining 'how to' code, I often expand the details out for ease of explanation.  Obviously, all of this code can be optimized and cleaned up later)

        # Get todays date
        timeNow = datetime.now()

        # Only process IF there is a deadline date
        if card['due']:

            # Convert Trello date to datetime
            dueDate = datetime.strptime(card['due'][:-5],"%Y-%m-%dT%H:%M:%S")

            # Work out the number of hours left
            timeLeft = dueDate - timeNow
            daysLeft = timeLeft.days * 24
            hoursLeft = int(timeLeft.seconds / 3600)
            totalLeft = daysLeft + hoursLeft

            if totalLeft <= 0:
                print "Overdue - missed deadline"
            elif totalLeft < 12:
                print "Critical - get a move on!"
            elif totalLeft < 24:
                print "Urgent - work faster"
            else:
                print "Ok, but keep working hard"

We'll also look for those checklists I mentioned and let them know what steps haven't been completed.

        # Are there any checklists?
        if card['idChecklists']:

            # idChecklists contain a list of checklistID values.
            # Query Trello for the items in each checklistID
            for chkLst in card['idChecklists']:

Much like we did for cards, we use Trello's api again to construct a command to ask for the items inside a checklist.  We can pull these down, along with their state (completed or not).  In this example, I'm passing a request for the fields name and state only - rather than all data that is associated with a checklist item.

                tFlds="&fields=name,state"
                tUrl=urlBase + "checklists/" + chkLst + "/checkItems" + urlTkKy + tFlds

This again will come back in json format, so we translate back into a list containing each item as a dictionary and we're done.  Then we can pass this 'items still to do' info back to the artist.

                fromTrello = requests.get(tUrl)
                chkItems = fromTrello.json()

                # Loop through, find incomplete and display
                for chkTask in chkItems:
                    if chkTask['state'] == 'incomplete':
                        print "TO DO : ", chkTask['name']

Look at how little you've finished!

Yup - your team no longer need to be asked what they've got left to deliver on.  With a little work, you can also develop your own 'task management' tool to oversee things as well.  You can write back and update Trello just as easily as you saw it was to retrieve data - the possibilities are endless...

Hopefully this article provided a small introduction to get you familiar with REST(web) api's and integrating some of Trello's many features into a script - and in this case, a rather handy one for providing feedback to a user regarding their outstanding tasks.  I did use this code to produce a nice pop-up window for Maya artists as shown in the screenshot below.  The code I used to identify the urgency of the task I changed to color-code the deadline text.

Yup - put to practical use...
I am looking to write more tips and tutorials for integration of other features as I go and venture into some of the other api-based web tools out there to help create a streamlined pipeline experience for artists.  For example, I've got some basic Slack integration to post updates to a group when a process has completed - say, someone has posted an updated play-blast, render or file to be approved.  But perhaps that's another post to the blog for another day...

Enjoy - and any questions feel free to comment below.

2 comments :

  1. Just to expand on this article, I had also added some code into a file-saver that was being used that would also change the label on a Trello card to indicate it had been updated and "Waiting for feedback". Extremely useful...

    I also tested embedded keywords in the card descriptions. These can be read and then analysed - which add's a few more ideas for scripts and processes into the list of 'what else can I automate'. I didn't do much in that respect (it was an after-thought, and I just toyed with the scripts in downtime to see if it might be plausible) :)

    If you've thought of any other things that you've used Trello for in terms of pipeline, do post comments here - I'm sure we'd all be keen to hear what else people have done.

    ReplyDelete
  2. What a good idea about pipeline management tool.
    Thanks

    ReplyDelete