ERPNext Foundation ERPNext Cloud User Manual Blog Discuss Frappé* Donate

[IMP] Update setup.py for custom apps


#1

Hi,

Recently we made some changes in installation/upgrade flow of requirements, to avoid conflicts for the dependencies in requirements.txt.

Ref PR:


If you have a custom app installed on your frappe-bench, then you may come across the
error while doing bench update or bench setup requirements

eg:

INFO:bench.utils:./env/bin/pip install -q  -e ./apps/dropbox_erpnext_broker 
Command "python setup.py egg_info" failed with error code 1 in /Users/saurabh/project/frappe-bench/apps/dropbox_erpnext_broker/
Traceback (most recent call last):
  File "/usr/local/bin/bench", line 11, in <module>
    load_entry_point('bench', 'console_scripts', 'bench')()
  File "/Users/saurabh/bench-repo/bench/cli.py", line 40, in cli
    bench_command()
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/saurabh/Library/Python/2.7/lib/python/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/Users/saurabh/bench-repo/bench/commands/setup.py", line 161, in setup_requirements
    setup_python_requirements()
  File "/Users/saurabh/bench-repo/bench/commands/setup.py", line 167, in setup_python_requirements
    update_requirements()
  File "/Users/saurabh/bench-repo/bench/utils.py", line 442, in update_requirements
    install_app(app, bench_path=bench_path)
  File "/Users/saurabh/bench-repo/bench/app.py", line 179, in install_app
    find_links=find_links))
  File "/Users/saurabh/bench-repo/bench/utils.py", line 159, in exec_cmd
    raise CommandFailedError(cmd)
bench.utils.CommandFailedError: ./env/bin/pip install -q  -e ./apps/dropbox_erpnext_broker 

Steps to resolve the issue

  1. Run ./env/bin/pip install -e ./apps/[app_name] to identify the actual issue
➜  frappe-bench ./env/bin/pip install -e ./apps/dropbox_erpnext_broker 
Obtaining file:///Users/saurabh/project/frappe-bench/apps/dropbox_erpnext_broker
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/Users/saurabh/project/frappe-bench/apps/dropbox_erpnext_broker/setup.py", line 3, in <module>
        from pip.req import parse_requirements
    ImportError: No module named req
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /Users/saurabh/project/frappe-bench/apps/dropbox_erpnext_broker/
  1. open setup.py for that particular app

  2. remove Ln No: 3 from setu.py
    from pip.req import parse_requirements -

  3. Replace code on line no 14
    old code:

requirements = parse_requirements("requirements.txt", session="")

new code:

with open('requirements.txt') as f:
        install_requires = f.read().strip().split('\n')
  1. Then in setup function remove kwarg dependency_links and update install_requires=install_requires

  2. save the file


Now again run bench update or bench setup requirements where you left…


#2

Thank you! This saved me today.

But really, the underlying problem was the removal of the req module from pip. (as they’ve discussed here)

The above suggested workaround will work, but it would require defining your own module or function to parse the requirements.txt file.

I found a better suggestion here. That is, to change the following line in setup.py:

from pip.req import parse_requirements

to:

from pip._internal.req import parse_requirements

#3

_internal as name and ‘_’ specifies its private module from pip. Module maintainer can make any changes to private modules without publishing them. So it’s not recommended to use private modules inside your code.


#4

Didn’t know about this. Thanks for pointing it out! It’s definitely an important thing to note.