← Cloudflare R2 / r2 / tutorials
Použití oznámení o události k shrnutí souborů PDF při nahrání
V tomto tutoriálu se naučíte používat oznámení o událostech ke zpracování souboru PDF při jeho nahrání do R2 bucketu. Použijete Workers AI k vytvoření souhrnu PDF a jeho uložení jako textového souboru ve stejném bucketu.
Předpoklady
Pro pokračování budete potřebovat:
- A účet Cloudflare ↗ s přístupem k R2.
- Mějte existující bucket R2. Přečtěte si Úvodní tutoriál pro R2.
- Nainstalujte
Node.js↗.
Správce verzí Node.js
Použijte správce verzí Node, jako je Volta ↗ nebo
nvm ↗ abyste se vyhnuli problémům s oprávněními a měnili
verze Node.js. Wrangler, o kterém se
dále hovoří v tomto průvodci, vyžaduje verzi Node 16.17.0 nebo novější.
1. Vytvořte nový projekt
Vytvoříte nový projekt Worker, který bude používat Static Assets k obsluze frontendu vaší aplikace. Uživatel může pomocí tohoto frontendu nahrát soubor PDF, který následně zpracuje váš Worker.
Vytvořte nový projekt Worker spuštěním následujících příkazů:
npm create cloudflare@latest -- pdf-summarizerPři nastavení vyberte následující možnosti:
- Pro S čím byste chtěli začít?, vyberte
Hello World example. - Pro Jakou šablonu chcete použít?, vyberte
Worker only. - Pro Jaký jazyk chcete použít?, vyberte
TypeScript. - Pro Chcete používat git pro správu verzí?, vyberte
Yes. - Pro Chcete nasadit svou aplikaci?, vyberte
No(před nasazením provedeme ještě několik změn).
Přejděte na pdf-summarizer adresář:
cd pdf-summarizer2. Vytvořte front-end
Pomocí Static Assets můžete servírovat frontend své aplikace přímo z Workeru. Chcete-li Static Assets použít, musíte do souboru Wrangler přidat požadované bindings.
{
"assets": {
"directory": "public"
}
}[assets]
directory = "public"Dále vytvořte public adresáře a přidejte index.html soubor. index.html soubor by měl obsahovat následující kód HTML:
Vyberte pro zobrazení kódu HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PDF Summarizer</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
background-color: #fefefe;
}
.content {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.upload-container {
background-color: #f0f0f0;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.upload-button {
background-color: #4caf50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.upload-button:hover {
background-color: #45a049;
}
footer {
background-color: #f0f0f0;
color: white;
text-align: center;
padding: 10px;
width: 100%;
}
footer a {
color: #333;
text-decoration: none;
margin: 0 10px;
}
footer a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="content">
<div class="upload-container">
<h2>Upload PDF File</h2>
<form id="uploadForm" onsubmit="return handleSubmit(event)">
<input
type="file"
id="pdfFile"
name="pdfFile"
accept=".pdf"
required
/>
<button type="submit" id="uploadButton" class="upload-button">
Upload
</button>
</form>
</div>
</div>
<footer>
<a
href="https://developers.cloudflare.com/r2/buckets/event-notifications/"
target="_blank"
>R2 Event Notification</a
>
<a
href="https://developers.cloudflare.com/queues/get-started/#3-create-a-queue"
target="_blank"
>Cloudflare Queues</a
>
<a href="https://developers.cloudflare.com/workers-ai/" target="_blank"
>Workers AI</a
>
<a
href="https://github.com/harshil1712/pdf-summarizer-r2-event-notification"
target="_blank"
>GitHub Repo</a
>
</footer>
<script>
handleSubmit = async (event) => {
event.preventDefault();
// Disable the upload button and show a loading message
const uploadButton = document.getElementById("uploadButton");
uploadButton.disabled = true;
uploadButton.textContent = "Uploading...";
// get form data
const formData = new FormData(event.target);
const file = formData.get("pdfFile");
if (file) {
// call /api/upload endpoint and send the file
await fetch("/api/upload", {
method: "POST",
body: formData,
});
event.target.reset();
} else {
console.log("No file selected");
}
uploadButton.disabled = false;
uploadButton.textContent = "Upload";
};
</script>
</body>
</html>Chcete-li zobrazit frontend aplikace, spusťte následující příkaz a přejděte na URL adresu zobrazenou v terminálu:
npm run dev ⛅️ wrangler 3.80.2
-------------------
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8787
╭───────────────────────────╮
│ [b] open a browser │
│ [d] open devtools │
│ [l] turn off local mode │
│ [c] clear console │
│ [x] to exit │
╰───────────────────────────╯Když otevřete tuto URL adresu v prohlížeči, uvidíte formulář pro nahrání souboru. Pokud zkusíte soubor nahrát, zjistíte, že se na server nenahraje. Je to proto, že frontend zatím není propojen s backendem. V dalším kroku upravíte svůj Worker tak, aby nahrávání souboru zpracovával.
3. Zpracujte nahrávání souborů
Chcete-li zpracovat nahrávání souborů, musíte nejprve přidat R2 binding. Do souboru Wrangler přidejte následující kód:
{
"r2_buckets": [
{
"binding": "MY_BUCKET",
"bucket_name": "<R2_BUCKET_NAME>"
}
]
}[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<R2_BUCKET_NAME>"Nahraďte <R2_BUCKET_NAME> s názvem vašeho bucketu R2.
Dále aktualizujte src/index.ts soubor. src/index.ts soubor by měl obsahovat následující kód:
export default {
async fetch(request, env, ctx): Promise<Response> {
// Get the pathname from the request
const pathname = new URL(request.url).pathname;
if (pathname === "/api/upload" && request.method === "POST") {
// Get the file from the request
const formData = await request.formData();
const file = formData.get("pdfFile") as File;
// Upload the file to Cloudflare R2
const upload = await env.MY_BUCKET.put(file.name, file);
return new Response("File uploaded successfully", { status: 200 });
}
return new Response("incorrect route", { status: 404 });
},
} satisfies ExportedHandler<Env>;Výše uvedený kód provádí následující:
- Zkontrolujte, zda se jedná o požadavek POST na
/api/uploadendpoint. Pokud ano, získá soubor z požadavku a nahraje ho do Cloudflare R2 pomocí Workers API. - Pokud požadavek není požadavkem POST na
/api/uploadendpoint, vrátí odpověď 404.
Vzhledem k tomu, že kód Workeru je napsán v TypeScriptu, spusťte následující příkaz pro přidání potřebných definic typů. Není to sice povinné, ale pomůže vám to předejít chybám.
npm run cf-typegenVývojový server můžete restartovat, abyste změny otestovali:
npm run dev4. Vytvořte queue
Oznámení o událostech zaznamenávají změny dat ve vašem bucketu R2. Budete muset vytvořit novou frontu pdf-summarize pro příjem oznámení:
npx wrangler queues create pdf-summarizerPřidejte vazbu do souboru Wrangler:
{
"queues": {
"consumers": [
{
"queue": "pdf-summarizer"
}
]
}
}[[queues.consumers]]
queue = "pdf-summarizer"5. Zpracujte event notifications
Nyní, když máte frontu pro příjem oznámení o událostech, je potřeba upravit Worker tak, aby tato oznámení zpracovával. Budete muset přidat Queue handler, který z PDF extrahuje textový obsah, pomocí Workers AI jej shrne a poté uloží do bucketu R2.
Aktualizujte src/index.ts soubor, do kterého přidáte handler Queue:
export default {
async fetch(request, env, ctx): Promise<Response> {
// No changes in the fetch handler
},
async queue(batch, env) {
for (let message of batch.messages) {
console.log(`Processing the file: ${message.body.object.key}`);
}
},
} satisfies ExportedHandler<Env>;Výše uvedený kód provádí následující:
-
queuehandler se zavolá, když je do fronty přidána nová zpráva. Prochází zprávy v dávce a zaznamenává název souboru.
Prozatím queue handler zatím nic nedělá. V dalších krocích upravíte queue handler tak, aby extrahoval textový obsah z PDF, shrnul ho pomocí Workers AI a poté ho přidal do bucketu.
6. Extrahujte textový obsah z PDF
Chcete-li extrahovat textový obsah z PDF, Worker použije unpdf ↗ knihovna. unpdf knihovna poskytuje nástroje pro práci se soubory PDF.
Nainstalujte unpdf knihovnu nainstalujte pomocí následujícího příkazu:
npm i unpdfAktualizujte src/index.ts soubor, do kterého importujete potřebné moduly z unpdf knihovna:
import { extractText, getDocumentProxy } from "unpdf";Dále aktualizujte queue handler pro extrakci textového obsahu z PDF:
async queue(batch, env) {
for(let message of batch.messages) {
console.log(`Processing file: ${message.body.object.key}`);
// Get the file from the R2 bucket
const file = await env.MY_BUCKET.get(message.body.object.key);
if (!file) {
console.error(`File not found: ${message.body.object.key}`);
continue;
}
// Extract the textual content from the PDF
const buffer = await file.arrayBuffer();
const document = await getDocumentProxy(new Uint8Array(buffer));
const {text} = await extractText(document, {mergePages: true});
console.log(`Extracted text: ${text.substring(0, 100)}...`);
}
}Výše uvedený kód provádí následující:
-
queuehandler načte soubor z R2 bucketu. -
queuehandler extrahuje textový obsah z PDF pomocíunpdfknihovna. -
queuehandler zaznamená textový obsah.
7. Použijte Workers AI k shrnutí obsahu
Chcete-li používat Workers AI, musíte do souboru Wrangler přidat binding Workers AI. Soubor Wrangler by měl obsahovat následující kód:
{
"ai": {
"binding": "AI"
}
}[ai]
binding = "AI"Definici typu AI přidáte spuštěním následujícího příkazu:
npm run cf-typegenAktualizujte src/index.ts soubor tak, aby pro shrnutí obsahu používal Workers AI:
async queue(batch, env) {
for(let message of batch.messages) {
// Extract the textual content from the PDF
const {text} = await extractText(document, {mergePages: true});
console.log(`Extracted text: ${text.substring(0, 100)}...`);
// Use Workers AI to summarize the content
const result: AiSummarizationOutput = await env.AI.run(
"@cf/facebook/bart-large-cnn",
{
input_text: text,
}
);
const summary = result.summary;
console.log(`Summary: ${summary.substring(0, 100)}...`);
}
} queue handler nyní používá Workers AI k shrnutí obsahu.
8. Přidejte shrnutí do R2 bucketu
Nyní, když máte shrnutí, je potřeba jej přidat do bucketu R2. Upravte src/index.ts soubor, do kterého přidáte shrnutí do R2 bucketu:
async queue(batch, env) {
for(let message of batch.messages) {
// Extract the textual content from the PDF
// ...
// Use Workers AI to summarize the content
// ...
// Add the summary to the R2 bucket
const upload = await env.MY_BUCKET.put(`${message.body.object.key}-summary.txt`, summary, {
httpMetadata: {
contentType: 'text/plain',
},
});
console.log(`Summary added to the R2 bucket: ${upload.key}`);
}
}Handler fronty nyní přidá souhrn do bucketu R2 jako textový soubor.
9. Povolte event notifications
Váš queue handler je připraven zpracovávat příchozí zprávy oznámení o událostech. Nyní musíte povolit oznámení o událostech pomocí wrangler r2 bucket notification create příkaz pro váš bucket. Následující příkaz vytvoří oznámení o události pro object-create typ události pro pdf přípona:
npx wrangler r2 bucket notification create <R2_BUCKET_NAME> --event-type object-create --queue pdf-summarizer --suffix "pdf"Nahraďte <R2_BUCKET_NAME> s názvem vašeho bucketu R2.
Oznámení o události se vytvoří pro pdf přípona. Když je nahrán nový soubor s pdf přípona je nahrána do R2 bucketu, pdf-summarizer fronta je aktivována.
10. Nasaďte svůj Worker
Chcete-li nasadit svého Workera, spusťte wrangler deploy příkaz:
npx wrangler deployVe výstupu wrangler deploy zkopírujte URL. Toto je URL vaší nasazené aplikace.
11. Otestujte
Chcete-li aplikaci otestovat, přejděte na URL adresu nasazené aplikace a nahrajte soubor PDF. Případně můžete použít Cloudflare dashboard ↗ k nahrání souboru PDF.
Chcete-li zobrazit protokoly, můžete použít wrangler tail příkazu.
npx wrangler tailLogy uvidíte ve svém terminálu. Můžete také přejít do Cloudflare dashboardu a zobrazit logy v sekci Workers Logs.
Pokud zkontrolujete svůj bucket R2, uvidíte souhrnný soubor.
Závěr
V tomto tutoriálu jste se naučili používat R2 event notifications ke zpracování objektu při nahrání. Vytvořili jste aplikaci pro nahrávání PDF souboru a konzumentského Workera, který vytváří shrnutí PDF souboru. Naučili jste se také použít Workers AI ke shrnutí obsahu PDF souboru a nahrání tohoto shrnutí do bucketu R2.
Stejný postup můžete použít i pro zpracování dalších typů souborů, jako jsou obrázky, videa a zvukové soubory. Stejně tak jej můžete použít pro zpracování dalších typů událostí, jako je smazání nebo aktualizace objektu.
Pokud si chcete prohlédnout kód k tomuto tutoriálu, najdete jej na GitHub ↗.