Spaces:
Sleeping
Sleeping
File size: 4,275 Bytes
3950c34 1ec6698 3950c34 1ec6698 3950c34 1ec6698 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | ---
title: PDF API
emoji: π
colorFrom: indigo
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
---
# PDF API
API sederhana untuk mengubah **HTML atau URL menjadi PDF**, ditenagai Express + Playwright (Chromium).
Tujuan: dijual sebagai API di RapidAPI dengan biaya infra minimal.
## Endpoint
| Method | Path | Auth | Keterangan |
| ------ | ------------- | ------ | -------------------------------------------- |
| GET | `/health` | publik | Cek status (untuk health check) |
| POST | `/pdf` | ya | PDF dari `html` atau `url` |
| POST | `/screenshot` | ya | Tangkapan layar (PNG/JPEG) dari `html`/`url` |
Auth: kirim header `X-RapidAPI-Proxy-Secret` (lewat RapidAPI) atau `x-api-key`.
Body `POST /pdf` (JSON):
```json
{ "html": "<h1>Halo</h1>", "format": "A4", "landscape": false }
```
Body `POST /screenshot` (JSON):
```json
{ "url": "https://example.com", "fullPage": true, "type": "png" }
```
Pakai **template + data** (Handlebars) untuk dokumen seperti invoice β pembeli cukup kirim data:
```json
{
"template": "<h1>Invoice {{number}}</h1>{{#each items}}<p>{{name}}: {{price}}</p>{{/each}}<b>Total: {{total}}</b>",
"data": { "number": "INV-001", "items": [{ "name": "Design", "price": "$50" }], "total": "$50" }
}
```
Pilih salah satu dari `html`, `url`, atau `template` (+ `data`) β berlaku untuk `/pdf` dan `/screenshot`.
Atau pakai **template bawaan** (`templateName`) β pembeli cukup kirim `data`, tanpa menyusun HTML. Tersedia: `invoice`.
```json
{
"templateName": "invoice",
"data": {
"company": { "name": "Acme Co", "email": "billing@acme.co" },
"client": { "name": "John Doe" },
"invoice": { "number": "INV-001", "date": "2026-06-01", "due": "2026-06-15" },
"items": [{ "description": "Design work", "quantity": 2, "price": "$25", "amount": "$50" }],
"subtotal": "$50", "tax": "$5", "total": "$55",
"notes": "Thank you!"
}
}
```
Response: `application/pdf`, atau `image/png` | `image/jpeg` (binary).
## Jalan lokal
```bash
npm install
npx playwright install chromium # unduh browser sekali saja
npm start # default http://localhost:8080
```
Tes cepat (hasil tersimpan ke out.pdf):
```bash
curl -X POST http://localhost:8080/pdf \
-H "Content-Type: application/json" \
-d "{\"html\":\"<h1>Halo PDF</h1>\"}" \
--output out.pdf
```
## Deploy gratis (pilih salah satu)
**Render / Railway / Fly.io / Google Cloud Run** β semuanya membaca `Dockerfile`:
1. Push repo ini ke GitHub.
2. Buat service baru dari repo, pilih environment **Docker**.
3. Set environment variable `API_KEY` dengan nilai rahasia.
Cloud Run cocok karena scale-to-zero (tidak ada tagihan saat sepi) dan free tier besar.
## Integrasi RapidAPI
1. Deploy dulu, catat URL publik backend (mis. `https://xxx.onrender.com`).
2. Di RapidAPI: **Add New API** β arahkan Base URL ke backend Anda.
3. Aktifkan opsi RapidAPI yang mengirim header rahasia `X-RapidAPI-Proxy-Secret`,
lalu ubah autentikasi backend untuk memverifikasi header itu (lihat catatan keamanan).
4. Tetapkan paket harga (mis. freemium + bayar per request).
## Keamanan
Sudah terpasang:
- **Autentikasi:** set `RAPIDAPI_PROXY_SECRET` (diverifikasi dari header
`X-RapidAPI-Proxy-Secret`) agar hanya gateway RapidAPI yang bisa mengakses
backend, dan/atau `API_KEY` (header `x-api-key`) untuk akses langsung.
Perbandingan rahasia memakai constant-time. Jika keduanya kosong, API TERBUKA
(hanya untuk tes lokal) dan server menampilkan peringatan saat start.
- **Proteksi SSRF:** setiap request jaringan yang dibuat halaman (navigasi awal,
redirect, dan sub-resource) divalidasi; alamat privat/loopback/link-local
(termasuk metadata cloud `169.254.169.254`) serta skema non-http(s) seperti
`file:` diblokir.
Disarankan sebelum skala besar:
- **Timeout render** agar tidak mudah di-abuse (body HTML sudah dibatasi 2 MB).
- **DNS rebinding:** validasi saat ini mengecek IP hasil resolve; untuk hardening
penuh, pin IP yang sudah divalidasi saat fetch.
## Langkah berikutnya
- Tambah opsi margin, ukuran halaman kustom, dan header/footer untuk PDF.
- Tambah timeout render dan rate limiting agar tahan abuse.
|