funbrew-pdf 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.
- funbrew_pdf-1.0.0/PKG-INFO +9 -0
- funbrew_pdf-1.0.0/README.md +84 -0
- funbrew_pdf-1.0.0/funbrew_pdf/__init__.py +3 -0
- funbrew_pdf-1.0.0/funbrew_pdf/client.py +127 -0
- funbrew_pdf-1.0.0/funbrew_pdf.egg-info/PKG-INFO +9 -0
- funbrew_pdf-1.0.0/funbrew_pdf.egg-info/SOURCES.txt +9 -0
- funbrew_pdf-1.0.0/funbrew_pdf.egg-info/dependency_links.txt +1 -0
- funbrew_pdf-1.0.0/funbrew_pdf.egg-info/requires.txt +1 -0
- funbrew_pdf-1.0.0/funbrew_pdf.egg-info/top_level.txt +1 -0
- funbrew_pdf-1.0.0/pyproject.toml +15 -0
- funbrew_pdf-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: funbrew-pdf
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: FUNBREW PDF API client for Python
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://pdf.funbrew.cloud
|
|
7
|
+
Project-URL: Documentation, https://pdf.funbrew.cloud/docs
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Requires-Dist: requests>=2.28
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# funbrew-pdf
|
|
2
|
+
|
|
3
|
+
Official Python client library for the [FUNBREW PDF API](https://pdf.funbrew.cloud). Type hints included.
|
|
4
|
+
|
|
5
|
+
[日本語ドキュメント](README.ja.md)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install funbrew-pdf
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from funbrew_pdf import FunbrewPdf
|
|
17
|
+
|
|
18
|
+
pdf = FunbrewPdf("sk-your-api-key")
|
|
19
|
+
|
|
20
|
+
# HTML to PDF
|
|
21
|
+
result = pdf.from_html("<h1>Hello World</h1>")
|
|
22
|
+
print(result["data"]["download_url"])
|
|
23
|
+
|
|
24
|
+
# URL to PDF
|
|
25
|
+
result = pdf.from_url("https://example.com")
|
|
26
|
+
|
|
27
|
+
# Template to PDF
|
|
28
|
+
result = pdf.from_template("invoice", {
|
|
29
|
+
"company_name": "Acme Inc.",
|
|
30
|
+
"amount": "1,000",
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
# Generate PDF and send via email
|
|
38
|
+
result = pdf.from_html_with_email(
|
|
39
|
+
"<h1>Invoice</h1>",
|
|
40
|
+
"customer@example.com",
|
|
41
|
+
subject="Your invoice is ready",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Test mode (no count, TEST watermark)
|
|
45
|
+
result = pdf.test("<h1>Test</h1>")
|
|
46
|
+
|
|
47
|
+
# File operations
|
|
48
|
+
info = pdf.info("uuid.pdf")
|
|
49
|
+
content = pdf.download("uuid.pdf")
|
|
50
|
+
with open("output.pdf", "wb") as f:
|
|
51
|
+
f.write(content)
|
|
52
|
+
pdf.delete("uuid.pdf")
|
|
53
|
+
|
|
54
|
+
# Usage stats
|
|
55
|
+
usage = pdf.usage()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Options
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
result = pdf.from_html("<h1>Hello</h1>",
|
|
62
|
+
options={"page-size": "A3"},
|
|
63
|
+
expiration_hours=168,
|
|
64
|
+
max_downloads=5,
|
|
65
|
+
password="secret",
|
|
66
|
+
watermark="CONFIDENTIAL",
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Error Handling
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from funbrew_pdf import FunbrewPdf, FunbrewError
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
result = pdf.from_html("<h1>Hello</h1>")
|
|
77
|
+
except FunbrewError as e:
|
|
78
|
+
print(e) # Error message
|
|
79
|
+
print(e.status_code) # HTTP status code
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""FUNBREW PDF API client for Python."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FunbrewError(Exception):
|
|
11
|
+
"""FUNBREW PDF API error."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, message: str, status_code: int = 0):
|
|
14
|
+
super().__init__(message)
|
|
15
|
+
self.status_code = status_code
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FunbrewPdf:
|
|
19
|
+
"""FUNBREW PDF API client.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
api_key: Your API key (sk-...)
|
|
23
|
+
base_url: API base URL (default: https://pdf.funbrew.cloud)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, api_key: str, base_url: str = "https://pdf.funbrew.cloud"):
|
|
27
|
+
self.api_key = api_key
|
|
28
|
+
self.base_url = base_url.rstrip("/")
|
|
29
|
+
self.session = requests.Session()
|
|
30
|
+
self.session.headers.update(
|
|
31
|
+
{
|
|
32
|
+
"Authorization": f"Bearer {api_key}",
|
|
33
|
+
"Content-Type": "application/json",
|
|
34
|
+
"Accept": "application/json",
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
self.session.timeout = 60
|
|
38
|
+
|
|
39
|
+
def from_html(self, html: str, **options: Any) -> dict:
|
|
40
|
+
"""Generate PDF from HTML content."""
|
|
41
|
+
return self._post("/api/pdf/generate-from-html", {"html": html, **options})
|
|
42
|
+
|
|
43
|
+
def from_url(self, url: str, **options: Any) -> dict:
|
|
44
|
+
"""Generate PDF from URL."""
|
|
45
|
+
return self._post("/api/pdf/generate-from-url", {"url": url, **options})
|
|
46
|
+
|
|
47
|
+
def from_template(
|
|
48
|
+
self, slug: str, variables: dict | None = None, **options: Any
|
|
49
|
+
) -> dict:
|
|
50
|
+
"""Generate PDF from template."""
|
|
51
|
+
return self._post(
|
|
52
|
+
"/api/pdf/generate-from-template",
|
|
53
|
+
{"template": slug, "variables": variables or {}, **options},
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def from_html_with_email(
|
|
57
|
+
self,
|
|
58
|
+
html: str,
|
|
59
|
+
to: str,
|
|
60
|
+
subject: str = "",
|
|
61
|
+
body: str = "",
|
|
62
|
+
**options: Any,
|
|
63
|
+
) -> dict:
|
|
64
|
+
"""Generate PDF and send via email."""
|
|
65
|
+
email: dict[str, str] = {"to": to}
|
|
66
|
+
if subject:
|
|
67
|
+
email["subject"] = subject
|
|
68
|
+
if body:
|
|
69
|
+
email["body"] = body
|
|
70
|
+
return self.from_html(html, email=email, **options)
|
|
71
|
+
|
|
72
|
+
def info(self, filename: str) -> dict:
|
|
73
|
+
"""Get PDF file info."""
|
|
74
|
+
return self._get(f"/api/pdf/info/{filename}")
|
|
75
|
+
|
|
76
|
+
def download(self, filename: str) -> bytes:
|
|
77
|
+
"""Download PDF file content as bytes."""
|
|
78
|
+
res = self.session.get(f"{self.base_url}/api/pdf/download/{filename}")
|
|
79
|
+
if not res.ok:
|
|
80
|
+
raise FunbrewError("Download failed", res.status_code)
|
|
81
|
+
return res.content
|
|
82
|
+
|
|
83
|
+
def delete(self, filename: str) -> dict:
|
|
84
|
+
"""Delete PDF file."""
|
|
85
|
+
return self._request("DELETE", f"/api/pdf/delete/{filename}")
|
|
86
|
+
|
|
87
|
+
def batch(self, items: list[dict]) -> dict:
|
|
88
|
+
"""Batch generate multiple PDFs."""
|
|
89
|
+
return self._post("/api/pdf/batch", {"items": items})
|
|
90
|
+
|
|
91
|
+
def batch_status(self, batch_uuid: str) -> dict:
|
|
92
|
+
"""Get batch generation status."""
|
|
93
|
+
return self._get(f"/api/pdf/batch/{batch_uuid}")
|
|
94
|
+
|
|
95
|
+
def merge(self, filenames: list[str], **options: Any) -> dict:
|
|
96
|
+
"""Merge multiple PDFs into one."""
|
|
97
|
+
return self._post("/api/pdf/merge", {"filenames": filenames, **options})
|
|
98
|
+
|
|
99
|
+
def usage(self) -> dict:
|
|
100
|
+
"""Get usage information."""
|
|
101
|
+
return self._get("/api/usage")
|
|
102
|
+
|
|
103
|
+
def test(self, html: str, **options: Any) -> dict:
|
|
104
|
+
"""Generate PDF in test mode (no count, TEST watermark)."""
|
|
105
|
+
return self.from_html(html, test=True, **options)
|
|
106
|
+
|
|
107
|
+
def _get(self, path: str) -> dict:
|
|
108
|
+
return self._request("GET", path)
|
|
109
|
+
|
|
110
|
+
def _post(self, path: str, data: dict) -> dict:
|
|
111
|
+
return self._request("POST", path, data)
|
|
112
|
+
|
|
113
|
+
def _request(self, method: str, path: str, data: dict | None = None) -> dict:
|
|
114
|
+
try:
|
|
115
|
+
res = self.session.request(
|
|
116
|
+
method,
|
|
117
|
+
f"{self.base_url}{path}",
|
|
118
|
+
json=data if method != "GET" else None,
|
|
119
|
+
)
|
|
120
|
+
body = res.json()
|
|
121
|
+
if not res.ok:
|
|
122
|
+
raise FunbrewError(
|
|
123
|
+
body.get("message", "API request failed"), res.status_code
|
|
124
|
+
)
|
|
125
|
+
return body
|
|
126
|
+
except requests.RequestException as e:
|
|
127
|
+
raise FunbrewError(f"Network error: {e}") from e
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: funbrew-pdf
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: FUNBREW PDF API client for Python
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://pdf.funbrew.cloud
|
|
7
|
+
Project-URL: Documentation, https://pdf.funbrew.cloud/docs
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Requires-Dist: requests>=2.28
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.28
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
funbrew_pdf
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "funbrew-pdf"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "FUNBREW PDF API client for Python"
|
|
9
|
+
license = {text = "MIT"}
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
dependencies = ["requests>=2.28"]
|
|
12
|
+
|
|
13
|
+
[project.urls]
|
|
14
|
+
Homepage = "https://pdf.funbrew.cloud"
|
|
15
|
+
Documentation = "https://pdf.funbrew.cloud/docs"
|