├── 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 | 
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 | 
40 |
41 | 
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 | 
51 |
52 | 
53 |
54 | ### Import the sample project
55 | 1. Open the Eclipse.
56 | 2. Click **File** -> **Import**.
57 |
58 | 
59 |
60 | 3. Select **General** -> **Existing Projects into Workspace**, then click **Next**.
61 |
62 | 
63 |
64 | 4. Select the sample project path via **Browse**, then click **Finish**.
65 |
66 | 
67 |
68 | 5. See the **PyDev Package Explorer**.
69 |
70 | 
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 | 
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 |
--------------------------------------------------------------------------------