Create a Custom Actor

This guide will demonstrate how to create a custom actor from scratch.

In this example, we will build a simple actor that emails the message sent to it.

Components of an Actor

Make a new directory and add the following files:

$ mkdir email-actor/ && cd email-actor/

$ touch Dockerfile actor.py

$ tree ../email-actor/
email-actor/
├── Dockerfile
└── actor.py

0 directories, 2 files

Write the Actor Function

The actor.py python script is where the code for your main function can be found. An example of a functional actor that emails the message sent to it:

"""Send Email from Actor with User Message"""
from agavepy.actors import get_context
import smtplib
import os

# function to email the message
def email_message(m):
   """Send Email from Actor With User Message"""

   # grab the environment variables set
   useremail_from = os.environ.get('useremail_from')
   useremail_to = os.environ.get('useremail_to')
   userpassword = os.environ.get('userpassword')

   if m == " ":
       print("Empty Message!")
   else:
       sent_from = useremail_from
       to = [useremail_to]
       subject = 'Actor Email'
       message = m

       try:
           smtp_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
           smtp_server.ehlo()
           smtp_server.login(useremail_from, userpassword)
           smtp_server.sendmail(sent_from, to, message)
           smtp_server.close()
           print("Email sent successfully!")
       except Exception as ex:
           print("Exception occured",ex)


def main():
   """Main entry to grab message context from user input"""
   context = get_context()
   message = context['raw_message']
   email_message(message)

if __name__ == '__main__':
   main()

You can cut and paste the code block above into a new file called, e.g., pi.py, or download it from the following link:

https://raw.githubusercontent.com/shwetagopaul92/summer-institute-2021-tapis-actors/master/docs/scripts/email_actor/actor.py

This code makes use of the agavepy python library which we will install in the Docker container. The library includes an “actors” object which is useful to grab the message and other context from the environment. And, it can be used to interact with other parts of the Tapis platform. Add the above code to your actor.py file.

Here we are using the smtplib SMTP protocol client to send email to any Internet machine.

Define Environment Variables

We can use the -e flag to set (optional) environment variables for the actor at creation time. These variables will be part of the “context” taken from the environment, as in the example python script above. For our example, we will pass our Gmail username and password as environment variables to the actor. These environment variables will not be visible to anyone else. Alternatively this can be done using a secrets.json file.

Create a Dockerfile

The requirements are python, agavepy which is available through PyPi. A bare-bones Dockerfile needs to satisfy those dependencies, add the actor python script, and set a default command to run the actor python script. Add the following lines to your Dockerfile:

# pull base image
FROM python:3.6

# install requirements
RUN pip3 install agavepy

# add the python script to docker container
ADD actor.py /actor.py

# command to run the python script
CMD ["python", "/actor.py"]

Tip

Creating small Docker images is important for maintaining actor speed and efficiency

Build and Push the Dockerfile

The Docker image must be pushed to a public repository in order for the actor to use it. Use the following Docker commands in your local actor folder to build and push to a repository that you have access to:

Note

Make sure to replace taccuser with your Dockerhub username.

# Build and tag the image
$ docker build -t taccuser/email-actor:1.0 .
Sending build context to Docker daemon  4.096kB
Step 1/5 : FROM python:3.7-slim
...
Successfully built b0a76425e8b3
Successfully tagged taccuser/email-actor:1.0

# Push the tagged image to Docker Hub
$ docker push taccuser/email-actor:1.0
The push refers to repository [docker.io/taccuser/word-count]
...
1.0: digest: sha256:67cc6f6f00589d9ae83b99d779e4893a25e103d07e4f660c14d9a0ee06a9ddaf size: 1995