{"id":13566015,"url":"https://github.com/mormahr/pdf-service","last_synced_at":"2025-04-03T23:30:52.685Z","repository":{"id":38084683,"uuid":"259762059","full_name":"mormahr/pdf-service","owner":"mormahr","description":"A dockerized HTTP service, that generates PDF files from HTML using Weasyprint.","archived":false,"fork":false,"pushed_at":"2025-03-25T07:05:46.000Z","size":1220,"stargazers_count":6,"open_issues_count":24,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T02:07:49.681Z","etag":null,"topics":["docker","html-to-pdf","pdf","pdf-generation","service","weasyprint"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mormahr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-28T22:05:13.000Z","updated_at":"2024-01-31T10:45:18.000Z","dependencies_parsed_at":"2024-08-01T13:22:59.879Z","dependency_job_id":"e446d75e-7ae3-4672-aa81-53c7f8108a59","html_url":"https://github.com/mormahr/pdf-service","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mormahr%2Fpdf-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mormahr%2Fpdf-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mormahr%2Fpdf-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mormahr%2Fpdf-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mormahr","download_url":"https://codeload.github.com/mormahr/pdf-service/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247097644,"owners_count":20883122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","html-to-pdf","pdf","pdf-generation","service","weasyprint"],"created_at":"2024-08-01T13:02:00.150Z","updated_at":"2025-04-03T23:30:51.576Z","avatar_url":"https://github.com/mormahr.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eWeasyPrint in Docker\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\u003cstrong\u003eStateless HTTP API to convert HTML to PDF\u003c/strong\u003e\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://codecov.io/github/mormahr/pdf-service?branch=main\"\u003e\u003cimg alt=\"codecov.io\" src=\"https://codecov.io/github/mormahr/pdf-service/coverage.svg?branch=main\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/r/mormahr/pdf-service\"\u003e\u003cimg alt=\"Docker Image Version\" src=\"https://img.shields.io/docker/v/mormahr/pdf-service?sort=semver\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/r/mormahr/pdf-service\"\u003e\u003cimg alt=\"Docker Pulls\" src=\"https://img.shields.io/docker/pulls/mormahr/pdf-service\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://hub.docker.com/r/mormahr/pdf-service\"\u003e\u003cimg alt=\"Docker Image Size\" src=\"https://img.shields.io/docker/image-size/mormahr/pdf-service?sort=semver\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nA dockerized HTTP service, that generates PDF files from HTML using [WeasyPrint][weasyprint].\nThe primary use-case is generation of documents from developer controlled templates, such as\ninvoices. It is not meant as a general webpage to PDF converter. The service expects input HTML and\nother resources to be safe and doesn't do any hardening or sandboxing that would be required for\narbitrary inputs. Please consult the [security](#security) section of this document.\n\n## Usage\n\nRun the docker image `mormahr/pdf-service` and `POST` the HTML to `/generate` on port 8080.\n\nConsult the [API](#API) section for details about supported features and how to use them.\nSee the [deployment](#deployment) section ([security](#security) in particular) for best practices in\nproduction environments.\n\n```sh\ndocker run --rm -d --name pdf -p 8080:8080 mormahr/pdf-service\n\ncurl \\\n  -H \"Content-Type: text/html\" \\\n  --data '\u003cp\u003eHello World!\u003c/p\u003e' \\\n  http://localhost:8080/generate \\\n  \u003e hello_world.pdf\n\ndocker stop pdf\n```\n\n## API\n\n### Basic \"simple\" API without asset support\n\nMake a `POST` request to `/generate` with the HTML file you want to render as the body.\nThe response will be the PDF file.\n\n```sh\ncurl \\\n  -H \"Content-Type: text/html\" \\\n  --data '\u003cp\u003eHello World!\u003c/p\u003e' \\\n  https://pdf.example.com/generate \\\n  \u003e hello_world.pdf\n```\n\n### Multipart API\n\nMake a `POST` request to `/generate` with a `Content-Type` of `multipart/form-data`. Provide your\nHTML input as `index.html` and add any other required assets. The assets can be referenced _in the \nHTML_ either as an absolute URL like `/image.png` or a relative one `image.png`. Relative URLs are\nresolved against `/`. **Omit the leading slash** for the `multipart/form-data` `name` attribute.\n\n```sh\ncurl \\\n  -F index.html=@index.html \\\n  -F image.png=@image.png \\\n  -F sub-path/image.png=@sub-path/image.png \\\n  https://pdf.example.com/generate \\\n  \u003e hello_world.pdf\n```\n\n```html\n\u003c!-- index.html --\u003e\n\u003cp\u003eWith an image:\u003c/p\u003e\n\u003cimg src=\"/image.png\" /\u003e\n\u003cimg src=\"/sub-path/image.png\" /\u003e\n```\n\n## Deployment\n\n### Versioning\n\nThe docker image is tagged as `mormahr/pdf-service`.\n\nWe follow [semver][semver] as well as possible, including visual changes when we detect them.\nAs such, we also tag release versions like `:1.1.0`. We support semver major (`:1`) or minor (`:1.1`) tags that use the latest minor or patch\nrelease version.\n\nImages of the current development version are continuously pushed to the `:edge` tag.\nWe strongly recommend that you use a release version instead of `:edge`.\n\n### Licensing\n\nThe service code is licensed under the MIT license. WeasyPrint, the underlying PDF generator\nlibrary, is licensed under the BSD license. The prebuilt production container image contains a \nvariety of licenses, including GPLv2 and GPLv3 code.\n\n### Security\n\nIt's not recommended allowing untrusted HTML input.\nUse trusted HTML templates and sanitize user inputs.\n\nFetching of external assets is prohibited as of now. You can add internal assets with the [multipart\nAPI](#multipart-API).\n\nIf your instance is exposed publicly, I recommend using a reverse proxy to terminate TLS connections\nand require authentication. You could use HTTP Basic Auth and then pass the pdf-service URL to your\nclient software via an environment variable. This way auth information can be embedded like this:\n`https://API_USER:API_TOKEN@pdf.example.com/generate`, where `API_USER` and `API_TOKEN` are the\ncredentials you set up in the reverse proxy.\n\n### Environment variables\n\n- `WORKER_COUNT` (default: 4) Sets the worker pool size of the gunicorn server executing pdf_service.\n\n- `HOST` if the hostname isn't set on the container, pass it as an environment variable to identify\n    the service in Sentry.\n  \n- `SENTRY_DSN` Enable the Sentry integration and use this DSN to submit data.\n- `SENTRY_TRACES_SAMPLE_RATE` (`0.0` ... `1.0`) If the Sentry integration is enabled this controls\n  the tracing sample rate. It defaults to `1.0`. Set it to `0.0` to disable tracing.\n- `SENTRY_ENVIRONMENT` This sets the environment sent to Sentry. Defaults to `development`.\n- `SENTRY_RELEASE` This sets the release sent to Sentry. We set this to the current git SHA and you\n  normally shouldn't need to overwrite it.\n- `SENTRY_TAG_*` Set a tag to a specific value for all transactions.\n  For example to set the tag `test` to `abc`, set the environment variable `SENTRY_TAG_TEST=abc`.\n\n### Health check\n\nThe service has a `/health` endpoint that will respond with a `200` status code if the service is\nrunning. This endpoint is also configured as a docker [`HEALTHCHECK`][docker-healthcheck].\n\n### Supported architectures\n\nThe docker image supports the `linux/amd64` (regular Intel and AMD 64bit processors on x86_64) and \n`linux/arm64` (Apple Silicon, AWS Graviton, etc.) architectures.\nImage sizes and other information that varies between architectures is taken from the `linux/amd64`\nvariant.\n\nIf you need a different architecture, please open an issue with your use-case.\n\nNative Windows docker images are not supported. The linux image can be run on Windows using Docker\nDesktop.\n\n## Development\n\n### Setup the development environment\n\n- Setup python venv \n- `pip install -r requirements.txt -r requirements-dev.txt` (or: `pip install -e '.[dev]'`)\n- Install docker and docker-compose to run tests. \n  Tests run in docker to ensure render output doesn't differ based on platform.\n  \n### Running\n\n- Run the development server with `python -m pdf_service`\n- Run tests with `./test` or `./test-watch`\n  - Tests are executed within docker, to ensure render results are identical to the containerized\n    version. The image contains external dependencies, but code and test files will be mounted from\n    the project source. If you want to rebuild the dev image add `--build` to the end of the\n    command. This will instruct `docker-compose` to rebuild the image.\n\n### Visual tests with reference images\n\n`e2e/data` contains reference inputs `*.html` and corresponding output `.png`.\nThe e2e test will render the html files and compare the output with the reference images to ensure \nno changes slipped in.\n\nTo update reference images or add new test cases run `./regenerate-e2e-references`.\n\n[weasyprint]: https://weasyprint.org\n[semver]: https://semver.org\n[container-os-article-1]: https://opensource.com/article/18/1/containers-gpl-and-copyleft\n[stackoverflow-aGPL-modified]: https://softwareengineering.stackexchange.com/questions/107883/agpl-what-you-can-do-and-what-you-cant#comment202259_107931\n[docker-healthcheck]: https://docs.docker.com/engine/reference/builder/#healthcheck\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmormahr%2Fpdf-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmormahr%2Fpdf-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmormahr%2Fpdf-service/lists"}