### Setup Development Environment for IoT Device SDK Source: https://github.com/azure/azure-iot-sdk-python/blob/main/devbox_setup.md Run this script from the root directory to install development dependencies and an editable install of the source code. ```bash python scripts/env_setup.py ``` -------------------------------- ### Start Dante Service Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Starts the Dante proxy server service. This command assumes the service is already configured and installed. ```bash sudo service danted start ``` -------------------------------- ### Install Azure IoT Device SDK (End User) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/devbox_setup.md Install the SDK package for end-users who do not need to modify the code. ```bash pip install azure-iot-device ``` -------------------------------- ### Start Squid Service Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Starts the Squid proxy server service. This command assumes the service is already configured and installed. ```bash sudo service squid start ``` -------------------------------- ### Install Apache Utilities for htpasswd Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Installs the apache2-utils package, which provides the htpasswd utility for managing user credentials for basic authentication. ```bash sudo apt-get install apache2-utils ``` -------------------------------- ### Install Dante Server Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Installs the Dante server package, which provides SOCKS4 and SOCKS5 proxy functionality. This is used for setting up SOCKS proxies. ```bash sudo apt-get install dante-server ``` -------------------------------- ### Install Squid Proxy Server Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Installs the Squid proxy server package on Debian/Ubuntu-based systems. This is the first step in setting up an HTTP/HTTPS proxy. ```bash sudo apt-get install squid ``` -------------------------------- ### Install Docker Package Source: https://github.com/azure/azure-iot-sdk-python/blob/main/sdklab/meantimerecovery/README.md Install the Python 'docker' package to enable programmatic access to the Docker Engine API. This is required for the mean_time_recover_with_docker.py script. ```bash pip install docker ``` -------------------------------- ### Create X.509 Certificate Chain (Default) Source: https://github.com/azure/azure-iot-sdk-python/wiki/X509_Chain Use this command to generate a certificate chain with a single leaf certificate. Ensure the 'cryptography' library is installed. ```bash python create_x509_chain_crypto.py "leviosa" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd" ``` -------------------------------- ### Native Async Example Source: https://github.com/azure/azure-iot-sdk-python/wiki/Async This snippet shows a native asynchronous implementation using `asyncio.sleep` to represent I/O operations. It schedules the same number of operations as the emulation example for comparison. ```python OPERATION_COUNT = 800 BLOCKING_TIME = 10 async def async_fn(): await asyncio.sleep(BLOCKING_TIME) #represents I/O async def main(): await asyncio.gather(*[asyncio.ensure_future(async_fn()) for i in range(OPERATION_COUNT)]) ``` -------------------------------- ### Create X.509 Certificate Chain (Multiple Leaf Certificates) Source: https://github.com/azure/azure-iot-sdk-python/wiki/X509_Chain Generate a certificate chain with a specified number of leaf certificates by providing the '--device-count' argument. The 'cryptography' library must be installed. ```bash python create_x509_chain_crypto.py "nox" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd" --device-count "3" ``` -------------------------------- ### Pytest Describe and It Decorators Example Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Demonstrates the use of `pytest.mark.describe` for test classes and `pytest.mark.it` for test functions to structure test output according to specified syntax rules. ```python import pytest @pytest.mark.describe(".foo()") class TestFoo(object): @pytest.mark.it("Returns the string 'foo'") def test_returns_foo(self): assert foo() == "foo" ``` -------------------------------- ### Async Emulation Example Source: https://github.com/azure/azure-iot-sdk-python/wiki/Async This snippet demonstrates how to emulate asynchronous behavior using `ThreadPoolExecutor` by wrapping a blocking function with `run_in_executor`. It schedules a large number of blocking operations. ```python OPERATION_COUNT = 800 BLOCKING_TIME = 10 def emulate_async(fn): async def async_fn_wrapper(*args, **kwargs): loop = asyncio.get_event_loop() await loop.run_in_executor(None, fn, *args, **kwargs) return async_fn_wrapper @emulate_async def blocking_sync_fn(): time.sleep(BLOCKING_TIME) #represents I/O async def main(): await asyncio.gather(*[asyncio.ensure_future(blocking_sync_fn()) for i in range(OPERATION_COUNT)]) ``` -------------------------------- ### Class Definition for Testing Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Example class definition that will be used for demonstrating unit testing principles for class methods and instantiation. ```python class FooClient(object): def __init__(self): self.bar = "buzz" self.io = IOLibrary() self.io.tls_type = ssl.PROTOCOL_TLSv1_2 self.io.verify_mode = ssl.CERT_REQUIRED self.io.check_hostname = True def connect(): self.io.connect() def send_message(message, qos): self.io.send(message, qos) ``` -------------------------------- ### Anti-pattern: Handler Called Multiple Times Source: https://github.com/azure/azure-iot-sdk-python/wiki/callbacks Do not assume a handler is called only once. This example shows how a handler intended for a single event can be triggered multiple times due to re-connections. ```python class ReconnectingSender(MessageSender): """ Object that adds reconnect functionality to the MessageSender class. If the connection drops, this object will re-connect using some internal retry rules. """ def __init__(self): # handler that gets called whenever the network gets connected self.on_network_connected_handler = None def connect(self): # connects the network def send(self): # sends a message ``` ```python class Application(object): def __init__(self): self.sender = ReconnectingSender() def connect_and_send(self): def on_connected(): # send a message after the network is connected sender.send("Application Started") self.sender.on_network_connected_handler = on_connected self.sender.connect() ``` -------------------------------- ### Test FooClient.bar() with Spy Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Tests the `.bar()` method of `FooClient` by spying on the `valuemanager.get` method. This ensures the method retrieves the stored value and that the `get` method is called exactly once. ```python @pytest.mark.describe("FooClient - .bar()") class TestFooClientBar(object): @pytest.mark.it("Returns stored value upon call to .bar method") def test_returns_next_primate(self, mocker): foo = FooClient() stored_value = 3 foo.boo(stored_value) # No need to mock the prime_generator, let it operate as normal mocker.spy(foo.valuemanager, "get") res = foo.bar() assert res == stored_value assert foo.valuemanager.get.call_count == 1 ``` -------------------------------- ### Create Device Client with x.509 Auth (v1 vs v2) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/migration_guide.md Compare v1 and v2 SDKs for creating a device client using x.509 authentication. V2 requires an x.509 object with certificate and key file paths during client creation. ```Python from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue client = IoTHubClient(connection_string, IoTHubTransportProvider.MQTT) # Get the x.509 certificate information client.set_option("x509certificate", X509_CERTIFICATE) client.set_option("x509privatekey", X509_PRIVATEKEY) ``` ```Python from azure.iot.device.aio import IoTHubDeviceClient from azure.iot.device import Message # Get the x.509 certificate path from the environment x509 = X509( cert_file=os.getenv("X509_CERT_FILE"), key_file=os.getenv("X509_KEY_FILE"), pass_phrase=os.getenv("X509_PASS_PHRASE") ) client = IoTHubDeviceClient.create_from_x509_certificate(hostname=hostname, device_id=device_id, x509=x509) await device_client.connect() ``` -------------------------------- ### Create Device Client with Symmetric Key Auth (v1 vs v2) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/migration_guide.md Compare v1 and v2 SDKs for creating a device client using symmetric key authentication. V2 simplifies client creation by only requiring the connection string. ```Python from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue client = IoTHubClient(connection_string, IoTHubTransportProvider.MQTT) ``` ```Python from azure.iot.device.aio import IoTHubDeviceClient from azure.iot.device import Message client = IoTHubDeviceClient.create_from_connection_string(connection_string) await device_client.connect() ``` -------------------------------- ### Run Simple Send Message Sample in Codespaces Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Navigate to the samples directory and run the simple_send_message.py script using Python 3 within a GitHub Codespace environment. ```bash cd azure-iot-device/samples python3 simple_send_message.py ``` -------------------------------- ### Create Azure IoT Hub using Azure CLI Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Use this command to create an Azure IoT Hub instance. This operation may take a few minutes. ```bash az iot hub create --resource-group --name ``` -------------------------------- ### Create Provisioning Device Client with Symmetric Key Source: https://github.com/azure/azure-iot-sdk-python/wiki/key-word-arguments-during-client-creations Use `create_from_symmetric_key` to instantiate a provisioning device client. The `keep_alive` argument can be specified to control the connection's keep-alive interval. ```python provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host=provisioning_host, registration_id=registration_id, id_scope=id_scope, symmetric_key=symmetric_key, keep_alive=65 ) ``` -------------------------------- ### Test FooClient Instantiation Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Test the instantiation of `FooClient` by verifying instance attributes and the configuration of its internal IO library. Each logical requirement is tested separately. ```python @pytest.mark.describe("FooClient - Instantiation") class TestFooInstantiation(object): @pytest.mark.it("Sets the .bar instance attribute to 'buzz'") def test_sets_bar(self): foo = FooClient() assert foo.bar == "buzz" @pytest.mark.it("Configures the IO library") def test_configures_io(self): foo = FooClient() assert isinstance(foo.io, IOLibrary) assert foo.io.tls_type == ssl.PROTOCOL_TLSv1_2 assert foo.io.verify_mode == ssl.CERT_REQUIRED assert foo.io.check_hostname == True ``` -------------------------------- ### Get Current SAS Token Source: https://github.com/azure/azure-iot-sdk-python/blob/main/doc/sk_authentication_provider.md Retrieve the current Shared Access Signature (SAS) token string using the `get_current_sas_token` instance method. ```python auth_provider.get_current_sas_token() ``` -------------------------------- ### Provision Device with X.509 Certificate (DPS) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Provisions a device to IoTHub using the Device Provisioning Service with an X.509 certificate. Requires PROVISIONING_HOST, PROVISIONING_IDSCOPE, PROVISIONING_REGISTRATION_ID, X509_CERT_FILE, X509_KEY_FILE, and PASS_PHRASE environment variables. ```python import asyncio from azure.iot.device.aio import ProvisioningDeviceClient async def main(): provisioning_host = "" id_scope = "" registration_id = "" x509_cert_file = "" x509_key_file = "" pass_phrase = "" provisioning_client = ProvisioningDeviceClient.create_from_x509_certificate( provisioning_host, id_scope, registration_id, x509_cert_file, x509_key_file, pass_phrase, ) registration_result = await provisioning_client.register() print("The following device ID was registered: {}".format(registration_result.registration_id)) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Avoid Multiple Client Instances Source: https://github.com/azure/azure-iot-sdk-python/wiki/Pitfalls Creating multiple `IoTHubDeviceClient` instances with the same connection string can lead to instability as clients compete for resources and connections are repeatedly closed and reopened. ```python client = IoTHubDeviceClient.create_from_connection_string(conn_str) client.send_message(msg) # some time passes client = IoTHubDeviceClient.create_from_connection_string(conn_str) client.send_message(msg2) ``` -------------------------------- ### Test FooClient .send_message() with Parametrization Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Test the `.send_message()` method of `FooClient` using parametrization to cover different Quality of Service (QoS) levels. This verifies that the message is sent correctly for each QoS setting. ```python @pytest.mark.describe("Foo - .send_message()") class TestFooSendMessage(object): @pytest.mark.it("Sends a message via the IO library") @pytest.mark.parametrize( "qos", [pytest.param(0, id="QoS 0"), pytest.param(1, id="QoS 1"), pytest.param(2, id="QoS 2")], ) def test_sends_via_io(self, mocker, qos): foo = FooClient() io_mock = mocker.patch(foo, "io") message = "my_message" foo.send_message(message, qos) assert io_mock.send_message.call_count == 1 assert io_mock.send_message.call_args == mocker.call(message) ``` -------------------------------- ### Build MQTT Broker Docker Image Source: https://github.com/azure/azure-iot-sdk-python/blob/main/sdklab/meantimerecovery/README.md Build the Docker image for the MQTT broker using the provided Dockerfile. This image will be used by the Python script to create containers. ```bash docker build -t mqtt-broker . ``` -------------------------------- ### Mocking an Async Coroutine Method with Pytest Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_async Example of mocking an asynchronous method 'bar' on a FooClient instance using pytest-mocker. It ensures the mocked method returns a completed future with a specific value, allowing the test to await the result. ```python @pytest.mark.describe("Foo - Bar") class TestBar(object): @pytest.mark.it("Returns 'buzz' when called") async def test_returns_buzz(self, mocker): foo = FooClient() mocker.patch(foo, "bar", return_value=(await create_completed_future("buzz"))) res = await foo.bar() assert res == "buzz" ``` -------------------------------- ### Provision Device with Symmetric Key (DPS) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Provisions a device to IoTHub using the Device Provisioning Service with a symmetric key. Requires PROVISIONING_HOST, PROVISIONING_IDSCOPE, PROVISIONING_REGISTRATION_ID, and PROVISIONING_SYMMETRIC_KEY environment variables. ```python import asyncio from azure.iot.device.aio import ProvisioningDeviceClient async def main(): provisioning_host = "" id_scope = "" registration_id = "" symmetric_key = "" provisioning_client = ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host, id_scope, registration_id, symmetric_key, ) registration_result = await provisioning_client.register() print("The following device ID was registered: {}".format(registration_result.registration_id)) # Now you can create an IoT Hub device client with the connection string obtained from the provisioning result # For example: # connection_string = "HostName={}.azure-devices.net;DeviceId={};SharedAccessKey={}".format( # registration_result.iot_hub_hostname, # registration_result.device_id, # registration_result.device_key, # ) # device_client = IoTHubDeviceClient.create_from_connection_string(connection_string) # await device_client.connect() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Set Device Connection String for Codespaces Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Set the device connection string as an environment variable within a GitHub Codespace. This is required before running the sample. ```bash export IOTHUB_DEVICE_CONNECTION_STRING="" ``` -------------------------------- ### Create Device Client with WebSockets Enabled Source: https://github.com/azure/azure-iot-sdk-python/wiki/key-word-arguments-during-client-creations Use the `websockets=True` keyword argument when creating a device client from a connection string to enable communication over WebSockets. This is useful when port 8883 is blocked by a firewall. ```python device_client = IoTHubDeviceClient.create_from_connection_string(conn_str, websockets=True) ``` -------------------------------- ### Provision Multiple Devices with Symmetric Key Group (DPS) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Provisions multiple devices to IoTHub using the Device Provisioning Service with derived symmetric keys from a group key. Requires PROVISIONING_HOST, PROVISIONING_IDSCOPE, and device-specific IDs (e.g., PROVISIONING_DEVICE_ID_1). The group symmetric key must be known and device keys derived beforehand. ```python import asyncio from azure.iot.device.aio import ProvisioningDeviceClient async def main(): provisioning_host = "" id_scope = "" group_symmetric_key = "" # Example for two devices device_ids = ["device_1", "device_2"] for device_id in device_ids: provisioning_client = ProvisioningDeviceClient.create_from_group_symmetric_key( provisioning_host, id_scope, device_id, group_symmetric_key, ) registration_result = await provisioning_client.register() print("Device {} was registered with ID: {}".format(device_id, registration_result.registration_id)) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Send Telemetry to IoTHub (v1 vs v2) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/migration_guide.md Compare v1 and v2 SDKs for sending telemetry messages. V2 uses an asynchronous `send_message` method and a simpler way to add custom properties. ```Python # create the device client message = IoTHubMessage("telemetry message") message.message_id = "message id" message.correlation_id = "correlation-id" prop_map = message.properties() prop_map.add("property", "property_value") client.send_event_async(message, send_confirmation_callback, user_ctx) ``` ```Python # create the device client message = Message("telemetry message") message.message_id = "message id" message.correlation_id = "correlation id" message.custom_properties["property"] = "property_value" await client.send_message(message) ``` -------------------------------- ### Squid Configuration with Authentication Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies A recommended squid.conf configuration for enabling basic authentication using NCSA passwords. Requires the 'basic_ncsa_auth' helper and a password file. ```squidconf auth_param basic program /usr/lib/squid3/basic_ncsa_auth /etc/squid/passwords auth_param basic realm Squid proxy-caching web server auth_param basic credentialsttl 2 hours acl authenticated proxy_auth REQUIRED http_access allow authenticated http_access deny all http_port 3128 ``` -------------------------------- ### Invoke Direct Method (Azure CLI) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Use this Azure CLI command to invoke a direct method on a device. Replace placeholders with your device ID, IoT Hub name, and the desired method name. ```bash az iot hub invoke-device-method --device-id --hub-name --method-name ``` -------------------------------- ### Provision Device with Symmetric Key and Payload (DPS) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Provisions a device to IoTHub using the Device Provisioning Service with a symmetric key and a custom payload. Requires PROVISIONING_HOST, PROVISIONING_IDSCOPE, PROVISIONING_REGISTRATION_ID, and PROVISIONING_SYMMETRIC_KEY environment variables. ```python import asyncio from azure.iot.device.aio import ProvisioningDeviceClient async def main(): provisioning_host = "" id_scope = "" registration_id = "" symmetric_key = "" provisioning_client = ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host, id_scope, registration_id, symmetric_key, payload={'custom': {'key': 'value'}} ) registration_result = await provisioning_client.register() print("The following device ID was registered: {}".format(registration_result.registration_id)) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Receive Message from IoTHub (v1 vs v2) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/migration_guide.md Compare v1 and v2 SDKs for receiving messages. V2 uses an event handler (`on_message_received`) for processing incoming messages. ```Python # create the device client def receive_message_callback(message, counter): global RECEIVE_CALLBACKS message = message.get_bytearray() size = len(message_buffer) print ( "the data in the message received was : <<<%s>>> & Size=%d" % (message_buffer[:size].decode('utf-8'), size) ) map_properties = message.properties() key_value_pair = map_properties.get_internals() print ( "custom properties are: %s" % key_value_pair ) return IoTHubMessageDispositionResult.ACCEPTED client.set_message_callback(message_listener_callback, RECEIVE_CONTEXT) ``` ```Python # create the device client # define behavior for receiving a message def message_handler(message): print("the data in the message received was ") print(message.data) print("custom properties are") print(message.custom_properties) # set the message handler on the client client.on_message_received = message_handler ``` -------------------------------- ### Define GenericClient and Concrete Clients Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_inheritance This code defines a base abstract class `GenericClient` and two concrete implementations, `FooClient` and `BarClient`, demonstrating inheritance and abstract methods. ```python import abc import six @six.add_metaclass(abc.ABCMeta) class GenericClient(object): def __init__(self): self.method_b_call_count = 0 def method_a(self): return "buzz" @abc.abstractmethod def method_b(self): self.method_b_call_count += 1 class FooClient(GenericClient): def method_b(self): super(self, FooClient).method_b() return "foo" class BarClient(GenericClient): def method_b(self): super(self, BarClient).method_b() return "bar" ``` -------------------------------- ### Test FooClient .connect() Method Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Test the `.connect()` method of `FooClient` using mocking to verify that the underlying IO library's `connect` method is called exactly once. ```python @pytest.mark.describe("Foo - .connect()") class TestFooConnect(object): @pytest.mark.it("Connects via the IO library") def test_connect_via_io(self, mocker): foo = FooClient() io_mock = mocker.patch(foo, "io") foo.connect() assert io_mock.connect.call_count == 1 ``` -------------------------------- ### Add Library Specific Logging (Python) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/solutions/producer_consumer.md Configure logging for a specific library, such as Paho MQTT, by setting up a timed rotating file handler. This allows for detailed debugging and monitoring of library-specific events. ```python paho_log_handler = logging.handlers.TimedRotatingFileHandler( filename="{}".format(LOG_DIRECTORY), when="S", interval=LOG_ROTATION_INTERVAL, backupCount=LOG_BACKUP_COUNT, ) paho_log_handler.setLevel(level=logging.DEBUG) paho_log_handler.setFormatter(log_formatter) paho_logger = logging.getLogger("paho") paho_logger.addHandler(paho_log_handler) ``` -------------------------------- ### Namespace Package Initialization Source: https://github.com/azure/azure-iot-sdk-python/wiki/nspkg This code is part of the azure-iot-nspkg package and is used to define implicit namespaces in Python 2. It should only be included if running Python 2. ```python __path__ = __import__("pkgutil").extend_path(__path__, __name__) ``` -------------------------------- ### FooClient Class Definition Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_basics Defines a sample client class with HTTP and value management interactions. This class serves as a basis for demonstrating unit tests. ```python class FooClient(object): def __init__(self): self.httpclient = HttpClient("http://myurl") self.valuemanager = ValueManager def boo(self, val): self.valuemanager.set(val) def bar(self): return valuemanager.get(val) def buzz(self): self.httpclient.send("buzz") ``` -------------------------------- ### Basic Parameter Callback Usage Source: https://github.com/azure/azure-iot-sdk-python/wiki/callbacks Demonstrates a function accepting a callback and executing it within a try-except block to handle potential exceptions. A bare except is used due to the unknown nature of callback exceptions. ```python def foo(callback): # do something try: callback() except: # noqa: E722 do not use bare 'except' pass def bar(): def on_complete(): print("completed") foo(callback=on_complete) if __name__ == '__main__': bar() ``` -------------------------------- ### Set Device Connection String Environment Variable Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Set the device connection string as an environment variable. Ensure no quotation marks are used on Windows command prompt. ```cmd set IOTHUB_DEVICE_CONNECTION_STRING= ``` ```bash export IOTHUB_DEVICE_CONNECTION_STRING="" ``` -------------------------------- ### Show Device Twin Properties (Azure CLI) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Use this Azure CLI command to view the current properties of a device twin. Replace placeholders with your device ID and IoT Hub name. ```bash az iot hub device-twin show --device-id --hub-name ``` -------------------------------- ### Parse Connection String Source: https://github.com/azure/azure-iot-sdk-python/blob/main/doc/sk_authentication_provider.md Use the `parse` static method to create a SymmetricKeyAuthenticationProvider instance from a connection string. It supports device and module connection strings with or without a key name. ```python SymmetricKeyAuthenticationProvider.parse(connection_string) ``` -------------------------------- ### Add IoT Extension and Register Device Identity using Azure CLI Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Add the IoT extension to Azure CLI and register a device identity for your IoT Hub. ```bash az extension add --name azure-iot az iot hub device-identity create --hub-name --device-id ``` -------------------------------- ### Test Dante SOCKS5 Proxy with Authentication Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Tests the SOCKS5 Dante proxy with authentication enabled using curl. Requires a username and password configured in the OS. ```bash curl --proxy socks5://127.0.0.1:1080 --proxy-user https://httpbin.org/ip ``` -------------------------------- ### Generate Root Verification Certificate Source: https://github.com/azure/azure-iot-sdk-python/wiki/X509_Chain Create a verification certificate for the root CA. The '--mode verification' and '--nonce' arguments are required. The '--root-verify' argument defaults to True and does not need to be specified. ```bash python create_x509_chain_crypto.py "leviosa" --mode verification --issuer-password "hogwarts" --nonce 3189FC796AB321C17F0A74011E72C64E9FD98FECE90AE0E5 ``` -------------------------------- ### Optional Parameter Callback with LBYL Source: https://github.com/azure/azure-iot-sdk-python/wiki/callbacks Illustrates how to handle optional callbacks by checking for their existence before invocation (Look Before You Leap). This pattern is necessary to differentiate between a missing callback and a callback that raises a specific error like TypeError. ```python def foo(callback=None): # do something if callback: try: callback() except: # noqa: E722 do not use bare 'except' raise FooError("callback raised exception") else: pass def bar(): def on_complete(): print("completed") foo(callback=on_complete) if __name__ == '__main__': bar() ``` -------------------------------- ### Display Garbage Collection Statistics Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/solutions/stingy_connection.md This command-line output shows the format of garbage collection statistics that the application displays periodically. It includes counts for collections, collected items, and uncollectable items. ```commandline GC stats are:- collections -> 124 collected -> 3212 uncollectable -> 0 collections -> 11 collected -> 366 uncollectable -> 0 collections -> 1 collected -> 323 uncollectable -> 0 ``` -------------------------------- ### Add Paho MQTT Library Logging Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/how-to-guides/connect_retry_with_telemetry.md Configure a TimedRotatingFileHandler to capture DEBUG level logs from the Paho MQTT library. This helps in troubleshooting connection issues specific to the MQTT client. ```python paho_log_handler = logging.handlers.TimedRotatingFileHandler( filename="{}".format(LOG_DIRECTORY) + "/paho.log", when="S", interval=LOG_ROTATION_INTERVAL, backupCount=LOG_BACKUP_COUNT, ) paho_log_handler.setLevel(level=logging.DEBUG) paho_log_handler.setFormatter(log_formatter) paho_logger = logging.getLogger("paho") paho_logger.addHandler(paho_log_handler) ``` -------------------------------- ### Monitor IoT Hub Events (Azure CLI) Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/async-hub-scenarios/README.md Use this Azure CLI command to monitor messages received by your IoT Hub. Replace `` with your hub's name. ```bash az iot hub monitor-events --hub-name --output table ``` -------------------------------- ### Dante Configuration (SOCKS5 - Auth) Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies A recommended danted.conf configuration for a SOCKS5 proxy with username authentication. It uses 'username' for both client and SOCKS methods. ```danteconf logoutput: syslog user.privileged: root internal: 0.0.0.0 port=1080 external: eth0 socksmethod: username clientmethod: username client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error proxyprotocol: socks_v5 } ``` -------------------------------- ### Create Squid Password File Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Creates an empty file to store password credentials for Squid proxy authentication. This file is used in conjunction with htpasswd. ```bash sudo touch /etc/squid/passwords ``` -------------------------------- ### Show Device Connection String using Azure CLI Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Retrieve the device connection string for your registered device identity. This string is required for the device to connect to IoT Hub. ```bash az iot hub device-identity connection-string show --device-id --hub-name ``` -------------------------------- ### Monitor IoT Hub Events using Azure CLI Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/README.md Begin monitoring for telemetry events on your IoT Hub. This command is useful for verifying that messages are being received. ```bash az iot hub monitor-events --hub-name --output json ``` -------------------------------- ### Generate Intermediate Verification Certificate Source: https://github.com/azure/azure-iot-sdk-python/wiki/X509_Chain Generate a verification certificate for an intermediate CA. Set '--root-verify' to False and provide the appropriate '--issuer-password' for the intermediate certificate. ```bash python create_x509_chain_crypto.py "leviosa" --mode verification --issuer-password "hogwartsi" --nonce 1CA27CF9052136A642764D0EA87A943DE67F8203AD1D4B2D --root-verify False ``` -------------------------------- ### Basic Class Method Test - Python Source: https://github.com/azure/azure-iot-sdk-python/wiki/unittesting_unit_examples Demonstrates a simple unit test for a class method that returns a fixed string value. ```python class Foo(object): def buzz(self): return "buzz" ``` ```python @pytest.mark.describe("Foo - .buzz()") class TestFooBuzz(object): @pytest.mark.it("Returns 'buzz'") def returns_buzz(self): f = Foo() assert f.buzz() == "buzz" ``` -------------------------------- ### Add Paho MQTT Library Logging Source: https://github.com/azure/azure-iot-sdk-python/blob/main/samples/solutions/stingy_connection.md This Python code demonstrates how to add specific logging for the Paho MQTT library. It configures a timed rotating file handler to capture DEBUG level logs from the 'paho' logger. ```python paho_log_handler = logging.handlers.TimedRotatingFileHandler( filename="{}/paho.log".format(LOG_DIRECTORY), when="S", interval=LOG_ROTATION_INTERVAL, backupCount=LOG_BACKUP_COUNT, ) paho_log_handler.setLevel(level=logging.DEBUG) paho_log_handler.setFormatter(log_formatter) paho_logger = logging.getLogger("paho") paho_logger.addHandler(paho_log_handler) ``` -------------------------------- ### Add User to Squid Password File Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies Adds a new user and prompts for a password to be stored in the Squid password file for authentication. Replace with the desired username. ```bash sudo htpasswd /etc/squid/passwords ``` -------------------------------- ### Dante Configuration (SOCKS5 - No Auth) Source: https://github.com/azure/azure-iot-sdk-python/wiki/Manual-Testing-of-Proxies A recommended danted.conf configuration for a SOCKS5 proxy without authentication. It specifies logging, user privileges, internal/external interfaces, and SOCKS method. ```danteconf logoutput: syslog user.privileged: root internal: 0.0.0.0 port=1080 external: eth0 socksmethod: none clientmethod: none client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect disconnect error proxyprotocol: socks_v5 } ``` -------------------------------- ### Remove MQTT Broker Docker Image Source: https://github.com/azure/azure-iot-sdk-python/blob/main/sdklab/meantimerecovery/README.md Remove the previously built MQTT broker Docker image. ```bash docker image rm mqtt-broker ```