This week, we present the beta version of our new Python programming library. It's a complete overhaul, taking full advantage of the developments in the Python language over the last few years.
The original version of our Python programming library was written 13 years ago, when Python 2.7 was still the standard. To access Yoctopuce modules, we chose to use - as with many languages - our dynamic library written in C. Although we provide this dynamic library precompiled for most architectures and operating systems, some architectures such as MIPSel are not supported.
Since then, the Python language has evolved considerably, and new features of real interest to the user have appeared, including typing and asynchronous programming. As Python is one of the most popular languages among Yoctopuce users, we decided to completely rewrite our library to enable users to take full advantage of these new features, and to remove all external dependencies.
You'll be able to use this new library with any Python version 3.8 or higher. Older versions, unfortunately, don't support typed syntax, but don't worry: we'll continue to maintain the original version to support older machines and existing applications. Both versions of the library will be available in parallel.
Installation
The library is available from PyPi, from GitHub and of course from our website.
Unlike the old Python library, this version is designed from the outset to be used as a PyPi package. The package name is yoctolib and can be installed with the following command:
pip install yoctolib
Once installed, you can include the library files using the package name yoctolib.
from yoctolib.yocto_relay import YRelay
If you've downloaded the library from GitHub or our website, you can install the library using the -e option and the Yoctopuce library path.
For example, the following code downloads the library from GitHub and installs it in the list of available packages:
~/test $ git clone https://github.com/yoctopuce/yoctolib_typedpython.git ~/test $ pip install -e ~/test/yoctolib_typedpython
Finally, if you don't want to use pip at all, you can always copy the source files into your project directory and reference them directly.
New features
Now that we've seen how to install and include the library, let's take a look at what's new in this version.
Typing
This library uses Python typing. The use of Python typing improves code readability and enables errors to be detected before the application is executed.
All the library's code is typed, making it easier to detect errors in the code that interacts with our API.
Typing allows errors to be detected directly from the IDE
If you don't use typing in your application, it's not a problem. The code will function identically, but your IDE will have more difficulty detecting errors.
Asynchronous programming
As with JavaScript, TypeScript and C#, Python now supports asynchronous programming with the async and await keywords, enabling you to efficiently manage multiple parallel execution streams without the need for threads.
As a reminder, the async keyword is used to declare an asynchronous function, and the await keyword is used to call this function asynchronously, i.e. allowing other tasks to run in between if necessary, until the asynchronous function has been executed. This syntax makes it possible to run several tasks in parallel in a Python interpreter. For more details, please read the Python documentation page dedicated to this topic.
The use of asynchronous code in Python is fairly recent, but is rapidly gaining in popularity as it enables better performance on small machines.
Internally, our new library is based on asynchronous functions using async/await. However, so as not to force all users to adopt asynchronous code, the library also exposes a synchronous interface 100% compatible with our original library. This synchronous version is actually a wrapper around the asynchronous version, enabling "old-fashioned" use in synchronous mode.
To use the synchronous version, simply include the yocto_xxxxxx.py files in your application as before. For example, here's the synchronous version of a program that lists modules connected locally:
def main():
errmsg = YRefParam()
if YAPI.RegisterHub("localhost", errmsg) != YAPI.SUCCESS:
print("YAPI.RegisterHub : " + str(errmsg))
return
print('Device list:')
module = YModule.FirstModule()
while module is not None:
serial = module.get_serialNumber()
product_name = module.get_productName()
print(serial + ' (' + product_name + ')')
module = module.nextModule()
YAPI.FreeAPI()
if __name__ == '__main__':
main()
To use the asynchronous version of the library, use the yocto_xxxxxx_aio.py files, and the async/await keywords.
Here's the asynchronous version of the same program:
from yoctolib.yocto_api_aio import YRefParam, YAPI, YModule
async def main():
errmsg = YRefParam()
if await YAPI.RegisterHub("localhost", errmsg) != YAPI.SUCCESS:
print("YAPI.RegisterHub : " + str(errmsg))
return
print('Device list:')
module = YModule.FirstModule()
while module is not None:
serial = await module.get_serialNumber()
product_name = await module.get_productName()
print(serial + ' (' + product_name + ')')
module = module.nextModule()
await YAPI.FreeAPI()
if __name__ == '__main__':
asyncio.run(main(), debug=False)
As you can see, the code is very similar. You simply need to add await to asynchronous function calls. To find out whether a function is asynchronous, you'll need to consult our library documentation or the source code, but thanks to typing, 99% of the time your IDE should warn you if you've forgotten an await. In general, our functions are asynchronous, with the exception of the FindXXX(), FirstXXX(), and nextXXX() methods.
Limitations
Access to USB ports
The most attentive will have noticed that in our example we've used YAPI.RegisterHub("localhost") instead of the traditional YAPI.RegisterHub("usb"). The reason is that this library does not currently support direct access to USB ports.
Like the JavaScript, TypeScript, PHP, and Java libraries, VirtualHub must be installed to access USB ports. The procedure for installing VirtualHub is explained in this post.
This limitation is due to the fact that this library is written 100% in Python and that the Python VM does not allow direct access to USB devices. We have a few ideas for getting around this limitation, but for the time being, using VirtualHub is the best solution.
The data logger
We are currently rethinking the use of the data logger to make it more efficient on machines with very little RAM, but this version is not yet available. As a result, the data logger is not yet supported in this version, but this limitation is temporary.
Conclusion
This new library is still in beta testing, so there may still be a few bugs. It is, however, usable and actively tested internally.
The focus of this version is to make the library more efficient on very small machines. The new asynchronous API also makes it easier to integrate our modules into asynchronous software.
As usual, if you have any problems or suggestions, please let us know either on GitHub or by email.