The MQ Light team recently announced the availability of the Early Access version of the MQ Light Python client.

This blog covers developing and deploying Python apps using the MQ Light Service for Bluemix and the MQ Light API. By following the steps below, you will be able to get a sample up and running, see worker-offload in action, understand how it works, and get started with developing your own Python apps using the MQ Light Service for Bluemix.

The MQ Light for Bluemix service is deprecated from 9 August 2017. See the MQ Light retirement schedule blog for more information. As an alternative, you can use the MQ Light API in Message Hub.

The following blog posts cover getting started with MQ Light Service for Bluemix for various languages:

If you have read any of these blogs, then a few parts of this post are going to be familiar to you, such as what the sample is meant to do, or the Bluemix-related content. You can skip those bits, and focus on the Python specific details. At the end of this blog, there is a section on getting the Liberty for Java and Python apps to talk with each other!

Tip: For more information about MQ Light in Bluemix, see IBM Bluemix: Getting started with IBM MQ Light.

Where can I get the sample?

This sample is available here.

  • Click on Download ZIP – this will download a Zip file containing pre-built versions of the Python sample. If you just want to try out the sample and have a quick look at the source code, this is the best option.
  • Use Git to clone the repository:
    git clone https://github.com/ibm-messaging/mqlight-python-bluemix
    

What is this sample about?

The sample app is actually composed of two simple apps: a web front-end that sends messages to a back-end where they are processed (the processing does a simply action of capitalizing the words), and then returned to the front-end. In Bluemix, your app will look something like this, depending on what back-ends you have running:

screenshot1_python

This sample illustrates:

  • How easy it is to get disjointed apps talking to each other using the MQ Light Service.
  • How the MQ Light Service can be used to perform worker-offload, providing benefits such as:
    – the front-end will remain responsive while the back-end is processing your data (in this sample the actual processing is not very intensive, but imagine if your application had to process a heavy workload, such as a video!)
    – the number of instances of the back-end app can be scaled to have several workers processing the front-end requests to get the work done much more quickly.

You can also do more advanced stuff, like having several back-end apps in different languages processing the workload from the front-end, but let’s take one step at a time – let’s see the sample in action!

How do I get it running on Bluemix?

If this is the first time that you are going to deploy an app to Bluemix, you will need to:

  1. If you don’t already have an account, sign up for IBM Bluemix.
  2. Install and setup the Cloud Foundry command line interface by following these instructions, which will enable you to manage your Bluemix applications from your machine (don’t forget to cf login)
  3. You will have to create an MQ Light Service instance that your apps can use when they are deployed to Bluemix:
    cf cs MQLight standard MQLight-sampleservice
  4. Now you’ll have an MQ Light service instance named MQLight-sampleservice, using the standard plan. You are now ready to push the apps themselves, so navigate to the root directory where you downloaded the apps, and run:
    cf push

Firstly, this uploads the app files themselves, then it sorts out all of the setup for you, taking information from the requirements.txt file to download the Python dependencies (there is a requirements.txt file in each sample). This command also binds the service you created to both the apps which were pushed, and starts them up.

Tip: To do all this, this command uses the manifest.yml that is in the root directory to facilitate the deployment. This file is optional, but avoids having to specify all of the arguments each time you run the command (another tip: have a look at cf push -h if you want to specify these manually):

  • name is the name of your application in Bluemix.
  • disk is how much disk space your application have.
  • command is the command that is run to start your app once it is setup in Bluemix. In this case, it is the same command you used to start them locally.
  • path is the path to the app on your local machine.
  • memory is how much RAM you assign the app.
  • instances indicates how many instances of the app Bluemix creates – this is only relevant to the back-end worker.
  • no-route indicates that the back-end does not need a route (URL) created for it.
  • host indicates the route (URL) to create for the front-end (i.e. where the web app is available). Note that ${random-word} generates a random word that should lower the chances of trying the create an already taken route.
  • services lists the services that you want to bind the app to upon creation. In this case it is the MQ Light service you created in the previous step.

When it’s done, you can run the cf apps command or check your Bluemix dashboard to see the apps running:

screenshot2_python

Head to the URL listed along with the front-end in the cf apps command or in your Bluemix dashboard and if everything went well, you will see the front-end, as presented in the screen shot in the Sample app section. When you click the ‘Submit work’ button, the app publishes messages to the mqlight/sample/words topic, which are received and processed by the back-end workers (we deployed two of them when we used cf push), and returned capitalized:

screenshot4_python

Now that the app has been successfully deployed to Bluemix… how does it actually work? Have a look at the following section if you are interested.

What’s under the covers?

Looking at frontend/python-frontend.py, you can get an idea of what is going on. Early on, you can check to see whether you’re running in Bluemix by checking for the presence of VCAP_SERVICES. If you find it, you can grab the necessary details from Bluemix, otherwise you can run it locally and use the default local settings.

if os.environ.get('VCAP_SERVICES'):
    vcap_services = os.environ.get('VCAP_SERVICES')
    decoded = json.loads(vcap_services)['mqlight'][0]
    service = str(decoded['credentials']['connectionLookupURI'])
    username = str(decoded['credentials']['username'])
    password = str(decoded['credentials']['password'])
    security_options = {
        'property_user': username,
        'property_password': password
    }
else:
    service = 'amqp://127.0.0.1:5672'
    security_options = {}

You can then start the MQ Light client using these options:

client = mqlight.Client(
    service=service,
    client_id=CLIENT_ID,
    security_options=security_options,
    on_started=subscribe)

Here you can see the app subscribing, and specifying process_message as the callback that is called when a message arrives::

client.subscribe(
        topic_pattern=SUBSCRIBE_TOPIC,
        share=SHARE_ID,
        on_message=process_message)

Now that you understand how this sample works, are you ready to develop your own Python apps? The next section gives a few tips about how to do that.

Developing your own Python apps for Bluemix

When writing your own app (which can be based on this sample if it helps!), you can either modify the source code and push your apps to Bluemix to test them… or you can install MQ Light onto your own machine and test it locally! This way, you can test out your apps more efficiently, and once you feel that your app is ready, get it deployed onto Bluemix. Here is a quick guide explaining how you can get the sample running on your own machine. You should be able to follow very similar steps for your own apps.

  1. Take a look at Getting started with MQ Light, and ensure that you have MQ Light and Python set up on your machine as described. When you have completed this process and started MQ Light, you will have a web browser open up automatically with the MQ Light Web UI.
  2. Clone the sample repository:
    git clone https://github.com/ibm-messaging/mqlight-python-bluemix.git
  3. Enter the directory where you’ve pulled the samples in:
    cd mqlight-python-bluemix
  4. (Optional, but good practice) Make a virtual Python environment:
    virtualenv .
  5. Pull the dependencies (As both samples have the same dependencies you only need to do it in one of them):
    pip install -r ./frontend/requirements.txt
  6. Start the frontend:
    python ./frontend/python-frontend.py
  7. Start the backend:
    python ./backend/python-backend.py

Note
In the samples, both applications use the same port (8000). This works fine in Bluemix, but for local usage you need to change the port of one of them. For example, the code below is in both python-backend.py, and python-frontend.py:

if __name__ == '__main__':
    port = int(os.getenv('PORT', '8000'))
    bottle.run(host='0.0.0.0', port=port)

Once started, each sample should output:

Bottle v0.12.8 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:8000/
Hit Ctrl-C to quit.

You can point your browser to the address to access the application.

Troubleshooting your own Python apps for Bluemix

To troubleshoot your Python apps using the MQ Light Service for Bluemix, there are two useful sources of information: the MQ Light UI, available both on your local MQ Light installation and for the MQ Light Service for Bluemix, and the logs from your Bluemix apps.

To get to the MQ Light UI:

  • For your app running locally: it should have been fired up when you started MQ Light, but if you closed it, point your browser to localhost:9180
  • For your app running on Bluemix: login to the Bluemix Web UI, and from the Dashboard, click on your instance of the MQ Light Service.

In both cases, you will be able to see senders appearing on the left-hand side, and receivers on the right-hand side, with any messages flowing in the middle.

For example, going back to the sample, after clicking on the ‘Submit work’ button, you should see something similar to the screenshot below. You can click on ‘Topic List’ for senders and on ‘Details’ for receivers to get more information about the connected applications. Click on ‘Details’ in any of the messages to get some more information on it, such as the payload, who sent it, to where, and whether or not anyone is waiting for it. This is perfect for troubleshooting messaging applications as you can see what your messages are actually doing.

screenshot3_python

To see the logs generated by your app on Bluemix, you can use the cf logs command:

  • To tail your logs as they are being generated (from a separate command prompt while pushing for example)
  • To see your app’s most recent logs using the --recent option

Tips:

  • Only the logs following the latest app startup will be shown.
  • If you have several instances of an app running, use the drop down box next to ‘Instances’ (under ‘Files and logs’) to see the logs from each of them

Working with the Liberty for Java sample

If you have already gone through the Getting started with Liberty for Java apps using the MQ Light Service for Bluemix, then you will have a Python back-end app hooked into the same instance of the MQ Light service. If those are stopped, and you have only your Liberty for Java apps started (ie. your Python apps are stopped), you should see the following when you click the button:

screenshot6_python

As you can see, it is only the Liberty for Java back-end that is doing the work. If you start the Python back-end you created above and click the button, you should then see something like:

screenshot5_python

This time, each message sent by the Python front-end is processed by both the Liberty for Java and the Python back-ends. Head over to your Liberty for Java front-end and you should see the same thing. And just like that, you’ve got Liberty for Java and Python apps talking to each other. Nice.

The way this works is:

  • JMS publish/subscribe inter-works between JMS and Python.
  • JMS topic names are the same as Python topic names.

    In Python, the topics are simply defined in the application files, for example, in the front-end app:

    SUBSCRIBE_TOPIC = 'mqlight/sample/wordsuppercase'
    PUBLISH_TOPIC = 'mqlight/sample/words'
  • In Liberty for Java, topics are specified in the server.xml file:

    <jmsTopic id="jms/BackEndWorkerListenTopic" jndiName="jms/BackEndWorkerListenTopic">
       <properties.wmqJms baseTopicName="mqlight/sample/words"/>
    </jmsTopic>
    
    <jmsTopic id="jms/BackEndWorkerNotificationTopic" jndiName="jms/BackEndWorkerNotificationTopic>"
       <properties.wmqJms baseTopicName="mqlight/sample/wordsuppercase"/>
    </jmsTopic>
    

    In BackEndMDB.java:

    @MessageDriven(
            activationConfig = { @ActivationConfigProperty(
                    propertyName = "destinationType", propertyValue = "javax.jms.Topic"), @ActivationConfigProperty(
                    propertyName = "destination", propertyValue = "jms/BackEndWorkerListenTopic")
            }, 
            mappedName = "jms/as_MQLight-sampleservice")
    
  • The JMS equivalent of a shared destination, is enabled in JMS 1.1 by setting the cloneSupport option on the destination.

In this example, you can simply have every message being ‘processed’ twice (once by each back-end), but in reality you’ve got lots of options with this pattern. Perhaps a Python app could take messages and display them in a responsive web app, while a Liberty for Java app stores the same messages in a database or does analytics without affecting the responsiveness of your front-end at all. But what if you only want each message to be processed once? The MQ Light API supports the concept of ‘shares’ where multiple clients can be subscribed to the same destination, but each message is only received by a single client – this is perfect for scaling up to deal with heavy load and there are other workshops that deal with that particular scenario.

Join The Discussion

Your email address will not be published.