ডেটাপ্লেক্স এবং জেনারেটিভ এআই সহ প্রোগ্রাম্যাটিক ডেটা গুণমান

১. ভূমিকা

এই কোডল্যাবটি ডেটা বিশেষজ্ঞদের জন্য একটি প্রযুক্তিগত রূপরেখা প্রদান করে। এটি ডেটা গভর্নেন্সের জন্য একটি "কোড-ফার্স্ট" পদ্ধতির রূপরেখা দেয় এবং দেখায় কীভাবে শক্তিশালী কোয়ালিটি ও মেটাডেটা ম্যানেজমেন্টকে সরাসরি ডেভেলপমেন্ট লাইফসাইকেলে অন্তর্ভুক্ত করা যায়। এর মূলে, ডেটাপ্লেক্স ইউনিভার্সাল ক্যাটালগ একটি ইন্টেলিজেন্ট ডেটা ফ্যাব্রিক হিসেবে কাজ করে, যা প্রতিষ্ঠানগুলোকে তাদের ডেটা লেক থেকে শুরু করে ডেটা ওয়্যারহাউস পর্যন্ত সমগ্র ডেটা ক্ষেত্র জুড়ে কেন্দ্রীয়ভাবে ডেটা পরিচালনা, পর্যবেক্ষণ এবং গভর্নেন্স করতে সক্ষম করে।

এই কোডল্যাবটি দেখায় কিভাবে ডেটাপ্লেক্স, বিগকোয়েরি এবং জেমিনি সিএলআই ব্যবহার করে জটিল ডেটাকে সরলীকরণ করা, প্রোগ্রাম্যাটিকভাবে এর প্রোফাইল তৈরি করা, বুদ্ধিমান ডেটা কোয়ালিটি রুল সাজেশন তৈরি করা এবং স্বয়ংক্রিয় কোয়ালিটি স্ক্যান স্থাপন করা যায়। এর প্রধান উদ্দেশ্য হলো ম্যানুয়াল, ইউআই-চালিত প্রক্রিয়াগুলো—যেগুলোতে ভুলের সম্ভাবনা বেশি এবং যা স্কেল করা কঠিন—থেকে সরে এসে একটি শক্তিশালী, ভার্সন-নিয়ন্ত্রণযোগ্য "পলিসি-অ্যাজ-কোড" ফ্রেমওয়ার্ক প্রতিষ্ঠা করা।

পূর্বশর্ত

  • গুগল ক্লাউড কনসোল সম্পর্কে প্রাথমিক ধারণা
  • কমান্ড লাইন ইন্টারফেস এবং গুগল ক্লাউড শেলে প্রাথমিক দক্ষতা

আপনি যা শিখবেন

  • ব্যাপক প্রোফাইলিং সক্ষম করতে ম্যাটেরিয়ালাইজড ভিউ ব্যবহার করে কীভাবে নেস্টেড বিগকোয়েরি ডেটা ফ্ল্যাট করা যায়।
  • ডেটাপ্লেক্স পাইথন ক্লায়েন্ট লাইব্রেরি ব্যবহার করে কীভাবে প্রোগ্রাম্যাটিকভাবে ডেটাপ্লেক্স প্রোফাইল স্ক্যান চালু ও পরিচালনা করা যায়।
  • প্রোফাইল ডেটা কীভাবে এক্সপোর্ট করবেন এবং সেটিকে একটি জেনারেটিভ এআই মডেলের ইনপুট হিসেবে কীভাবে গঠন করবেন।
  • প্রোফাইল ডেটা বিশ্লেষণ করতে এবং ডেটাপ্লেক্স-সম্মত একটি YAML রুল ফাইল তৈরি করতে জেমিনি CLI-এর জন্য কীভাবে একটি প্রম্পট ডিজাইন করা যায়।
  • এআই-সৃষ্ট কনফিগারেশন যাচাই করার জন্য একটি ইন্টারেক্টিভ, হিউম্যান-ইন-দ্য-লুপ (HITL) প্রক্রিয়ার গুরুত্ব।
  • তৈরি করা নিয়মগুলোকে স্বয়ংক্রিয় ডেটা গুণমান স্ক্যান হিসেবে কীভাবে প্রয়োগ করবেন।

আপনার যা যা লাগবে

  • একটি গুগল ক্লাউড অ্যাকাউন্ট এবং গুগল ক্লাউড প্রজেক্ট
  • ক্রোমের মতো একটি ওয়েব ব্রাউজার

মূল ধারণা: ডেটাপ্লেক্স ডেটা কোয়ালিটির স্তম্ভসমূহ

একটি কার্যকর ডেটা কোয়ালিটি স্ট্র্যাটেজি তৈরির জন্য ডেটাপ্লেক্স-এর মূল উপাদানগুলো বোঝা অপরিহার্য।

  • ডেটা প্রোফাইল স্ক্যান: এটি একটি ডেটাপ্লেক্স জব যা ডেটা বিশ্লেষণ করে এবং পরিসংখ্যানগত মেটাডেটা তৈরি করে, যার মধ্যে রয়েছে নাল পার্সেন্টেজ, স্বতন্ত্র মানের সংখ্যা এবং মানের বিন্যাস। এটি আমাদের প্রোগ্রাম্যাটিক 'ডিসকভারি' পর্যায় হিসেবে কাজ করে।
  • ডেটা কোয়ালিটি রুলস: ঘোষণামূলক বিবৃতি যা আপনার ডেটাকে অবশ্যই পূরণ করতে হবে এমন শর্তাবলী সংজ্ঞায়িত করে (যেমন, NonNullExpectation , SetExpectation , RangeExpectation )।
  • নিয়ম পরামর্শের জন্য জেনারেটিভ এআই: একটি ডেটা প্রোফাইল বিশ্লেষণ করতে এবং প্রাসঙ্গিক ডেটা কোয়ালিটি নিয়ম পরামর্শ দিতে একটি বৃহৎ ল্যাঙ্গুয়েজ মডেল (যেমন জেমিনি) ব্যবহার করা হয়। এটি একটি বেসলাইন কোয়ালিটি ফ্রেমওয়ার্ক নির্ধারণের প্রক্রিয়াকে ত্বরান্বিত করে।
  • ডেটা কোয়ালিটি স্ক্যান: একটি ডেটাপ্লেক্স জব যা পূর্বনির্ধারিত বা কাস্টম নিয়মের একটি সেটের ভিত্তিতে ডেটা যাচাই করে।
  • প্রোগ্রাম্যাটিক গভর্নেন্স: এর মূল বিষয় হলো গভর্নেন্স কন্ট্রোল (যেমন কোয়ালিটি রুলস) কোড হিসেবে (উদাহরণস্বরূপ, YAML ফাইল এবং পাইথন স্ক্রিপ্টে) পরিচালনা করা। এটি অটোমেশন, ভার্সনিং এবং CI/CD পাইপলাইনে ইন্টিগ্রেশন সক্ষম করে।
  • হিউম্যান-ইন-দ্য-লুপ (HITL): একটি স্বয়ংক্রিয় কর্মপ্রবাহে মানুষের দক্ষতা এবং তত্ত্বাবধানকে একীভূত করার একটি গুরুত্বপূর্ণ নিয়ন্ত্রণ বিন্দু। কৃত্রিম বুদ্ধিমত্তা (AI) দ্বারা তৈরি কনফিগারেশনের ক্ষেত্রে, প্রয়োগের পূর্বে পরামর্শগুলোর সঠিকতা, ব্যবসায়িক প্রাসঙ্গিকতা এবং নিরাপত্তা যাচাই করার জন্য HITL অপরিহার্য।

২. সেটআপ এবং প্রয়োজনীয়তা

ক্লাউড শেল শুরু করুন

যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যায়, এই কোডল্যাবে আপনি গুগল ক্লাউড শেল ব্যবহার করবেন, যা ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

গুগল ক্লাউড কনসোল থেকে, উপরের ডানদিকের টুলবারে থাকা ক্লাউড শেল আইকনটিতে ক্লিক করুন:

ক্লাউড শেল সক্রিয় করুন

পরিবেশটি প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে। এটি শেষ হলে, আপনি এইরকম কিছু দেখতে পাবেন:

গুগল ক্লাউড শেল টার্মিনালের স্ক্রিনশট, যা দেখাচ্ছে যে পরিবেশটি সংযুক্ত হয়েছে।

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার সমস্ত কাজ একটি ব্রাউজারের মধ্যেই করা যাবে। আপনাকে কিছুই ইনস্টল করতে হবে না।

প্রয়োজনীয় এপিআইগুলো সক্রিয় করুন এবং পরিবেশ কনফিগার করুন।

ক্লাউড শেলের ভিতরে, নিশ্চিত করুন যে আপনার প্রজেক্ট আইডি সেটআপ করা আছে:

export PROJECT_ID=$(gcloud config get-value project)
gcloud config set project $PROJECT_ID
export LOCATION="us-central1"
export BQ_LOCATION="us"
export DATASET_ID="dataplex_dq_codelab"
export TABLE_ID="ga4_transactions"

gcloud services enable dataplex.googleapis.com \
                       bigquery.googleapis.com \
                       serviceusage.googleapis.com

এই উদাহরণে আমরা অবস্থান হিসেবে us (মাল্টি-রিজিওন) ব্যবহার করছি, কারণ আমরা যে পাবলিক স্যাম্পল ডেটা ব্যবহার করব তাও us (মাল্টি-রিজিওন) অবস্থিত। BigQuery-এর নিয়ম অনুযায়ী, একটি কোয়েরির জন্য সোর্স ডেটা এবং ডেস্টিনেশন টেবিল একই অবস্থানে থাকতে হবে।

একটি ডেডিকেটেড BigQuery ডেটাসেট তৈরি করুন

আমাদের নমুনা ডেটা এবং ফলাফল সংরক্ষণের জন্য একটি নতুন BigQuery ডেটাসেট তৈরি করুন।

bq --location=us mk --dataset $PROJECT_ID:$DATASET_ID

নমুনা ডেটা প্রস্তুত করুন

এই কোডল্যাবের জন্য, আপনি গুগল মার্চেন্ডাইজ স্টোর থেকে সংগৃহীত অস্পষ্ট ই-কমার্স ডেটা সম্বলিত একটি পাবলিক ডেটাসেট ব্যবহার করবেন। যেহেতু পাবলিক ডেটাসেটগুলো শুধুমাত্র পঠনযোগ্য (read-only), তাই আপনাকে আপনার নিজের ডেটাসেটে এর একটি পরিবর্তনযোগ্য (mutable) অনুলিপি তৈরি করতে হবে। নিম্নলিখিত bq কমান্ডটি আপনার dataplex_dq_codelab ডেটাসেটে ga4_transactions নামে একটি নতুন টেবিল তৈরি করে। স্ক্যানগুলো যাতে দ্রুত চলে, তা নিশ্চিত করার জন্য এটি শুধুমাত্র একটি দিনের (২০২১-০১-৩১) ডেটা কপি করে।

bq query \
--use_legacy_sql=false \
--destination_table=$PROJECT_ID:$DATASET_ID.$TABLE_ID \
--replace=true \
'SELECT * FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_20210131`'

ডেমো ডিরেক্টরি সেটআপ করুন

শুরু করার জন্য, আপনাকে একটি গিটহাব রিপোজিটরি ক্লোন করতে হবে, যেটিতে এই কোডল্যাবের জন্য প্রয়োজনীয় ফোল্ডার কাঠামো এবং সহায়ক ফাইলসমূহ রয়েছে।

git clone https://github.com/GoogleCloudPlatform/devrel-demos
cd devrel-demos/data-analytics/programmatic-dq

এই ডিরেক্টরিটি এখন আপনার সক্রিয় কর্মক্ষেত্র। পরবর্তী সমস্ত ফাইল এখানেই তৈরি করা হবে।

৩. ডেটাপ্লেক্স প্রোফাইলিংয়ের মাধ্যমে স্বয়ংক্রিয় ডেটা আবিষ্কার

ডেটাপ্লেক্স ডেটা প্রোফাইলিং আপনার ডেটা সম্পর্কে পরিসংখ্যানগত তথ্য, যেমন নাল পার্সেন্টেজ, ইউনিকনেস এবং ভ্যালু ডিস্ট্রিবিউশন, স্বয়ংক্রিয়ভাবে আবিষ্কার করার জন্য একটি শক্তিশালী টুল। আপনার ডেটার গঠন এবং গুণমান বোঝার জন্য এই প্রক্রিয়াটি অপরিহার্য। তবে, ডেটাপ্লেক্স প্রোফাইলিংয়ের একটি পরিচিত সীমাবদ্ধতা হলো একটি টেবিলের মধ্যে থাকা নেস্টেড বা পুনরাবৃত্ত ফিল্ড (যেমন, RECORD বা ARRAY টাইপ) সম্পূর্ণরূপে পরীক্ষা করতে না পারা। এটি একটি কলাম যে একটি জটিল টাইপের তা শনাক্ত করতে পারলেও, সেই নেস্টেড কাঠামোর মধ্যে থাকা স্বতন্ত্র ফিল্ডগুলোর প্রোফাইল তৈরি করতে পারে না।

এই সমস্যা সমাধানের জন্য, আমরা ডেটাগুলোকে বিশেষভাবে নির্মিত ম্যাটেরিয়ালাইজড ভিউ-তে রূপান্তরিত করব। এই কৌশলটি প্রতিটি ফিল্ডকে একটি শীর্ষ-স্তরের কলামে পরিণত করে, যা ডেটাপ্লেক্সকে প্রত্যেকটিকে আলাদাভাবে প্রোফাইল করতে সক্ষম করে।

নেস্টেড স্কিমা বোঝা

প্রথমে, চলুন আমাদের সোর্স টেবিলের স্কিমাটি পরীক্ষা করে দেখি। গুগল অ্যানালিটিক্স ৪ (GA4) ডেটাসেটে বেশ কিছু নেস্টেড এবং রিপিটেড কলাম রয়েছে। সমস্ত নেস্টেড স্ট্রাকচার সহ সম্পূর্ণ স্কিমাটি প্রোগ্রাম্যাটিকভাবে পাওয়ার জন্য, আপনি bq show কমান্ডটি ব্যবহার করতে পারেন এবং আউটপুটটি একটি JSON ফাইল হিসাবে সেভ করতে পারেন।

bq show --schema --format=json $PROJECT_ID:$DATASET_ID.$TABLE_ID > bq_schema.json

bq_schema.json ফাইলটি পরীক্ষা করলে ডিভাইস, জিও, ইকমার্স এবং পুনরাবৃত্ত রেকর্ড আইটেমের মতো জটিল কাঠামো প্রকাশ পায়। কার্যকর প্রোফাইলিংয়ের জন্য এই কাঠামোগুলোকেই সরলীকরণ করা প্রয়োজন।

ম্যাটেরিয়ালাইজড ভিউ ব্যবহার করে ডেটা ফ্ল্যাট করা

এই নেস্টেড ডেটা চ্যালেঞ্জের সবচেয়ে কার্যকর এবং বাস্তবসম্মত সমাধান হলো ম্যাটেরিয়ালাইজড ভিউ (MV) তৈরি করা। ফ্ল্যাট করা ফলাফলগুলো আগে থেকে গণনা করে রাখার মাধ্যমে, MV-গুলো কোয়েরির পারফরম্যান্স এবং খরচের ক্ষেত্রে উল্লেখযোগ্য সুবিধা প্রদান করে, এবং একই সাথে বিশ্লেষক ও প্রোফাইলিং টুলগুলোর জন্য একটি সরল, রিলেশনাল-সদৃশ কাঠামো সরবরাহ করে।

স্বাভাবিকভাবেই প্রথমে মনে হতে পারে সবকিছুকে একটি একক, বিশাল দৃশ্যে একত্রিত করে ফেলা। তবে, এই স্বতঃস্ফূর্ত পদ্ধতির মধ্যে একটি বিপজ্জনক ফাঁদ লুকিয়ে আছে, যা মারাত্মক ডেটা বিকৃতির কারণ হতে পারে। চলুন জেনে নেওয়া যাক কেন এটি একটি গুরুতর ভুল।

  1. mv_ga4_user_session_flat.sql
CREATE OR REPLACE MATERIALIZED VIEW `$PROJECT_ID.$DATASET_ID.mv_ga4_user_session_flat`
OPTIONS (
  enable_refresh = true,
  refresh_interval_minutes = 30
) AS
SELECT
  event_date, event_timestamp, event_name, user_pseudo_id, user_id, stream_id, platform,
  device.category AS device_category,
  device.operating_system AS device_os,
  device.operating_system_version AS device_os_version,
  device.language AS device_language,
  device.web_info.browser AS device_browser,
  geo.continent AS geo_continent,
  geo.country AS geo_country,
  geo.region AS geo_region,
  geo.city AS geo_city,
  traffic_source.name AS traffic_source_name,
  traffic_source.medium AS traffic_source_medium,
  traffic_source.source AS traffic_source_source
FROM
  `$PROJECT_ID.$DATASET_ID.ga4_transactions`;
  1. mv_ga4_ecommerce_transactions.sql
CREATE OR REPLACE MATERIALIZED VIEW `$PROJECT_ID.$DATASET_ID.mv_ga4_ecommerce_transactions`
OPTIONS (
  enable_refresh = true,
  refresh_interval_minutes = 30
) AS
SELECT
  event_date, event_timestamp, user_pseudo_id, ecommerce.transaction_id,
  ecommerce.total_item_quantity,
  ecommerce.purchase_revenue_in_usd,
  ecommerce.purchase_revenue,
  ecommerce.refund_value_in_usd,
  ecommerce.refund_value,
  ecommerce.shipping_value_in_usd,
  ecommerce.shipping_value,
  ecommerce.tax_value_in_usd,
  ecommerce.tax_value,
  ecommerce.unique_items
FROM
  `$PROJECT_ID.$DATASET_ID.ga4_transactions`
WHERE
  ecommerce.transaction_id IS NOT NULL;
  1. mv_ga4_ecommerce_items.sql
CREATE OR REPLACE MATERIALIZED VIEW `$PROJECT_ID.$DATASET_ID.mv_ga4_ecommerce_items`
OPTIONS (
  enable_refresh = true,
  refresh_interval_minutes = 30
) AS
SELECT
  event_date, event_timestamp, event_name, user_pseudo_id, ecommerce.transaction_id,
  item.item_id,
  item.item_name,
  item.item_brand,
  item.item_variant,
  item.item_category,
  item.item_category2,
  item.item_category3,
  item.item_category4,
  item.item_category5,
  item.price_in_usd,
  item.price,
  item.quantity,
  item.item_revenue_in_usd,
  item.item_revenue,
  item.coupon,
  item.affiliation,
  item.item_list_name,
  item.promotion_name
FROM
  `$PROJECT_ID.$DATASET_ID.ga4_transactions`,
  UNNEST(items) AS item
WHERE
  ecommerce.transaction_id IS NOT NULL;

এখন, bq কমান্ড-লাইন টুল ব্যবহার করে এই টেমপ্লেটগুলো চালান। envsubst কমান্ডটি প্রতিটি ফাইল পড়বে, $PROJECT_ID এবং $DATASET_ID মতো ভেরিয়েবলগুলোকে আপনার শেল এনভায়রনমেন্টের মান দিয়ে প্রতিস্থাপন করবে এবং চূড়ান্ত, বৈধ SQL-টিকে bq query কমান্ডে পাইপ করবে।

envsubst < mv_ga4_user_session_flat.sql | bq query --use_legacy_sql=false
envsubst < mv_ga4_ecommerce_transactions.sql | bq query --use_legacy_sql=false
envsubst < mv_ga4_ecommerce_items.sql | bq query --use_legacy_sql=false

পাইথন ক্লায়েন্টের মাধ্যমে প্রোফাইল স্ক্যানগুলো সম্পাদন করুন।

এখন যেহেতু আমাদের কাছে ফ্ল্যাট করা ও প্রোফাইলযোগ্য ভিউগুলো আছে, আমরা প্রোগ্রামিংয়ের মাধ্যমে প্রতিটির জন্য ডেটাপ্লেক্স ডেটা প্রোফাইল স্ক্যান তৈরি ও চালাতে পারি। নিচের পাইথন স্ক্রিপ্টটি এই প্রক্রিয়াটি স্বয়ংক্রিয় করতে google-cloud-dataplex ক্লায়েন্ট লাইব্রেরি ব্যবহার করে।

স্ক্রিপ্টটি চালানোর আগে, আপনার প্রজেক্ট ডিরেক্টরির মধ্যে একটি বিচ্ছিন্ন পাইথন এনভায়রনমেন্ট তৈরি করা একটি অত্যন্ত গুরুত্বপূর্ণ উত্তম অনুশীলন। এটি নিশ্চিত করে যে প্রজেক্টের ডিপেন্ডেন্সিগুলো আলাদাভাবে পরিচালিত হয়, যা আপনার ক্লাউড শেল এনভায়রনমেন্টের অন্যান্য প্যাকেজের সাথে সংঘাত প্রতিরোধ করে।

# Create the virtual environment
python3 -m venv dq_venv

# Activate the environment
source dq_venv/bin/activate

এখন, নতুন সক্রিয় করা পরিবেশে ডেটাপ্লেক্স ক্লায়েন্ট লাইব্রেরিটি ইনস্টল করুন।

# Install the Dataplex client library
pip install google-cloud-dataplex

পরিবেশ প্রস্তুত এবং লাইব্রেরি ইনস্টল করা হয়ে গেলে, আপনি অর্কেস্ট্রেশন স্ক্রিপ্ট তৈরি করার জন্য প্রস্তুত।

ক্লাউড শেল টুলবারে, ওপেন এডিটর-এ ক্লিক করুন। 1_run_dataplex_scans.py নামে একটি নতুন ফাইল তৈরি করুন এবং এতে নিম্নলিখিত পাইথন কোডটি পেস্ট করুন। আপনি যদি গিটহাব রিপোজিটরি ক্লোন করেন, তাহলে এই ফাইলটি আপনার ফোল্ডারে আগে থেকেই থাকবে।

এই স্ক্রিপ্টটি প্রতিটি ম্যাটেরিয়ালাইজড ভিউ-এর জন্য একটি স্ক্যান তৈরি করবে (যদি সেটি আগে থেকে বিদ্যমান না থাকে), স্ক্যানটি চালাবে এবং তারপর সমস্ত স্ক্যান জব সম্পূর্ণ না হওয়া পর্যন্ত পোল করতে থাকবে।

import os
import sys
import time
from google.cloud import dataplex_v1
from google.api_core.exceptions import AlreadyExists


def create_and_run_scan(
    client: dataplex_v1.DataScanServiceClient,
    project_id: str,
    location: str,
    data_scan_id: str,
    target_resource: str,
) -> dataplex_v1.DataScanJob | None:
    """
    Creates and runs a single data profile scan.
    Returns the executed Job object without waiting for completion.
    """
    parent = client.data_scan_path(project_id, location, data_scan_id).rsplit('/', 2)[0]
    scan_path = client.data_scan_path(project_id, location, data_scan_id)

    # 1. Create Data Scan (skips if it already exists)
    try:
        data_scan = dataplex_v1.DataScan()
        data_scan.data.resource = target_resource
        data_scan.data_profile_spec = dataplex_v1.DataProfileSpec()

        print(f"[INFO] Creating data scan '{data_scan_id}'...")
        client.create_data_scan(
            parent=parent,
            data_scan=data_scan,
            data_scan_id=data_scan_id
        ).result()  # Wait for creation to complete
        print(f"[SUCCESS] Data scan '{data_scan_id}' created.")
    except AlreadyExists:
        print(f"[INFO] Data scan '{data_scan_id}' already exists. Skipping creation.")
    except Exception as e:
        print(f"[ERROR] Error creating data scan '{data_scan_id}': {e}")
        return None

    # 2. Run Data Scan
    try:
        print(f"[INFO] Running data scan '{data_scan_id}'...")
        run_response = client.run_data_scan(name=scan_path)
        print(f"[SUCCESS] Job started for '{data_scan_id}'. Job ID: {run_response.job.name.split('/')[-1]}")
        return run_response.job
    except Exception as e:
        print(f"[ERROR] Error running data scan '{data_scan_id}': {e}")
        return None


def main():
    """Main execution function"""
    # --- Load configuration from environment variables ---
    PROJECT_ID = os.environ.get("PROJECT_ID")
    LOCATION = os.environ.get("LOCATION")
    DATASET_ID = os.environ.get("DATASET_ID")

    if not all([PROJECT_ID, LOCATION, DATASET_ID]):
        print("[ERROR] One or more required environment variables are not set.")
        print("Please ensure PROJECT_ID, LOCATION, and DATASET_ID are exported in your shell.")
        sys.exit(1)

    print(f"[INFO] Using Project: {PROJECT_ID}, Location: {LOCATION}, Dataset: {DATASET_ID}")

    # List of Materialized Views to profile
    TARGET_VIEWS = [
        "mv_ga4_user_session_flat",
        "mv_ga4_ecommerce_transactions",
        "mv_ga4_ecommerce_items"
    ]
    # ----------------------------------------------------

    client = dataplex_v1.DataScanServiceClient()
    running_jobs = []

    # 1. Create and run jobs for all target views
    print("\n--- Starting Data Profiling Job Creation and Execution ---")
    for view_name in TARGET_VIEWS:
        data_scan_id = f"profile-scan-{view_name.replace('_', '-')}"
        target_resource = f"//bigquery.googleapis.com/projects/{PROJECT_ID}/datasets/{DATASET_ID}/tables/{view_name}"

        job = create_and_run_scan(client, PROJECT_ID, LOCATION, data_scan_id, target_resource)
        if job:
            running_jobs.append(job)
    print("-------------------------------------------------------\n")

    if not running_jobs:
        print("[ERROR] No jobs were started. Exiting.")
        return

    # 2. Poll for all jobs to complete
    print("--- Monitoring job completion status (checking every 30 seconds) ---")
    completed_jobs = {}

    while running_jobs:
        jobs_to_poll_next = []

        print(f"\n[STATUS] Checking status for {len(running_jobs)} running jobs...")

        for job in running_jobs:
            job_id_short = job.name.split('/')[-1][:13] 
            try:
                updated_job = client.get_data_scan_job(name=job.name)
                state = updated_job.state

                if state in (dataplex_v1.DataScanJob.State.RUNNING, dataplex_v1.DataScanJob.State.PENDING, dataplex_v1.DataScanJob.State.CANCELING):
                    print(f"  - Job {job_id_short}... Status: {state.name}")
                    jobs_to_poll_next.append(updated_job) 
                else:
                    print(f"  - Job {job_id_short}... Status: {state.name} (Complete)")
                    completed_jobs[job.name] = updated_job

            except Exception as e:
                print(f"[ERROR] Could not check status for job {job_id_short}: {e}")

        running_jobs = jobs_to_poll_next

        if running_jobs:
            time.sleep(30)

    # 3. Print final results
    print("\n--------------------------------------------------")
    print("[SUCCESS] All data profiling jobs have completed.")
    print("\nFinal Job Status Summary:")
    for job_name, job in completed_jobs.items():
        job_id_short = job_name.split('/')[-1][:13]
        print(f"  - Job {job_id_short}: {job.state.name}")
        if job.state == dataplex_v1.DataScanJob.State.FAILED:
            print(f"    - Failure Message: {job.message}")

    print("\nNext step: Analyze the profile results and generate quality rules.")


if __name__ == "__main__":
    main()

এখন, আপনার ক্লাউড শেল টার্মিনাল থেকে স্ক্রিপ্টটি চালান।

python 1_run_dataplex_scans.py

স্ক্রিপ্টটি এখন আপনার তিনটি ম্যাটেরিয়ালাইজড ভিউ-এর প্রোফাইলিং পরিচালনা করবে এবং রিয়েল-টাইম স্ট্যাটাস আপডেট প্রদান করবে। এটি সম্পন্ন হলে, আপনি প্রতিটি ভিউ-এর জন্য একটি সমৃদ্ধ, মেশিন-পাঠযোগ্য পরিসংখ্যানগত প্রোফাইল পাবেন, যা আমাদের ওয়ার্কফ্লো-এর পরবর্তী ধাপ—এআই-চালিত ডেটা কোয়ালিটি রুল তৈরির জন্য প্রস্তুত থাকবে।

সম্পন্ন হওয়া প্রোফাইল স্ক্যানগুলো আপনি গুগল ক্লাউড কনসোলে দেখতে পারবেন।

  1. নেভিগেশন মেনুতে, ডেটাপ্লেক্স ইউনিভার্সাল ক্যাটালগে যান এবং গভর্ন সেকশনে প্রোফাইলে যান।

5acda859404968c.png

  1. আপনি আপনার তিনটি প্রোফাইল স্ক্যান তাদের সর্বশেষ চাকরির স্ট্যাটাস সহ তালিকাভুক্ত দেখতে পাবেন। বিস্তারিত ফলাফল দেখতে আপনি যেকোনো একটি স্ক্যানে ক্লিক করতে পারেন।

8a09dae0ef485289.png

BigQuery প্রোফাইল থেকে AI-প্রস্তুত ইনপুট

ডেটাপ্লেক্স প্রোফাইল স্ক্যানগুলো সফলভাবে সম্পন্ন হয়েছে। ফলাফলগুলো ডেটাপ্লেক্স এপিআই-এর মধ্যে উপলব্ধ থাকলেও, একটি জেনারেটিভ এআই মডেলের ইনপুট হিসেবে ব্যবহার করার জন্য, আমাদের সেগুলোকে একটি কাঠামোগত, স্থানীয় ফাইলে এক্সট্র্যাক্ট করতে হবে।

নিম্নলিখিত পাইথন স্ক্রিপ্ট, 2_dq_profile_save.py , প্রোগ্রাম্যাটিকভাবে আমাদের mv_ga4_user_session_flat ভিউ-এর জন্য সর্বশেষ সফল প্রোফাইল স্ক্যান জবটি খুঁজে বের করে। এরপর এটি সম্পূর্ণ ও বিস্তারিত প্রোফাইল ফলাফল সংগ্রহ করে এবং dq_profile_results.json নামের একটি স্থানীয় JSON ফাইল হিসেবে সংরক্ষণ করে। এই ফাইলটি পরবর্তী ধাপে আমাদের AI বিশ্লেষণের জন্য সরাসরি ইনপুট হিসেবে কাজ করবে।

আপনার ক্লাউড শেল এডিটরে, 2_dq_profile_save.py নামে একটি নতুন ফাইল তৈরি করুন এবং এর মধ্যে নিম্নলিখিত কোডটি পেস্ট করুন। আগের ধাপের মতোই, আপনি যদি রিপোজিটরিটি ক্লোন করে থাকেন তবে ফাইল তৈরি করার ধাপটি বাদ দিতে পারেন।

import os
import sys
import json
from google.cloud import dataplex_v1
from google.api_core.exceptions import NotFound
from google.protobuf.json_format import MessageToDict

# --- Configuration ---
# The Materialized View to analyze is fixed for this step.
TARGET_VIEW = "mv_ga4_user_session_flat"
OUTPUT_FILENAME = "dq_profile_results.json"


def save_to_json_file(content: dict, filename: str):
    """Saves the given dictionary content to a JSON file."""
    try:
        with open(filename, "w", encoding="utf-8") as f:
            # Use indent=2 for a readable, "pretty-printed" JSON file.
            json.dump(content, f, indent=2, ensure_ascii=False)
        print(f"\n[SUCCESS] Profile results were saved to '{filename}'.")
    except (IOError, TypeError) as e:
        print(f"[ERROR] An error occurred while saving the file: {e}")


def get_latest_successful_job(
    client: dataplex_v1.DataScanServiceClient,
    project_id: str,
    location: str,
    data_scan_id: str
) -> dataplex_v1.DataScanJob | None:
    """Finds and returns the most recently succeeded job for a given data scan."""
    scan_path = client.data_scan_path(project_id, location, data_scan_id)
    print(f"\n[INFO] Looking for the latest successful job for scan '{data_scan_id}'...")

    try:
        # List all jobs for the specified scan, which are ordered most-recent first.
        jobs_pager = client.list_data_scan_jobs(parent=scan_path)

        # Iterate through jobs to find the first one that succeeded.
        for job in jobs_pager:
            if job.state == dataplex_v1.DataScanJob.State.SUCCEEDED:
                return job

        # If no successful job is found after checking all pages.
        return None
    except NotFound:
        print(f"[WARN] No scan history found for '{data_scan_id}'.")
        return None


def main():
    """Main execution function."""
    # --- Load configuration from environment variables ---
    PROJECT_ID = os.environ.get("PROJECT_ID")
    LOCATION = os.environ.get("LOCATION")

    if not all([PROJECT_ID, LOCATION]):
        print("[ERROR] Required environment variables PROJECT_ID or LOCATION are not set.")
        sys.exit(1)

    print(f"[INFO] Using Project: {PROJECT_ID}, Location: {LOCATION}")
    print(f"--- Starting Profile Retrieval for: {TARGET_VIEW} ---")

    # Construct the data_scan_id based on the target view name.
    data_scan_id = f"profile-scan-{TARGET_VIEW.replace('_', '-')}"

    # 1. Initialize Dataplex client and get the latest successful job.
    client = dataplex_v1.DataScanServiceClient()
    latest_job = get_latest_successful_job(client, PROJECT_ID, LOCATION, data_scan_id)

    if not latest_job:
        print(f"\n[ERROR] No successful job record was found for '{data_scan_id}'.")
        print("Please ensure the 'run_dataplex_scans.py' script has completed successfully.")
        return

    job_id_short = latest_job.name.split('/')[-1]
    print(f"[SUCCESS] Found the latest successful job: '{job_id_short}'.")

    # 2. Fetch the full, detailed profile result for the job.
    print(f"[INFO] Retrieving detailed profile results for job '{job_id_short}'...")
    try:
        request = dataplex_v1.GetDataScanJobRequest(
            name=latest_job.name,
            view=dataplex_v1.GetDataScanJobRequest.DataScanJobView.FULL,
        )
        job_with_full_results = client.get_data_scan_job(request=request)
    except Exception as e:
        print(f"[ERROR] Failed to retrieve detailed job results: {e}")
        return

    # 3. Convert the profile result to a dictionary and save it to a JSON file.
    if job_with_full_results.data_profile_result:
        profile_dict = MessageToDict(job_with_full_results.data_profile_result._pb)
        save_to_json_file(profile_dict, OUTPUT_FILENAME)
    else:
        print("[WARN] The job completed, but no data profile result was found within it.")

    print("\n[INFO] Script finished successfully.")


if __name__ == "__main__":
    main()

এখন, আপনার টার্মিনাল থেকে স্ক্রিপ্টটি চালান:

python 2_dq_profile_save.py

সফলভাবে সম্পন্ন হলে, আপনার ডিরেক্টরিতে dq_profile_results.json নামের একটি নতুন ফাইল তৈরি হবে। এই ফাইলে সমৃদ্ধ ও বিস্তারিত পরিসংখ্যানগত মেটাডেটা রয়েছে, যা আমরা ডেটার গুণমান সংক্রান্ত নিয়মাবলী তৈরি করতে ব্যবহার করব। আপনি যদি dq_profile_results.json ফাইলের বিষয়বস্তু দেখতে চান, তাহলে নিম্নলিখিত কমান্ডটি চালান:

cat dq_profile_results.json

৪. জেমিনি সিএলআই ব্যবহার করে ডেটার গুণমান সংক্রান্ত নিয়মাবলী তৈরি করা

Gemini CLI ইনস্টল এবং কনফিগার করুন

যদিও আপনি প্রোগ্রাম্যাটিকভাবে জেমিনি এপিআই (Gemini API) কল করতে পারেন, জেমিনি সিএলআই (Gemini CLI)-এর মতো একটি টুল ব্যবহার করে জেনারেটিভ এআই (generative AI)-কে সরাসরি আপনার টার্মিনাল ওয়ার্কফ্লোতে একীভূত করার একটি শক্তিশালী ও ইন্টারেক্টিভ উপায় পাওয়া যায়। জেমিনি সিএলআই শুধু একটি চ্যাটবট নয়; এটি একটি কমান্ড-লাইন ওয়ার্কফ্লো টুল যা আপনার লোকাল ফাইল পড়তে, আপনার কোড বুঝতে এবং জটিল কাজ স্বয়ংক্রিয় করতে জিক্লাউড (gcloud)-এর মতো অন্যান্য সিস্টেম টুলের সাথে ইন্টারঅ্যাক্ট করতে পারে। এই কারণে এটি আমাদের ব্যবহারের জন্য আদর্শ।

পূর্বশর্ত

প্রথমে, প্রয়োজনীয় পূর্বশর্তটি নিশ্চিত করুন: আপনার ক্লাউড শেল এনভায়রনমেন্টে Node.js ভার্সন ২০ বা তার উচ্চতর সংস্করণ ইনস্টল করা থাকতে হবে। আপনি node -v চালিয়ে আপনার ভার্সন যাচাই করতে পারেন।

ইনস্টলেশন

জেমিনি সিএলআই ব্যবহার করার দুটি উপায় আছে: সাময়িকভাবে ইনস্টল করা অথবা আরও স্থায়ীভাবে ইনস্টল করা। আমরা এখানে উভয় পদ্ধতি নিয়েই আলোচনা করব।

আপনি কোনো স্থায়ী ইনস্টলেশন ছাড়াই সরাসরি একটি সেশনের জন্য Gemini CLI চালাতে পারেন। এটি 'পরীক্ষা করে দেখার' সবচেয়ে পরিষ্কার এবং দ্রুততম উপায়, কারণ এটি আপনার পরিবেশকে সম্পূর্ণ অপরিবর্তিত রাখে।

আপনার ক্লাউড শেল টার্মিনালে, চালান:

npx https://github.com/google-gemini/gemini-cli

এই কমান্ডটি সাময়িকভাবে CLI প্যাকেজটি ডাউনলোড ও রান করে।

যেকোনো বাস্তব প্রকল্পের জন্য, প্রস্তাবিত সর্বোত্তম পদ্ধতি হলো আপনার প্রজেক্ট ডিরেক্টরিতে স্থানীয়ভাবে CLI ইনস্টল করা। এই পদ্ধতির বেশ কিছু গুরুত্বপূর্ণ সুবিধা রয়েছে:

  • ডিপেন্ডেন্সি আইসোলেশন: এটি নিশ্চিত করে যে আপনার প্রোজেক্টের নিজস্ব CLI ভার্সন থাকবে, যা অন্যান্য প্রোজেক্টের সাথে ভার্সনগত সংঘাত প্রতিরোধ করে।
  • পুনরুৎপাদনযোগ্যতা: যে কেউ আপনার প্রজেক্ট ক্লোন করলে হুবহু একই ডিপেন্ডেন্সিগুলো ইনস্টল করতে পারবে, যা আপনার সেটআপকে নির্ভরযোগ্য এবং বহনযোগ্য করে তোলে।
  • সর্বোত্তম অনুশীলনের সাথে সামঞ্জস্য: এটি Node.js প্রোজেক্টের ডিপেন্ডেন্সি ব্যবস্থাপনার জন্য আদর্শ মডেল অনুসরণ করে এবং গ্লোবাল (-g) ইনস্টলেশনের ঝুঁকিগুলো এড়িয়ে চলে।

স্থানীয়ভাবে CLI ইনস্টল করতে, আপনার প্রজেক্ট ফোল্ডার ( programmatic-dq ) থেকে নিম্নলিখিত কমান্ডটি চালান:

npm install @google/gemini-cli

এটি programmatic-dq-এর ভিতরে একটি node_modules ফোল্ডার তৈরি করে। আপনি এইমাত্র ইনস্টল করা সংস্করণটি চালানোর জন্য npx কমান্ডটি ব্যবহার করুন।

npx gemini

প্রথমবার সেটআপ

আপনি যে পদ্ধতিই বেছে নিন না কেন, প্রথমবার CLI চালু করার সময় এটি আপনাকে একটি এককালীন সেটআপ প্রক্রিয়ার মাধ্যমে পথ দেখাবে।

8a25fab5951c6c39.png

আপনাকে একটি কালার থিম বেছে নিতে এবং তারপর প্রমাণীকরণ করতে বলা হবে। সবচেয়ে সহজ পদ্ধতি হলো, অনুরোধ করা হলে আপনার গুগল অ্যাকাউন্ট দিয়ে সাইন ইন করা। এই কোডল্যাবের জন্য প্রদত্ত ফ্রি টিয়ারটিই যথেষ্ট।

এখন যেহেতু CLI ইনস্টল এবং কনফিগার করা হয়ে গেছে, আপনি নিয়মগুলো তৈরি করার জন্য প্রস্তুত। CLI তার বর্তমান ডিরেক্টরিতে থাকা ফাইলগুলো সম্পর্কে অবগত, যা পরবর্তী ধাপের জন্য অত্যন্ত গুরুত্বপূর্ণ।

ডেটার গুণমান বিধি তৈরি করুন

যদিও একটি এলএলএম-কে (LLM) একবারে একটি কনফিগারেশন ফাইল তৈরি করতে বলা সম্ভব, জেনারেটিভ মডেলগুলোর অনির্দিষ্ট প্রকৃতির কারণে এর আউটপুট সবসময় gcloud-এর মতো টুলগুলোর জন্য প্রয়োজনীয় কঠোর স্কিমার সাথে পুরোপুরি সঙ্গতিপূর্ণ নাও হতে পারে। একটি আরও নির্ভরযোগ্য পদ্ধতি হলো একটি ইন্টারেক্টিভ, বহু-ধাপের প্রক্রিয়া, যেখানে প্রথমে আপনি এআই-কে একজন বিশ্লেষক হিসেবে একটি পরিকল্পনা প্রস্তাব করতে দেন, আপনি (মানব বিশেষজ্ঞ) সেই পরিকল্পনাটি পর্যালোচনা ও অনুমোদন করেন, এবং শুধুমাত্র তারপরেই এআই আপনার অনুমোদিত নির্দেশাবলীর উপর ভিত্তি করে চূড়ান্ত কোড তৈরি করে।

এই পদ্ধতিটি প্রক্রিয়াটিকে একটি সাধারণ নির্দেশ থেকে একটি সহযোগিতামূলক অধিবেশনে রূপান্তরিত করে, যা চূড়ান্ত ফলাফলকে নির্ভুল, যাচাইকৃত এবং স্থাপনের জন্য প্রস্তুত করে তোলে।

প্রথমে, আমরা জেমিনিকে পরিসংখ্যানগত প্রোফাইল বিশ্লেষণ করতে এবং একজন বিশেষজ্ঞ ডেটা ইঞ্জিনিয়ারের মতো কাজ করে একটি কর্মপরিকল্পনা প্রস্তাব করতে বলব। আমরা এটিকে স্পষ্টভাবে বলে দিচ্ছি যেন এখনই YAML ফাইলটি না লেখে। এর ফলে এটির মনোযোগ বিশ্লেষণ এবং যৌক্তিকতা প্রমাণের উপর কেন্দ্রীভূত থাকবে।

আপনার ইন্টারেক্টিভ জেমিনি সিএলআই সেশনে, নিম্নলিখিত প্রম্পটটি পেস্ট করুন:

cd9792a6f1eb9f3.png

You are an expert Google Cloud Dataplex engineer. 
Your first task is to create a plan. I have a file in the current directory named ./dq_profile_results.json. 
Based on the statistical data within that file, propose a step-by-step plan to create a Dataplex data quality rules file. 
Your plan should identify which specific columns are good candidates for rules like nonNullExpectation, setExpectation, or rangeExpectation, and explain why based on the metrics (e.g., "Plan to create a nonNullExpectation for column X because its null percentage is 0%"). 
Do not write the YAML file yet. Just provide the plan.

জেমিনি JSON ফাইলটি বিশ্লেষণ করবে এবং এর অনুরূপ একটি কাঠামোগত পরিকল্পনা ফেরত দেবে:

Plan to create Dataplex data quality rules

1. Create a row count rule:
  - Analysis: The profile shows a total of 26,489 rows.
  - Proposed Rule: I will implement a rowCount rule to ensure the table's row count remains within a healthy range (e.g., 20,000 to 30,000). This is a fundamental check to guard against major data loading failures or unexpected deletions.
2. Implement non-null expectation rules:
  - Analysis: The profiling results show that many columns have no null values. For example, event_date, event_timestamp, event_name, user_pseudo_id, stream_id, and platform all appear to be fully populated.
  - Proposed Rules: I will create nonNullExpectation rules for columns where the nullRatio is 0 or not present, indicating they are always expected to contain a value:
    - event_date
    - event_timestamp
    - event_name
    - user_pseudo_id
    - stream_id
    - platform
    - device_category
    - device_os
3. Implement set expectation rules:
  - Analysis: Several columns contain a small, finite set of values, making them ideal for set validation.
  - Proposed Rules: I will create setExpectation rules for these columns:
    - platform: It only contains the value "WEB".
    - device_category: It contains only "desktop", "mobile", and "tablet".
    - geo_continent: It has a well-defined list of continents.
traffic_source_medium: It has a small list of valid mediums like "organic", "(none)", and "referral".
4. Implement range expectation rules:
  - Analysis: The profile provides minimum and maximum values for numeric and string length fields.
  - Proposed Rules: I will create rangeExpectation rules for the following:
    - event_timestamp: The profile shows a clear min and max. I will use these values to create a range check.
    - event_date (String Length): The profile indicates that the minLength and maxLength are both 8, which is perfect for enforcing a YYYYMMDD format.

সম্পূর্ণ ওয়ার্কফ্লোর মধ্যে এটিই সবচেয়ে গুরুত্বপূর্ণ ধাপ: হিউম্যান-ইন-দ্য-লুপ (HITL) পর্যালোচনা। জেমিনি দ্বারা তৈরি পরিকল্পনাটি সম্পূর্ণরূপে ডেটার পরিসংখ্যানগত প্যাটার্নের উপর ভিত্তি করে তৈরি। আপনার ব্যবসায়িক প্রেক্ষাপট, ভবিষ্যতের ডেটা পরিবর্তন, বা আপনার ডেটার পেছনের নির্দিষ্ট উদ্দেশ্য সম্পর্কে এর কোনো ধারণা নেই। মানব বিশেষজ্ঞ হিসেবে আপনার ভূমিকা হলো এই পরিকল্পনাটিকে কোডে রূপান্তর করার আগে যাচাই, সংশোধন এবং অনুমোদন করা।

জেমিনি যে পরিকল্পনাটি দিয়েছে তা মনোযোগ সহকারে পর্যালোচনা করুন।

  • এটা কি বোধগম্য?
  • এটি কি আপনার ব্যবসায়িক জ্ঞানের সাথে সামঞ্জস্যপূর্ণ?
  • এমন কোনো নিয়ম আছে কি যা পরিসংখ্যানগতভাবে সঠিক কিন্তু বাস্তবে অকেজো?

জেমিনি থেকে আপনি যে ফলাফল পাবেন তা ভিন্ন হতে পারে। আপনার লক্ষ্য হলো এটিকে আরও পরিমার্জিত করা।

উদাহরণস্বরূপ, ধরুন প্ল্যানটিতে একটি rowCount নিয়মের পরামর্শ দেওয়া হয়েছে, কারণ স্যাম্পল ডেটাতে টেবিলটিতে নির্দিষ্ট সংখ্যক সারি রয়েছে। একজন মানব বিশেষজ্ঞ হিসেবে, আপনি হয়তো জানেন যে এই টেবিলের আকার প্রতিদিন বাড়ার সম্ভাবনা রয়েছে, যা একটি কঠোর সারি গণনার নিয়মকে অবাস্তব করে তোলে এবং সম্ভবত ভুল অ্যালার্ট তৈরি করবে। এটি ব্যবসায়িক প্রেক্ষাপট প্রয়োগের একটি নিখুঁত উদাহরণ, যা এআই-এর মধ্যে নেই।

এখন, আপনি জেমিনিকে ফিডব্যাক দেবেন এবং কোড তৈরি করার জন্য চূড়ান্ত কমান্ড দেবেন। আপনি প্রকৃতপক্ষে যে প্ল্যানটি পেয়েছেন এবং যে সংশোধনগুলো করতে চান, তার উপর ভিত্তি করে আপনাকে অবশ্যই নিম্নলিখিত প্রম্পটটি পরিবর্তন করতে হবে।

নীচের নির্দেশিকাটি একটি টেমপ্লেট । প্রথম লাইনে আপনি আপনার নির্দিষ্ট সংশোধনগুলি যোগ করবেন। জেমিনি আপনাকে যে পরিকল্পনাটি দিয়েছে তা যদি নিখুঁত হয় এবং কোনও পরিবর্তনের প্রয়োজন না হয়, তবে আপনি কেবল সেই লাইনটি মুছে ফেলতে পারেন।

একই জেমিনি সেশনে, নিম্নলিখিত প্রম্পটটির আপনার অভিযোজিত সংস্করণটি পেস্ট করুন:

[YOUR CORRECTIONS AND APPROVAL GO HERE. Examples:
- "The plan looks good. Please proceed."
- "The rowCount rule is not necessary, as the table size changes daily. The rest of the plan is approved. Please proceed."
- "For the setExpectation on the geo_continent column, please also include 'Antarctica'."]

Once you have incorporated my feedback, please generate the `dq_rules.yaml` file.

You must adhere to the following strict requirements:

- Schema Compliance: The YAML structure must strictly conform to the DataQualityRule specification. For a definitive source of truth, you must refer to the sample_rule.yaml file in the current directory and the DataQualityRule class definition in the local virtual environment path: ./dq_venv/.../google/cloud/dataplex_v1/types/data_quality.py.

- Data-Driven Values: All rule parameters, such as thresholds or expected values, must be derived directly from the statistical metrics in dq_profile_results.json.

- Rule Justification: For each rule, add a comment (#) on the line above explaining the justification, as you outlined in your plan.

- Output Purity: The final output must only be the raw YAML code block, perfectly formatted and ready for immediate deployment.

জেমিনি এখন আপনার সুনির্দিষ্ট, যাচাইকৃত নির্দেশাবলীর উপর ভিত্তি করে YAML কন্টেন্ট তৈরি করবে। কাজ শেষ হলে, আপনি আপনার ওয়ার্কিং ডিরেক্টরিতে dq_rules.yaml নামের একটি নতুন ফাইল পাবেন।

ডেটা কোয়ালিটি স্ক্যান তৈরি করুন এবং চালান

এখন যেহেতু আপনার কাছে একটি AI-দ্বারা-তৈরি ও মানব-দ্বারা-যাচাইকৃত dq_rules.yaml ফাইল আছে, আপনি আত্মবিশ্বাসের সাথে এটি স্থাপন করতে পারেন।

/quit টাইপ করে অথবা দুইবার Ctrl+C চেপে Gemini CLI থেকে বের হন।

নিম্নলিখিত gcloud কমান্ডটি একটি নতুন Dataplex ডেটা স্ক্যান রিসোর্স তৈরি করে। এটি এখনও স্ক্যানটি চালায় না; এটি কেবল Dataplex-এর সাথে স্ক্যানটির সংজ্ঞা এবং কনফিগারেশন (আমাদের YAML ফাইল) নিবন্ধন করে।

আপনার টার্মিনালে এই কমান্ডটি চালান:

export DQ_SCAN="dq-scan"
gcloud dataplex datascans create data-quality $DQ_SCAN \
    --project=$PROJECT_ID \
    --location=$LOCATION \
    --data-quality-spec-file=dq_rules.yaml \
    --data-source-resource="//bigquery.googleapis.com/projects/$PROJECT_ID/datasets/$DATASET_ID/tables/mv_ga4_user_session_flat"

স্ক্যানটি এখন সংজ্ঞায়িত হয়ে গেলে, আপনি এটি কার্যকর করার জন্য একটি জব ট্রিগার করতে পারেন।

gcloud dataplex datascans run $DQ_SCAN --location=$LOCATION --project=$PROJECT_ID

এই কমান্ডটি একটি জব আইডি আউটপুট করবে। আপনি গুগল ক্লাউড কনসোলের ডেটাপ্লেক্স বিভাগে এই জবটির অবস্থা পর্যবেক্ষণ করতে পারবেন। কাজটি সম্পন্ন হলে, বিশ্লেষণের জন্য ফলাফলগুলো একটি বিগকোয়েরি টেবিলে লেখা হবে।

৫. হিউম্যান-ইন-দ্য-লুপ (HITL)-এর গুরুত্বপূর্ণ ভূমিকা

নিয়ম তৈরির প্রক্রিয়াকে ত্বরান্বিত করতে জেমিনি ব্যবহার করা অত্যন্ত শক্তিশালী হলেও, এআই-কে একজন সম্পূর্ণ স্বয়ংক্রিয় পাইলট হিসেবে নয়, বরং একজন অত্যন্ত দক্ষ সহ-পাইলট হিসেবে বিবেচনা করা অপরিহার্য। হিউম্যান-ইন-দ্য-লুপ (HITL) প্রক্রিয়াটি কোনো ঐচ্ছিক পরামর্শ নয়; এটি যেকোনো শক্তিশালী ও নির্ভরযোগ্য ডেটা গভর্নেন্স ওয়ার্কফ্লোর একটি অলঙ্ঘনীয় ও মৌলিক পদক্ষেপ। কঠোর মানবিক তত্ত্বাবধান ছাড়া শুধু এআই-নির্মিত উপাদানসমূহ প্রয়োগ করা ব্যর্থতারই নামান্তর।

AI দ্বারা তৈরি dq_rules.yaml ফাইলটিকে একজন অত্যন্ত দ্রুত কিন্তু অনভিজ্ঞ AI ডেভেলপারের জমা দেওয়া একটি পুল রিকোয়েস্ট হিসেবে ভাবুন। আপনার গভর্নেন্স পলিসির 'মেইন ব্রাঞ্চ'-এ এটিকে মার্জ করে ডেপ্লয় করার আগে, একজন সিনিয়র মানব বিশেষজ্ঞ—অর্থাৎ আপনি—এর দ্বারা এটির একটি পুঙ্খানুপুঙ্খ পর্যালোচনা প্রয়োজন। লার্জ ল্যাঙ্গুয়েজ মডেলের অন্তর্নিহিত দুর্বলতাগুলো প্রশমিত করার জন্য এই পর্যালোচনা অপরিহার্য।

এই মানব পর্যালোচনা কেন অপরিহার্য এবং আপনাকে বিশেষভাবে কী কী দেখতে হবে, তার একটি বিশদ বিবরণ এখানে দেওয়া হলো:

১. প্রাসঙ্গিক বৈধতা: এআই-এর ব্যবসায়িক সচেতনতার অভাব রয়েছে

  • এলএলএম-এর দুর্বলতা : একজন এলএলএম প্যাটার্ন এবং পরিসংখ্যানে পারদর্শী হলেও, আপনার ব্যবসায়িক প্রেক্ষাপট সম্পর্কে তার কোনো ধারণাই নেই। উদাহরণস্বরূপ, যদি new_campaign_id কলামটিতে ৯৮% নাল রেশিও থাকে, একজন এলএলএম পরিসংখ্যানগত কারণে এই কলামটিকে উপেক্ষা করতে পারে।
  • মানুষের গুরুত্বপূর্ণ ভূমিকা: আপনি, মানব বিশেষজ্ঞ হিসেবে, জানেন যে আগামী সপ্তাহে একটি বড় পণ্য উন্মোচনের জন্য ' new_campaign_id ফিল্ডটি গতকালই যোগ করা হয়েছে। আপনি জানেন যে এর নাল রেশিও এখন বেশি থাকার কথা, কিন্তু তা উল্লেখযোগ্যভাবে কমে আসবে বলে আশা করা হচ্ছে। আপনি এও জানেন যে, একবার এটি পূরণ হয়ে গেলে, এটিকে অবশ্যই একটি নির্দিষ্ট ফরম্যাট অনুসরণ করতে হবে। এআই-এর পক্ষে এই বাহ্যিক ব্যবসায়িক জ্ঞান অনুমান করা কোনোভাবেই সম্ভব নয়। আপনার ভূমিকা হলো এআই-এর পরিসংখ্যানগত পরামর্শগুলোতে এই ব্যবসায়িক প্রেক্ষাপট প্রয়োগ করা এবং প্রয়োজন অনুযায়ী সেগুলোকে বাতিল বা পরিবর্ধন করা।

২. সঠিকতা ও নির্ভুলতা: বিভ্রম এবং সূক্ষ্ম ত্রুটি থেকে সুরক্ষা

  • এলএলএম-এর দুর্বলতা: এলএলএম "আত্মবিশ্বাসের সাথে ভুল" করতে পারে। এটি "বিভ্রম" করতে পারে বা এমন কোড তৈরি করতে পারে যা সূক্ষ্মভাবে ভুল। উদাহরণস্বরূপ, এটি একটি YAML ফাইল তৈরি করতে পারে যেখানে নিয়মের নাম সঠিক কিন্তু প্যারামিটারটি অবৈধ, অথবা এটি নিয়মের প্রকারের বানান ভুল করতে পারে (যেমন, সঠিক setExpectation এর পরিবর্তে setExpectations লেখা)। এই সূক্ষ্ম ত্রুটিগুলোর কারণে ডেপ্লয়মেন্ট ব্যর্থ হবে, কিন্তু এগুলো খুঁজে বের করা কঠিন হতে পারে।
  • মানুষের গুরুত্বপূর্ণ ভূমিকা: আপনার কাজ হলো চূড়ান্ত লিন্টার এবং স্কিমা ভ্যালিডেটর হিসেবে কাজ করা। আপনাকে অবশ্যই অফিসিয়াল ডেটাপ্লেক্স DataQualityRule স্পেসিফিকেশনের সাথে জেনারেট করা YAML-কে পুঙ্খানুপুঙ্খভাবে পরীক্ষা করতে হবে। আপনি শুধু এটি দেখতে 'সঠিক' কিনা তা-ই দেখছেন না; আপনি এর সিনট্যাকটিক এবং সিমান্টিক শুদ্ধতা যাচাই করছেন, যাতে এটি টার্গেট এপিআই-এর সাথে ১০০% সঙ্গতিপূর্ণ হয়। এই কারণেই কোডল্যাব জেমিনিকে স্কিমা ফাইলগুলো রেফারেন্স করতে বলে—যাতে ভুলের সম্ভাবনা কমে—কিন্তু চূড়ান্ত যাচাইয়ের দায়িত্ব আপনারই।

৩. নিরাপত্তা ও ঝুঁকি প্রশমন: পরবর্তী পরিণতি প্রতিরোধ

  • এলএলএম-এর দুর্বলতা: প্রোডাকশনে প্রয়োগ করা একটি ত্রুটিপূর্ণ ডেটা কোয়ালিটি রুলের মারাত্মক পরিণতি হতে পারে। যদি এআই কোনো আর্থিক লেনদেনের পরিমাণের জন্য খুব বেশি বিস্তৃত একটি rangeExpectation প্রস্তাব করে, তবে এটি জালিয়াতিমূলক কার্যকলাপ শনাক্ত করতে ব্যর্থ হতে পারে। বিপরীতভাবে, যদি এটি অল্প পরিমাণ ডেটার উপর ভিত্তি করে খুব কঠোর একটি রুল প্রস্তাব করে, তবে এটি আপনার অন-কল টিমকে হাজার হাজার ফলস-পজিটিভ অ্যালার্ট দিয়ে ভাসিয়ে দিতে পারে, যার ফলে অ্যালার্ট ফ্যাটিগ (alert fatigue) দেখা দেবে এবং আসল সমস্যাগুলো এড়িয়ে যাওয়ার সম্ভাবনা থাকবে।
  • মানুষের গুরুত্বপূর্ণ ভূমিকা: আপনিই নিরাপত্তা প্রকৌশলী। এআই (AI) দ্বারা প্রস্তাবিত প্রতিটি নিয়মের সম্ভাব্য পরবর্তী প্রভাব আপনাকে অবশ্যই মূল্যায়ন করতে হবে। নিজেকে জিজ্ঞাসা করুন: "এই নিয়মটি ব্যর্থ হলে কী হবে? সতর্কবার্তাটি কি কার্যকর? এই নিয়মটি ভুলভাবে পাস হলে ঝুঁকি কী?" এই ঝুঁকি মূল্যায়ন একটি অনন্য মানবিক ক্ষমতা, যা যাচাইয়ের সুবিধার বিপরীতে ব্যর্থতার খরচ পরিমাপ করে।

৪. একটি অবিচ্ছিন্ন প্রক্রিয়া হিসেবে শাসনব্যবস্থা: দূরদর্শী জ্ঞানের অন্তর্ভুক্তি

  • এলএলএম-এর দুর্বলতা: এআই-এর জ্ঞান ডেটার একটি স্থির চিত্রের উপর ভিত্তি করে তৈরি—প্রোফাইলের ফলাফল একটি নির্দিষ্ট সময়ের। ভবিষ্যৎ ঘটনা সম্পর্কে এর কোনো জ্ঞান নেই।
  • মানুষের গুরুত্বপূর্ণ ভূমিকা: আপনার গভর্নেন্স কৌশল অবশ্যই দূরদর্শী হতে হবে। আপনি জানেন যে আগামী মাসে একটি ডেটা সোর্স মাইগ্রেট করার কথা রয়েছে, যা stream_id পরিবর্তন করে দেবে। আপনি জানেন যে geo_country তালিকায় একটি নতুন দেশ যুক্ত করা হচ্ছে। HITL প্রক্রিয়া হলো সেই জায়গা যেখানে আপনি এই ভবিষ্যৎ-অবস্থার জ্ঞানকে অন্তর্ভুক্ত করেন, এবং পরিকল্পিত ব্যবসায়িক বা প্রযুক্তিগত পরিবর্তনের সময় কোনো সমস্যা এড়ানোর জন্য নিয়মগুলোকে আপডেট বা সাময়িকভাবে নিষ্ক্রিয় করেন। ডেটার গুণমান কোনো এককালীন ব্যবস্থা নয়; এটি একটি জীবন্ত প্রক্রিয়া যার বিবর্তন আবশ্যক, এবং একমাত্র মানুষই সেই বিবর্তনকে পরিচালনা করতে পারে।

সংক্ষেপে, HITL হলো একটি অপরিহার্য গুণমান নিশ্চিতকরণ ও সুরক্ষা ব্যবস্থা, যা কৃত্রিম বুদ্ধিমত্তা-চালিত শাসনব্যবস্থাকে একটি অভিনব কিন্তু ঝুঁকিপূর্ণ ধারণা থেকে একটি দায়িত্বশীল, সম্প্রসারণযোগ্য এবং এন্টারপ্রাইজ-স্তরের অনুশীলনে রূপান্তরিত করে। এটি নিশ্চিত করে যে চূড়ান্তভাবে প্রয়োগ করা নীতিগুলি কেবল কৃত্রিম বুদ্ধিমত্তা দ্বারা ত্বরান্বিতই নয়, বরং মানব-যাচাইকৃতও, যা যন্ত্রের গতির সাথে মানব বিশেষজ্ঞদের প্রজ্ঞা ও প্রেক্ষাপটকে একত্রিত করে।

তবে, মানবিক তত্ত্বাবধানের উপর এই জোর দেওয়াটা এআই-এর গুরুত্বকে হ্রাস করে না। বরং, জেনারেটিভ এআই স্বয়ং এইচআইটিএল প্রক্রিয়াটিকে ত্বরান্বিত করতে একটি অত্যন্ত গুরুত্বপূর্ণ ভূমিকা পালন করে।

এআই ছাড়া একজন ডেটা ইঞ্জিনিয়ারকে যা করতে হতো:

  1. ডেটার প্রোফাইলিং করার জন্য ম্যানুয়ালি জটিল SQL কোয়েরি লিখুন (যেমন, প্রতিটি কলামের জন্য COUNT DISTINCT , AVG , MIN , MAX )।
  2. যত্নসহকারে প্রতিটি স্প্রেডশিট ধরে ফলাফলগুলো বিশ্লেষণ করুন।
  3. YAML রুল ফাইলের প্রতিটি লাইন একেবারে গোড়া থেকে লেখা, যা একটি ক্লান্তিকর এবং ভুল হওয়ার সম্ভাবনাযুক্ত কাজ।

এআই এই শ্রমসাধ্য ও সময়সাপেক্ষ ধাপগুলোকে স্বয়ংক্রিয় করে তোলে। এটি একজন অক্লান্ত বিশ্লেষকের মতো কাজ করে, যা তাৎক্ষণিকভাবে পরিসংখ্যানগত চিত্রটি বিশ্লেষণ করে এবং নীতিমালার একটি সুগঠিত ও ৮০% সম্পূর্ণ "প্রথম খসড়া" প্রদান করে।

এটি মানুষের কাজের প্রকৃতিকে মৌলিকভাবে পরিবর্তন করে দেয়। হাতে-কলমে ডেটা বিশ্লেষণ এবং গতানুগতিক কোডিংয়ে ঘণ্টার পর ঘণ্টা ব্যয় করার পরিবর্তে, মানব বিশেষজ্ঞ অবিলম্বে সর্বোচ্চ-মূল্যের কাজগুলিতে মনোযোগ দিতে পারেন:

  • গুরুত্বপূর্ণ ব্যবসায়িক প্রেক্ষাপট প্রয়োগ করা।
  • এআই-এর যুক্তির সঠিকতা যাচাই করা হচ্ছে।
  • কোন নিয়মগুলো সত্যিই গুরুত্বপূর্ণ, সে সম্পর্কে কৌশলগত সিদ্ধান্ত গ্রহণ করা।

এই অংশীদারিত্বে, এআই ‘কী’ (পরিসংখ্যানগত প্যাটার্নগুলো কী?) বিষয়টি সামলায়, ফলে মানুষ ‘কেন’ (এই প্যাটার্নটি আমাদের ব্যবসার জন্য কেন গুরুত্বপূর্ণ?) এবং ‘এর ফল কী’ (এর ফলে আমাদের নীতি কী হওয়া উচিত?)—এই বিষয়গুলোতে মনোযোগ দেওয়ার সুযোগ পায়। সুতরাং, এআই প্রক্রিয়াটিকে প্রতিস্থাপন করে না; বরং এটি প্রক্রিয়ার প্রতিটি চক্রকে আরও দ্রুত, স্মার্ট এবং অধিক কার্যকর করে তোলে।

৬. আপনার পরিবেশ পরিষ্কার করা

এই কোডল্যাবে ব্যবহৃত রিসোর্সগুলোর জন্য আপনার গুগল ক্লাউড অ্যাকাউন্টে ভবিষ্যতে কোনো চার্জ হওয়া এড়াতে, রিসোর্সগুলো ধারণকারী প্রজেক্টটি ডিলিট করে দেওয়া উচিত। তবে, আপনি যদি প্রজেক্টটি রাখতে চান, তাহলে আপনার তৈরি করা স্বতন্ত্র রিসোর্সগুলো ডিলিট করতে পারেন।

ডেটাপ্লেক্স স্ক্যানগুলি মুছে ফেলুন

প্রথমে, আপনার তৈরি করা প্রোফাইল এবং কোয়ালিটি স্ক্যানগুলো ডিলিট করুন। গুরুত্বপূর্ণ রিসোর্স ভুলবশত মুছে যাওয়া রোধ করতে, এই কমান্ডগুলোতে এই কোডল্যাবে তৈরি করা স্ক্যানগুলোর নির্দিষ্ট নাম ব্যবহার করা হয়েছে।

# Delete the Data Quality Scan
gcloud dataplex datascans delete dq-scan \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

# Delete the Data Profile Scans
gcloud dataplex datascans delete profile-scan-mv-ga4-user-session-flat \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

gcloud dataplex datascans delete profile-scan-mv-ga4-ecommerce-transactions \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

gcloud dataplex datascans delete profile-scan-mv-ga4-ecommerce-items \
    --location=us-central1 \
    --project=$PROJECT_ID --quiet

BigQuery ডেটাসেটটি মুছে ফেলুন

এরপর, BigQuery ডেটাসেটটি ডিলিট করুন। এই কমান্ডটি অপরিবর্তনীয় এবং এটি কোনো নিশ্চিতকরণ ছাড়াই ডেটাসেট ও এর সমস্ত টেবিল মুছে ফেলার জন্য -f (ফোর্স) ফ্ল্যাগ ব্যবহার করে।

# Manually type this command to confirm you are deleting the correct dataset
bq rm -r -f --dataset $PROJECT_ID:dataplex_dq_codelab

৭. অভিনন্দন!

আপনি সফলভাবে কোডল্যাবটি সম্পন্ন করেছেন!

আপনি একটি এন্ড-টু-এন্ড, প্রোগ্রাম্যাটিক ডেটা গভর্নেন্স ওয়ার্কফ্লো তৈরি করেছেন। আপনি জটিল BigQuery ডেটাকে বিশ্লেষণের জন্য উপযুক্ত করে তুলতে Materialized Views ব্যবহার করে কাজ শুরু করেছেন। এরপর আপনি পরিসংখ্যানগত মেটাডেটা তৈরি করার জন্য প্রোগ্রাম্যাটিকভাবে Dataplex প্রোফাইল স্ক্যান চালিয়েছেন। সবচেয়ে গুরুত্বপূর্ণভাবে, আপনি প্রোফাইল আউটপুট বিশ্লেষণ করতে এবং বুদ্ধিমত্তার সাথে একটি "পলিসি-অ্যাজ-কোড" আর্টিফ্যাক্ট ( dq_rules.yaml ) তৈরি করতে Gemini CLI ব্যবহার করেছেন। তারপর আপনি এই কনফিগারেশনটিকে একটি স্বয়ংক্রিয় ডেটা কোয়ালিটি স্ক্যান হিসাবে স্থাপন করতে CLI ব্যবহার করেছেন, যা একটি আধুনিক, স্কেলেবল গভর্নেন্স কৌশলের চক্রটি সম্পূর্ণ করেছে।

আপনি এখন গুগল ক্লাউডে নির্ভরযোগ্য, এআই-ত্বরিত এবং মানব-যাচাইকৃত ডেটা কোয়ালিটি সিস্টেম তৈরির মৌলিক কাঠামোটি সম্পর্কে অবগত হয়েছেন।

এরপর কী?

  • CI/CD-এর সাথে সংযুক্ত করুন: dq_rules.yaml ফাইলটি নিয়ে একটি গিট রিপোজিটরিতে কমিট করুন। একটি CI/CD পাইপলাইন তৈরি করুন (যেমন, ক্লাউড বিল্ড বা গিটহাব অ্যাকশন ব্যবহার করে) যা রুল ফাইলটি আপডেট হওয়ার সাথে সাথে স্বয়ংক্রিয়ভাবে ডেটাপ্লেক্স স্ক্যানটি ডেপ্লয় করবে।
  • কাস্টম SQL রুল অন্বেষণ করুন: সাধারণ রুল টাইপগুলোর বাইরে যান। Dataplex কাস্টম SQL রুল সমর্থন করে, যা আরও জটিল ও ব্যবসায়-নির্দিষ্ট লজিক প্রয়োগ করতে পারে, যা পূর্বনির্ধারিত চেকের মাধ্যমে প্রকাশ করা যায় না। আপনার অনন্য প্রয়োজন অনুযায়ী ভ্যালিডেশনকে সাজিয়ে তোলার জন্য এটি একটি শক্তিশালী ফিচার।
  • দক্ষতা ও খরচের জন্য স্ক্যান অপ্টিমাইজ করুন: খুব বড় টেবিলের ক্ষেত্রে, সবসময় সম্পূর্ণ ডেটাসেট স্ক্যান না করে আপনি পারফরম্যান্স উন্নত করতে এবং খরচ কমাতে পারেন। স্ক্যানকে নির্দিষ্ট সময়সীমা বা ডেটা সেগমেন্টে সীমাবদ্ধ করতে ফিল্টার ব্যবহার করে দেখুন, অথবা আপনার ডেটার একটি প্রতিনিধিত্বমূলক শতাংশ পরীক্ষা করার জন্য স্যাম্পলড স্ক্যান কনফিগার করুন।
  • ফলাফলগুলো দেখুন: প্রতিটি ডেটাপ্লেক্স ডেটা কোয়ালিটি স্ক্যানের আউটপুট একটি বিগকোয়েরি টেবিলে লেখা হয়। আপনার সংজ্ঞায়িত ডাইমেনশন (যেমন, সম্পূর্ণতা, বৈধতা) অনুযায়ী একত্রিত করে, সময়ের সাথে সাথে আপনার ডেটা কোয়ালিটি স্কোর ট্র্যাক করে এমন ড্যাশবোর্ড তৈরি করতে এই টেবিলটিকে লুকার স্টুডিওর সাথে সংযুক্ত করুন। এটি পর্যবেক্ষণকে সক্রিয় করে তোলে এবং সকল স্টেকহোল্ডারের কাছে দৃশ্যমান করে।
  • সর্বোত্তম অনুশীলনগুলো ভাগ করে নিন: সম্মিলিত অভিজ্ঞতাকে কাজে লাগাতে এবং আপনার ডেটার গুণমান কৌশল উন্নত করতে আপনার প্রতিষ্ঠানের মধ্যে জ্ঞান বিনিময়কে উৎসাহিত করুন। আপনার প্রশাসনিক প্রচেষ্টার সর্বোত্তম ব্যবহার নিশ্চিত করতে ডেটার উপর আস্থার সংস্কৃতি গড়ে তোলা অপরিহার্য।
  • ডকুমেন্টেশনটি পড়ুন: