क्लाउड स्टोरेज ट्रिगर


आप क्लाउड स्टोरेज में फ़ाइलों और फ़ोल्डरों को अपलोड करने, अपडेट करने या हटाने के जवाब में एक फ़ंक्शन ट्रिगर कर सकते हैं।

इस पृष्ठ के उदाहरण एक नमूना फ़ंक्शन पर आधारित हैं जो क्लाउड स्टोरेज पर छवि फ़ाइलें अपलोड होने पर ट्रिगर होता है। यह नमूना फ़ंक्शन दर्शाता है कि ईवेंट विशेषताओं तक कैसे पहुंचें, क्लाउड फ़ंक्शंस इंस्टेंस में फ़ाइल कैसे डाउनलोड करें, और क्लाउड स्टोरेज ईवेंट को संभालने के अन्य बुनियादी सिद्धांत।

आवश्यक मॉड्यूल आयात करें

आरंभ करने के लिए, क्लाउड स्टोरेज इवेंट को संभालने के लिए आवश्यक मॉड्यूल आयात करें:

नोड.जे.एस

 const {onObjectFinalized} = require("firebase-functions/v2/storage");

अजगर

 from firebase_functions import storage_fn

पूरा नमूना तैयार करने के लिए, फायरबेस एडमिन एसडीके और इमेज प्रोसेसिंग टूल के लिए निर्भरताएँ भी जोड़ें:

नोड.जे.एस

 const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const logger = require("firebase-functions/logger");
const path = require("path");

// library for image resizing
const sharp = require("sharp");

initializeApp();

अजगर

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

क्लाउड स्टोरेज फ़ंक्शन का दायरा बनाएं

अपने फ़ंक्शन को एक विशिष्ट क्लाउड स्टोरेज बकेट तक सीमित करने और कोई भी वांछित विकल्प सेट करने के लिए निम्नलिखित पैटर्न का उपयोग करें:

नोड.जे.एस

// scope handler to a specific bucket, using storage options parameter
export archivedopts = onObjectArchived({ bucket: "myBucket" }, (event) => {
  //…
});

अजगर

# Scope handler to a specific bucket using storage options parameter
@storage_fn.on_object_archived(bucket="myBucket")
def archived_bucket(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

इसके विपरीत, उदाहरण थंबनेल जेनरेटर फ़ंक्शन को प्रोजेक्ट के लिए डिफ़ॉल्ट बकेट के दायरे में रखा गया है:

नोड.जे.एस

exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {
// ...
});

अजगर

@storage_fn.on_object_archived()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

फ़ंक्शन स्थान सेट करें

स्थानों के बीच बेमेल के परिणामस्वरूप तैनाती विफलता हो सकती है। साथ ही, क्लाउड स्टोरेज बकेट के स्थान और फ़ंक्शन के स्थान के बीच की दूरी महत्वपूर्ण नेटवर्क विलंबता पैदा कर सकती है। इन स्थितियों से बचने के लिए, फ़ंक्शन स्थान निर्दिष्ट करें ताकि यह इनमें से किसी एक तरीके से बकेट/ट्रिगर स्थान से मेल खाए:

  • फ़ंक्शन स्थान ट्रिगर स्थान के समान है
  • फ़ंक्शन स्थान ट्रिगर स्थान के अंदर होता है (जब ट्रिगर क्षेत्र दोहरा/बहु क्षेत्र होता है)
  • यदि ट्रिगर क्षेत्र us-central1 पर सेट है तो फ़ंक्शन किसी भी स्थान पर हो सकता है

क्लाउड स्टोरेज इवेंट को संभालें

क्लाउड स्टोरेज इवेंट पर प्रतिक्रिया देने के लिए ये हैंडलर उपलब्ध हैं:

नोड.जे.एस

  • onObjectArchived केवल तभी भेजा जाता है जब बकेट ने ऑब्जेक्ट संस्करण सक्षम किया हो। यह घटना इंगित करती है कि किसी ऑब्जेक्ट का लाइव संस्करण एक संग्रहीत संस्करण बन गया है, या तो क्योंकि इसे संग्रहीत किया गया था या क्योंकि इसे उसी नाम के ऑब्जेक्ट के अपलोड द्वारा अधिलेखित कर दिया गया था।
  • onObjectDeleted तब भेजा जाता है जब कोई ऑब्जेक्ट स्थायी रूप से हटा दिया गया हो। इसमें वे ऑब्जेक्ट शामिल हैं जो बकेट के जीवनचक्र कॉन्फ़िगरेशन के भाग के रूप में अधिलेखित हैं या हटा दिए गए हैं। ऑब्जेक्ट वर्जनिंग सक्षम वाले बकेट के लिए, यह तब नहीं भेजा जाता है जब कोई ऑब्जेक्ट संग्रहीत किया जाता है ( onArchive देखें), भले ही संग्रहण storage.objects.delete विधि के माध्यम से होता हो।
  • onObjectFinalized तब भेजा जाता है जब बकेट में एक नया ऑब्जेक्ट (या किसी मौजूदा ऑब्जेक्ट की नई पीढ़ी) सफलतापूर्वक बनाया जाता है। इसमें किसी मौजूदा ऑब्जेक्ट को कॉपी करना या फिर से लिखना शामिल है। एक असफल अपलोड इस घटना को ट्रिगर नहीं करता है।
  • onMetadataUpdated किसी मौजूदा ऑब्जेक्ट का मेटाडेटा बदलने पर भेजा जाता है।

अजगर

  • on_object_archived केवल तभी भेजा जाता है जब बकेट ने ऑब्जेक्ट संस्करण सक्षम किया हो। यह घटना इंगित करती है कि किसी ऑब्जेक्ट का लाइव संस्करण एक संग्रहीत संस्करण बन गया है, या तो क्योंकि इसे संग्रहीत किया गया था या क्योंकि इसे उसी नाम के ऑब्जेक्ट के अपलोड द्वारा अधिलेखित कर दिया गया था।
  • on_object_deleted तब भेजा जाता है जब कोई ऑब्जेक्ट स्थायी रूप से हटा दिया गया हो। इसमें वे ऑब्जेक्ट शामिल हैं जो बकेट के जीवनचक्र कॉन्फ़िगरेशन के भाग के रूप में अधिलेखित हैं या हटा दिए गए हैं। ऑब्जेक्ट वर्जनिंग सक्षम वाले बकेट के लिए, यह तब नहीं भेजा जाता है जब कोई ऑब्जेक्ट संग्रहीत किया जाता है ( onArchive देखें), भले ही संग्रहण storage.objects.delete विधि के माध्यम से होता हो।
  • on_object_finalized तब भेजा जाता है जब बकेट में एक नया ऑब्जेक्ट (या किसी मौजूदा ऑब्जेक्ट की नई पीढ़ी) सफलतापूर्वक बनाया जाता है। इसमें किसी मौजूदा ऑब्जेक्ट को कॉपी करना या फिर से लिखना शामिल है। एक असफल अपलोड इस घटना को ट्रिगर नहीं करता है।
  • on_metadata_updated किसी मौजूदा ऑब्जेक्ट का मेटाडेटा बदलने पर भेजा जाता है।

क्लाउड स्टोरेज ऑब्जेक्ट विशेषताओं तक पहुंचें

क्लाउड फ़ंक्शंस कई क्लाउड स्टोरेज ऑब्जेक्ट विशेषताओं को उजागर करता है जैसे कि अपडेट की गई फ़ाइल के लिए ऑब्जेक्ट का आकार और सामग्री प्रकार। जब भी ऑब्जेक्ट के मेटाडेटा में कोई परिवर्तन होता है तो metageneration विशेषता बढ़ जाती है। नई वस्तुओं के लिए, metageneration मान 1 है।

नोड.जे.एस

const fileBucket = event.data.bucket; // Storage bucket containing the file.
const filePath = event.data.name; // File path in the bucket.
const contentType = event.data.contentType; // File content type.

अजगर

bucket_name = event.data.bucket
file_path = pathlib.PurePath(event.data.name)
content_type = event.data.content_type

थंबनेल जेनरेशन नमूना निकास मामलों का पता लगाने के लिए इनमें से कुछ विशेषताओं का उपयोग करता है जिसमें फ़ंक्शन वापस आता है:

नोड.जे.एस

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith("image/")) {
  return logger.log("This is not an image.");
}
// Exit if the image is already a thumbnail.
const fileName = path.basename(filePath);
if (fileName.startsWith("thumb_")) {
  return logger.log("Already a Thumbnail.");
}

अजगर

# Exit if this is triggered on a file that is not an image.
if not content_type or not content_type.startswith("image/"):
    print(f"This is not an image. ({content_type})")
    return

# Exit if the image is already a thumbnail.
if file_path.name.startswith("thumb_"):
    print("Already a thumbnail.")
    return

फ़ाइल डाउनलोड करें, रूपांतरित करें और अपलोड करें

कुछ मामलों में, क्लाउड स्टोरेज से फ़ाइलें डाउनलोड करना आवश्यक नहीं हो सकता है। हालाँकि, क्लाउड स्टोरेज में संग्रहीत फ़ाइल से थंबनेल छवि उत्पन्न करने जैसे गहन कार्य करने के लिए, आपको फ़ंक्शंस इंस्टेंस पर फ़ाइलें डाउनलोड करने की आवश्यकता होती है - अर्थात, वर्चुअल मशीन जो आपका कोड चलाती है।

नोड.जेएस के लिए sharp और पायथन के लिए पिलो जैसे इमेज-प्रोसेसिंग प्रोग्राम के साथ क्लाउड फ़ंक्शंस का उपयोग करके, आप ग्राफ़िकल छवि फ़ाइलों पर हेरफेर कर सकते हैं। अपलोड की गई छवि फ़ाइल के लिए थंबनेल छवि बनाने का एक उदाहरण निम्नलिखित है:

नोड.जे.एस

/**
 * When an image is uploaded in the Storage bucket,
 * generate a thumbnail automatically using sharp.
 */
exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {

  const fileBucket = event.data.bucket; // Storage bucket containing the file.
  const filePath = event.data.name; // File path in the bucket.
  const contentType = event.data.contentType; // File content type.

  // Exit if this is triggered on a file that is not an image.
  if (!contentType.startsWith("image/")) {
    return logger.log("This is not an image.");
  }
  // Exit if the image is already a thumbnail.
  const fileName = path.basename(filePath);
  if (fileName.startsWith("thumb_")) {
    return logger.log("Already a Thumbnail.");
  }

  // Download file into memory from bucket.
  const bucket = getStorage().bucket(fileBucket);
  const downloadResponse = await bucket.file(filePath).download();
  const imageBuffer = downloadResponse[0];
  logger.log("Image downloaded!");

  // Generate a thumbnail using sharp.
  const thumbnailBuffer = await sharp(imageBuffer).resize({
    width: 200,
    height: 200,
    withoutEnlargement: true,
  }).toBuffer();
  logger.log("Thumbnail created");

  // Prefix 'thumb_' to file name.
  const thumbFileName = `thumb_${fileName}`;
  const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);

  // Upload the thumbnail.
  const metadata = {contentType: contentType};
  await bucket.file(thumbFilePath).save(thumbnailBuffer, {
    metadata: metadata,
  });
  return logger.log("Thumbnail uploaded!");
});

फ़ाइल को अपने क्लाउड फ़ंक्शंस इंस्टेंस पर एक अस्थायी निर्देशिका में डाउनलोड करें। इस स्थान पर, आप आवश्यकतानुसार फ़ाइल को संसाधित कर सकते हैं और फिर क्लाउड स्टोरेज पर अपलोड कर सकते हैं। अतुल्यकालिक कार्य करते समय, सुनिश्चित करें कि आप अपने कॉलबैक में एक जावास्क्रिप्ट वादा लौटाएँ।

अजगर

@storage_fn.on_object_finalized()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    """When an image is uploaded in the Storage bucket, generate a thumbnail
    automatically using Pillow."""

    bucket_name = event.data.bucket
    file_path = pathlib.PurePath(event.data.name)
    content_type = event.data.content_type

    # Exit if this is triggered on a file that is not an image.
    if not content_type or not content_type.startswith("image/"):
        print(f"This is not an image. ({content_type})")
        return

    # Exit if the image is already a thumbnail.
    if file_path.name.startswith("thumb_"):
        print("Already a thumbnail.")
        return

    bucket = storage.bucket(bucket_name)

    image_blob = bucket.blob(str(file_path))
    image_bytes = image_blob.download_as_bytes()
    image = Image.open(io.BytesIO(image_bytes))

    image.thumbnail((200, 200))
    thumbnail_io = io.BytesIO()
    image.save(thumbnail_io, format="png")
    thumbnail_path = file_path.parent / pathlib.PurePath(f"thumb_{file_path.stem}.png")
    thumbnail_blob = bucket.blob(str(thumbnail_path))
    thumbnail_blob.upload_from_string(thumbnail_io.getvalue(), content_type="image/png")

यह कोड एक अस्थायी निर्देशिका में सहेजी गई छवि के लिए 200x200 थंबनेल बनाता है, फिर इसे क्लाउड स्टोरेज पर वापस अपलोड करता है।