Predix Python SDK 1.0 Release Roundup

Jayson DeLancey
5 min readMar 21, 2018

--

The GE Digital Volcano App came out last summer with an early version of the Predix Python SDK known as PredixPy. This is a client library that is ready to help Python developers get started with many Predix Services in 10 lines of code or less.

This newest release candidate includes:

  • verified to work on Python 3.6 and Python 2.7
  • allows you to encrypt your manifest configuration files
  • provides more flexibility for object initialization
  • supports Predix Cache (Redis)
  • supports Predix Database as a Service (PostgreSQL)
  • supports Predix Event Hub
  • supports UAA user management CRUD operations
  • more unit and integration test coverage
  • bug fixes, performance improvements, more documentation

That’s enough change that this can be called version 1.0. If you find the project to be useful, please check it out on GitHub at PredixDev/predixpy and let us know what you like or want to see from the project.

MCVE

As a best practice for asking questions on Stack Overflow you frequently should provide a Minimal, Complete, and Verifiable Example to demonstrate a problem. For the rest of this post, I’d like to provide MVCEs for solutions that PredixPy can now provide.

You can find many more examples in the PredixPy Cookbook.

Manifest Encryption

If you are pushing apps to Cloud Foundry, chances are you will have a manifest.yml file. PredixPy is flexible enough that you don’t have to store configuration details in the manifest, but it’s there so that is the default place the SDK looks for reading/writing details like uris, Predix-Zone-Id and client id/secrets.

This can make some developers uncomfortable that the manifest could be checked into a public source code repository with the credentials exposed. The Predix App Framework that is part of PredixPy now allows you to encrypt those values by adding a parameter when you initialize the Manifest.

In [1]: import predix.admin.app
In [2]: admin = predix.admin.app.Manifest(encrypted=True)

By default it will not encrypt them and you need to pass them to your app afterall anyway but you will see a warning about it.

In [3]: admin.write_manifest('manifest.secrets.yml', encrypted=False)
WARNING:root:Writing manifest manifest.yml unencrypted.
In [4]: admin.write_manifest('manifest.yml', encrypted=True)

I still wouldn’t check it into a public repository, but at least it can be encrypted while at rest.

In addition to encrypting the manifest, I get tired of coming up with client ids and secrets all the time. The docs often show the following example:

admin.create_client('client-id', 'client-secret')

These are now keyword arguments so you can continue to pass them in the original order yourself, or allow the SDK to generate a guid to use as the client id and a cryptographically-secure pseudorandom letter, digit, punctuation generator as a temporary secret that meets password guidelines.

admin.create_client()

That should clean up some of the samples that are tempting to copy and paste without changing example client ids and secrets.

Service Object Initialization

PredixPy tries to make greenfield projects easy by giving control of the whole service instance lifecycle from creation / provisioning to data ingestion and consumption. Some projects don’t need all that automation, so now there is a bit more flexibility in using any of the services from Python.

The parameters needed can be passed in as keyword arguments like the following example demonstrates:

In [1]: import predix.security.acsIn [2]: acs = predix.security.acs.AccessControl?
Init signature: predix.security.acs.AccessControl(uri=None, zone_id=None, *args, **kwargs)

You can explicitly pass whatever uri and zone_id you want to use. If you don’t pass any values, the default behavior is to:

  • Check if VCAP variables are defined (as they would be in the Predix Cloud for bound services)
  • Check for PredixPy environment variables, which are defined in the manifest.yml if you used PredixPy to create the service initially

This is all described in the Getting Started Concepts but works more consistently across all the supported services now.

Redis and PostgreSQL

You can now create these data management services by scripting it in Python:

import predix.admin.app
admin = predix.admin.app.Manifest()
admin.create_cache()
admin.create_dbaas()

Creating Predix Cache and Predix Database as a Service are asnchronous paid services so it can take several minutes for the instances to be provisioned and available for use. There are parameters for you to override the default names and plans if you care about those settings.

If you are unfamiliar with GoTTY, please check out my post Go Inside the Container to learn how you can setup a bash shell to work with redis-cli and psql. More importantly, you can use this bash shell to test any Python scripting you do when working with these services to help you develop faster. The PredixPy SDK primarily helps you establish the connection and everything else works the same way as the popular Python redis and sqlalchemy libraries document.

Event Hub

If you prefer to listen, you can find out a bit more about Event Hub from this introductory video:

A common use case for the service is supporting Event-Oriented Architectures that have a Pub-Sub pattern coming from machines. If you are familiar with services like RabbitMQ some of the differences with Event Hub come down to protocol and message contract.

You can get started by creating the service. You will need a UAA instance and client with appropriate scopes and authorities, but PredixPy handles those details.

import predix.admin.app
admin = predix.admin.app.Manifest()
admin.create_uaa('admin-secret-ab')
admin.create_client('client-id-bc', 'client-secret-mb')
admin.create_eventhub(publish=True, subscribe=True)

To subscribe to messages, you just listen and wait:

import predix.app
app = predix.app.Manifest()
eh = app.get_eventhub()
for msg in eh.subscriber.subscribe():
print(msg)

To publish messages, you just queue it up and publish.

import predix.app
app = predix.app.Manifest()
eh = app.get_eventhub()
for i in range(10, 0, -1):
msg_id = str(i)
msg_body = 'Final Countdown {}'.format(msg_id)
eh.publisher.add_message(msg_id, msg_body)
eh.publisher.publish_queue()

Pretty straightforward eh?

Cloud Foundry Automation

PredixPy is primarily a client library for working with Predix APIs. Since Predix Services are running in a Cloud Foundry ecosystem, the scope of the SDK creeped into things like test automation and cloud foundry management.

You can run cf commands or use the predix cli to get work done, but I am always looking for ways to automate and don’t particularly like writing bash scripts.

Here’s a collection of fun CF tricks:

import predix.admin.app
admin = predix.admin.app.Manifest()
# Get a list of marketplace services
print(admin.space.get_services())
# Create a space, name it something unique, then target it
import predix.admin.cf.spaces
predix.admin.cf.spaces.create_temp_space()
print(admin.space.name)
# Invite my team to join the fun
admin.space.org.add_user('my-team@ge.com')
print(admin.space.org.get_users())

It’s not a complete Cloud Foundry Client API but does offer some of the more common things that have come up as useful to automate.

PredixPy 1.0

That’s a taste of what’s new in PredixPy 1.0. There are still more services to be added and not every feature of the services is available yet, but it should still be able to get you through 80% of the most common use cases.

This is an open-source community SDK, so if you see something wrong — raise an issue or fork and submit a PR.

Hope that helps.

--

--

Jayson DeLancey

Manage Developer Relations @Dolby; Maker at Robot Garden; Previously HERE, GE, Rackspace, DreamWorks Animation, MathWorks, Carnegie Mellon