gRPC-Python দিয়ে শুরু করা

1. ভূমিকা

এই কোডল্যাবে, আপনি gRPC-Python ব্যবহার করে একটি ক্লায়েন্ট এবং সার্ভার তৈরি করবেন যা পাইথনে লেখা একটি রুট-ম্যাপিং অ্যাপ্লিকেশনের ভিত্তি তৈরি করবে।

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

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

এই জেনারেট করা কোডটি কেবল সার্ভার এবং ক্লায়েন্টের মধ্যে যোগাযোগের জটিলতাই নয়, ডেটা সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশনেরও যত্ন নেয়।

তুমি কি শিখবে

  • একটি পরিষেবা API সংজ্ঞায়িত করতে প্রোটোকল বাফার কীভাবে ব্যবহার করবেন।
  • স্বয়ংক্রিয় কোড জেনারেশন ব্যবহার করে প্রোটোকল বাফার সংজ্ঞা থেকে কীভাবে একটি gRPC-ভিত্তিক ক্লায়েন্ট এবং সার্ভার তৈরি করবেন।
  • জিআরপিসির সাথে ক্লায়েন্ট-সার্ভার যোগাযোগের ধারণা।

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

2. শুরু করার আগে

তোমার যা লাগবে

  • পাইথন ৩.৯ বা তার বেশি। আমরা পাইথন ৩.১৩ সুপারিশ করি। প্ল্যাটফর্ম-নির্দিষ্ট ইনস্টলেশন নির্দেশাবলীর জন্য, পাইথন সেটআপ এবং ব্যবহার দেখুন। বিকল্পভাবে, uv বা pyenv এর মতো সরঞ্জাম ব্যবহার করে একটি নন-সিস্টেম পাইথন ইনস্টল করুন।
  • পাইথন প্যাকেজ ইনস্টল করার জন্য pip
  • venv ব্যবহার করে পাইথন ভার্চুয়াল পরিবেশ তৈরি করা যাবে।

ensurepip এবং venv প্যাকেজগুলি Python স্ট্যান্ডার্ড লাইব্রেরির অংশ এবং সাধারণত ডিফল্টরূপে উপলব্ধ।

তবে, কিছু ডেবিয়ান-ভিত্তিক ডিস্ট্রিবিউশন (উবুন্টু সহ) পাইথন পুনঃবিতরণ করার সময় এগুলি বাদ দিতে পছন্দ করে। প্যাকেজগুলি ইনস্টল করতে, চালান:

sudo apt install python3-pip python3-venv

কোডটি পান

আপনার শেখার গতি বাড়ানোর জন্য, এই কোডল্যাবটি আপনাকে শুরু করতে সাহায্য করার জন্য একটি পূর্ব-নির্মিত সোর্স কোড স্ক্যাফোল্ড অফার করে। নিম্নলিখিত ধাপগুলি আপনাকে অ্যাপ্লিকেশনটি সম্পূর্ণ করার ক্ষেত্রে সহায়তা করবে, যার মধ্যে grpc_tools.protoc প্রোটোকল বাফার কম্পাইলার প্লাগইন ব্যবহার করে gRPC কোড তৈরি করা অন্তর্ভুক্ত।

জিআরপিসি-কোডল্যাবস

এই কোডল্যাবের স্ক্যাফোল্ড সোর্স কোড codelabs/grpc-python-getting-started/start_here ডিরেক্টরিতে পাওয়া যাবে। যদি আপনি নিজে কোডটি বাস্তবায়ন করতে না চান, তাহলে সম্পূর্ণ সোর্স কোডটি completed ডিরেক্টরিতে পাওয়া যাবে।

প্রথমে, কোডল্যাব ওয়ার্কিং ডিরেক্টরি তৈরি করুন এবং এতে সিডি দিন:

mkdir grpc-python-getting-started && cd grpc-python-getting-started

কোডল্যাবটি ডাউনলোড করে এক্সট্রাক্ট করুন:

curl -sL https://github.com/grpc-ecosystem/grpc-codelabs/archive/refs/heads/v1.tar.gz \
  | tar xvz --strip-components=4 \
  grpc-codelabs-1/codelabs/grpc-python-getting-started/start_here

অন্যথায়, আপনি শুধুমাত্র কোডল্যাব ডিরেক্টরি সম্বলিত .zip ফাইলটি ডাউনলোড করতে পারেন এবং ম্যানুয়ালি এটি আনজিপ করতে পারেন।

৩. পরিষেবাটি সংজ্ঞায়িত করুন

আপনার প্রথম ধাপ হল অ্যাপ্লিকেশনের gRPC পরিষেবা, এর RPC পদ্ধতি এবং এর অনুরোধ এবং প্রতিক্রিয়া বার্তার ধরণগুলি প্রোটোকল বাফার ইন্টারফেস সংজ্ঞা ভাষা ব্যবহার করে সংজ্ঞায়িত করা। আপনার পরিষেবাটি প্রদান করবে:

  • GetFeature নামক একটি RPC পদ্ধতি যা সার্ভার প্রয়োগ করে এবং ক্লায়েন্ট কল করে।
  • GetFeature পদ্ধতি ব্যবহার করার সময় ক্লায়েন্ট এবং সার্ভারের মধ্যে আদান-প্রদান করা ডেটা স্ট্রাকচার হল Point এবং Feature । ক্লায়েন্ট সার্ভারে তার GetFeature অনুরোধে Point হিসেবে ম্যাপ কোঅর্ডিনেট প্রদান করে এবং সার্ভার একটি সংশ্লিষ্ট Feature মাধ্যমে উত্তর দেয় যা সেই কোঅর্ডিনেটগুলিতে যা কিছু আছে তা বর্ণনা করে।

এই RPC পদ্ধতি এবং এর বার্তার ধরণগুলি প্রদত্ত সোর্স কোডের protos/route_guide.proto ফাইলে সংজ্ঞায়িত করা হবে।

প্রোটোকল বাফারগুলি সাধারণত প্রোটোবুফ নামে পরিচিত। gRPC পরিভাষা সম্পর্কে আরও তথ্যের জন্য, gRPC এর মূল ধারণা, স্থাপত্য এবং জীবনচক্র দেখুন।

বার্তার ধরণ

সোর্স কোডের protos/route_guide.proto ফাইলে, প্রথমে Point বার্তার ধরণ নির্ধারণ করুন। একটি Point একটি মানচিত্রে একটি অক্ষাংশ-দ্রাঘিমাংশ স্থানাঙ্ক জোড়াকে প্রতিনিধিত্ব করে। এই কোডল্যাবের জন্য, স্থানাঙ্কগুলির জন্য পূর্ণসংখ্যা ব্যবহার করুন:

message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

message কাঠামোর প্রতিটি ক্ষেত্রের জন্য 1 এবং 2 নম্বরগুলি অনন্য আইডি নম্বর।

এরপর, Feature বার্তার ধরণ নির্ধারণ করুন। একটি Feature একটি Point দ্বারা নির্দিষ্ট স্থানে থাকা কোনও কিছুর নাম বা ডাক ঠিকানার জন্য একটি string ফিল্ড ব্যবহার করে:

message Feature {
  // The name or address of the feature.
  string name = 1;

  // The point where the feature is located.
  Point location = 2;
}

পরিষেবা পদ্ধতি

route_guide.proto ফাইলটিতে RouteGuide নামে একটি service কাঠামো রয়েছে যা অ্যাপ্লিকেশনের পরিষেবা দ্বারা প্রদত্ত এক বা একাধিক পদ্ধতি সংজ্ঞায়িত করে।

RouteGuide সংজ্ঞার ভেতরে rpc পদ্ধতি GetFeature যোগ করুন। যেমনটি আগে ব্যাখ্যা করা হয়েছে, এই পদ্ধতিটি একটি নির্দিষ্ট স্থানাঙ্কের সেট থেকে একটি অবস্থানের নাম বা ঠিকানা অনুসন্ধান করবে, তাই GetFeature একটি নির্দিষ্ট Point জন্য একটি Feature ফেরত দেবে:

service RouteGuide {
  // Definition of the service goes here

  // Obtains the feature at a given position.
  rpc GetFeature(Point) returns (Feature) {}
}

এটি একটি ইউনারি RPC পদ্ধতি: একটি সহজ RPC যেখানে ক্লায়েন্ট সার্ভারে একটি অনুরোধ পাঠায় এবং স্থানীয় ফাংশন কলের মতো প্রতিক্রিয়া ফিরে আসার জন্য অপেক্ষা করে।

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

এরপর, প্রোটোকল বাফার কম্পাইলার ব্যবহার করে .proto ফাইল থেকে ক্লায়েন্ট এবং সার্ভার উভয়ের জন্য বয়লারপ্লেট gRPC কোড তৈরি করুন।

gRPC পাইথন কোড জেনারেশনের জন্য, আমরা grpcio-tools তৈরি করেছি। এতে রয়েছে:

  1. নিয়মিত প্রোটোক কম্পাইলার যা message সংজ্ঞা থেকে পাইথন কোড তৈরি করে।
  2. gRPC প্রোটোবাফ প্লাগইন যা service সংজ্ঞা থেকে পাইথন কোড (ক্লায়েন্ট এবং সার্ভার স্টাব) তৈরি করে।

আমরা pip ব্যবহার করে grpcio-tools Python প্যাকেজ ইনস্টল করব। সিস্টেম প্যাকেজ থেকে আপনার প্রোজেক্টের নির্ভরতা আলাদা করার জন্য একটি নতুন python ভার্চুয়াল পরিবেশ (venv) তৈরি করি:

python3 -m venv --upgrade-deps .venv

bash/zsh শেলে ভার্চুয়াল পরিবেশ সক্রিয় করতে:

source .venv/bin/activate

উইন্ডোজ এবং নন-স্ট্যান্ডার্ড শেলের জন্য, https://docs.python.org/3/library/venv.html#how-venvs-work এ টেবিলটি দেখুন।

এরপর, grpcio-tools ইনস্টল করুন (এটি grpcio প্যাকেজটিও ইনস্টল করে):

pip install grpcio-tools

পাইথন বয়লারপ্লেট কোড তৈরি করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:

python -m grpc_tools.protoc --proto_path=./protos  \
 --python_out=. --pyi_out=. --grpc_python_out=. \
 ./protos/route_guide.proto

এটি route_guide.proto তে সংজ্ঞায়িত ইন্টারফেসের জন্য নিম্নলিখিত ফাইলগুলি তৈরি করবে:

  1. route_guide_pb2.py তে এমন কোড রয়েছে যা message সংজ্ঞা থেকে তৈরি হওয়া ক্লাসগুলিকে গতিশীলভাবে তৈরি করে
  2. route_guide_pb2.pyi হল একটি "স্টাব ফাইল" অথবা "টাইপ হিন্ট ফাইল" যা message সংজ্ঞা থেকে তৈরি হয়। এতে কেবল স্বাক্ষর থাকে, কোন বাস্তবায়ন নেই। IDE গুলি আরও ভালোভাবে স্বয়ংক্রিয়ভাবে সম্পন্ন এবং ত্রুটি সনাক্তকরণ প্রদানের জন্য স্টাব ফাইল ব্যবহার করতে পারে।
  3. route_guide_pb2_grpc.py service সংজ্ঞা থেকে তৈরি করা হয়েছে এবং এতে gRPC-নির্দিষ্ট ক্লাস এবং ফাংশন রয়েছে।

gRPC-নির্দিষ্ট কোডে রয়েছে:

  1. RouteGuideStub , যা একটি gRPC ক্লায়েন্ট RouteGuide RPC চালু করতে ব্যবহার করতে পারে।
  2. RouteGuideServicer , যা RouteGuide পরিষেবা বাস্তবায়নের জন্য ইন্টারফেস সংজ্ঞায়িত করে।
  3. add_RouteGuideServicer_to_server ফাংশন যা একটি RouteGuideServicer কে একটি gRPC সার্ভারে নিবন্ধন করতে ব্যবহৃত হয়।

৫. পরিষেবা তৈরি করুন

প্রথমে দেখা যাক কিভাবে আপনি একটি RouteGuide সার্ভার তৈরি করেন। RouteGuide সার্ভার তৈরি এবং চালানো দুটি কাজের আইটেমে বিভক্ত:

  • আমাদের পরিষেবা সংজ্ঞা থেকে উৎপন্ন সার্ভিসার ইন্টারফেস বাস্তবায়ন করা, পরিষেবার প্রকৃত "কাজ" সম্পাদনকারী ফাংশনগুলির সাথে।
  • ক্লায়েন্টদের অনুরোধ শুনতে এবং প্রতিক্রিয়া প্রেরণের জন্য একটি নির্দিষ্ট পোর্টে একটি gRPC সার্ভার চালানো।

আপনি start_here/route_guide_server.py তে প্রাথমিক RouteGuide সার্ভারটি খুঁজে পেতে পারেন।

RouteGuide বাস্তবায়ন করুন

route_guide_server.py একটি RouteGuideServicer ক্লাস আছে যা জেনারেট করা ক্লাস route_guide_pb2_grpc.RouteGuideServicer কে সাবক্লাস করে:

# RouteGuideServicer provides an implementation
# of the methods of the RouteGuide service.
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):

RouteGuideServicer সমস্ত RouteGuide পরিষেবা পদ্ধতি প্রয়োগ করে।

আসুন একটি সহজ RPC বাস্তবায়নের বিশদ পর্যালোচনা করি। GetFeature পদ্ধতি ক্লায়েন্টের কাছ থেকে একটি Point পায় এবং Feature এর ডাটাবেস থেকে সংশ্লিষ্ট বৈশিষ্ট্যের তথ্য ফেরত দেয়।

def GetFeature(self, request, context):
    feature = get_feature(self.db, request)
    if feature is None:
        return route_guide_pb2.Feature(name="", location=request)
    else:
        return feature

এই পদ্ধতিতে RPC-এর জন্য একটি route_guide_pb2.Point অনুরোধ এবং একটি grpc.ServicerContext অবজেক্ট পাস করা হয় যা RPC-নির্দিষ্ট তথ্য যেমন টাইমআউট লিমিট প্রদান করে। এটি একটি route_guide_pb2.Feature প্রতিক্রিয়া প্রদান করে।

সার্ভার শুরু করা হচ্ছে

একবার আপনি সমস্ত RouteGuide পদ্ধতি বাস্তবায়ন করার পরে, পরবর্তী পদক্ষেপ হল একটি gRPC সার্ভার শুরু করা যাতে ক্লায়েন্টরা আসলে আপনার পরিষেবা ব্যবহার করতে পারে:

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
        RouteGuideServicer(),
        server,
    )
    listen_addr = "localhost:50051"
    server.add_insecure_port(listen_addr)
    print(f"Starting server on {listen_addr}")
    server.start()
    server.wait_for_termination()

সার্ভার start() পদ্ধতিটি ব্লকিং নয়। অনুরোধগুলি পরিচালনা করার জন্য একটি নতুন থ্রেড তৈরি করা হবে। server.start() কলকারী থ্রেডের প্রায়শই অন্য কোনও কাজ করার থাকে না। এই ক্ষেত্রে, আপনি server.wait_for_termination() কল করে সার্ভারটি বন্ধ না হওয়া পর্যন্ত কলিং থ্রেডটি পরিষ্কারভাবে ব্লক করতে পারেন।

৬. ক্লায়েন্ট তৈরি করুন

এই বিভাগে, আমরা আমাদের RouteGuide পরিষেবার জন্য একটি ক্লায়েন্ট তৈরি করার বিষয়ে আলোচনা করব। আপনি start_here/route_guide_client.py ওয়েবসাইটে প্রাথমিক ক্লায়েন্ট কোড দেখতে পারেন।

একটি স্টাব তৈরি করুন

পরিষেবা পদ্ধতি কল করার জন্য, আমাদের প্রথমে একটি স্টাব তৈরি করতে হবে।

আমরা route_guide_client.py ফাইলের ভিতরে আমাদের .proto থেকে তৈরি route_guide_pb2_grpc মডিউলের RouteGuideStub ক্লাসটি ইন্সট্যান্টিয়েট করি।

channel = grpc.insecure_channel("localhost:50051")
stub = route_guide_pb2_grpc.RouteGuideStub(channel)

কলিং পরিষেবা পদ্ধতি

RPC পদ্ধতিগুলি যা একটি একক প্রতিক্রিয়া প্রদান করে - যা রেসপন্স-ইউনারি পদ্ধতি নামে পরিচিত - এর জন্য gRPC পাইথন সিঙ্ক্রোনাস (ব্লকিং) এবং অ্যাসিঙ্ক্রোনাস (নন-ব্লকিং) নিয়ন্ত্রণ প্রবাহ শব্দার্থবিদ্যা উভয়কেই সমর্থন করে।

সরল RPC

প্রথমে, আসুন একটি Point সংজ্ঞায়িত করি যার মাধ্যমে পরিষেবাটি কল করা হবে। এটি route_guide_pb2 প্যাকেজ থেকে কিছু বৈশিষ্ট্য সহ একটি বস্তুকে ইনস্ট্যান্টিয়েট করার মতোই সহজ হওয়া উচিত:

point = route_guide_pb2.Point(latitude=412346009, longitude=-744026814)

সরল RPC GetFeature এ একটি সিঙ্ক্রোনাস কল স্থানীয় পদ্ধতিতে কল করার মতোই সহজ। RPC কল সার্ভারের প্রতিক্রিয়ার জন্য অপেক্ষা করে এবং হয় একটি প্রতিক্রিয়া ফেরত দেবে অথবা একটি ব্যতিক্রম উত্থাপন করবে। আমরা পদ্ধতিটি কল করতে পারি এবং প্রতিক্রিয়াটি এভাবে দেখতে পারি:

feature = stub.GetFeature(point)
print(feature)

আপনি Feature অবজেক্টের ক্ষেত্রগুলি পরিদর্শন করতে পারেন এবং অনুরোধের ফলাফল আউটপুট করতে পারেন:

if feature.name:
    print(f"Feature called '{feature.name}' at {format_point(feature.location)}")
else:
    print(f"Found no feature at at {format_point(feature.location)}")

৭. চেষ্টা করে দেখুন

সার্ভারটি চালান:

python route_guide_server.py

অন্য একটি টার্মিনাল থেকে, ভার্চুয়াল পরিবেশটি আবার সক্রিয় করুন, তারপর ক্লায়েন্টটি চালান:

python route_guide_client.py

আপনি এইরকম আউটপুট দেখতে পাবেন, স্পষ্টতার জন্য টাইমস্ট্যাম্প বাদ দেওয়া হবে:

name: "16 Old Brook Lane, Warwick, NY 10990, USA"
location {
  latitude: 412346009
  longitude: -744026814
}

Feature called '16 Old Brook Lane, Warwick, NY 10990, USA' at latitude: 412346009, longitude: -744026814

৮. এরপর কী?