django-wkhtmltopdf на IIS: [WinError 6] Неверный дескриптор - PullRequest
1 голос
/ 20 марта 2019

это мой самый первый вопрос, поэтому, пожалуйста, прости меня, если я забыл что-то упомянуть или что-то не так с ним:)

Я установил проект python (3.5.3) -django (2.1.5) на Windows-сервере IIS (10). Все отлично работает.

Проблема

Только wkhtmltopdf (0.12.5) ведет себя странно.

Когда я запускаю его на локальном хосте, командная строка дает мне

Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

и я могу найти сгенерированный .pdf-файл в моей папке загрузок, как и ожидалось.

Когда я изменяю ALLOWED_HOSTS на IP-адрес Сервера и вызываю URL, чтобы сгенерировать pdf, он говорит, что

Ошибка на / pdf /

[WinError 6] Неверный дескриптор

с трассировкой:

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ Джанго \ ядро ​​\ обработчики \ exception.py" во внутреннем 34. response = get_response (запрос)

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ Джанго \ ядро ​​\ обработчики \ base.py" в _get_response 156. response = self.process_exception_by_middleware (e, request)

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ Джанго \ ядро ​​\ обработчики \ base.py" в _get_response 154. response = response.render ()

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ Джанго \ шаблон \ response.py" в рендере 106. self.content = self.rendered_content

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ wkhtmltopdf \ views.py" в rendered_content 80. cover_template = self.resolve_template (self.cover_template)

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ wkhtmltopdf \ utils.py" в render_pdf_from_template 237. cover_filename = cover.filename, если cover else Нет)

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ wkhtmltopdf \ utils.py" в convert_to_pdf 166. return wkhtmltopdf (pages = pages, ** cmd_options)

Файл "C: \ my_project \ myenv \ Lib \ сайт-пакеты \ wkhtmltopdf \ utils.py" в wkhtmltopdf 147. return check_output (ck_args, ** ck_kwargs)

Файл "C: \ Program Files \ Python35 \ lib \ subprocess.py" в check_output 316. ** kwargs) .stdout

Файл "C: \ Program Files \ Python35 \ lib \ subprocess.py" запущен 383. с Popen (* popenargs, ** kwargs) в качестве процесса:

Файл "C: \ Program Files \ Python35 \ lib \ subprocess.py" в init 640. errread, errwrite) = self._get_handles (стандартный ввод, стандартный вывод, стандартный вывод)

Файл "C: \ Program Files \ Python35 \ lib \ subprocess.py" в _get_handles 884. errwrite = _winapi.GetStdHandle (_winapi.STD_ERROR_HANDLE)

Тип исключения: ошибка OSE / pdf / Значение исключения: [WinError 6] Das Ручка ist ungültig

В папке C:\Users\myapplicationpool\AppData\Local\Temp я вижу, что wkhtmltopdf генерирует .html-файл, называемый, например, wkhtmltopdfgn1s7k5r.html, но каким-то образом прогресс застревает.

Как уже упоминалось здесь и здесь другие тоже имели такую ​​же проблему. Но меняется

if 'stdout' in kwargs:
    raise ValueError('stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)

до

if 'stdout' in kwargs:
    raise ValueError('stdout argument not allowed, it will be overridden.')
kwargs.pop('stderr', None)
process = Popen(stdout=PIPE, stderr=PIPE, stdin=PIPE, *popenargs, **kwargs)

не имеет никакого эффекта. Я думаю, что это решение работает только для файла subprocess.py в Python 2.7, и я использую Python 3+, и функции этого файла изменены.

Я дал полные права доступа для пользователей IUSR & IIS_USRS к папке wkhtmltopdf, где лежат bin-folder & wkhtmltopdf.exe, когда я читал, что это также может помочь, но это не так.

Вопросы

У кого-нибудь есть идеи, что я могу попробовать и помочь мне?

Эта проблема действительно связана с подпроцессами wkhtmltopdf & python или мне скорее нужно изменить / добавить обработчики моего djangohandler FastCgiModule в IIS? Как бы я это сделал?

Почему это работает, когда я запускаю его на сервере локально как localhost без каких-либо проблем, но не когда я вызываю страницу через IP-адрес сервера?- как уже упоминалось: все остальное работает совершенно нормально.

Настройка

Я добавил wkhtmltopdf в INSTALLED_APPS и настроил его так:

settings.py

WKHTMLTOPDF_CMD = 'C:/wkhtmltopdf/bin/wkhtmltopdf'

(как я также читал, что часто возникает проблема из-за пробелов в путях, когда он установлен в 'Program Files'.)

urls.py

path('pdf/', views.MyPDFView.as_view(), name='pdfview'),

views.py

from wkhtmltopdf.views import PDFTemplateResponse
class MyPDFView(View):
    template_name='mypdfview.html'

    def get(self, request):
        response = PDFTemplateResponse(request=self.request,
                                       template=self.template_name,
                                       filename='hello' + '.pdf',
                                       context=self.context,
                                       show_content_in_browser=False,
                                       cmd_options={
                                        'margin-top': 50,
                                        },
                                       )
        return response

mypdfview.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Hello World</title>
</head>
<body>
    <h1>Some headline here.</h1>
</body>
</html>

Редактировать 1: каким-то образом мое приветствие исчезло - добавлено ... Редактировать 2: Кажется, мне не разрешеносказать: "Привет всем"!?

1 Ответ

0 голосов
/ 20 марта 2019

Чтобы сделать тот же обходной путь, который был предложен для python 2.7, вам нужно отредактировать файл wkhtmltopdf / utils.py , метод wkhtmltopdf():

from .subprocess import check_output, PIPE

...

def wkhtmltopdf(pages, output=None, **kwargs):
    ...  

    except (AttributeError, IOError):
        # can't call fileno() on mod_wsgi stderr object
        pass

    # add this:
    if not ck_kwargs.get('stderr'):
        ck_kwargs['stderr'] = PIPE

    return check_output(ck_args, **ck_kwargs)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...