Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to accept multiple html file #14

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
FROM openlabs/docker-wkhtmltopdf:latest
FROM ubuntu:14.04.3
MAINTAINER Sharoon Thomas <[email protected]>

RUN sed 's/main$/main universe/' -i /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

# Download and install wkhtmltopdf
RUN apt-get install -y build-essential xorg libssl-dev libxrender-dev wget gdebi
RUN wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-trusty-amd64.deb
RUN gdebi --n wkhtmltox-0.12.2.1_linux-trusty-amd64.deb

# Install dependencies for running web service
RUN apt-get install -y python-pip
RUN pip install werkzeug executor gunicorn

# Copy the python app that gunicorn will use
ADD app.py /app.py
EXPOSE 80

ENTRYPOINT ["usr/local/bin/gunicorn"]

# Show the extended help
# Execute gunicorn on the docker
ENTRYPOINT ["/usr/local/bin/gunicorn"]
CMD ["-b", "0.0.0.0:80", "--log-file", "-", "app:application"]
35 changes: 27 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ docker port 071599a1373e 80
where 071599a1373e is the container SHA that docker assigned when
`docker run` was executed in the previous command.

Take a note of the public port number where docker binds to.
or

```sh
docker ps
```

To obtain some information about de container, which include de ip and the port where the container runs. Take a note of the public port number where docker binds to.

## Using the webservice

Expand All @@ -38,14 +44,20 @@ This is a convenient way to use the service from command line
utilities like curl.

```sh
curl -X POST -vv -F 'file=@path/to/local/file.html' http://<docker-host>:<port>/ -o path/to/output/file.pdf
curl -X POST -vv -F 'fichs=@path/to/local/file.html' http://<docker-host>:<port>/ -o path/to/output/file.pdf
```

where:

* docker-host is the hostname or address of the docker host running the container
* port is the public port to which the container is bound to.

To add multiple html files simply add them to the curl command:

```sh
curl -X POST -vv -F '[email protected]' -F '[email protected]' -F '[email protected]' http://<docker-host>:<port>/ -o path/to/output/file.pdf
```

### JSON API

If you are planning on using this service in your application,
Expand All @@ -60,7 +72,9 @@ import requests

url = 'http://<docker_host>:<port>/'
data = {
'contents': open('/file/to/convert.html').read().encode('base64'),
'fichs': {
'f1' : open('/file/to/file1.html').read().encode('base64')
}
}
headers = {
'Content-Type': 'application/json', # This is important
Expand All @@ -69,10 +83,10 @@ response = requests.post(url, data=json.dumps(data), headers=headers)

# Save the response contents to a file
with open('/path/to/local/file.pdf', 'wb') as f:
f.write(response.content)
f.write(response.content.decode('base64'))
```

Here is another example in python, but this time we pass options to wkhtmltopdf.
Here is another example in python, but this time we pass multiple files and options to wkhtmltopdf.
When passing our settings we omit the double dash "--" at the start of the option.
For documentation on what options are available, visit http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

Expand All @@ -82,15 +96,20 @@ import requests

url = 'http://<docker_host>:<port>/'
data = {
'contents': open('/file/to/convert.html').read().encode('base64'),
'fichs': {
'f1' : open('/file/to/file1.html').read().encode('base64'),
'f2' : open('/file/to/file2.html').read().encode('base64'),
'f3' : open('/file/to/file3.html').read().encode('base64')
},
'options': {
#Omitting the "--" at the start of the option
'margin-top': '6',
'margin-left': '6',
'margin-right': '6',
'margin-bottom': '6',
'page-width': '105mm',
'page-height': '40mm'
'page-height': '40mm',
'enable-javascript': ''
}
}
headers = {
Expand All @@ -100,7 +119,7 @@ response = requests.post(url, data=json.dumps(data), headers=headers)

# Save the response contents to a file
with open('/path/to/local/file.pdf', 'wb') as f:
f.write(response.content)
f.write(response.content.decode('base64'))
```

## TODO
Expand Down
76 changes: 45 additions & 31 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#! /usr/bin/env python
"""
WSGI APP to convert wkhtmltopdf As a webservice

:copyright: (c) 2013 by Openlabs Technologies & Consulting (P) Limited
:license: BSD, see LICENSE for more details.
"""
Expand All @@ -12,7 +11,6 @@
from werkzeug.wrappers import Request, Response
from executor import execute


@Request.application
def application(request):
"""
Expand All @@ -26,46 +24,62 @@ def application(request):

request_is_json = request.content_type.endswith('json')

with tempfile.NamedTemporaryFile(suffix='.html') as source_file:
if request_is_json:
# If a JSON payload is there, all data is in the payload
payload = json.loads(request.data)
ficheros = payload.get('fichs', {})
options = payload.get('options', {})
elif request.files:
# Check if any files were uploaded
ficheros = request.files.getlist('fichs')
# Load any options that may have been provided in options
options = json.loads(request.form.get('options', '{}'))

# Adding the args for wkhtmltopdf
args = ['wkhtmltopdf']

# Add Global Options
if options:
for option, value in options.items():
args.append('--%s' % option)
if value:
args.append('"%s"' % value)

if ficheros:
if request_is_json:
# If a JSON payload is there, all data is in the payload
payload = json.loads(request.data)
source_file.write(payload['contents'].decode('base64'))
options = payload.get('options', {})
for f, value in ficheros.items():
sf = tempfile.NamedTemporaryFile(suffix='.html', delete=False)
sf.write(value.decode('base64'))
sf.close()
# Add source file name
args += [sf.name]
elif request.files:
# First check if any files were uploaded
source_file.write(request.files['file'].read())
# Load any options that may have been provided in options
options = json.loads(request.form.get('options', '{}'))

source_file.flush()
for f in ficheros:
sf = tempfile.NamedTemporaryFile(suffix='.html', delete=False)
sf.write(f.read())
sf.close()
# Add source file name
args += [sf.name]

# Evaluate argument to run with subprocess
args = ['wkhtmltopdf']
# Add source file name and output file name
pdf_file_name = 'pdf_file.pdf'
args += [pdf_file_name]

# Add Global Options
if options:
for option, value in options.items():
args.append('--%s' % option)
if value:
args.append('"%s"' % value)

# Add source file name and output file name
file_name = source_file.name
args += [file_name, file_name + ".pdf"]

# Execute the command using executor
execute(' '.join(args))
# Execute the command using executor
execute(' '.join(args))

if request_is_json:
return Response(open(pdf_file_name, 'r').read().encode('base64'))
else:
return Response(
wrap_file(request.environ, open(file_name + '.pdf')),
mimetype='application/pdf',
wrap_file(request.environ, open(pdf_file_name, 'r')),
mimetype='application/pdf'
)


if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple(
'127.0.0.1', 5000, application, use_debugger=True, use_reloader=True
)