Skip to main content

Workfront Bridge Project Library for Python

Project description

# workfront-bridge

Workfront Bridge is a library that make the creation of bridge projects in
workfront easily.

## Design

Projects and tasks in workfront have custom forms. Those custom forms have
several parameters which are fullfill when the project is created(some other
parameters are being fullfilled while the project is developed and task are
being excetuted).

The library tries to divide and group logical blocks of tasks that can be
convined to build a workfront project.
So, in order to achieve this, two main abstractions are provided:

* Project Containers
* Blocks

### Workfront Blocks

A Block is a group of one or more task that live inside a workfront template
Each particular block must knows its tasks, the parameters of them and the
dependencies among them so it can instantiate and configure them without
The fact that the tasks live inside a workfront template project is just a
convinient way of storing them(workfront does not allow to define a group of
template task out of a template project).

### Workfront Project Containers

Project Containers represents empty workfront project templates associated with
one or more custom forms that can allocate different blocks.
The idea of these project containers is to build different project types by
adding different type of blocks to it.
So, basically a workfront project will be constructed by creating a project
container, setting the corresponding parameters to it and appending blocks to
the project container according to the behaviour that is needed for that
project. In this process, the parameters for the different blocks will be also

## Creating Blocks

Inherit from **WFBlock** class to create a new specific block. A Workfront
service and a template id needs to be provided to the WFBlock constructor. The
template id must have only the tasks that belongs to this block.
Also fields can be marked as optional and required to be automatically validated
when a new project is being constructed with this block.

For example, supose you want to add a block with 1 task:
* My task : which has 2 parameters; name (required) and age (optional)

Here it is an example of how you would make the block representing that task:

class MyWFBlock(WFBlock):
def __init__(self, wf):
template_id = template_id_from_name(wf, "My block template")
super(WFEmailTestSeedBlock, self).__init__(wf, template_id)

In order to set the concrete values for those parameters the
**set_task_param_value** method must be used.
The **set_task_param_value** receives a **task identifier** (that can be an
integer, indicating the number of the task in the template project, or a string
for the name of the task).
Properties can be utilize for a clean design:

def name(self):
return self._name

def name(self, value): = value
self.set_task_param_value("My task", "name", value)

The purpose of using the **set_task_param_value** is that when the block is used
inside a project container and a workfront project is build, the block knows
how to configure the value in the group of task represented by this block.

### Starter task

Each block has as default starter task the first task. However this can be
changed by using the **_set_starter_task(task_identifier)** method when
inheriting from WFBlock.
This can be handy when having indentation task that only organize task. So, for
example if you have the following tasks in the block:

* Grouping Task
* Task 1
* Task 2

You should set the Task 1 as a starter task skipping the Grouping Task that only
gives some visual clarity indenting Task 1 and 2.
Why ? This is required when for example Task 1 is Automatic. The workfront proxy
only starts Automatic tasks when they are a direct predecessor of a completed
So, in this case, when the predecessor of Grouping task is complete (and
starter task is the Grouping Task), Task 1 will not start (because Grouping Task
predecessor is an indirect predecessor of Task 1). So to avoid that, Task 1
must be set as starter task.
This can be achieved in the constructor of the block like this :

def __init(...)
# Other blcok stuff...
self._set_starter_task(2) # Task 1 is the second task
# or you can set it by name
self._set_starter_task("Task 1")

## Creating Project Containers

To create a project container the new block should inherit from
After that, the template id of the workfront template project and the required
and optional parameters should be provided. This can be done calling the parent
constructor and the methods **_set_required_fields** and
**_set_optional_fields** (you can make use of the **template_id_from_name**
function to get the template id):

class MyWFProjectContainer(WFProjectContainer)
def __init__(self, wf, prj_name):
tid = template_id_from_name(wf, "My WF Template")
super(MyWFProjectContainer, self).__init__(wf, tid, prj_name)

Then you can set the variables that will fullfill the parameter values of the
project calling the **set_param_value** method. For example:

def my_param_value(self):
return self._my_param_value

def my_param_value(self, v):
self._my_param_value = v
self.set_param_value("workfront_param_value_req", v)

You can check the **WFProjectEmailContainer** in
for a complete example.

### Using Blocks inside a Project Container

Blocks are made to be appended to a project container. A project container can
have one or more blocks of the same type.
When adding a block to a project container, the block is appended to the project
making this new block, dependent of the last added block. So for example, if
block1, block2, block3 are appended to the same project block in that order,
the workfront project will be created so that the starter task in block2 will
only be excetuted when the last task in block1 is completed. The same happens to
block3; the starter task created that belongs to block3 will only start after
the last task from block2 finishes.

The project container does not have any restriction in the order that the blocks
are added to the project block, it is the user responsability to add the blocks
in an order that has some logic.

We recommend using project builders in order to make life easier for those who
want to create workfront projects using this library. This allows user to
re-use the code logic used to create particular workfront projects.

## Using Project Builders

To easily create projects you can use project builders. Project builders provide
a simple interface with setters to create different projects structures.

So for example, to create a simple email project with 2 test list and 1 seed
list you will do something similar to this:

from workfront.workfront import Workfront
from workfront_bridge.projects.email_builder import EmailProjectBuilder

# Create a Workfront Service object (using the workfront-sdk)
wf = Workfront("", "pass***")

# A project builder needs a Workfront service and a name to be constructed
builder = EmailProjectBuilder(wf, "Project Test Name")

# Then, the subject and a html is needed to be validated:
.set_subject("This is the subject!")
# In the case of email builder you can use a zip to construct the html. In that
# case you will use this:
# b.set_html_zip("s3://some/s3/path/")

# Then, add two test list and a live seed list

# Finally, build and obtain the Workfront project
wf_project =
# When calling build a WFBrigeException can arise telling you if some
# parameters are missing, or something is wrong.

Project details

Release history Release notifications | RSS feed

This version


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

workfront-bridge-0.1.tar.gz (11.5 kB view hashes)

Uploaded source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page