-
Notifications
You must be signed in to change notification settings - Fork 37
Service Wrapper
This sample demonstrates how simple it is to wrap an existing service and expose it on the DXL fabric.
In this particular case, the OpenWeatherMap “current weather” data is exposed as a DXL service. This service wrapper delegates to the OpenWeatherMap REST API.
The code for the sample is broken into two main sections.
The majority of code for the service wrapper is shown below:
# The OpenWeatherMap "Current Weather" URL (see http://openweathermap.org/current)
CURRENT_WEATHER_URL = "http://api.openweathermap.org/data/2.5/weather?{0}&APPID={1}"
# The "current weather" topic
SERVICE_CURRENT_WEATHER_TOPIC = "/openweathermap/service/openweathermap/current"
# Create the client
with DxlClient(config) as client:
# Connect to the fabric
client.connect()
#
# Register the service
#
# Create "Current Weather" incoming request callback
class CurrentWeatherCallback(RequestCallback):
def on_request(self, request):
try:
# Extract information from request
query = request.payload.decode(encoding="UTF-8")
logger.info("Service received request payload: " + query)
# Send HTTP request to OpenWeatherMap
req = URLRequest(
CURRENT_WEATHER_URL.format(query, API_KEY), None,
{'Content-Type': 'text/json'})
f = urlopen(req)
weather_response = f.read()
f.close()
# Create the response message
response = Response(request)
# Populate the response payload
response.payload = weather_response
# Send the response
client.send_response(response)
except Exception as ex:
print(str(ex))
# Send error response
client.send_response(ErrorResponse(
request, error_message=str(ex).encode(encoding="UTF-8")))
# Create service registration object
info = ServiceRegistrationInfo(client, SERVICE_NAME)
# Add a topic for the service to respond to
info.add_topic(SERVICE_CURRENT_WEATHER_TOPIC, CurrentWeatherCallback())
# Register the service with the fabric (wait up to 10 seconds for registration to complete)
client.register_service_sync(info, 10)
logger.info("Weather service is running...")
# Wait forever
while True:
time.sleep(60)
The service wrapper registers a RequestCallback
that will be invoked when "current weather" query Request
messages are received.
The actual query (which can be weather by zip code, location, city, etc.) is extracted from the Request
message's payload
attribute.
The OpenWeatherMap REST API is invoked via HTTP with the query that was received in the DXL request message's payload
.
A DXL Response
message is created with a payload
containing the result of invoking the OpenWeatherMap REST API and sent back to the invoking DXL client via the send_response()
method of the DxlClient
instance.
The following sample shows how the service shown above can be invoked over DXL.
# The "current weather" topic
SERVICE_CURRENT_WEATHER_TOPIC = "/openweathermap/service/openweathermap/current"
# Create the "Current Weather" request
req = Request(SERVICE_CURRENT_WEATHER_TOPIC)
# Populate the request payload
# Examples include:
# By ZIP code: zip=97140,us
# By geographic coordinates: lat=35&lon=139
# By city name: q=London,uk
req.payload = "zip=97140,us".encode()
# Send the request and wait for a response (synchronous)
res = client.sync_request(req)
# Extract information from the response (if an error did not occur)
if res.message_type != Message.MESSAGE_TYPE_ERROR:
response_dict = json.loads(res.payload.decode(encoding="UTF-8"))
print("Client received response payload: \n" + \
json.dumps(response_dict, sort_keys=True, indent=4, separators=(',', ': ')))
else:
logger.error("Error: %s (%s)", res.error_message, res.error_code)
A DXL Request
message is created and its payload
is set to the query (zip code, location, city, etc.) to perform against the OpenWeatherMap REST API.
A synchronous request is sent to the DXL service via the sync_request()
method of the DxlClient
instance.
The results of the query are extracted from the Response
that was received and displayed.
The output should appear similar to the following (query for the current weather for zip code 97140):
Client received response payload:
{
"base": "stations",
"clouds": {
"all": 0
},
"cod": 200,
"coord": {
"lat": 45.36,
"lon": -122.84
},
"dt": 1476216689,
"id": 5751632,
"main": {
"grnd_level": 1010.59,
"humidity": 66,
"pressure": 1010.59,
"sea_level": 1034.15,
"temp": 287.158,
"temp_max": 287.158,
"temp_min": 287.158
},
"name": "Sherwood",
"sys": {
"country": "US",
"message": 0.171,
"sunrise": 1476195849,
"sunset": 1476235829
},
"weather": [
{
"description": "clear sky",
"icon": "01d",
"id": 800,
"main": "Clear"
}
],
"wind": {
"deg": 83.0013,
"speed": 3.1
}
}
Data Exchange Layer (DXL) Overview
OpenDXL Python Client
SDK Modules
OpenDXL Python Client Examples
- Basic
- Advanced