%3CLINGO-SUB%20id%3D%22lingo-sub-1765351%22%20slang%3D%22en-US%22%3EImprove%20your%20Python%20IoT%20project%20with%20event%20handlers!%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1765351%22%20slang%3D%22en-US%22%3E%3CP%3EIf%20you%E2%80%99re%20a%20Python%20developer%2C%20you%20probably%20are%20already%20familiar%20with%20the%20simplicity%20of%20event%20handlers.%20They%20make%20it%20easy%20for%20your%20application%20to%20respond%20to%20events%20without%20manually%20spinning%20up%20a%20thread%20to%20poll%20for%20updates.%20This%20is%20even%20more%20important%20for%20IoT%20devices%20that%20may%20be%20resource%20constrained%20while%20still%20needing%20to%20receive%20information%20from%20the%20cloud%20at%20any%20time.%20And%20if%20you%20are%20coding%20for%20IoT%20devices%20that%20connect%20to%20Azure%20IoT%20using%20Python%2C%20then%20you%E2%80%99ll%20be%20happy%20to%20learn%20that%20our%20Python%20SDK%20makes%20this%20easy%20to%20achieve!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%20recently%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-iot-sdk-python%2Freleases%2Ftag%2F2020-09-30%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3Ereleased%3C%2FA%3E%26nbsp%3Ba%20new%20and%20improved%20programming%20model%20based%20on%20event%20handlers%20in%20the%20Azure%20IoT%20Python%20Device%20SDK.%20Until%20now%2C%20developers%20had%20to%20spin%20up%20listener%20threads%20to%20poll%20for%20incoming%20messages%20to%20devices%E2%80%94this%20model%20required%20a%20more%20complicated%20API%20and%20management%20of%20additional%20resources%20by%20the%20developer.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAs%20a%20quick%20example%2C%20let's%20look%20at%20a%20sample%20for%20receiving%20a%20message%20from%20the%20cloud%20on%20a%20device%20using%20event%20handlers%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-python%22%3E%3CCODE%3E%20%20%20%20%20%20%20%20%23%20The%20connection%20string%20for%20a%20device%20should%20never%20be%20stored%20in%20code.%20For%20the%20sake%20of%20simplicity%20we're%20using%20an%20environment%20variable%20here.%0A%0A%20%20%20%20%20%20%20%20conn_str%20%3D%20os.getenv(%22IOTHUB_DEVICE_CONNECTION_STRING%22)%0A%0A%20%20%20%20%20%20%20%20%23%20The%20client%20object%20is%20used%20to%20interact%20with%20your%20Azure%20IoT%20hub.%0A%20%20%20%20%20%20%20%20device_client%20%3D%20IoTHubDeviceClient.create_from_connection_string(conn_str)%0A%0A%20%20%20%20%20%20%20%20%23%20connect%20the%20client.%0A%20%20%20%20%20%20%20%20device_client.connect()%0A%0A%20%20%20%20%20%20%20%20%23%20define%20behavior%20for%20receiving%20a%20message%0A%20%20%20%20%20%20%20%20def%20message_handler(message)%3A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22the%20data%20in%20the%20message%20received%20was%20%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(message.data)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22custom%20properties%20are%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20print(message.custom_properties)%0A%0A%20%20%20%20%20%20%20%20%23%20set%20the%20message%20handler%20on%20the%20client%0A%20%20%20%20%20%20%20%20device_client.on_message_received%20%3D%20message_handler%0A%0A%20%20%20%20%20%20%20%20%23%20finally%2C%20disconnect%0A%20%20%20%20%20%20%20%20device_client.disconnect()%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20this%20example%2C%20you%20can%20see%20how%20the%20code%20does%20not%20create%20any%20new%20threads%20and%20receiving%20a%20message%20is%20as%20simple%20as%20assigning%20the%20event%20handler.%20The%20developer%20does%20not%20have%20to%20worry%20about%20any%20thread%20management%20which%20makes%20writing%20and%20maintaining%20code%20much%20easier%2C%20especially%20as%20your%20IoT%20projects%20scale%20to%20include%20more%20functionality.%20Event%20handlers%20can%20be%20used%20with%20the%20Azure%20IoT%20Python%20SDK%20in%20all%20receive%20message%20scenarios--%20receiving%20C2D%20messages%2C%20direct%20methods%2C%20device%20twin%20patches%2C%20etc.%20To%20see%20how%20you%20can%20adapt%20your%20code%20to%20use%20handlers%2C%20you%20can%20explore%20the%20samples%20in%20our%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-iot-sdk-python%2Ftree%2Fmaster%2Fazure-iot-device%2Fsamples%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3EGithub%20repository%3C%2FA%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%20hope%20our%20new%20event%20helps%20simplify%20your%20IoT%20development%20experience%20with%20the%20Python%20SDK%20and%20optimize%20your%20IoT%20code.%20As%20always%2C%20please%20reach%20out%20to%20us%20on%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fanswers%2Fquestions%2Ftopics%2Fsingle%2F25497.html%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3EMicrosoft%20Q%26amp%3BA%26nbsp%3B%3C%2FA%3E(tag%20with%20%3CEM%3Eazure-iot-sdk%3C%2FEM%3E)%20or%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-iot-sdk-python%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3EGithub%3C%2FA%3E%20with%20any%20questions%20or%20feedback.%20Thanks%20and%20happy%20developing!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1259017649%22%20id%3D%22toc-hId-1259017649%22%3EFAQs%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3E%3CSTRONG%3EI%E2%80%99ve%20already%20written%20my%20applications%20with%20the%20listener%20Python%20SDK%20programming%20model%2C%20do%20I%20need%20to%20update%20the%20code%20to%20use%20handlers%3F%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENo%2C%20the%20listener%20API%20isn%E2%80%99t%20going%20away%20and%20is%20still%20fully%20supported%20by%20the%20Python%20SDK.%20We%20introduced%20handlers%20because%20we%20believe%20they%20are%20much%20easier%20for%20developers%20to%20work%20with%20and%2C%20under%20the%20covers%2C%20they%20allow%20the%20SDK%20to%20be%20a%20lot%20more%20adaptable.%20We%20do%20highly%20recommend%20adapting%20your%20code%20to%20use%20the%20new%20handlers.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3E%3CSTRONG%3EWhat%20scenarios%20will%20benefit%20from%20using%20handlers%20as%20opposed%20to%20the%20polling%20programming%20model%3F%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAll%20scenarios%20will%20benefit%20from%20the%20newer%20model%20in%20terms%20of%20ease%20of%20use.%20There%20are%20no%20changes%20in%20functionality%2C%20we%20have%20just%20introduced%20a%20simpler%2C%20cleaner%2C%20and%20easier%20way%20to%20use%20all%20of%20the%20existing%20receive%20functionality.%20However%2C%20going%20forth%2C%20any%20new%20receive-based%20patterns%20that%20may%20be%20introduced%20will%20only%20support%20the%20newer%20handler%20model.%20The%20older%2C%20polling-based%20model%20remains%20supported%2C%20yet%20we%20will%20not%20continue%20to%20develop%20on%20this%20model%20and%20highly%20recommend%20using%20event%20handlers%20moving%20forward.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3E%3CSTRONG%3EI%20see%20that%20the%20Python%20SDK%20also%20supports%20both%20a%20synchronous%20and%20asynchronous%20programming%20model.%20What%20should%20I%20consider%20when%20deciding%20between%20writing%20sync%20or%20async%20code%3F%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAre%20you%20already%20comfortable%20with%20async%2Fawait%20programming%20models%3F%20Do%20you%20need%20to%20do%20a%20high%20volume%20of%20operations%20simultaneously%3F%20If%20so%2C%20our%20async%20await%20pattern%20may%20be%20best%20for%20you%2C%20as%20it%20is%20optimized%20to%20operate%20asynchronously%20so%20your%20code%20isn't%20slowed%20down%20by%20I%2FO%20delay.%3C%2FP%3E%0A%3CP%3EOtherwise%2C%20for%20users%20who%20may%20not%20be%20familiar%20with%20this%20paradigm%2C%20and%20who%20don't%20need%20to%20optimize%20performance%20for%20a%20high%20volume%20of%20simultaneous%20operations%2C%20the%20synchronous%20model%20will%20probably%20be%20more%20familiar%20and%20simpler%20to%20use.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3E%3CSTRONG%3EDoes%20it%20matter%20if%20I%E2%80%99m%20using%20Python%202%20or%20Python%203%3F%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENo%2C%20handlers%20are%20supported%20for%20both%20Python%202%20and%20Python%203%2C%20and%20for%20both%20synchronous%20and%20asynchronous%20programming.%20The%20synchronous%20client%20is%20compatible%20for%20both%20Python%202%20and%20Python%203%2C%20whereas%20the%20asynchronous%20client%20only%20works%20with%20Python%203.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1765351%22%20slang%3D%22en-US%22%3E%3CP%3EAre%20you%20developing%20an%20IoT%20project%20with%20Python%3F%20See%20how%20using%20event%20handlers%20with%20our%20Azure%20IoT%20Python%20SDK%20makes%20it%20easy%20to%20manage%20receiving%20messages%20from%20the%20cloud.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22PythonHeartIoT.png%22%20style%3D%22width%3A%20370px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F225464i5369CF1D35AB4C28%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22PythonHeartIoT.png%22%20alt%3D%22PythonHeartIoT.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-TEASER%3E
Microsoft

If you’re a Python developer, you probably are already familiar with the simplicity of event handlers. They make it easy for your application to respond to events without manually spinning up a thread to poll for updates. This is even more important for IoT devices that may be resource constrained while still needing to receive information from the cloud at any time. And if you are coding for IoT devices that connect to Azure IoT using Python, then you’ll be happy to learn that our Python SDK makes this easy to achieve!

 

We recently released a new and improved programming model based on event handlers in the Azure IoT Python Device SDK. Until now, developers had to spin up listener threads to poll for incoming messages to devices—this model required a more complicated API and management of additional resources by the developer.

 

As a quick example, let's look at a sample for receiving a message from the cloud on a device using event handlers:

 

 

        # The connection string for a device should never be stored in code. For the sake of simplicity we're using an environment variable here.

        conn_str = os.getenv("IOTHUB_DEVICE_CONNECTION_STRING")

        # The client object is used to interact with your Azure IoT hub.
        device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)

        # connect the client.
        device_client.connect()

        # 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
        device_client.on_message_received = message_handler

        # finally, disconnect
        device_client.disconnect()

 

 

In this example, you can see how the code does not create any new threads and receiving a message is as simple as assigning the event handler. The developer does not have to worry about any thread management which makes writing and maintaining code much easier, especially as your IoT projects scale to include more functionality. Event handlers can be used with the Azure IoT Python SDK in all receive message scenarios-- receiving C2D messages, direct methods, device twin patches, etc. To see how you can adapt your code to use handlers, you can explore the samples in our Github repository.

 

We hope our new event helps simplify your IoT development experience with the Python SDK and optimize your IoT code. As always, please reach out to us on Microsoft Q&A (tag with azure-iot-sdk) or Github with any questions or feedback. Thanks and happy developing!

 

FAQs

 

I’ve already written my applications with the listener Python SDK programming model, do I need to update the code to use handlers?

 

No, the listener API isn’t going away and is still fully supported by the Python SDK. We introduced handlers because we believe they are much easier for developers to work with and, under the covers, they allow the SDK to be a lot more adaptable. We do highly recommend adapting your code to use the new handlers.

 

What scenarios will benefit from using handlers as opposed to the polling programming model?

 

All scenarios will benefit from the newer model in terms of ease of use. There are no changes in functionality, we have just introduced a simpler, cleaner, and easier way to use all of the existing receive functionality. However, going forth, any new receive-based patterns that may be introduced will only support the newer handler model. The older, polling-based model remains supported, yet we will not continue to develop on this model and highly recommend using event handlers moving forward.

 

I see that the Python SDK also supports both a synchronous and asynchronous programming model. What should I consider when deciding between writing sync or async code?

 

Are you already comfortable with async/await programming models? Do you need to do a high volume of operations simultaneously? If so, our async await pattern may be best for you, as it is optimized to operate asynchronously so your code isn't slowed down by I/O delay.

Otherwise, for users who may not be familiar with this paradigm, and who don't need to optimize performance for a high volume of simultaneous operations, the synchronous model will probably be more familiar and simpler to use.

 

Does it matter if I’m using Python 2 or Python 3?

 

No, handlers are supported for both Python 2 and Python 3, and for both synchronous and asynchronous programming. The synchronous client is compatible for both Python 2 and Python 3, whereas the asynchronous client only works with Python 3.