How to Get Started with Code (Python) on Zapier#

Looking for Javascript instead of Python? Visit our Code (Javascript) documentation.

Introduction#

With Zapier's Code action you can extend our platform to do just about anything using one of the simplest programming languages available - Python! Run code in response to any trigger that Zapier supports.

Some example use cases include:

  • Transform incorrect dates or convert between other data types.
  • Use custom regular expressions to extract extra data like emails or tracking numbers from large text blobs.
  • Make an extra API call to a different service with requests without building a full dev app.
  • Augment data from a trigger with extra data from some other source (either generated or external API).
  • Anything else you can dream up!

Warning - this is advanced stuff! You probably need to be a programmer to use this - though you are welcome to play with it. Technical support for bugs in your code is not provided!

How does it work?#

The environment is vanilla Python 2.7.10. Your script is sandboxed and can only run for a limited amount of time and within a limited amount of memory. If you exceed those limits - your script will be killed (you can upgrade to a paid Zapier to increase your limits).

Since the amount of data that might feed into your script might be large or highly dynamic - you'll need to define an input mapping via our GUI. This is a really simple step - the screenshot below shows a very basic example:

Scroll to the examples section to see an assortment of starter scripts.

In your code you will have access to a few variables:

Data Variables#

  • input_data The dictionary of data you did right above your code snippet (not available in triggers). All values will be strings.
  • output A dictionary or list of dictionaries that will be the "return value" of this code. You can explicitly return early if you like. This must be JSON serializable!

Note: you may see old code examples using input which we changed to input_data to reduce confusion. Both work - but we prefer the less confusion input_data since input was a built in function for Python!

Utilities#

  • requests An easy to use HTTP client - read the documentation here.
  • StoreClient An easy to use database or cache for stashing key & values to maintain state between runs - read the documentation here.
  • print Super helpful if you want to debug your function - you'll need to test your zap to see the values (the logs are returned to you in a runtime_meta added automatically to your output).

Testing/Debugging#

Running your zap via the dashboard or the editor is the canonical way to confirm the behavior you expect - your Task History will have all relevant details around the ran code's input_data, output and logs. Step 6 (the test step) in the editor can be used for a tighter feedback loop.

Try asking for by tagging questions as Zapier on Stackoverflow!

↑ Was this documentation useful? Yes No (Suggest Edits)

Code (Python) Examples#

Important! Every example depends on specific input_data - which is provided under the "Input Data" field when setting up your - this example screenshot shows three demonstration inputs you can use in your code like this: input_data['body'], input_data['name'], and input_data['subject']. Be sure you read the code examples and provide the right inputs otherwise nothing will work as expected!

In this section we provide some examples - it is important to note that Python is an advanced programming language - if you get lost it might make sense to ask a programmer friend or learn python yourself.

Introductory Examples#

Each of the four examples below expects a name in the "Input Data" field.

A easy example might be something as trivial as:

return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}

You can also bind the result to output - the code above has exactly the same behavior as the code below:

output = {'id': 1234, 'hello': 'world!', 'name': input_data['name']}

You'll notice that when it comes to code - you can solve the same problems in hundreds of unique ways!

An example with an early empty return might be something as trivial as:

if input_data['name'] == 'Larry':
    return [] # we don't work for Larry!

return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}

If you return an empty list [], we will not trigger any actions downstream that depend on the code step's output (they will be halted). However, other steps that don't depend on the code step's output will still run unless a filter stops the Zap from going further.

Introductory HTTP Example#

A more complex example (no "Input Data" needed):

response = requests.get('http://example.com/')
response.raise_for_status() # optional but good practice in case the call fails!
return {'id': 1234, 'rawHTML': response.text}

Introductory Logging Example#

This example expects a name in the "Input Data" field:

if input_data.get('name'):
    print 'got name!', input_data['name']

return {'id': 1234, 'hello': 'world!', 'name': input_data['name']}

Test your action and look at the data to see the print result - great for debugging your code!

Simple Math - Divide by Two#

This example expects a rawNumber in the "Input Data" field:

return {
  'calculatedNumber': int(input_data['rawNumber']) / 2
}

Simple Email Extraction#

This example expects a rawText in the "Input Data" field:

import re
emails = re.findall(r'[\w._-]+@[\w._-]+\.[\w._-]+', input_data['rawText'])
return {
    'firstEmail': emails[0] if emails else None
}

Complex Multiple Email Extraction#

This example expects a rawText in the "Input Data" field:

import re
emails = re.findall(r'[\w._-]+@[\w._-]+\.[\w._-]+', input_data['rawText'])
return [
    {'email': email} for email in emails
]

This will trigger multiple downstream actions - one for each email found! If no emails are found - nothing happens.

Formatting a Comma Separated List#

There may be cases where you need to create a comma separated list but you need to eliminate the blank values from the list. This snippet will help you create the list and remove blanks. This example expects a values entry in the "Input Data" field like this:

import re
values = re.sub('(^,+|,+$)', '', input_data['values'])
values = re.sub(',+', ',', values)
return [{'values': values}]

Weather JSON API Call#

This example expects a zipCode in the "Input Data" field:

zc = input_data['zipCode']
url = 'http://api.openweathermap.org/data/2.5/weather?zip=' + zc + ',us'
response = requests.get(url)
response.raise_for_status() # optional but good practice in case the call fails!
return response.json()

Store State#

It isn't uncommon to want to stash some data away for the next run, our StoreClient can do exactly that. For example - this is a counter that counts how many times it is ran:

store = StoreClient('some secret')

count = store.get('some counter') or 0
count += 1
store.set('some counter', count)
return {'the count': count}

Only Once Per Hour#

In conjunction with a Filter step, you could use code like this to limit the number of times your zap can run per hour (which is configurable):

every_seconds = 60 * 60

store = StoreClient('some secret')

import time
now = int(time.time())
last_post = store.get('last_post') or now - every_seconds + 1

output = {'run': 'no'}
if last_post < (now - every_seconds):
    output = {'run': 'yes'}
    store.set('last_post', now)

  # don't forget to set up a filter after this that checks if run is exactly yes

Note! Without a follow up Filter step this won't work!

↑ Was this documentation useful? Yes No (Suggest Edits)

StoreClient (Python)#

Storing and retrieving data with StoreClient is very simple.

There is no need to import it - it comes pre-imported in your Code environment.

You will need to provide a secret that will protect your data. I recommend using Random.org's excellent password generator. Be very sure you pick a complex secret - if anyone guesses it they'll be able to read and write your data!

Instantiating a client is very simple:

store = StoreClient('your secret here')

Most likely you just want to get and set some values - this is the simplest possible example:

store = StoreClient('your secret here')
store.set('hello', 'world')
value = store.get('hello') # return 'world'
store.delete('hello')

If the value doesn't exist during your get() call - it will return a None value.

Bulk Operations#

You can also save and retrieve multiple keys and values - a slightly more complex example:

store = StoreClient('your secret here')
store.set_many({'hello': 'world', 'foo': 'bar'})
values = store.get_many('hello', 'foo') # return {'hello': 'world', 'foo': 'bar'}
store.delete_many('hello', 'foo')
store.clear() # or, if you want to wipe everything

Note, you can call get_many and delete_many in a few different ways:

store.get_many('hello', 'foo') # as args
store.get_many(['hello', 'foo']) # as list
store.get_many({'hello': None, 'foo': None}) # as dict

And similarly with set_many:

store.set_many({'hello': 'world', 'foo': 'bar'}) # as dict
store.set_many(hello='world', foo='bar') # as kwargs

Limitations#

  • Any JSON serializable value can be saved.
  • The secret must be under 32 chars in length.
  • Every key must be under 32 chars in length.
  • Every value must be under 2500 bytes.
  • Only 500 keys may be saved per secret.
↑ Was this documentation useful? Yes No (Suggest Edits)

Common Problems with Code (Python) on Zapier#

I need help!#

Try asking for by tagging questions as Zapier on Stack Overflow!

Requiring or Using External Libraries#

Unfortunately you cannot require external libraries or install libraries commonly referred to as "pip modules". Only the standard Python library and requests is available in the Code app and requests is already included in the namespace.

Time & Memory Limits#

Free users are limited to 1 second and 128mb of RAM. Paid users get well over double that at 10 seconds and 256mb of RAM. Your Zap will hit an error if you exceed these limits.

My Floats Get Converted to Integers (or vice versa)!#

If you have a python code step that returns a value like this:

return {'result': 1.0}

it may appear up as 1 (not 1.0) in task history and test results. This is an artifact of the UI. The Zapier web UI does not distinguish between int and float values; they are all just numbers. In your Python code step you can use int(aNumber) or float(aNumber) to make sure to convert the value to the data type you require.

I am getting various SyntaxError's, NameError's or other weird bugs.#

Python is a fairly complex language and you should probably be a programmer or willing to dedicate some serious time to learn to code - while we can't help you fix your code, try asking for by tagging questions as Zapier on Stack Overflow.

↑ Was this documentation useful? Yes No (Suggest Edits)

Popular Things to Do with Code (Python) on Zapier#

Coming soon!

Get Help