Здравствуйте! Развернул проект в heroku. Один из контроллеров использует подпроцессы для обработки данных. Вначале, подпроцессы (exe) располагались в том же каталоге, где находится приложение.
На локальном сервере для разработки и отладки это работало. Но после того как я развернул проект на heroku, после вызова данного контроллера, http-запрос завершился ошибкой Errno2 — FileNotFound SOME.EXE. То есть сервер не видел этот exe, который вызывался python-скриптом в контроллере.

В heroku есть консоль bash, с помощью которой проверил наличие этого exe в той папке. Он там был, сюрприз-сюрприз.

В подробном отчёте об ошибке я посмотрел пути, где сервер искал файлы exe. Они следующие:

(b'/app/.heroku/python/bin/SOME.EXE',
b'/usr/local/bin/SOME.EXE',
b'/usr/bin/SOME.EXE',
b'/bin/SOME.EXE')

Ну ладно, взял я всё поменял в проекте, поместил скрипты, exe в первый путь:

b'/app/.heroku/python/bin/SOME.EXE'

Записал изменения через коммит, развернул заново. Появилась ошибка Permission denied: ‘SOME.EXE’

Снова через bash посмотрел, всё там где и нужно.

В этой строке происходит ошибка:

 p = subprocess.Popen(['SOME.EXE'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text = True)

После чего, я подумал, может с правами что не так. Ну через ту же консоль попытался изменить права на выполнение. Не получилось.

Пробовал и так

 chmod u+x .heroku/python/bin/SOME.EXE

и так:

 chmod a+x .heroku/python/bin/SOME.EXE


Права имеет владелец файла читать и редактировать. Всё как было так и есть, команды не сработали.

Стек: python 3.8.5 + django 3.0 + heroku + WSGI: waitress 1.4.4

Спрашиваю здесь, потому что поддержка heroku не спешит особо с кодом помогать.

Traceback:

/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/exception.py in inner
response = get_response(request) …
▶ Local vars
/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = self.process_exception_by_middleware(e, request) …
▶ Local vars
/app/.heroku/python/lib/python3.7/site-packages/django/core/handlers/base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
/app/inputData/views.py in upload_file
j = makeBin.main('hex.ascii', ‘bin’) …
▶ Local vars
/app/.heroku/python/bin/makeBin.py in main
import subprocess
import os
from diehard.settings import BASE_DIR
def main(inpPath, outPath):
‘'’init_path = os.path.join(BASE_DIR, ‘inputData’)
os.chdir(init_path)'''
p = subprocess.Popen(, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text = True) …
p.communicate(input='\n\n\n' + inpPath + ‘\n’ + outPath)

if “__name__” == “__main__”:
main(inpPath, outPath)
▶ Local vars
/app/.heroku/python/lib/python3.7/subprocess.py in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
pass_fds, cwd, env,
startupinfo, creationflags, shell,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite,
restore_signals, start_new_session) …
except:
# Cleanup if the child failed starting.
for f in filter(None, (self.stdin, self.stdout, self.stderr)):
try:
f.close()
except OSError:
▶ Local vars
/app/.heroku/python/lib/python3.7/subprocess.py in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename) …
▶ Local vars