Lesson 14 - 3rd Party Python Packages¶
Goal¶
In this lesson we’ll learn how to import 3rd party Python packages to
use in an operation’s python_script action.
Get Started¶
We’ll be installing our 3rd party Python package in this lesson using pip. If you don’t already have pip installed on your machine, see the pip documentation. We’ll also need to add a requirements.txt file to a python-lib folder which is at the same level as the bin folder that the CLI executable resides in.
The folder structure where the CLI executable is should look something like this:
- cslang
- bin
- cslang
- cslang.bat
- content
- CloudSlang ready-made content
- lib
- includes all the Java .jar files for the CLI
- python-lib
- requirements.txt
- bin
And finally, we’ll need a new file, fancy_text.sl in the tutorials/hiring folder, to house a new operation.
Requirements¶
In the requirements.txt file we’ll list all the Python packages we need for our project. In our case we’ll add a package that will allow us to create large lettered strings using ordinary screen characters. The package is called pyfiglet. A quick search on PyPI tells us that the current version (at the time this tutorial was written) is 0.7.2, so we’ll use that one. We also need to install setuptools since pyfiglet depends on it. Each package we need takes up one line in our requirements.txt file.
pyfiglet == 0.7.2
setuptools
Installing¶
Now we need to use pip to download and install our packages.
To do so, run the following command from the python-lib directory:
pip install -r requirements.txt -t .
Note: If your machine is behind a proxy you’ll need to specify the proxy
using pip‘s --proxy flag.
If everything has gone well, you should now see the pyfiglet package’s files in the python-lib folder along with the setuptools files.
Operation¶
Next, let’s write an operation that will let us turn normal text into
something fancy using pyfiglet. All we need to do is import
pyfiglet as we would normally do in Python and use it. We also have
to do a little bit of work to turn the regular string we get from
calling renderText into something that will look right in our HTML
email.
namespace: tutorials.hiring
operation:
name: fancy_text
inputs:
- text
action:
python_script: |
from pyfiglet import Figlet
f = Figlet(font='slant')
fancy = '<pre>' + f.renderText(text).replace('\n','<br>').replace(' ', ' ') + '</pre>'
outputs:
- fancy
Note: CloudSlang uses the Jython implementation of Python 2.7. For information on Jython’s limitations, see the Jython FAQ.
Task¶
Now we can create a task in the new_hire flow to send some text to
the fancy_text operation and publish the output so we can use it in
our email. We’ll put the new task between print_finish and
send_mail.
- fancy_name:
do:
fancy_text:
- text: first_name + ' ' + last_name
publish:
- fancy_text: fancy
Use It¶
Finally, we need to change the body of the email to include our new fancy text.
- send_mail:
do:
mail.send_mail:
- hostname
- port
- from
- to
- subject: "'New Hire: ' + first_name + ' ' + last_name"
- body: >
fancy_text + '<br>' +
'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '<br>' +
'Missing items: ' + missing + ' Cost of ordered items: ' + str(total_cost)
navigate:
FAILURE: FAILURE
SUCCESS: SUCCESS
Run It¶
We can save the files and run the flow. When the email is sent it should include the new fancy text we added to it.
run --f <folder path>/tutorials/hiring/new_hire.sl --cp <folder path>/tutorials/base,<folder path>/tutorials/hiring,<content folder path>/base --i first_name=john,last_name=doe --spf <folder path>/tutorials/properties/bcompany.yaml
Up Next¶
In the next lesson we’ll see how to use an asynchronous loop.
New Code - Complete¶
new_hire.sl
namespace: tutorials.hiring
imports:
base: tutorials.base
mail: io.cloudslang.base.mail
flow:
name: new_hire
inputs:
- first_name
- middle_name:
required: false
- last_name
- missing:
default: "''"
overridable: false
- total_cost:
default: 0
overridable: false
- order_map: >
{'laptop': 1000, 'docking station':200, 'monitor': 500, 'phone': 100}
- hostname:
system_property: tutorials.hiring.hostname
- port:
system_property: tutorials.hiring.port
- from:
system_property: tutorials.hiring.system_address
- to:
system_property: tutorials.hiring.hr_address
workflow:
- print_start:
do:
base.print:
- text: "'Starting new hire process'"
- create_email_address:
loop:
for: attempt in range(1,5)
do:
create_user_email:
- first_name
- middle_name
- last_name
- attempt
publish:
- address
break:
- CREATED
- FAILURE
navigate:
CREATED: get_equipment
UNAVAILABLE: print_fail
FAILURE: print_fail
- get_equipment:
loop:
for: item, price in order_map
do:
order:
- item
- price
publish:
- missing: self['missing'] + unavailable
- total_cost: self['total_cost'] + cost
navigate:
AVAILABLE: print_finish
UNAVAILABLE: print_finish
- print_finish:
do:
base.print:
- text: >
'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '\n' +
'Missing items: ' + missing + ' Cost of ordered items: ' + str(total_cost)
- fancy_name:
do:
fancy_text:
- text: first_name + ' ' + last_name
publish:
- fancy_text: fancy
- send_mail:
do:
mail.send_mail:
- hostname
- port
- from
- to
- subject: "'New Hire: ' + first_name + ' ' + last_name"
- body: >
fancy_text + '<br>' +
'Created address: ' + address + ' for: ' + first_name + ' ' + last_name + '<br>' +
'Missing items: ' + missing + ' Cost of ordered items:' + str(total_cost)
navigate:
FAILURE: FAILURE
SUCCESS: SUCCESS
- on_failure:
- print_fail:
do:
base.print:
- text: "'Failed to create address for: ' + first_name + ' ' + last_name"
fancy_text.sl
namespace: tutorials.hiring
operation:
name: fancy_text
inputs:
- text
action:
python_script: |
from pyfiglet import Figlet
f = Figlet(font='slant')
fancy = '<pre>' + f.renderText(text).replace('\n','<br>').replace(' ', ' ') + '</pre>'
outputs:
- fancy