Is there a way to have a conditional requirements.txt file for my Python application based on platform?

I have a python application that I wrote to be compatible with both, Linux and Windows platforms. However there is one problem… One of the python packages I need for Windows is not compatible with Linux. Fortunately there is another package that provides the same functionality on Linux. All other dependencies are compatible in both platforms.

I know I could have 2 separate requirement files to address both platform dependencies separately. Something like win_requirements.txt and linux_requirements.txt, however this approach doesn’t feel like the best way to do it.

I wonder if there is a way I can have only one requirements.txt file so any user can use pip install -r requirements.txt to install all the dependencies regardless of what platform they are?

Maybe something like??:

SOAPpy>=0.12.22
pycrypto>=2.6.1
suds>=0.4
Python-ldap>=2.4.19
paramiko>=1.15.2
nose>=1.3.4
selenium>=2.44.0
bottle>=0.12.8
CherryPy>=3.6.0
pika>=0.9.14
if platform.system() == 'Linux':
    wmi-client-wrapper>=0.0.12
else if platform.system() == 'Windows':
    WMI>=1.4.9

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can add certain conditional requirements after a semi-colon. Particularly useful for sys_platform and python_version.

Examples:

atomac==1.1.0; sys_platform == 'darwin'
futures>=3.0.5; python_version < '3.0'
futures>=3.0.5; python_version == '2.6' or python_version=='2.7'

Apparently you can also exclude particular versions of a library:

futures>=3.0,!=3.0.5

They are defined in PEP 508 and PEP 0345 (Environment Markers) but the syntax appears to follow the draft PEP 0496.

Method 2

You could create an install.py script and call pip by script.

import pip

_all_ = [
    "SOAPpy>=0.12.22",
    "pycrypto>=2.6.1",
    "suds>=0.4",
    "Python-ldap>=2.4.19",
    "paramiko>=1.15.2",
    "nose>=1.3.4",
    "selenium>=2.44.0",
    "bottle>=0.12.8",
    "CherryPy>=3.6.0",
    "pika>=0.9.14",
]

windows = ["wmi-client-wrapper>=0.0.12",]

linux = ["WMI>=1.4.9",]

darwin = []

def install(packages):
    for package in packages:
        pip.main(['install', package])

if __name__ == '__main__':

    from sys import platform

    install(_all_) 
    if platform == 'windows':
        install(windows)
    if platform.startswith('linux'):
        install(linux)
    if platform == 'darwin': # MacOS
        install(darwin)

Another way to resolve this issue using only requirements files should be using inheritance of requirements

requirements.txt

SOAPpy>=0.12.22
pycrypto>=2.6.1
suds>=0.4
Python-ldap>=2.4.19
paramiko>=1.15.2
nose>=1.3.4
selenium>=2.44.0
bottle>=0.12.8
CherryPy>=3.6.0

windows.txt

-r requirements.txt
WMI>=1.4.9

linux.txt

-r requirements.txt
WMI>=1.4.9

Then you can call just the requirement equivalent to platform.

pip install -r windows.txt
pip install -r linux.txt

Method 3

You can add additional requirements to any package after a semicolon. You may limit any package with multi-condition by and, or. more conditions: https://www.python.org/dev/peps/pep-0508/#environment-markers

examples:

futures>=3.0.5; python_version < '3.0'
futures>=3.0.5; python_version == '2.6' or python_version=='2.7'
futures>3 ; python_version >= "3.6" and sys_platform == "linux"
futures>3.3 ; python_version >= "3.6" and sys_platform == "darwin"

Method 4

Use this in the requirements.txt file

uwsgi==2.0.18; platform_system != "Windows"

in this case pip will install uwsgi if not running on Windows


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x