Finglish
Finglish

Reputation: 9956

Django: why when I use Ghostscript via popen in django do I get a "file not found" error

I am trying to use ghostscript to convert a pdf to jpg from inside Django, but when I try to use subprocess.popen to run a ghostscript command I get a "file not found" error. If I run exactly the same script from a py file via the command line it works correctly.

Here is my script:

import os
import subprocess

path =  "/tmp/e15hntd/"

### this next line is what seems to cause the file not found error

sp = subprocess.Popen("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + path + "/static.jpg " + path + "/source.pdf")

after searching around for possible solutions I tried several alternative versions of the offending line e.g.:

sp = subprocess.Popen(['gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])

or:

sp = subprocess.call("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + path + "/static.jpg " + path + "/source.pdf")

Here is the full error:

[Errno 2] No such file or directory

Traceback:

File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in wrapper
366.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
91.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
89.         response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py" in inner
196.             return view(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapper
25.             return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
91.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in bound_func
21.                 return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.6/dist-packages/django/db/transaction.py" in inner
209.                 return func(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in change_view
1054.                 self.save_model(request, new_object, form, True)
File "/home/Django/Update/admin.py" in save_model
41.             sp = subprocess.call("gs -dSAFER -dNOPAUSE -dQUIET -dBATCH -sDEVICE=jpeg -sOUTPUTFILE=" + unique_path + "/static.jpg " + unique_path + "/source.pdf" + unique_path + "/source.pdf")
File "/usr/lib/python2.6/subprocess.py" in call
480.     return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py" in __init__
633.                             errread, errwrite)
File "/usr/lib/python2.6/subprocess.py" in _execute_child
1139.                 raise child_exception

Upvotes: 1

Views: 1209

Answers (1)

Luke Woodward
Luke Woodward

Reputation: 64959

The error you're getting means that the subprocess module cannot find the executable it wants to run.

If the script runs from the command-line then the gs executable clearly exists, so it looks like the gs executable is not on the PATH that your Django application is running with. Does it help if you specify the full path to gs (e.g. /usr/bin/gs) instead?

Incidentally, I get the same error message if I try to get subprocess to start a nonexistent executable:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("nonexistent")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

EDIT: if your process uses command-line arguments, the executable name and the argument must be specified as separate list items, as in the second of your attempts at running gs:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call("ls /usr")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
>>> subprocess.call(["ls", "/usr"])
bin  games  include  lib  lib32  lib64  local  sbin  share  src  X11R6
0

The first example didn't work because I don't have an executable named ls /usr anywhere on my system.

Could you try modifying the second of your attempts to use the full path of gs, for example:

sp = subprocess.Popen(['/usr/bin/gs', '-dSAFER', '-dNOPAUSE', '-dQUIET', '-dBATCH', '-sDEVICE=jpeg', '-sOUTPUTFILE=' + path + "/static.jpg", path + "/source.pdf"])

Upvotes: 2

Related Questions