1. खास जानकारी
इस लैब में, आपको इवेंट प्रोसेसिंग को ट्रिगर करने के लिए Cloud Storage बकेट इवेंट और Eventarc का इस्तेमाल करने का तरीका पता चलेगा. डेटा का विश्लेषण करने और इमेज को प्रोसेस करने के लिए, Cloud Functions (2nd gen) का इस्तेमाल किया जाएगा. यह फ़ंक्शन Google के Vision API का इस्तेमाल करेगा और नतीजे के तौर पर मिलने वाली इमेज को वापस Cloud Storage बकेट में सेव करेगा.
आपको क्या सीखने को मिलेगा
इमेज प्रोसेसिंग पाइपलाइन बनाने का तरीका.
- स्टोरेज बकेट कॉन्फ़िगर करें
- Cloud Storage में ऑब्जेक्ट पढ़ने और लिखने के लिए Cloud फ़ंक्शन बनाएं
- खाने की इमेज का पता लगाने के लिए, Vision API को इंटिग्रेट करें
- क्लाउड फ़ंक्शन डिप्लॉय करें
- Eventarc ट्रिगर को डिप्लॉय करें
- एंड-टू-एंड समाधान की जांच और पुष्टि करें
ज़रूरी शर्तें
- यह लैब, Cloud Console और शेल एनवायरमेंट को अच्छी तरह से समझता है.
- पहले से मौजूद Cloud Storage, Cloud Functions या Vision API इस्तेमाल करना मददगार है. हालांकि, ऐसा करना ज़रूरी नहीं है.
2. सेटअप और ज़रूरी शर्तें
Cloud प्रोजेक्ट का सेटअप
- Google Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से Gmail या Google Workspace खाता नहीं है, तो आपको नया खाता बनाना होगा.
- प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों का डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करता. इसे कभी भी अपडेट किया जा सकता है.
- प्रोजेक्ट आईडी, Google Cloud के सभी प्रोजेक्ट के लिए यूनीक होता है. साथ ही, इसे बदला नहीं जा सकता. इसे सेट करने के बाद बदला नहीं जा सकता. Cloud Console, एक यूनीक स्ट्रिंग अपने-आप जनरेट करता है; आम तौर पर, आपको उसके होने की कोई परवाह नहीं होती. ज़्यादातर कोडलैब में, आपको प्रोजेक्ट आईडी का रेफ़रंस देना होगा. आम तौर पर, इसे
PROJECT_ID
के तौर पर पहचाना जाता है. अगर आपको जनरेट किया गया आईडी पसंद नहीं है, तो किसी भी क्रम में एक और आईडी जनरेट किया जा सकता है. इसके अलावा, खुद भी आज़माया जा सकता है और देखें कि वह उपलब्ध है या नहीं. इस चरण के बाद इसे बदला नहीं जा सकता और प्रोजेक्ट के कुल समय तक बना रहेगा. - आपकी जानकारी के लिए, एक तीसरी वैल्यू यानी प्रोजेक्ट नंबर है. इसका इस्तेमाल कुछ एपीआई करते हैं. दस्तावेज़ में इन तीनों वैल्यू के बारे में ज़्यादा जानें.
- इसके बाद, आपको क्लाउड संसाधनों/एपीआई का इस्तेमाल करने के लिए, Cloud Console में बिलिंग चालू करनी होगी. इस कोडलैब का इस्तेमाल करने पर, आपको ज़्यादा पैसे नहीं चुकाने होंगे. इस ट्यूटोरियल के अलावा, संसाधनों को बंद करने के लिए कि आपको बिलिंग न करनी पड़े. इसके लिए, अपने बनाए गए संसाधनों को मिटाएं या पूरा प्रोजेक्ट मिटाएं. Google Cloud के नए उपयोगकर्ता, 300 डॉलर के मुफ़्त ट्रायल वाले प्रोग्राम में हिस्सा ले सकते हैं.
Cloud Shell चालू करें
खोज बार की दाईं ओर मौजूद आइकॉन पर क्लिक करके, Cloud Shell को चालू करें.
एनवायरमेंट का सेटअप
- Cloud Shell टर्मिनल में, नीचे दिए गए निर्देशों को चलाकर प्रोजेक्ट और संसाधन से जुड़े एनवायरमेंट वैरिएबल बनाएं.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NAME=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1
export UPLOAD_BUCKET=gs://menu-item-uploads-$PROJECT_ID
export BUCKET_THUMBNAILS=gs://menu-item-thumbnails-$PROJECT_ID
export MENU_SERVICE_NAME=menu-service
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")
- लैब के लिए ज़रूरी एपीआई चालू करें
gcloud services enable \
vision.googleapis.com \
cloudfunctions.googleapis.com \
pubsub.googleapis.com \
cloudbuild.googleapis.com \
logging.googleapis.com \
eventarc.googleapis.com \
artifactregistry.googleapis.com \
run.googleapis.com \
--quiet
- लैब के लिए ज़रूरी एपीआई चालू करें. (Qwiklabs का खास चरण)
gcloud services disable cloudfunctions.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
- डेटा स्टोर करने की जगह का क्लोन बनाएं
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/cloud-functions
3. Cloud Storage बकेट कॉन्फ़िगर करना
स्टोरेज बकेट बनाएं
इमेज प्रोसेसिंग की अपनी पाइपलाइन के लिए, अपलोड और थंबनेल Cloud Storage बकेट बनाएं.
दो बकेट बनाने के लिए, gsutil mb कमांड और कोई यूनीक नाम का इस्तेमाल करें:
- अपलोड बकेट जहां इमेज को पहले अपलोड किया जाएगा
- जनरेट की गई थंबनेल इमेज को सेव करने के लिए थंबनेल बकेट
नई इमेज अपलोड करने के लिए बकेट बनाएं:
gsutil mb -p $PROJECT_ID -l $REGION $UPLOAD_BUCKET
आउटपुट का उदाहरण:
Creating gs://menu-item-uploads-cymbal-eats-8399-3119/...
जनरेट किए गए थंबनेल सेव करने के लिए बकेट बनाएं:
gsutil mb -p $PROJECT_ID -l $REGION $BUCKET_THUMBNAILS
आउटपुट का उदाहरण:
Creating gs://menu-item-thumbnails-cymbal-eats-8399-3119/...
बकेट की अनुमतियां अपडेट करें
उपयोगकर्ताओं को पढ़ने की अनुमतियां देने के लिए, स्टोरेज बकेट की अनुमतियां अपडेट करें.
अपनी बकेट में ऑब्जेक्ट पढ़ने और लिखने की अनुमति देने के लिए, gsutil iam ch कमांड का इस्तेमाल करें:
gsutil iam ch allUsers:objectViewer $UPLOAD_BUCKET
gsutil iam ch allUsers:objectViewer $BUCKET_THUMBNAILS
आउटपुट का उदाहरण
Updated IAM policy for project [cymbal-eats-8399-3119]. [...]
4. सेवा खाते कॉन्फ़िगर करें
थंबनेल प्रोसेस करने के लिए, Cloud Function का इस्तेमाल करने के लिए अपनी पसंद के मुताबिक सेवा खाता बनाएं:
export CF_SERVICE_ACCOUNT=thumbnail-service-sa
gcloud iam service-accounts create ${CF_SERVICE_ACCOUNT}
Artifact Registry से, रीड ऑपरेशन की अनुमति देने के लिए artifactregistry.reader
को भूमिका दें:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role "roles/artifactregistry.reader"
जनरेट की गई इमेज को थंबनेल बकेट में सेव करने की अनुमति देने के लिए, storage.objectCreator
की भूमिका दें:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role "roles/storage.objectCreator"
Cloud Run सेवा को शुरू करने की अनुमति देने के लिए, run.invoker
की भूमिका दें:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role "roles/run.invoker"
सेवा देने वाली कंपनियों से इवेंट पाने के लिए, eventarc.eventReceiver
की भूमिका असाइन करें:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role "roles/eventarc.eventReceiver"
Cloud Storage सेवा खाते को pubsub.publisher
की भूमिका दें. इससे सेवा खाते को, बकेट में इमेज अपलोड करने पर इवेंट पब्लिश करने की अनुमति मिल जाएगी.
GCS_SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)
gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
--member "serviceAccount:$GCS_SERVICE_ACCOUNT" \
--role "roles/pubsub.publisher"
5. इमेज प्रोसेसिंग फ़ंक्शन की खास जानकारी
Cloud Storage से इमेज डाउनलोड करने, इमेज का साइज़ बदलने, और इमेज को Cloud Storage में वापस अपलोड करने के लिए फ़ंक्शन बनाएं. इमेज के लिए जानकारी का लेबल असाइन करने के लिए, फ़ंक्शन Vision API को कॉल करेगा. फ़ंक्शन, ब्यौरे के लेबल की जांच करेगा. अगर लेबल, इमेज की पहचान "फ़ूड" के तौर पर करता है, तो मेन्यू आइटम की इमेज और थंबनेल अपडेट करने के लिए, मेन्यू सेवा को एक इवेंट भेजा जाएगा.
फ़ंक्शन को ट्रिगर करना
Cloud Storage के फ़ंक्शन, Cloud Storage से Pub/Sub सूचनाओं पर आधारित होते हैं और मिलते-जुलते इवेंट टाइप के साथ काम करते हैं:
इस लैब में, Cloud Storage में किसी ऑब्जेक्ट को तय करने के बाद, फ़ंक्शन को डिप्लॉय और ट्रिगर किया जा सकता है.
ऑब्जेक्ट को फ़ाइनल करें
"लिखें" लिखने पर, ऑब्जेक्ट इवेंट ट्रिगर को पूरा करता है Cloud Storage ऑब्जेक्ट को फ़ाइनल कर दिया गया है. खास तौर पर, इसका मतलब यह है कि कोई नया ऑब्जेक्ट बनाने या किसी मौजूदा ऑब्जेक्ट को ओवरराइट करने से यह इवेंट ट्रिगर होता है. यह ट्रिगर संग्रह और मेटाडेटा अपडेट की कार्रवाइयों को अनदेखा करता है.
6. Cloud Storage इंटिग्रेट करें
Cloud Storage एक ऐसी सेवा है जिसकी मदद से, Google Cloud में ऑब्जेक्ट सेव किए जाते हैं. ऑब्जेक्ट डेटा का ऐसा हिस्सा होता है जिसमें बदलाव नहीं किया जा सकता. इसमें किसी भी फ़ॉर्मैट की फ़ाइल शामिल होती है. ऑब्जेक्ट को बकेट नाम के कंटेनर में स्टोर किया जाता है. सभी बकेट किसी प्रोजेक्ट से जुड़े होते हैं और आपके पास अपने प्रोजेक्ट को किसी संगठन के ग्रुप में रखने का विकल्प होता है. क्लाइंट लाइब्रेरी और एपीआई , Cloud Storage के साथ इंटिग्रेट करते हैं
इस लैब में, आपको Cloud Storage में ऑब्जेक्ट पढ़ने और लिखने के लिए, क्लाइंट लाइब्रेरी का इस्तेमाल करना होगा.
क्लाइंट लाइब्रेरी इंस्टॉल करना
क्लाउड क्लाइंट लाइब्रेरी कई लोकप्रिय प्रोग्रामिंग भाषाओं में उपलब्ध हैं. लाइब्रेरी का इस्तेमाल शुरू करने के लिए, आपको क्लाइंट लाइब्रेरी इंस्टॉल करनी होगी.
क्लाइंट लाइब्रेरी का इस्तेमाल करना
लागू करने से जुड़ी जानकारी, प्रोग्रामिंग भाषा पर निर्भर करती है. अपने ऐप्लिकेशन में क्लाइंट लाइब्रेरी का इस्तेमाल करने के लिए, सबसे पहले Cloud Storage डिपेंडेंसी इंपोर्ट करना है. उदाहरण के लिए, Node.js प्रोजेक्ट में इंपोर्ट, Package.json फ़ाइल में जोड़ा जाता है. नीचे दिया गया स्निपेट इस लैब की Package.json फ़ाइल की सूचना दिखाता है.
package.json
{ "name": "thumbnail-service", "version": "0.1.0", "dependencies": { "@google-cloud/functions-framework": "^3.0.0", "@google-cloud/storage": "^5.18.2", "@google-cloud/vision": "^2.4.2", ... } }
CloudEvent कॉलबैक रजिस्टर करें
Functions फ़्रेमवर्क के साथ CloudEvent कॉलबैक रजिस्टर करें, जो बकेट में नई इमेज अपलोड किए जाने पर Cloud Storage से ट्रिगर होगा.
index.js
functions.cloudEvent('process-thumbnails', async (cloudEvent) => { console.log(`Event ID: ${cloudEvent.id}`); console.log(`Event Type: ${cloudEvent.type}`); ...
स्टोरेज से जुड़ा रेफ़रंस ऑब्जेक्ट बनाना
क्लाइंट लाइब्रेरी इंपोर्ट होने के बाद, आपको एक नया स्टोरेज क्लाइंट और बकेट बनाना होगा, ताकि आपका ऐप्लिकेशन इंटरैक्ट कर सके.
index.js
const storage = new Storage(); const bucket = storage.bucket(file.bucket); const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);
Cloud Storage ऑब्जेक्ट डाउनलोड करना
index.js
await bucket.file(file.name).download({ destination: originalFile });
Cloud Storage में ऑब्जेक्ट अपलोड करें
Cloud Storage पर डेटा अपलोड करने के अनुरोध तीन तरीकों से किए जा सकते हैं: एक अनुरोध वाला, फिर से शुरू किया जा सकने वाला या एक्सएमएल एपीआई के एक से ज़्यादा हिस्सों वाला अपलोड. बड़े अपलोड या स्ट्रीमिंग अपलोड के लिए, फिर से शुरू किए जा सकने वाले अपलोड का इस्तेमाल करें. एक्सएमएल एपीआई फ़ाइलों को अलग-अलग हिस्सों में अपलोड किया जाता है और एक ऑब्जेक्ट के तौर पर जोड़ा जाता है. छोटे ऑब्जेक्ट के लिए, एक अनुरोध वाले अपलोड का इस्तेमाल करें.
नीचे दिया गया कोड, एक अनुरोध वाले अपलोड का इस्तेमाल करके, क्लाउड स्टोरेज पर इमेज अपलोड करता है.
index.js
const thumbnailImage = await thumbBucket.upload(thumbFile);
7. Vision API इंटिग्रेट करें
Cloud Vision की मदद से डेवलपर, ऐप्लिकेशन में दृष्टि का पता लगाने वाली सुविधाओं को आसानी से इंटिग्रेट कर सकते हैं. इनमें इमेज लेबल करना, चेहरा और लैंडमार्क की पहचान, ऑप्टिकल कैरेक्टर रिकग्निशन (ओसीआर), और अश्लील कॉन्टेंट को टैग करना शामिल है.
क्लाइंट लाइब्रेरी इंस्टॉल करना
क्लाउड क्लाइंट लाइब्रेरी कई लोकप्रिय प्रोग्रामिंग भाषाओं में उपलब्ध हैं. लाइब्रेरी का इस्तेमाल शुरू करने के लिए, आपको क्लाइंट लाइब्रेरी इंस्टॉल करनी होगी.
इमेज एनोटेटर क्लाइंट बनाना
आधिकारिक क्लाइंट SDK टूल का इस्तेमाल करके, Google API को ऐक्सेस करने के लिए, एपीआई के खोज से जुड़े दस्तावेज़ के आधार पर सेवा ऑब्जेक्ट बनाया जाता है. इस दस्तावेज़ में, SDK टूल के एपीआई के बारे में जानकारी होती है. आपको अपने क्रेडेंशियल का इस्तेमाल करके, Vision API की डिस्कवरी सेवा से इसे फ़ेच करना होगा.
index.js
const client = new vision.ImageAnnotatorClient();
Vision API अनुरोध बनाएं
Vision API, इमेज फ़ाइल के कॉन्टेंट को आपके अनुरोध के मुख्य हिस्से में, base64 कोड में बदले गए स्ट्रिंग के तौर पर भेजकर, इमेज फ़ाइल पर सुविधा की पहचान कर सकता है.
इमेज के बारे में जानकारी देने के लिए, इमेज रिसॉर्स का इस्तेमाल करके अनुरोध करें. इस एपीआई को किया गया अनुरोध, अनुरोधों की सूची के साथ एक ऑब्जेक्ट के तौर पर दिखता है. इस सूची के हर आइटम में दो तरह की जानकारी होती है:
- base64 कोड में बदली गई इमेज का डेटा
- उन सुविधाओं की सूची जिनके बारे में आपको उस इमेज के बारे में जानकारी चाहिए.
index.js
const client = new vision.ImageAnnotatorClient(); const visionRequest = { image: { source: { imageUri: `gs://${file.bucket}/${file.name}` } }, features: [ { type: 'LABEL_DETECTION' }, ] }; const visionPromise = client.annotateImage(visionRequest);
8. Cloud फ़ंक्शन डिप्लॉय करें
इमेज का साइज़ बदलने वाली यह सेवा, Cymbal Eagles के बड़े सिस्टम का हिस्सा है. इस सेक्शन में, आपको सिर्फ़ इमेज प्रोसेसिंग की सुविधा से जुड़े कॉम्पोनेंट डिप्लॉय करने होंगे. पूरी प्रोसेस में, इमेज अपलोड करने के लिए यूज़र इंटरफ़ेस (यूआई) शामिल होता है. साथ ही, इस मेटाडेटा को सेव करने के लिए, डाउनस्ट्रीम अनुरोध भी शामिल होता है. उन सुविधाओं को इस लैब के हिस्से के तौर पर इंस्टॉल नहीं किया जाता है.
फ़ंक्शन डिप्लॉयमेंट के दौरान ये कॉम्पोनेंट बनाए जाएंगे:
- Cloud फ़ंक्शन
- Cloud Run सेवा
- Eventarc ट्रिगर
- Pub/Sub के विषय और सदस्यता
Cloud Shell टर्मिनल में, menu-item-uploads-$PROJECT_ID
पर ट्रिगर बकेट के साथ Cloud Function डिप्लॉय करने के लिए, नीचे दिया गया निर्देश चलाएं:
gcloud functions deploy process-thumbnails \
--gen2 \
--runtime=nodejs16 \
--source=thumbnail \
--region=$REGION \
--project=$PROJECT_ID \
--entry-point=process-thumbnails \
--trigger-bucket=$UPLOAD_BUCKET \
--service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--set-env-vars=BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS,MENU_SERVICE_URL=$MENU_SERVICE_URL \
--max-instances=1 \
--quiet
अगर अपलोड स्टोरेज बकेट पर अनुमति से जुड़ी समस्या की वजह से डिप्लॉयमेंट नहीं हो पाता है, तो कृपया पिछले चरण के IAM बदलावों के लागू होने का इंतज़ार करें. आम तौर पर, इसमें एक से दो मिनट लगते हैं. इसके बाद, डिप्लॉयमेंट को फिर से करने की कोशिश करें.
आउटपुट का उदाहरण
Deploying function (may take a while - up to 2 minutes)...done. [...]
Cloud Console में, बनाए गए Cloud Function की समीक्षा करें:
Cloud Console में, इस फ़ंक्शन के लिए बनाई गई Cloud Run सेवा की समीक्षा करें:
Cloud Console में, फ़ंक्शन के लिए बनाए गए Eventarc ट्रिगर की समीक्षा करें:
Cloud Console में, Eventarc ट्रिगर के लिए बनाई गई Pub/Sub विषय और सदस्यता देखें:
9. एंड-टू-एंड समाधान की जांच और पुष्टि करें
Cloud Storage में एक नई फ़ोटो अपलोड करें. साथ ही, इमेज के विश्लेषण के बाद, पाइपलाइन की प्रोग्रेस पर नज़र रखें. क्लाउड फ़ंक्शन लॉग को मॉनिटर करके, एंड-टू-एंड समाधान की जांच की जाएगी.
सही इमेज अपलोड करना
- इस इमेज को अपने कंप्यूटर पर सेव करें
- फ़ाइल 1.jpg का नाम बदलें
- Cloud Storage कंसोल खोलें
- menu-item-uploads-... बकेट पर क्लिक करें
- फ़ाइलें अपलोड करें पर क्लिक करें
- स्टोरेज बकेट में 1.jpg अपलोड करें
- Cloud Console में, Cloud Functions पर जाएं
- प्रोसेस-थंबल पर क्लिक करें
- लॉग टैब पर क्लिक करें
- menu-item-thumbnails-$PROJECT_ID Cloud Storage बकेट में जाएं
- पुष्टि करें कि थंबनेल इमेज, थंबनेल बकेट में बनाई गई हो
ऐसी इमेज अपलोड करना जो खाने की नहीं है
यह पुष्टि करने के लिए कि फ़ंक्शन ठीक से काम कर रहा है, आपको एक ऐसी इमेज अपलोड करनी होगी जिसमें कोई ऐसी चीज़ न हो जिसे "फ़ूड" की कैटगरी में रखा जाएगा आइटम.
- इस इमेज को अपने कंप्यूटर पर सेव करें
- फ़ाइल 2.jpg का नाम बदलें
- Cloud Storage कंसोल खोलें
- menu-item-uploads-... बकेट पर क्लिक करें
- फ़ाइलें अपलोड करें पर क्लिक करें
- स्टोरेज बकेट में 2.jpg अपलोड करें
- Cloud Console में, Cloud Functions पर जाएं
- प्रोसेस-थंबल पर क्लिक करें
- लॉग टैब पर क्लिक करें
10. बधाई हो!
बधाई हो, आपने लैब पूरा कर लिया है!
आने वाले समय में मिलने वाली सुविधाएं:
Cymbal Eagles के अन्य कोडलैब एक्सप्लोर करें:
- Eventarc की मदद से Cloud Workflows को ट्रिगर करना
- Cloud Run की मदद से Private CloudSQL से कनेक्ट करना
- Cloud Run की मदद से, पूरी तरह से मैनेज किए जा रहे डेटाबेस से कनेक्ट करना
- पहचान अवेयर प्रॉक्सी (IAP) की मदद से बिना सर्वर वाले सुरक्षित ऐप्लिकेशन
- क्लाउड शेड्यूलर की मदद से, Cloud Run जॉब ट्रिगर करना
- Cloud Run के लिए सुरक्षित तरीके से डिप्लॉय करना
- Cloud Run इन्ग्रेस ट्रैफ़िक को सुरक्षित करना
- GKE Autopilot की मदद से निजी AlloyDB से कनेक्ट करना
व्यवस्थित करें
इस ट्यूटोरियल में इस्तेमाल किए गए संसाधनों के लिए, आपके Google Cloud खाते पर शुल्क न लगे. इसके लिए, उस प्रोजेक्ट को मिटा दें जिसमें संसाधन शामिल हैं या प्रोजेक्ट को बनाए रखें और अलग-अलग संसाधनों को मिटाएं.
प्रोजेक्ट मिटाया जा रहा है
बिलिंग हटाने का सबसे आसान तरीका, ट्यूटोरियल के लिए बनाए गए प्रोजेक्ट को मिटाना है.