Easy Mock Services with Atmo

In this post, I’ll introduce you to a super cool tool Atmo for simulating HTTP based APIs for development, testing, presentations or demos. You can consider Atmo as a Service Virtualization tool or a Mock server. Find out more about both the topics at https://www.infoq.com/articles/stubbing-mocking-service-virtualization-differences

There are many commercial service virtualization and open source tools & frameworks like SoapUI, Postman, MockServer, JSONServer, WireMock etc. available for creating Mock services or APIs. However, Atmo is my favourite because it is easy to setup and offers a highly intuitive user interface to define Mock services. You can either deploy a Mock service locally or in the cloud with Zeit.

Atmo is created by Raathigeshan Kugarajan. It comes in two flavours the original core built with React & JSONServer and the new standalone cross-platform Desktop version built with Electron and Express.

atmo-screen

In this post, you will see how to use the Desktop version of Atmo for setting up a simple Mock service returning JSON response.

Installation

Download the Windows or Mac Desktop app from http://getatmo.com and launch the app.

Creating a Project

With Atmo you can create a project to logically group the Mock services. For example, you’re working on multiple projects and want to create set of Mock services for each one of these projects.

On launch, Atmo will display a Dialog with options to Create a new Project or Open a saved project.

For this example let’s create a new project called ToDo App 

create_project

Define a Mock Service

After creating a new project Atmo will load an empty form to define a service. In this example, we will define an service or REST API endpoint to get a list of to-do items:

GET /todos
  1. In Url box enter todos
  2. Select GET operation from the drop-down
  3. Keep the default header for Content-Type. The Mock service will return a JSON list
  4. Select Response Type as JSON  (you have a choice to return XML, Simple Text or Custom response)
  5. Select OK as Response Code (since this a GET method)
  6. Enter sample JSON response that will be returned by the Mock service

create_endpoint

Now the newly defined service is ready to deploy.

Deploying Service

Atmo can either deploy the newly created service on localhost or you can deploy in Zeit. Let’s deploy this on the localhost.

  1. Save the newly created service
  2. Click on Deploy option from the sidebar
  3. Once the service is deployed, Atmo will show the Url in the header section. You can click on the link (for example http://localhost:9000/todos). This will open the default Browser and call the GET method. The Browser should display the raw JSON returned by the Mock service.

deploy

You can now use this service endpoint to mock a dependency in your application.

Here’s step-by-step recording –

You can do much more than a simple GET service with Atmo. You can add more logic or secure services using advanced project settings. You can deploy the services in Zeit cloud to share with other developers.

Atmo has helped me immensely in my Development and Testing workflows to create prototypes of the services for UI development or Mock the third party APIs during the development & testing.

Update – Recently one of my colleagues pointed me to Mockoon. It has similar features as Atmo and super easy to setup.

Cozmo, IFTTT and Jenkins Build Notifications

CozmoJenkins.png

Recently I bought Anki Cozmo. This little tiny robot is amazing and a great companion on your desk. Cozmo comes with a great personality. He is full of fun, he plays games with you, do tricks, animate and makes a lot of joy. Cozmo comes with a Camera that can detect faces and greet people and pets. It also has a SDK which allows you to customize Cozmo and create cool Apps and IoT connected programs.

In this post, I’ll show how to use Cozmo with my Jenkins IFTTT Build Notification plugin to send build notification to Cozmo. He will animate to these notifications and do some tricks like lighting up his cubes. This will make Cozmo an eXtreme Feedback Device

The Cozmo SDK comes with a bundle of examples and apps that you can play and modify. There is a bunch of examples that connect Cozmo to IFTTT and use different channels like Gmail or Sports news. I took the Gmail example and modified it to get Jenkins notifications. Here’s how this works on a high level:

Cozmo.png

Step 1 – Connecting Cozmo from IFTTT

In order to connect Cozmo from IFTTT, we need a computer running Cozmo exposed to the internet. You can do this either by using a static IP or using a tool like ngrok which sets up a secure tunnel to localhost running on your computer. To set up ngrok follow instructions from https://ngrok.com/download

Run this command to create a secure public URL for port 8080:

 ./ngrok http 8080 

Note the HTTP forwarding address shown in the terminal (e.g., http://4916890d.ngrok.io). This is required while creating the IFTTT applet.

ngrok.png

WARNING: Using ngrok exposes your local web server to the internet. See the ngrok   documentation for more information: https://ngrok.com/docs

Step 2 – IFTTT Jenkins Cozmo Script

Cozmo SDK is presently available in Python. The IFTTT examples use aiohttp module to create a web server with an endpoint with a handler to call the Cozmo SDK:

#!/usr/bin/env python3
# Copyright (c) 2016 Anki, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License in the file LICENSE.txt or at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Program modified by Unmesh Gundecha, http://unmesh.me
'''"If This Then That" Jenkins example
This example demonstrates how "If This Then That" (http://ifttt.com) can be used
make Cozmo respond when a Jenkins build job is completed. Instructions below
will lead you through setting up an applet on the IFTTT website. When the applet
trigger is called (which sends a web request received by the web server started
in this example), Cozmo will annouce the the Build status, play an animation and
light up the cubes.
Please place Cozmo on the charger for this example. When necessary, he will be
rolled off and back on.
Follow these steps to set up and run the example:
1) Provide a a static ip, URL or similar that can be reached from the If This
Then That server. One easy way to do this is with ngrok, which sets up
a secure tunnel to localhost running on your machine.
To set up ngrok:
a) Follow instructions here to download and install:
https://ngrok.com/download
b) Run this command to create a secure public URL for port 8080:
./ngrok http 8080
c) Note the HTTP forwarding address shown in the terminal (e.g., http://55e57164.ngrok.io).
You will use this address in your applet, below.
WARNING: Using ngrok exposes your local web server to the internet. See the ngrok
documentation for more information: https://ngrok.com/docs
2) Set up your applet on the "If This Then That" website.
a) Sign up and sign into https://ifttt.com
b) Create an applet: https://ifttt.com/create
c) Set up your trigger.
1. Click "this".
2. Select "Maker Webhooks" as your service.
3. Under "Choose a Trigger", select “Receive a Web request".
4. In "Recive a Web Request", enter "JenkinsBuild" as "Event Name"
5. Click "Create Trigger" button
d) Set up your action.
1. Click “that".
2. Select “Maker Webhooks" to set it as your action channel. Connect to the Maker channel if prompted.
3. Click “Make a web request" and fill out the fields as follows. Remember your publicly
accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field,
followed by "/iftttJenkins" as shown below:
URL: http://55e57164.ngrok.io/iftttJenkins
Method: POST
Content Type: application/json
Body: {"project" : "{{Value1}}", "build" : "{{Value2}}", "status": "{{Value3}}"}
5. Click “Create Action" then “Finish".
3) Test your applet.
a) Run this script at the command line: ./ifttt_jenkins.py
b) On ifttt.com, on your applet page, click “Check now”. See that IFTTT confirms that the applet
was checked.
4) Setup Jenkins Job – requires IFTTT Build Notification Plugin
a) In your Jenkins job "Post-build Action" section add a new "IFTTT Build Notifier"
action with following values:
Event Name: JenkinsBuild
Key: <Your Make Webhooks Key>
Note: You can get your unique Maker Webhooks Key from https://ifttt.com/services/maker_webhooks/settings
5) Run your Jenkins job to test the setup.
In response to the ifttt web request, Cozmo should roll off the charger, raise and lower
his lift, announce the status, and then animate and light-up the cubes.
'''
import asyncio
import re
import sys
try:
from aiohttp import web
except ImportError:
sys.exit("Cannot import from aiohttp. Do `pip3 install –user aiohttp` to install")
import cozmo
from common import IFTTTRobot
from cozmo.objects import LightCube1Id, LightCube2Id, LightCube3Id
app = web.Application()
async def serve_jenkins(request):
'''Define an HTTP POST handler for receiving requests from If This Then That.
You may modify this method to change how Cozmo reacts to the Jenkins build
notification
'''
json_object = await request.json()
# Extract the name of the project and build status.
project_name = json_object["project"]
status = json_object["status"]
robot = request.app['robot']
async def read_name():
try:
async with robot.perform_off_charger():
'''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
await robot.get_in_position()
# First, have Cozmo play an animation
await robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()
# Next, have Cozmo speak the name of the project and the build status.
if status == "SUCCESS":
await robot.say_text("Build for " + project_name + " is successful").wait_for_completed()
elif status == "FAILURE":
await robot.say_text("Build for " + project_name + " is failed").wait_for_completed()
else:
await robot.say_text("Build for " + project_name + " is completed" + status).wait_for_completed()
# Last, have Cozmo animate & Cubes flash light based on build status
await rock_n_roll(robot, status)
except cozmo.RobotBusy:
cozmo.logger.warning("Robot was busy so didn't receive status for: "+ project_name)
# Perform Cozmo's task in the background so the HTTP server responds immediately.
asyncio.ensure_future(read_name())
return web.Response(text="OK")
async def rock_n_roll(robot, status):
cube1 = robot.world.get_light_cube(LightCube1Id) # looks like a paperclip
cube2 = robot.world.get_light_cube(LightCube2Id) # looks like a lamp / heart
cube3 = robot.world.get_light_cube(LightCube3Id) # looks like the letters 'ab' over 'T'
if status == "SUCCESS":
light_color = cozmo.lights.green_light
await robot.play_anim_trigger(cozmo.anim.Triggers.PeekABooGetOutHappy).wait_for_completed()
elif status == "FAILURE":
light_color = cozmo.lights.red_light
await robot.play_anim_trigger(cozmo.anim.Triggers.FrustratedByFailure).wait_for_completed()
else:
light_color = cozmo.lights.blue_light
if cube1 is not None:
cube1.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube1Id cube – check the battery.")
if cube2 is not None:
cube2.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube2Id cube – check the battery.")
if cube3 is not None:
cube3.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube3Id cube – check the battery.")
await asyncio.sleep(10)
cube1.set_lights_off()import asyncio
import re
import sys
try:
from aiohttp import web
except ImportError:
sys.exit("Cannot import from aiohttp. Do `pip3 install –user aiohttp` to install")
import cozmo
from common import IFTTTRobot
from cozmo.objects import LightCube1Id, LightCube2Id, LightCube3Id
app = web.Application()
async def serve_jenkins(request):
'''Define an HTTP POST handler for receiving requests from If This Then That.
You may modify this method to change how Cozmo reacts to the Jenkins build
notification
'''
json_object = await request.json()
# Extract the name of the project and build status.
project_name = json_object["project"]
status = json_object["status"]
robot = request.app['robot']
async def read_name():
try:
async with robot.perform_off_charger():
'''If necessary, Move Cozmo's Head and Lift to make it easy to see Cozmo's face.'''
await robot.get_in_position()
# First, have Cozmo play an animation
await robot.play_anim_trigger(cozmo.anim.Triggers.ReactToPokeStartled).wait_for_completed()
# Next, have Cozmo speak the name of the project and the build status.
if status == "SUCCESS":
await robot.say_text("Build for " + project_name + " is successful").wait_for_completed()
elif status == "FAILURE":
await robot.say_text("Build for " + project_name + " is failed").wait_for_completed()
else:
await robot.say_text("Build for " + project_name + " is completed" + status).wait_for_completed()
# Last, have Cozmo animate & Cubes flash light based on build status
await rock_n_roll(robot, status)
except cozmo.RobotBusy:
cozmo.logger.warning("Robot was busy so didn't receive status for: "+ project_name)
# Perform Cozmo's task in the background so the HTTP server responds immediately.
asyncio.ensure_future(read_name())
return web.Response(text="OK")
async def rock_n_roll(robot, status):
cube1 = robot.world.get_light_cube(LightCube1Id) # looks like a paperclip
cube2 = robot.world.get_light_cube(LightCube2Id) # looks like a lamp / heart
cube3 = robot.world.get_light_cube(LightCube3Id) # looks like the letters 'ab' over 'T'
if status == "SUCCESS":
light_color = cozmo.lights.green_light
await robot.play_anim_trigger(cozmo.anim.Triggers.PeekABooGetOutHappy).wait_for_completed()
elif status == "FAILURE":
light_color = cozmo.lights.red_light
await robot.play_anim_trigger(cozmo.anim.Triggers.FrustratedByFailure).wait_for_completed()
else:
light_color = cozmo.lights.blue_light
if cube1 is not None:
cube1.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube1Id cube – check the battery.")
if cube2 is not None:
cube2.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube2Id cube – check the battery.")
if cube3 is not None:
cube3.set_lights(light_color)
else:
cozmo.logger.warning("Cozmo is not connected to a LightCube3Id cube – check the battery.")
await asyncio.sleep(10)
cube1.set_lights_off()
cube2.set_lights_off()
cube3.set_lights_off()
# Attach the function as an HTTP handler.
app.router.add_post('/iftttJenkins', serve_jenkins)
if __name__ == '__main__':
cozmo.setup_basic_logging()
cozmo.robot.Robot.drive_off_charger_on_connect = False
# Use our custom robot class with extra helper methods
cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot
try:
app_loop = asyncio.get_event_loop()
sdk_conn = cozmo.connect_on_loop(app_loop)
# Wait for the robot to become available and add it to the app object.
app['robot'] = app_loop.run_until_complete(sdk_conn.wait_for_robot())
except cozmo.ConnectionError as e:
sys.exit("A connection error occurred: %s" % e)
web.run_app(app)
cube2.set_lights_off()
cube3.set_lights_off()
# Attach the function as an HTTP handler.
app.router.add_post('/iftttJenkins', serve_jenkins)
if __name__ == '__main__':
cozmo.setup_basic_logging()
cozmo.robot.Robot.drive_off_charger_on_connect = False
# Use our custom robot class with extra helper methods
cozmo.conn.CozmoConnection.robot_factory = IFTTTRobot
try:
app_loop = asyncio.get_event_loop()
sdk_conn = cozmo.connect_on_loop(app_loop)
# Wait for the robot to become available and add it to the app object.
app['robot'] = app_loop.run_until_complete(sdk_conn.wait_for_robot())
except cozmo.ConnectionError as e:
sys.exit("A connection error occurred: %s" % e)
web.run_app(app)

view raw
ifttt_jenkins.py
hosted with ❤ by GitHub

Complete source code is available at https://github.com/upgundecha/cozmo-python-sdk

Step 3 – Creating IFTTT Recipe

IFTTT is a web service that lets you create chains of simple conditional statements, called applets. An applet is triggered by changes that occur within other web services such as Gmail, Facebook, Instagram, or Twitter. An applet may send an e-mail message if the user tweets using a hashtag or copy a photo on Facebook to a user’s archive if someone tags a user in a photo or it can trigger an support IoT device to a specific action.

In this example, we will create custom IFTTT Trigger and Action using Maker Webhooks feature.

  1. Sign up and sign into https://ifttt.com
    1. Create an applet: https://ifttt.com/create
    2. Set up your trigger.
      1.         Click “this”.
      2.         Select “Maker Webhooks” as your service.
      3.         Under “Choose a Trigger”, select “Receive a Web request”.
      4.         In “Receive a Web Request”, enter “JenkinsBuild” as “Event Name”
      5.         Click “Create Trigger” button
    3.     Set up your action.
      1.        Click “that”.
      2.        Select “Maker Webhooks” to set it as your action channel. Connect to the Maker channel if prompted.
      3.        Click “Make a web request” and fill out the fields as follows. Remember your publicly accessible URL from above (e.g., http://55e57164.ngrok.io) and use it in the URL field, followed by “/iftttJenkins” as shown below:

URL: http: // 55e57164.ngrok.io / iftttJenkins
Method: POST
Content Type: application / json
Body: {“project”: “{{Value1}}”, “build”: “{{Value2}}”, “status”: “{{Value3}}”

Click “Create Action” then “Finish”.

Here is video loop for above settings:

ifttt_maker.gif

Step 4 – Configuring Jenkins Build Job

Setup Jenkins Job – requires IFTTT Build Notification Plugin

In Jenkins job “Post-build Action” section add a new “IFTTT Build Notifier” action with following values:

  1. Event Name: JenkinsBuild
  2. Key: <Make Webhooks Key>

Note: You can get your unique Maker Webhooks Key from https://ifttt.com/services/maker_webhooks/setting

Finally, run the Jenkins job to test the setup. In response to the ifttt web request, Cozmo should roll off the charger, raise and lower his lift, announce the status, and then animate and light-up the cubes.

Here is video loop for above settings:

jenkins.gif

Running it together

Here’s video with Cozmo’s reaction to a passed build vs. a failed build:

You can also connect CI tools like Travis or Circle CI using curl command to Maker endpoint.
We can add more actions to this web server and make Cozmo thrill.