├── CONTRIBUTING.md ├── Images ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png └── 9.png ├── LICENSE ├── Python ├── .project ├── .pydevproject ├── device │ └── d2cMsgSender.py └── service │ └── deviceManager.py ├── README.md └── includes └── iot-hub-get-started-nav-tabs.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Azure samples 2 | 3 | Thank you for your interest in contributing to Azure samples! 4 | 5 | ## Ways to contribute 6 | 7 | You can contribute to [Azure samples](https://azure.microsoft.com/documentation/samples/) in a few different ways: 8 | 9 | - Submit feedback on [this sample page](https://azure.microsoft.com/documentation/samples/iot-hub-python-get-started/) whether it was helpful or not. 10 | - Submit issues through [issue tracker](https://github.com/Azure-Samples/iot-hub-python-get-started/issues) on GitHub. We are actively monitoring the issues and improving our samples. 11 | - If you wish to make code changes to samples, or contribute something new, please follow the [GitHub Forks / Pull requests model](https://help.github.com/articles/fork-a-repo/): Fork the sample repo, make the change and propose it back by submitting a pull request. -------------------------------------------------------------------------------- /Images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/1.png -------------------------------------------------------------------------------- /Images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/10.png -------------------------------------------------------------------------------- /Images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/11.png -------------------------------------------------------------------------------- /Images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/12.png -------------------------------------------------------------------------------- /Images/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/13.png -------------------------------------------------------------------------------- /Images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/2.png -------------------------------------------------------------------------------- /Images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/3.png -------------------------------------------------------------------------------- /Images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/4.png -------------------------------------------------------------------------------- /Images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/5.png -------------------------------------------------------------------------------- /Images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/6.png -------------------------------------------------------------------------------- /Images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/7.png -------------------------------------------------------------------------------- /Images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/8.png -------------------------------------------------------------------------------- /Images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/iot-hub-python-get-started/a73b6df49d0e664508188afc5f871efc9a50baa1/Images/9.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Python/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | IoTHubRestSample 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.python.pydev.pythonNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Python/.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /${PROJECT_DIR_NAME} 5 | 6 | python 2.7 7 | Default 8 | 9 | -------------------------------------------------------------------------------- /Python/device/d2cMsgSender.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module Name: d2cMsgSender.py 3 | Project: IoTHubRestSample 4 | Copyright (c) Microsoft Corporation. 5 | 6 | Using [Send device-to-cloud message](https://msdn.microsoft.com/en-US/library/azure/mt590784.aspx) API to send device-to-cloud message from the simulated device application to IoT Hub. 7 | 8 | This source is subject to the Microsoft Public License. 9 | See http://www.microsoft.com/en-us/openness/licenses.aspx#MPL 10 | All other rights reserved. 11 | 12 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 13 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 15 | """ 16 | 17 | import base64 18 | import hmac 19 | import hashlib 20 | import time 21 | import requests 22 | import urllib 23 | 24 | class D2CMsgSender: 25 | 26 | API_VERSION = '2016-02-03' 27 | TOKEN_VALID_SECS = 10 28 | TOKEN_FORMAT = 'SharedAccessSignature sig=%s&se=%s&skn=%s&sr=%s' 29 | 30 | def __init__(self, connectionString=None): 31 | if connectionString != None: 32 | iotHost, keyName, keyValue = [sub[sub.index('=') + 1:] for sub in connectionString.split(";")] 33 | self.iotHost = iotHost 34 | self.keyName = keyName 35 | self.keyValue = keyValue 36 | 37 | def _buildExpiryOn(self): 38 | return '%d' % (time.time() + self.TOKEN_VALID_SECS) 39 | 40 | def _buildIoTHubSasToken(self, deviceId): 41 | resourceUri = '%s/devices/%s' % (self.iotHost, deviceId) 42 | targetUri = resourceUri.lower() 43 | expiryTime = self._buildExpiryOn() 44 | toSign = '%s\n%s' % (targetUri, expiryTime) 45 | key = base64.b64decode(self.keyValue.encode('utf-8')) 46 | signature = urllib.quote( 47 | base64.b64encode( 48 | hmac.HMAC(key, toSign.encode('utf-8'), hashlib.sha256).digest() 49 | ) 50 | ).replace('/', '%2F') 51 | return self.TOKEN_FORMAT % (signature, expiryTime, self.keyName, targetUri) 52 | 53 | def sendD2CMsg(self, deviceId, message): 54 | sasToken = self._buildIoTHubSasToken(deviceId) 55 | url = 'https://%s/devices/%s/messages/events?api-version=%s' % (self.iotHost, deviceId, self.API_VERSION) 56 | r = requests.post(url, headers={'Authorization': sasToken}, data=message) 57 | return r.text, r.status_code 58 | 59 | if __name__ == '__main__': 60 | connectionString = 'HostName=.azure-devices.net;SharedAccessKeyName=device;SharedAccessKey=' 61 | d2cMsgSender = D2CMsgSender(connectionString) 62 | deviceId = 'iotdevice1' 63 | message = 'Hello, IoT Hub' 64 | print(d2cMsgSender.sendD2CMsg(deviceId, message)) 65 | -------------------------------------------------------------------------------- /Python/service/deviceManager.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module Name: deviceManager.py 3 | Project: IoTHubRestSample 4 | Copyright (c) Microsoft Corporation. 5 | 6 | Using [Device Indentities REST APIs](https://msdn.microsoft.com/en-us/library/azure/mt548489.aspx) to create a new device identity, retrieve a device identity, and list device identities. 7 | 8 | This source is subject to the Microsoft Public License. 9 | See http://www.microsoft.com/en-us/openness/licenses.aspx#MPL 10 | All other rights reserved. 11 | 12 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 13 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 15 | """ 16 | 17 | import base64 18 | import hmac 19 | import hashlib 20 | import time 21 | import requests 22 | import urllib 23 | 24 | class DeviceManager: 25 | 26 | API_VERSION = '2016-02-03' 27 | TOKEN_VALID_SECS = 365 * 24 * 60 * 60 28 | TOKEN_FORMAT = 'SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s' 29 | 30 | def __init__(self, connectionString=None): 31 | if connectionString != None: 32 | iotHost, keyName, keyValue = [sub[sub.index('=') + 1:] for sub in connectionString.split(";")] 33 | self.iotHost = iotHost 34 | self.keyName = keyName 35 | self.keyValue = keyValue 36 | 37 | def _buildExpiryOn(self): 38 | return '%d' % (time.time() + self.TOKEN_VALID_SECS) 39 | 40 | def _buildSasToken(self): 41 | targetUri = self.iotHost.lower() 42 | expiryTime = self._buildExpiryOn() 43 | toSign = '%s\n%s' % (targetUri, expiryTime) 44 | key = base64.b64decode(self.keyValue.encode('utf-8')) 45 | signature = urllib.quote( 46 | base64.b64encode( 47 | hmac.HMAC(key, toSign.encode('utf-8'), hashlib.sha256).digest() 48 | ) 49 | ).replace('/', '%2F') 50 | return self.TOKEN_FORMAT % (targetUri, signature, expiryTime, self.keyName) 51 | 52 | def createDeviceId(self, deviceId): 53 | sasToken = self._buildSasToken() 54 | url = 'https://%s/devices/%s?api-version=%s' % (self.iotHost, deviceId, self.API_VERSION) 55 | body = '{deviceId: "%s"}' % deviceId 56 | r = requests.put(url, headers={'Content-Type': 'application/json', 'Authorization': sasToken}, data=body) 57 | return r.text, r.status_code 58 | 59 | def retrieveDeviceId(self, deviceId): 60 | sasToken = self._buildSasToken() 61 | url = 'https://%s/devices/%s?api-version=%s' % (self.iotHost, deviceId, self.API_VERSION) 62 | r = requests.get(url, headers={'Content-Type': 'application/json', 'Authorization': sasToken}) 63 | return r.text, r.status_code 64 | 65 | def listDeviceIds(self, top=None): 66 | if top == None: 67 | top = 1000 68 | sasToken = self._buildSasToken() 69 | url = 'https://%s/devices?top=%d&api-version=%s' % (self.iotHost, top, self.API_VERSION) 70 | r = requests.get(url, headers={'Content-Type': 'application/json', 'Authorization': sasToken}) 71 | return r.text, r.status_code 72 | 73 | def deleteDeviceId(self, deviceId): 74 | sasToken = self._buildSasToken() 75 | url = 'https://%s/devices/%s?api-version=%s' % (self.iotHost, deviceId, self.API_VERSION) 76 | r = requests.delete(url, headers={'Content-Type': 'application/json', 'Authorization': sasToken, 'If-Match': '*' }) 77 | # If-Match Etag, but if * is used, no need to precise the Etag of the device. The Etag of the device can be seen in the header requests.text response 78 | return r.text, r.status_code 79 | 80 | if __name__ == '__main__': 81 | connectionString = 'HostName=.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=' 82 | dm = DeviceManager(connectionString) 83 | deviceId = 'iotdevice1' 84 | print(dm.createDeviceId(deviceId)) 85 | print(dm.retrieveDeviceId(deviceId)) 86 | print(dm.listDeviceIds()) 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | services: iot-hub 3 | platforms: python 4 | author: msonecode 5 | --- 6 | 7 | # How to get started for using IoT Hub REST API in Python 8 | 9 | ## About this sample 10 | The sample project demonstrates how to get started for using IoT Hub REST API in Python. 11 | 12 | The REST APIs for IoT Hub offer programmatic access to the device and messaging services, as well as the resource provider, in IoT Hub. You can access messaging services within an IoT service running in Azure, or you can directly over the Internet from any application that can send an HTTP/HTTPS request and receive an HTTP/HTTPS response. You can visit the [IoT Hub REST API references](https://msdn.microsoft.com/en-us/library/azure/mt548492.aspx) on Microsoft Azure official site to learn more about these APIs, requirements, parameters, request and response via HTTP methods. 13 | 14 | In the sample project, steps at below will be proivded for us to get started. 15 | 16 | 1. Create an IoT Hub through Azure Portal. 17 | 2. Get the connection information from the settings on Azure portal. 18 | 3. A simple Python script shows how to create a device identity at the IoT Hub, list all registered device identities from IoT Hub. 19 | 4. A simple Python script shows how to send messages from the simulated device application to IoT Hub. 20 | 21 | 22 | ## Create an IoT Hub through Azure Portal 23 | 24 | To do this, refer to the article [Create an IoT Hub through Azure Portal](https://azure.microsoft.com/documentation/articles/iot-hub-csharp-csharp-getstarted/#create-an-iot-hub). 25 | 26 | 27 | 28 | ## Get the connection information 29 | - Getting the IoT Hub **Hostname** 30 | 31 | Copy the IoT Hub **Hostname** at the dashboard. 32 | 33 | ![Copy the IoT Hub Hostname at the dashboard](./Images/4.png) 34 | 35 | - Getting the **Shared access key** and **Connection string** of the policy 36 | 37 | Click the **Key** button to show the **Shared access policies**, then select one policy, then copy the **Shared access key** and **Connection string**. 38 | 39 | ![Click the Key button to show the Shared access policies](./Images/5.png) 40 | 41 | ![Copy the Shared access key and Connection string](./Images/6.png) 42 | 43 | ## Building the sample 44 | You can use Eclipse with PyDev Plugin to import the sample project. 45 | ### Preparation 46 | - Install the Python package **requests** via command pip install requests 47 | - Download [Eclipse](https://eclipse.org/downloads/) 48 | - Install PyDev plugin via Eclipse Marketplace, click **Help** -> **Eclipse Marketplace**, then input **PyDev** in the search box and enter, then click the **install** button and follow the tips to install until **Finish** and restart Eclipse. 49 | 50 | ![Install PyDev plugin via Eclipse Marketplace](./Images/7.png) 51 | 52 | ![Input PyDev in the search box and enter](./Images/8.png) 53 | 54 | ### Import the sample project 55 | 1. Open the Eclipse. 56 | 2. Click **File** -> **Import**. 57 | 58 | ![Click File -> Import](./Images/9.png) 59 | 60 | 3. Select **General** -> **Existing Projects into Workspace**, then click **Next**. 61 | 62 | ![Select General -> Existing Projects into Workspace](./Images/10.png) 63 | 64 | 4. Select the sample project path via **Browse**, then click **Finish**. 65 | 66 | ![Select the sample project path via Browse](./Images/11.png) 67 | 68 | 5. See the **PyDev Package Explorer**. 69 | 70 | ![See the PyDev Package Explorer](./Images/12.png) 71 | 72 | ## Running the sample 73 | There are two scripts separately at the **service** and **device** directories: 74 | 75 | - service/deviceManager.py: Using [Device Indentities REST APIs](https://msdn.microsoft.com/en-us/library/azure/mt548489.aspx) to create a new device identity, retrieve a device identity, and list device identities. 76 | 77 | - device/d2cMsgSender.py: Using [Send device-to-cloud message](https://msdn.microsoft.com/en-US/library/azure/mt590784.aspx) API to send device-to-cloud message from the simulated device application to IoT Hub. 78 | 79 | You can open the Python script on Eclipse, and click the right mouse button at the script window, then click the **Run As** -> **2 Python Run** to run the script, then see the result at the **Console** Window. 80 | 81 | ![Click the Run As -> 2 Python Run to run the script](./Images/13.png) 82 | 83 | ## Code sample running result 84 | The results for running `service/deviceManager.py`: 85 | 86 | 87 | 1. The result for calling the function `createDeviceId(deviceId)` 88 | 89 | - Creating an non-existed device identity, the result as below. 90 | ``` 91 | (u'{"deviceId":"iotdevice3","generationId":"635937464376399955","etag":"MA==","connectionState":"Disconnected","status":"enabled","statusReason":null,"connectionStateUpdatedTime":"0001-01-01T00:00:00","statusUpdatedTime":"0001-01-01T00:00:00","lastActivityTime":"0001-01-01T00:00:00","cloudToDeviceMessageCount":0,"authentication":{"symmetricKey":{"primaryKey":"PqZ70GzRIOv8Mfap31nzDjwqsRwt8X6VTLDUM48qDGk=","secondaryKey":"gZfLMBuwgNDOuYbJZNK8ZXLGCm5WJba4CVGvXBV/0qM="}}}', 200) 92 | ``` 93 | - If trying to create an existed device identity, an error information will be shown. 94 | 95 | ``` 96 | (u'{"Message":"ErrorCode:DeviceAlreadyExists;A device with ID \'iotdevice1\' is already registered.\r\nTracking Id:218b497e330b41119036553381cc63de-G:GatewayWorkerRole.11-B:1-P:8a500395-cf20-45f1-831b-e0a49c9bd5fa-TimeStamp:03/16/2016 17:26:37\r\nErrorCode:DeviceAlreadyExists"}', 409) 97 | ``` 98 | 99 | 2. The result for calling the function `retrieveDeviceId(deviceId)` 100 | ``` 101 | (u'{"deviceId":"iotdevice1","generationId":"635928930091746067","etag":"MA==","connectionState":"Disconnected","status":"enabled","statusReason":null,"connectionStateUpdatedTime":"2016-03-16T09:46:02.5862088","statusUpdatedTime":"0001-01-01T00:00:00","lastActivityTime":"2016-03-16T09:46:02.5862088","cloudToDeviceMessageCount":0,"authentication":{"symmetricKey":{"primaryKey":"F+x9Sg9zVZC+TWnrQ1vXm0sYH/SAtvv6Wa5WhWnHdQo=","secondaryKey":"vZaSU6/8Mah4Chu28Vzx07/Feqe1a2EeDeUNEo9EY10="}}}', 200) 102 | ``` 103 | 104 | 3. The result for calling the function `listDeviceId()` lists all the registered device identities. 105 | ``` 106 | (u'[{"deviceId":"iotdevice1","generationId":"635928930091746067","etag":"MA==","connectionState":"Disconnected","status":"enabled","statusReason":null,"connectionStateUpdatedTime":"2016-03-16T09:46:02.5862088","statusUpdatedTime":"0001-01-01T00:00:00","lastActivityTime":"2016-03-16T09:46:02.5862088","cloudToDeviceMessageCount":0,"authentication":{"symmetricKey":{"primaryKey":"F+x9Sg9zVZC+TWnrQ1vXm0sYH/SAtvv6Wa5WhWnHdQo=","secondaryKey":"vZaSU6/8Mah4Chu28Vzx07/Feqe1a2EeDeUNEo9EY10="}}}]', 200) 107 | ``` 108 | 109 | The result for running `device/d2cMsgSender.py` includes the empty content and status code 204 from the response if message is sent successfully: 110 | ``` 111 | (u'', 204) 112 | ``` 113 | -------------------------------------------------------------------------------- /includes/iot-hub-get-started-nav-tabs.md: -------------------------------------------------------------------------------- 1 | > [AZURE.SELECTOR] 2 | - [.NET](README.md) 3 | - [Node.js](README.md) 4 | - [Python](README.md) 5 | - [Java](README.md) 6 | - [Marketplace app](README.md) 7 | --------------------------------------------------------------------------------