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.
@@ -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,3 @@
1
+ from .client import FunbrewPdf, FunbrewError
2
+
3
+ __all__ = ["FunbrewPdf", "FunbrewError"]
@@ -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,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ funbrew_pdf/__init__.py
4
+ funbrew_pdf/client.py
5
+ funbrew_pdf.egg-info/PKG-INFO
6
+ funbrew_pdf.egg-info/SOURCES.txt
7
+ funbrew_pdf.egg-info/dependency_links.txt
8
+ funbrew_pdf.egg-info/requires.txt
9
+ funbrew_pdf.egg-info/top_level.txt
@@ -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"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+