1

I'm using https://github.com/jazzband/pip-tools to handle compiling the requirements.txt for a Django project.

Previously, I was using without a setup.py and so i was using base.in, local.in, and production.in.

When I needed a local requirements.txt after i finish pip-compile, I just run pip-sync base.txt local.txt and it will install the requirements for local environment.

When I needed a production requirements.txt after i finish pip-compile, I just run pip-sync base.txt production.txt and it will install the requirements for production environment.

So I switch away from using base.in is because I wanted to also lock the python version and i realized, setup.py and setup.cfg can help using python_requires

But now i become unsure of how to use setup.py and setup.cfg along with pip-tools to compile requirements.txt that can be environment-specific.

The only documentation for layered requirements is by using the different .in files as written in the README as https://github.com/jazzband/pip-tools#workflow-for-layered-requirements

So my question is:

Given:

  1. pip-tools
  2. setup.py and setup.cfg

how to still have layered requirements?

Kim Stacks
  • 10,202
  • 35
  • 151
  • 282

1 Answers1

4

pip-tools works smoothly with setup.py too. You just need to run it without providing it with an *.in file.

Mixed variant with setup.py and in files:

So assuming, that you have the following structure:

# setup.py replacing the base.in file
from distutils.core import setup


setup(
    name="MyLibrary",
    version="1.0",
    install_requires=[
        "requests",
        "bcrypt",
    ]
)

and a local.in file:

django

you need to do the following to compile the dependencies:

$ pip-compile -o base.txt 
$ pip-compile local.in
$ pip-sync base.txt local.txt

$ pip-compile -o base.txt will generate dependencies from setup.py using base.txt as an output file. It defaults to requirements.txt. $ pip-compile local.in is the same what you did before, as with the pip-sync part which doesn't change.

So the only magic here is to run pip-compile without providing it with an input file.

Setup.py only solution:

Setup.py supports extras_require which is a dictionary of named optional dependencies:

[...]
    extras_require={
        "local": ["pytest"],
    },
[...]

pip-tools has an option extra:

$ pip-compile --help |grep extra
  --extra TEXT     Name of an extras_require group to install;

So you could do the following:

pip-compile --extra local -o local.txt
pip-compile --extra production -o production.txt

The output files contain all requiremenets in install_requires + the extra requirements specified.

Afterwards you just sync the local/production.txt:

$ pip-sync local.txt
$ pip-sync production.txt

If I was you, I would grab the pure setup.py variant.

wankata
  • 855
  • 4
  • 12
  • Thank you this is more like it! I wish the original website supported this kind of documentation – Kim Stacks Feb 10 '22 at 06:07
  • I’m on mobile phone but will try your answer once back on laptop. Yes agree I think I will pick the pure setup.py way – Kim Stacks Feb 10 '22 at 06:07
  • Actually all of this is documented: https://github.com/jazzband/pip-tools/#requirements-from-setuppy tells you how to use pip-compile with setup.py. If you write `$ pip-compile --help` on the console, you will find out the option about the extras, the way I found it. – wankata Feb 10 '22 at 06:31
  • Oh I must have missed it. My bad – Kim Stacks Feb 10 '22 at 06:31
  • Hi, @KimStacks, were you able to test the solution? Is it working as expected? – wankata Feb 12 '22 at 03:55
  • Sorry something else went wrong and i am not sure why. i will give you the 100 points first. if you can help me with this other issue, that would be great. https://stackoverflow.com/questions/71089578/i-keep-having-subprocess-calledprocesserror-while-trying-to-run-pip-compile-for – Kim Stacks Feb 12 '22 at 06:42
  • works exactly like you said.... you're really good. i hope you have a twitter or github or a blog i can follow – Kim Stacks Feb 12 '22 at 07:36