Plyer: Platform independent compatibility layer

Kuldeep Grewal
4 min readJun 10, 2018

Plyer is an open source library to access features commonly found in various platforms via python. It is under heavy development with current version being 1.3.0 and provides support for Windows, MacOX, Linux, Android and iOS.

Content

  • History of plyer
  • How to use it?
  • An example with kivy
  • How plyer works?
  • Internal working
  • Contributing.
  • Conclusion.

History of plyer.

Kivy organisation started plyer project as a need to get access of various platform features since kivy organisation provides the framework to build cross-platform apps and softwares using python.

For example, In order to trigger the phone calling interface in the mobile devices, one needs to access the libraries provided by the respective platform in the native language itself.

For android one needs to get android.content.Intent and android.net.Uri and start a new activity with intent action Intent.ACTION_CALL and Intent.setData as telephone number to trigger a call.

For iOS one needs to get UIApplication and NSURL with tel(telephone number) as an object_str to trigger a call.

But how to do the same using python? To tackle this problem kivy started 3 projects:
PyJnius, PyObjus and Plyer.

Pyjnius: A Python module to access Java classes as Python classes using JNI.

Pyobjus: Python module for accessing Objective-C classes as Python classes using Objective-C runtime reflection.

Plyer: A platform-independent api to use features commonly found on various platforms in Python like Accelerometer, Calling, Text to speech, Wifi, Barometer and many more.

How to use plyer?

Using plyer is super easy.

Get accelerometer readings::

Get battery status::

Turn on flash::

I highly recommend you to try Kivy Remote Shell to see these examples work on a real android device. One important point to stress upon is that Plyer is independent of Kivy and can work as a separate entity.

Example with kivy.

Text to Speech converter. Just copy paste the following code and make sure you have kivy installed with version greater than 1.8.0.

Create a main.py file.

Create a text2speechdemo.kv file. [name for .kv file should be same]

Run the application using python main.py in any of the supported platforms listed in the introduction and use this awesome feature.

How plyer works?

Plyer tries not to reinvent the wheel, and calls for external libraries to implement the api in the easiest way, depending on the current platform.

  • On Android (python-for-android), pyjnius is used.
  • On iOS (kivy-ios), pyobjus is used
  • On windows/mac/linux, commonly found libraries and programs are used.

Let’s look at the calling feature implementation for android platform. One thing to notice is this line of code from jnius import autoclass where jnius is PyJnius and autoclass is a method that returns a Python class see code.

Using the above code to trigger calls.

Internal working.

This sounds cool, how does plyer recognises the platform and uses only those files which are needed?

To understand this you need to dive into the codebase of plyer, first let us look at the file structure of plyer.

- plyer
- facades
- __init__.py
- ... abstract classes of each feature (https://www.python.org/dev/peps/pep-3119/) way to abstract classes.
- platforms # Implementations.
- android/
- ios/
- linux/
- macosx/
- win/
- __init__.py
- __init__.py
- compat.py
- utils.py
- other files.

Let’s take a look at one example of accelerometer and see how it works.

When we do from plyer import accelerometer, since it's a module it goes to __init__.py (link) file where the real magic happens.

This file creates a proxy for each feature available in facades/__init__.py

where platform is an object of Platform class which is responsible to detect the platform name [Platform class internally usesfrom sys import platform to get the platform's name.] and name is the feature's name(accelerometer).
mod is the module and instance is the method which returns the class defined in the accelerometer.py file under each platform's implementation.

THE FLOW:

  • Goes to __init__.py
  • accelerometer = Proxy('accelerometer', facades.Accelerometer)
  • Goes to Proxy class
  • _ensure_obj gets called
  • object obj becomes the object of the class from plyer.platforms.android.accelerometer
  • ready to import.

Contributing

Project Plyer is open to contributions visit https://github.com/kivy/plyer#contributing for more info.

Conclusion

Thank you for reading this post — I hope you found this helpful. You can find me on GitHub, LinkedIn and CodeMentor. If you have any questions, feel free to reach out to me!

Want to read more?

Originally published at www.codementor.io.

--

--