pdfrender 0.1.0__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. pdfrender-1.0.0/PKG-INFO +44 -0
  2. pdfrender-1.0.0/README.md +35 -0
  3. pdfrender-1.0.0/pdfrender/__init__.py +8 -0
  4. pdfrender-1.0.0/pdfrender/api/__init__.py +1 -0
  5. pdfrender-1.0.0/pdfrender/api/account/__init__.py +1 -0
  6. pdfrender-1.0.0/pdfrender/api/account/get_me.py +176 -0
  7. pdfrender-1.0.0/pdfrender/api/render/__init__.py +1 -0
  8. pdfrender-1.0.0/pdfrender/api/render/render_html_to_pdf.py +273 -0
  9. pdfrender-1.0.0/pdfrender/client.py +268 -0
  10. pdfrender-1.0.0/pdfrender/errors.py +16 -0
  11. pdfrender-1.0.0/pdfrender/models/__init__.py +19 -0
  12. pdfrender-1.0.0/pdfrender/models/credits_info.py +95 -0
  13. pdfrender-1.0.0/pdfrender/models/me_response.py +135 -0
  14. pdfrender-1.0.0/pdfrender/models/problem.py +190 -0
  15. pdfrender-1.0.0/pdfrender/models/problem_errors_type_0_item.py +45 -0
  16. pdfrender-1.0.0/pdfrender/models/rate_limit_info.py +118 -0
  17. pdfrender-1.0.0/pdfrender/models/render_request.py +108 -0
  18. pdfrender-1.0.0/pdfrender/models/render_request_pdf_variant_type_0.py +9 -0
  19. pdfrender-1.0.0/pdfrender/py.typed +1 -0
  20. pdfrender-1.0.0/pdfrender/types.py +54 -0
  21. pdfrender-1.0.0/pyproject.toml +29 -0
  22. pdfrender-1.0.0/pyproject.toml.orig +25 -0
  23. pdfrender-0.1.0/.github/workflows/ci.yml +0 -74
  24. pdfrender-0.1.0/.github/workflows/release.yml +0 -68
  25. pdfrender-0.1.0/.gitignore +0 -257
  26. pdfrender-0.1.0/LICENSE +0 -21
  27. pdfrender-0.1.0/PKG-INFO +0 -96
  28. pdfrender-0.1.0/README.md +0 -48
  29. pdfrender-0.1.0/extras/docs/docs/api/data.md +0 -7
  30. pdfrender-0.1.0/extras/docs/docs/api/markdown.md +0 -15
  31. pdfrender-0.1.0/extras/docs/docs/api/pdf.md +0 -7
  32. pdfrender-0.1.0/extras/docs/docs/api/templates.md +0 -15
  33. pdfrender-0.1.0/extras/docs/docs/api/user-input.md +0 -3
  34. pdfrender-0.1.0/extras/docs/docs/guide/data-importer.md +0 -97
  35. pdfrender-0.1.0/extras/docs/docs/guide/db-accessor.md +0 -75
  36. pdfrender-0.1.0/extras/docs/docs/guide/markdown-extensions.md +0 -69
  37. pdfrender-0.1.0/extras/docs/docs/guide/pdf-rendering.md +0 -31
  38. pdfrender-0.1.0/extras/docs/docs/guide/templates.md +0 -71
  39. pdfrender-0.1.0/extras/docs/docs/index.md +0 -30
  40. pdfrender-0.1.0/extras/docs/docs/quickstart.md +0 -70
  41. pdfrender-0.1.0/extras/docs/mkdocs.yml +0 -64
  42. pdfrender-0.1.0/extras/examples/README.md +0 -20
  43. pdfrender-0.1.0/extras/examples/data/client.yml +0 -3
  44. pdfrender-0.1.0/extras/examples/data/invoice.yml +0 -11
  45. pdfrender-0.1.0/extras/examples/models.py +0 -26
  46. pdfrender-0.1.0/extras/examples/run.py +0 -74
  47. pdfrender-0.1.0/extras/examples/style.css +0 -35
  48. pdfrender-0.1.0/extras/examples/templates/invoice.md.jinja2 +0 -17
  49. pdfrender-0.1.0/pdf_render/__init__.py +0 -25
  50. pdfrender-0.1.0/pdf_render/data/__init__.py +0 -5
  51. pdfrender-0.1.0/pdf_render/data/accessor.py +0 -161
  52. pdfrender-0.1.0/pdf_render/data/importer.py +0 -209
  53. pdfrender-0.1.0/pdf_render/data/model_field_typing.py +0 -159
  54. pdfrender-0.1.0/pdf_render/import_functions.py +0 -43
  55. pdfrender-0.1.0/pdf_render/md/__init__.py +0 -3
  56. pdfrender-0.1.0/pdf_render/md/extensions/__init__.py +0 -13
  57. pdfrender-0.1.0/pdf_render/md/extensions/columns.py +0 -47
  58. pdfrender-0.1.0/pdf_render/md/extensions/flex_wrap.py +0 -52
  59. pdfrender-0.1.0/pdf_render/md/extensions/muted_text.py +0 -42
  60. pdfrender-0.1.0/pdf_render/md/extensions/nerdfont_glyph.py +0 -37
  61. pdfrender-0.1.0/pdf_render/md/extensions/page_break.py +0 -39
  62. pdfrender-0.1.0/pdf_render/md/rendering.py +0 -29
  63. pdfrender-0.1.0/pdf_render/pdf/__init__.py +0 -5
  64. pdfrender-0.1.0/pdf_render/pdf/document_template.py +0 -45
  65. pdfrender-0.1.0/pdf_render/pdf/metadata.py +0 -38
  66. pdfrender-0.1.0/pdf_render/pdf/options.py +0 -64
  67. pdfrender-0.1.0/pdf_render/pdf/rendering.py +0 -40
  68. pdfrender-0.1.0/pdf_render/templates/__init__.py +0 -4
  69. pdfrender-0.1.0/pdf_render/templates/environment.py +0 -158
  70. pdfrender-0.1.0/pdf_render/templates/filters/__init__.py +0 -9
  71. pdfrender-0.1.0/pdf_render/templates/filters/format_filters.py +0 -34
  72. pdfrender-0.1.0/pdf_render/templates/filters/getter_filters.py +0 -45
  73. pdfrender-0.1.0/pdf_render/templates/rendering.py +0 -75
  74. pdfrender-0.1.0/pdf_render/templates/tests/__init__.py +0 -0
  75. pdfrender-0.1.0/pdf_render/user_input/__init__.py +0 -3
  76. pdfrender-0.1.0/pdf_render/user_input/undefined_variable_form.py +0 -321
  77. pdfrender-0.1.0/pdfrender.egg-info/PKG-INFO +0 -96
  78. pdfrender-0.1.0/pdfrender.egg-info/SOURCES.txt +0 -70
  79. pdfrender-0.1.0/pdfrender.egg-info/dependency_links.txt +0 -1
  80. pdfrender-0.1.0/pdfrender.egg-info/entry_points.txt +0 -2
  81. pdfrender-0.1.0/pdfrender.egg-info/requires.txt +0 -28
  82. pdfrender-0.1.0/pdfrender.egg-info/scm_file_list.json +0 -66
  83. pdfrender-0.1.0/pdfrender.egg-info/scm_version.json +0 -8
  84. pdfrender-0.1.0/pdfrender.egg-info/top_level.txt +0 -1
  85. pdfrender-0.1.0/pyproject.toml +0 -119
  86. pdfrender-0.1.0/setup.cfg +0 -4
  87. pdfrender-0.1.0/tests/fixtures/data/address.yml +0 -9
  88. pdfrender-0.1.0/tests/fixtures/data/user.yml +0 -12
  89. pdfrender-0.1.0/tests/fixtures/data/user_address.yml +0 -15
  90. pdfrender-0.1.0/tests/fixtures/sqlalchemy_model.py +0 -35
  91. pdfrender-0.1.0/tests/fixtures/sqlmodel_model.py +0 -28
  92. pdfrender-0.1.0/tests/test_data_importer.py +0 -193
  93. pdfrender-0.1.0/tests/test_db_accessor.py +0 -225
  94. pdfrender-0.1.0/tests/test_model_field_typing.py +0 -170
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.3
2
+ Name: pdfrender
3
+ Version: 1.0.0
4
+ Summary: A client library for accessing pdfrender
5
+ Requires-Dist: httpx>=0.23.1,<0.29.0
6
+ Requires-Dist: attrs>=22.2.0
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+
10
+ # pdfrender — Python SDK
11
+
12
+ HTML and CSS to PDF API and MCP server. WeasyPrint with page headers, footers and page numbers, no headless browser. Hosted in Germany.
13
+
14
+ ```sh
15
+ pip install pdfrender
16
+ ```
17
+
18
+ [Get an API key](https://pdfrender.dev/go/pypi-sdk?to=/app/api-keys) and pass it to the client:
19
+
20
+ ```python
21
+ import os
22
+
23
+ from pdfrender import AuthenticatedClient
24
+ from pdfrender.api.account import get_me
25
+
26
+ client = AuthenticatedClient(
27
+ base_url="https://api.pdfrender.dev",
28
+ token=os.environ["PDFRENDER_API_KEY"],
29
+ auth_header_name="X-API-Key",
30
+ prefix="",
31
+ )
32
+ print(get_me.sync(client=client))
33
+ ```
34
+
35
+ Every operation is a module with `sync`, `sync_detailed`, `asyncio` and `asyncio_detailed`; file fields take a `pdfrender.types.File(payload=..., file_name=..., mime_type=...)`.
36
+
37
+ ## Operations
38
+
39
+ | Operation | Module | What it does |
40
+ |---|---|---|
41
+ | `GET /v1/me` | `pdfrender.api.account.get_me` | Your plan, remaining requests, and remaining credits |
42
+ | `POST /v1/render` | `pdfrender.api.render.render_html_to_pdf` | Render an HTML document to a PDF |
43
+
44
+ Generated with openapi-python-client from [`openapi.sdk.json`](../openapi.sdk.json). API reference: https://pdfrender.dev/docs · Support: https://pdfrender.dev/support
@@ -0,0 +1,35 @@
1
+ # pdfrender — Python SDK
2
+
3
+ HTML and CSS to PDF API and MCP server. WeasyPrint with page headers, footers and page numbers, no headless browser. Hosted in Germany.
4
+
5
+ ```sh
6
+ pip install pdfrender
7
+ ```
8
+
9
+ [Get an API key](https://pdfrender.dev/go/pypi-sdk?to=/app/api-keys) and pass it to the client:
10
+
11
+ ```python
12
+ import os
13
+
14
+ from pdfrender import AuthenticatedClient
15
+ from pdfrender.api.account import get_me
16
+
17
+ client = AuthenticatedClient(
18
+ base_url="https://api.pdfrender.dev",
19
+ token=os.environ["PDFRENDER_API_KEY"],
20
+ auth_header_name="X-API-Key",
21
+ prefix="",
22
+ )
23
+ print(get_me.sync(client=client))
24
+ ```
25
+
26
+ Every operation is a module with `sync`, `sync_detailed`, `asyncio` and `asyncio_detailed`; file fields take a `pdfrender.types.File(payload=..., file_name=..., mime_type=...)`.
27
+
28
+ ## Operations
29
+
30
+ | Operation | Module | What it does |
31
+ |---|---|---|
32
+ | `GET /v1/me` | `pdfrender.api.account.get_me` | Your plan, remaining requests, and remaining credits |
33
+ | `POST /v1/render` | `pdfrender.api.render.render_html_to_pdf` | Render an HTML document to a PDF |
34
+
35
+ Generated with openapi-python-client from [`openapi.sdk.json`](../openapi.sdk.json). API reference: https://pdfrender.dev/docs · Support: https://pdfrender.dev/support
@@ -0,0 +1,8 @@
1
+ """A client library for accessing pdfrender"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,176 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.me_response import MeResponse
9
+ from ...types import Response
10
+
11
+
12
+ def _get_kwargs() -> dict[str, Any]:
13
+
14
+ _kwargs: dict[str, Any] = {
15
+ "method": "get",
16
+ "url": "/v1/me",
17
+ }
18
+
19
+ return _kwargs
20
+
21
+
22
+ def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> MeResponse | None:
23
+ if response.status_code == 200:
24
+ response_200 = MeResponse.from_dict(response.json())
25
+
26
+ return response_200
27
+
28
+ if client.raise_on_unexpected_status:
29
+ raise errors.UnexpectedStatus(response.status_code, response.content)
30
+ else:
31
+ return None
32
+
33
+
34
+ def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[MeResponse]:
35
+ return Response(
36
+ status_code=HTTPStatus(response.status_code),
37
+ content=response.content,
38
+ headers=response.headers,
39
+ parsed=_parse_response(client=client, response=response),
40
+ )
41
+
42
+
43
+ def sync_detailed(
44
+ *,
45
+ client: AuthenticatedClient,
46
+ ) -> Response[MeResponse]:
47
+ """Your plan, remaining requests, and remaining credits
48
+
49
+ Check where you stand before a call fails.
50
+
51
+ Returns the plan this request runs on and whether your key was recognized.
52
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
53
+ calls without a key. It also returns the requests left in the current window
54
+ and the features your plan includes. On plans priced in credits, it returns
55
+ the credits left in the current billing period.
56
+
57
+ This call does not count against your rate limit, so the numbers it reports
58
+ are the numbers you have.
59
+
60
+ **Credits:** free. This endpoint is not metered.
61
+
62
+ Raises:
63
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
64
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
65
+
66
+ Returns:
67
+ Response[MeResponse]
68
+ """
69
+
70
+ kwargs = _get_kwargs()
71
+
72
+ response = client.get_httpx_client().request(
73
+ **kwargs,
74
+ )
75
+
76
+ return _build_response(client=client, response=response)
77
+
78
+
79
+ def sync(
80
+ *,
81
+ client: AuthenticatedClient,
82
+ ) -> MeResponse | None:
83
+ """Your plan, remaining requests, and remaining credits
84
+
85
+ Check where you stand before a call fails.
86
+
87
+ Returns the plan this request runs on and whether your key was recognized.
88
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
89
+ calls without a key. It also returns the requests left in the current window
90
+ and the features your plan includes. On plans priced in credits, it returns
91
+ the credits left in the current billing period.
92
+
93
+ This call does not count against your rate limit, so the numbers it reports
94
+ are the numbers you have.
95
+
96
+ **Credits:** free. This endpoint is not metered.
97
+
98
+ Raises:
99
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
100
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
101
+
102
+ Returns:
103
+ MeResponse
104
+ """
105
+
106
+ return sync_detailed(
107
+ client=client,
108
+ ).parsed
109
+
110
+
111
+ async def asyncio_detailed(
112
+ *,
113
+ client: AuthenticatedClient,
114
+ ) -> Response[MeResponse]:
115
+ """Your plan, remaining requests, and remaining credits
116
+
117
+ Check where you stand before a call fails.
118
+
119
+ Returns the plan this request runs on and whether your key was recognized.
120
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
121
+ calls without a key. It also returns the requests left in the current window
122
+ and the features your plan includes. On plans priced in credits, it returns
123
+ the credits left in the current billing period.
124
+
125
+ This call does not count against your rate limit, so the numbers it reports
126
+ are the numbers you have.
127
+
128
+ **Credits:** free. This endpoint is not metered.
129
+
130
+ Raises:
131
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
132
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
133
+
134
+ Returns:
135
+ Response[MeResponse]
136
+ """
137
+
138
+ kwargs = _get_kwargs()
139
+
140
+ response = await client.get_async_httpx_client().request(**kwargs)
141
+
142
+ return _build_response(client=client, response=response)
143
+
144
+
145
+ async def asyncio(
146
+ *,
147
+ client: AuthenticatedClient,
148
+ ) -> MeResponse | None:
149
+ """Your plan, remaining requests, and remaining credits
150
+
151
+ Check where you stand before a call fails.
152
+
153
+ Returns the plan this request runs on and whether your key was recognized.
154
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
155
+ calls without a key. It also returns the requests left in the current window
156
+ and the features your plan includes. On plans priced in credits, it returns
157
+ the credits left in the current billing period.
158
+
159
+ This call does not count against your rate limit, so the numbers it reports
160
+ are the numbers you have.
161
+
162
+ **Credits:** free. This endpoint is not metered.
163
+
164
+ Raises:
165
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
166
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
167
+
168
+ Returns:
169
+ MeResponse
170
+ """
171
+
172
+ return (
173
+ await asyncio_detailed(
174
+ client=client,
175
+ )
176
+ ).parsed
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,273 @@
1
+ from http import HTTPStatus
2
+ from io import BytesIO
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from ... import errors
8
+ from ...client import AuthenticatedClient, Client
9
+ from ...models.problem import Problem
10
+ from ...models.render_request import RenderRequest
11
+ from ...types import File, Response
12
+
13
+
14
+ def _get_kwargs(
15
+ *,
16
+ body: RenderRequest,
17
+ ) -> dict[str, Any]:
18
+ headers: dict[str, Any] = {}
19
+
20
+ _kwargs: dict[str, Any] = {
21
+ "method": "post",
22
+ "url": "/v1/render",
23
+ }
24
+
25
+ _kwargs["json"] = body.to_dict()
26
+
27
+ headers["Content-Type"] = "application/json"
28
+
29
+ _kwargs["headers"] = headers
30
+ return _kwargs
31
+
32
+
33
+ def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> File | Problem | None:
34
+ if response.status_code == 200:
35
+ response_200 = File(payload=BytesIO(response.content))
36
+
37
+ return response_200
38
+
39
+ if response.status_code == 400:
40
+ response_400 = Problem.from_dict(response.json())
41
+
42
+ return response_400
43
+
44
+ if response.status_code == 402:
45
+ response_402 = Problem.from_dict(response.json())
46
+
47
+ return response_402
48
+
49
+ if response.status_code == 403:
50
+ response_403 = Problem.from_dict(response.json())
51
+
52
+ return response_403
53
+
54
+ if response.status_code == 413:
55
+ response_413 = Problem.from_dict(response.json())
56
+
57
+ return response_413
58
+
59
+ if response.status_code == 422:
60
+ response_422 = Problem.from_dict(response.json())
61
+
62
+ return response_422
63
+
64
+ if response.status_code == 429:
65
+ response_429 = Problem.from_dict(response.json())
66
+
67
+ return response_429
68
+
69
+ if response.status_code == 500:
70
+ response_500 = Problem.from_dict(response.json())
71
+
72
+ return response_500
73
+
74
+ if response.status_code == 504:
75
+ response_504 = Problem.from_dict(response.json())
76
+
77
+ return response_504
78
+
79
+ if client.raise_on_unexpected_status:
80
+ raise errors.UnexpectedStatus(response.status_code, response.content)
81
+ else:
82
+ return None
83
+
84
+
85
+ def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[File | Problem]:
86
+ return Response(
87
+ status_code=HTTPStatus(response.status_code),
88
+ content=response.content,
89
+ headers=response.headers,
90
+ parsed=_parse_response(client=client, response=response),
91
+ )
92
+
93
+
94
+ def sync_detailed(
95
+ *,
96
+ client: AuthenticatedClient,
97
+ body: RenderRequest,
98
+ ) -> Response[File | Problem]:
99
+ """Render an HTML document to a PDF
100
+
101
+ Send an HTML document and get the PDF back as a download.
102
+
103
+ Inline images, fonts and CSS as `data:` URIs. External resources (http,
104
+ https, file) are not loaded: a document that references one is rejected with
105
+ 400, and the detail lists the URLs. Relative URLs are ignored. JavaScript is
106
+ not run.
107
+
108
+ Limits: 2 MB of HTML, 50 pages, and 20 seconds including time in the queue.
109
+ Without an API key, the limit is 8 seconds and one render runs at a time.
110
+
111
+ On a paid plan, set `pdf_variant` to `pdf/a-2b` or `pdf/a-3b` for PDF/A
112
+ output.
113
+
114
+ Works without an API key for 10 requests a day per IP address. With a
115
+ key, a rejected or failed call costs no credits.
116
+
117
+ **Credits:** 1 per call.
118
+
119
+ Args:
120
+ body (RenderRequest): An HTML document to render, an optional filename and an optional
121
+ PDF/A variant.
122
+
123
+ Raises:
124
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
125
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
126
+
127
+ Returns:
128
+ Response[File | Problem]
129
+ """
130
+
131
+ kwargs = _get_kwargs(
132
+ body=body,
133
+ )
134
+
135
+ response = client.get_httpx_client().request(
136
+ **kwargs,
137
+ )
138
+
139
+ return _build_response(client=client, response=response)
140
+
141
+
142
+ def sync(
143
+ *,
144
+ client: AuthenticatedClient,
145
+ body: RenderRequest,
146
+ ) -> File | Problem | None:
147
+ """Render an HTML document to a PDF
148
+
149
+ Send an HTML document and get the PDF back as a download.
150
+
151
+ Inline images, fonts and CSS as `data:` URIs. External resources (http,
152
+ https, file) are not loaded: a document that references one is rejected with
153
+ 400, and the detail lists the URLs. Relative URLs are ignored. JavaScript is
154
+ not run.
155
+
156
+ Limits: 2 MB of HTML, 50 pages, and 20 seconds including time in the queue.
157
+ Without an API key, the limit is 8 seconds and one render runs at a time.
158
+
159
+ On a paid plan, set `pdf_variant` to `pdf/a-2b` or `pdf/a-3b` for PDF/A
160
+ output.
161
+
162
+ Works without an API key for 10 requests a day per IP address. With a
163
+ key, a rejected or failed call costs no credits.
164
+
165
+ **Credits:** 1 per call.
166
+
167
+ Args:
168
+ body (RenderRequest): An HTML document to render, an optional filename and an optional
169
+ PDF/A variant.
170
+
171
+ Raises:
172
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
173
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
174
+
175
+ Returns:
176
+ File | Problem
177
+ """
178
+
179
+ return sync_detailed(
180
+ client=client,
181
+ body=body,
182
+ ).parsed
183
+
184
+
185
+ async def asyncio_detailed(
186
+ *,
187
+ client: AuthenticatedClient,
188
+ body: RenderRequest,
189
+ ) -> Response[File | Problem]:
190
+ """Render an HTML document to a PDF
191
+
192
+ Send an HTML document and get the PDF back as a download.
193
+
194
+ Inline images, fonts and CSS as `data:` URIs. External resources (http,
195
+ https, file) are not loaded: a document that references one is rejected with
196
+ 400, and the detail lists the URLs. Relative URLs are ignored. JavaScript is
197
+ not run.
198
+
199
+ Limits: 2 MB of HTML, 50 pages, and 20 seconds including time in the queue.
200
+ Without an API key, the limit is 8 seconds and one render runs at a time.
201
+
202
+ On a paid plan, set `pdf_variant` to `pdf/a-2b` or `pdf/a-3b` for PDF/A
203
+ output.
204
+
205
+ Works without an API key for 10 requests a day per IP address. With a
206
+ key, a rejected or failed call costs no credits.
207
+
208
+ **Credits:** 1 per call.
209
+
210
+ Args:
211
+ body (RenderRequest): An HTML document to render, an optional filename and an optional
212
+ PDF/A variant.
213
+
214
+ Raises:
215
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
216
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
217
+
218
+ Returns:
219
+ Response[File | Problem]
220
+ """
221
+
222
+ kwargs = _get_kwargs(
223
+ body=body,
224
+ )
225
+
226
+ response = await client.get_async_httpx_client().request(**kwargs)
227
+
228
+ return _build_response(client=client, response=response)
229
+
230
+
231
+ async def asyncio(
232
+ *,
233
+ client: AuthenticatedClient,
234
+ body: RenderRequest,
235
+ ) -> File | Problem | None:
236
+ """Render an HTML document to a PDF
237
+
238
+ Send an HTML document and get the PDF back as a download.
239
+
240
+ Inline images, fonts and CSS as `data:` URIs. External resources (http,
241
+ https, file) are not loaded: a document that references one is rejected with
242
+ 400, and the detail lists the URLs. Relative URLs are ignored. JavaScript is
243
+ not run.
244
+
245
+ Limits: 2 MB of HTML, 50 pages, and 20 seconds including time in the queue.
246
+ Without an API key, the limit is 8 seconds and one render runs at a time.
247
+
248
+ On a paid plan, set `pdf_variant` to `pdf/a-2b` or `pdf/a-3b` for PDF/A
249
+ output.
250
+
251
+ Works without an API key for 10 requests a day per IP address. With a
252
+ key, a rejected or failed call costs no credits.
253
+
254
+ **Credits:** 1 per call.
255
+
256
+ Args:
257
+ body (RenderRequest): An HTML document to render, an optional filename and an optional
258
+ PDF/A variant.
259
+
260
+ Raises:
261
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
262
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
263
+
264
+ Returns:
265
+ File | Problem
266
+ """
267
+
268
+ return (
269
+ await asyncio_detailed(
270
+ client=client,
271
+ body=body,
272
+ )
273
+ ).parsed