1. Giriş
Bu codelab'de, Python'da yazılmış bir rota eşleme uygulamasının temelini oluşturan bir istemci ve sunucu oluşturmak için gRPC-Python'ı kullanacaksınız.
Eğitimin sonunda, haritada belirli koordinatlarda bulunan yerin adını veya posta adresini almak için gRPC kullanarak uzak bir sunucuya bağlanan bir istemciniz olacak. Tam teşekküllü bir uygulama, bir rota üzerindeki önemli yerleri listelemek veya özetlemek için bu istemci-sunucu tasarımını kullanabilir.
Hizmet, istemci ve sunucu için standart kod oluşturmak üzere kullanılacak bir Protocol Buffers dosyasında tanımlanır. Böylece, bu işlevselliği uygularken zamandan ve emekten tasarruf edersiniz.
Oluşturulan bu kod, yalnızca sunucu ile istemci arasındaki iletişimin karmaşıklıklarını değil, aynı zamanda veri serileştirme ve seri durumdan çıkarma işlemlerini de ele alır.
Neler öğreneceksiniz?
- Hizmet API'sini tanımlamak için Protocol Buffers'ı kullanma.
- Otomatik kod oluşturma kullanarak bir Protokol Arabellek tanımından gRPC tabanlı istemci ve sunucu oluşturma.
- gRPC ile istemci-sunucu iletişimi hakkında bilgi sahibi olmanız gerekir.
Bu codelab, gRPC'ye yeni başlayan veya gRPC ile ilgili bilgilerini tazelemek isteyen Python geliştiricilerin yanı sıra dağıtılmış sistemler oluşturmakla ilgilenen herkes için hazırlanmıştır. Daha önce gRPC deneyimi gerekmez.
2. Başlamadan önce
İhtiyacınız olanlar
- Python 3.9 veya sonraki sürümler. Python 3.13'ü öneririz. Platforma özel yükleme talimatları için Python Kurulumu ve Kullanımı başlıklı makaleyi inceleyin. Alternatif olarak, uv veya pyenv gibi araçları kullanarak sistem dışı bir Python yükleyin.
- Python paketlerini yüklemek için pip.
- Python sanal ortamları oluşturmak için venv.
ensurepip
ve venv
paketleri, Python Standart Kitaplığı'nın bir parçasıdır ve genellikle varsayılan olarak kullanılabilir.
Ancak Ubuntu da dahil olmak üzere bazı Debian tabanlı dağıtımlar, python'u yeniden dağıtırken bunları hariç tutmayı tercih eder. Paketleri yüklemek için şu komutu çalıştırın:
sudo apt install python3-pip python3-venv
Kodu alın
Bu codelab, öğrenme sürecinizi kolaylaştırmak için başlamanıza yardımcı olacak önceden oluşturulmuş bir kaynak kodu iskeleti sunar. Aşağıdaki adımlar, grpc_tools.protoc
Protocol Buffer derleyici eklentisini kullanarak gRPC kodu oluşturma da dahil olmak üzere uygulamayı tamamlama konusunda size yol gösterecektir.
grpc-codelabs
Bu codelab'in iskele kaynak kodu, codelabs/grpc-python-getting-started/start_here dizininde bulunur. Kodu kendiniz uygulamayı tercih etmezseniz tamamlanmış kaynak kodu completed
dizininde bulabilirsiniz.
Öncelikle codelab çalışma dizinini oluşturun ve bu dizine gidin:
mkdir grpc-python-getting-started && cd grpc-python-getting-started
Codelab'i indirip ayıklayın:
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
Alternatif olarak, yalnızca codelab dizinini içeren .zip dosyasını indirebilir ve manuel olarak sıkıştırmasını açabilirsiniz.
3. Hizmeti tanımlama
İlk adımınız, Protocol Buffers arayüz tanımı dilini kullanarak uygulamanın gRPC hizmetini, RPC yöntemini ve istek ile yanıt mesajı türlerini tanımlamaktır. Hizmetinizde sunulacaklar:
- Sunucunun uyguladığı ve istemcinin çağırdığı
GetFeature
adlı bir RPC yöntemi. Point
veFeature
mesaj türleri,GetFeature
yöntemi kullanılırken istemci ile sunucu arasında değiştirilen veri yapılarıdır. İstemci, sunucuya gönderdiğiGetFeature
isteğinde harita koordinatlarınıPoint
olarak sağlar ve sunucu, bu koordinatlarda bulunan her şeyi açıklayan ilgili birFeature
ile yanıt verir.
Bu RPC yöntemi ve mesaj türleri, sağlanan kaynak kodun protos/route_guide.proto
dosyasında tanımlanır.
Protocol Buffers genellikle protobuf olarak bilinir. gRPC terminolojisi hakkında daha fazla bilgi için gRPC'nin Temel kavramlar, mimari ve yaşam döngüsü başlıklı makalesine bakın.
Mesaj türleri
Kaynak kodun protos/route_guide.proto
dosyasında önce Point
mesaj türünü tanımlayın. Point
, haritadaki bir enlem-boylam koordinat çiftini temsil eder. Bu codelab'de koordinatlar için tam sayıları kullanın:
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
1
ve 2
sayıları, message
yapısındaki her alan için benzersiz kimlik numaralarıdır.
Ardından, Feature
mesaj türünü tanımlayın. Bir Feature
, Point
ile belirtilen bir konumdaki bir şeyin adı veya posta adresi için string
alanını kullanır:
message Feature {
// The name or address of the feature.
string name = 1;
// The point where the feature is located.
Point location = 2;
}
Hizmet yöntemi
route_guide.proto
dosyasında, uygulamanın hizmeti tarafından sağlanan bir veya daha fazla yöntemi tanımlayan RouteGuide
adlı bir service
yapısı bulunur.
rpc
yöntemini RouteGuide
tanımının içine ekleyin.GetFeature
Daha önce açıklandığı gibi, bu yöntem belirli bir koordinat kümesinden bir konumun adını veya adresini arar. Bu nedenle, belirli bir Point
için GetFeature
işlevinin Feature
döndürmesini sağlayın:
service RouteGuide {
// Definition of the service goes here
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
}
Bu, tekli bir UPÇ yöntemidir: İstemcinin sunucuya istek gönderdiği ve yanıtın geri gelmesini beklediği basit bir UPÇ'dir (yerel bir işlev çağrısı gibi).
4. İstemci ve sunucu kodunu oluşturma
Ardından, protokol arabelleği derleyicisini kullanarak .proto
dosyasından hem istemci hem de sunucu için standart gRPC kodunu oluşturun.
gRPC Python kod üretimi için grpcio-tools'u oluşturduk. Şunları içermektedir:
message
tanımlarından Python kodu oluşturan normal protoc derleyicisi.service
tanımlarından Python kodu (istemci ve sunucu saplamaları) oluşturan gRPC protobuf eklentisi.
grpcio-tools
Python paketini pip kullanarak yükleyeceğiz. Projenizin bağımlılıklarını sistem paketlerinden ayırmak için yeni bir Python sanal ortamı (venv) oluşturalım:
python3 -m venv --upgrade-deps .venv
Sanal ortamı bash/zsh kabuğunda etkinleştirmek için:
source .venv/bin/activate
Windows ve standart dışı kabuklar için https://docs.python.org/3/library/venv.html#how-venvs-work adresindeki tabloya bakın.
Ardından, grpcio-tools'u yükleyin (bu işlem grpcio paketini de yükler):
pip install grpcio-tools
Python standart kodunu oluşturmak için aşağıdaki komutu kullanın:
python -m grpc_tools.protoc --proto_path=./protos \
--python_out=. --pyi_out=. --grpc_python_out=. \
./protos/route_guide.proto
Bu işlem, route_guide.proto
içinde tanımladığımız arayüzler için aşağıdaki dosyaları oluşturur:
route_guide_pb2.py
,message
tanımlarından oluşturulan sınıfları dinamik olarak oluşturan kodu içerir.route_guide_pb2.pyi
,message
tanımlarından oluşturulan bir "stub dosyası" veya "tür ipucu dosyası"dır. Yalnızca imzaları içerir ve uygulama içermez. Stub dosyaları, IDE'ler tarafından daha iyi otomatik tamamlama ve hata algılama sağlamak için kullanılabilir.route_guide_pb2_grpc.py
,service
tanımlarından oluşturulur ve gRPC'ye özgü sınıflar ve işlevler içerir.
gRPC'ye özel kod şunları içerir:
RouteGuideStub
, gRPC istemcisi tarafından RouteGuide RPC'lerini çağırmak için kullanılabilir.RouteGuideServicer
hizmetinin uygulamaları için arayüzü tanımlar.RouteGuide
add_RouteGuideServicer_to_server
işlevi,RouteGuideServicer
öğesini gRPC sunucusuna kaydetmek için kullanılır.
5. Hizmeti oluşturun
Öncelikle RouteGuide
sunucuyu nasıl oluşturduğunuza bakalım. RouteGuide
sunucusu oluşturma ve çalıştırma iki iş öğesine ayrılır:
- Hizmet tanımımızdan oluşturulan hizmet arayüzünü, hizmetin gerçek "işini" yapan işlevlerle uygulama.
- İstemcilerden gelen istekleri dinlemek ve yanıtları iletmek için belirli bir bağlantı noktasında gRPC sunucusu çalıştırma.
İlk RouteGuide
sunucusunu start_here/route_guide_server.py
içinde bulabilirsiniz.
RouteGuide'ı uygulama
route_guide_server.py
, oluşturulan sınıf route_guide_pb2_grpc.RouteGuideServicer
'ı alt sınıfa ayıran bir RouteGuideServicer
sınıfına sahip:
# RouteGuideServicer provides an implementation
# of the methods of the RouteGuide service.
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
RouteGuideServicer
, tüm RouteGuide
hizmet yöntemlerini uygular.
Basit bir RPC uygulamasını ayrıntılı olarak inceleyelim. Yöntem GetFeature
, istemciden Point
alır ve veritabanından ilgili özellik bilgilerini Feature
olarak döndürür.
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
Yönteme, RPC için bir route_guide_pb2.Point
istek ve zaman aşımı sınırları gibi RPC'ye özgü bilgileri sağlayan bir grpc.ServicerContext
nesnesi iletilir. route_guide_pb2.Feature
yanıtı döndürülür.
Sunucuyu başlatma
Tüm RouteGuide
yöntemlerini uyguladıktan sonraki adım, istemcilerin hizmetinizi gerçekten kullanabilmesi için bir gRPC sunucusu başlatmaktır:
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()
Sunucu start()
yöntemi engelleme yapmaz. İstekleri işlemek için yeni bir iş parçacığı oluşturulur. server.start()
işlevini çağıran iş parçacığı, bu süre zarfında genellikle başka bir iş yapmaz. Bu durumda, sunucu sonlandırılana kadar arama iş parçacığını temiz bir şekilde engellemek için server.wait_for_termination()
numaralı telefonu arayabilirsiniz.
6. İstemciyi oluşturma
Bu bölümde, RouteGuide
hizmetimiz için istemci oluşturma konusunu ele alacağız. İlk müşteri kodunu start_here/route_guide_client.py
bölümünde görebilirsiniz.
Taslak oluşturma
Hizmet yöntemlerini çağırmak için önce bir taslak oluşturmamız gerekir.
route_guide_client.py
dosyasındaki .proto
öğemizden oluşturulan route_guide_pb2_grpc
modülünün RouteGuideStub
sınıfını başlatırız.
channel = grpc.insecure_channel("localhost:50051")
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
Arama hizmeti yöntemleri
Tek bir yanıt döndüren RPC yöntemleri (response-unary yöntemleri olarak bilinir) için gRPC Python hem eşzamanlı (engelleyici) hem de eşzamansız (engelleyici olmayan) kontrol akışı semantiğini destekler.
Simple RPC
Öncelikle, hizmeti çağırmak için bir Point
tanımlayalım. Bu işlem, route_guide_pb2
paketinden bazı özelliklere sahip bir nesne oluşturmak kadar basit olmalıdır:
point = route_guide_pb2.Point(latitude=412346009, longitude=-744026814)
Basit RPC GetFeature
için yapılan senkronize bir çağrı, yerel bir yöntemi çağırmak kadar basittir. RPC çağrısı, sunucunun yanıt vermesini bekler ve yanıt döndürür veya istisna oluşturur. Yöntemi şu şekilde çağırabilir ve yanıtı görebiliriz:
feature = stub.GetFeature(point)
print(feature)
Özellik nesnesinin alanlarını inceleyebilir ve isteğin sonucunu çıkış olarak verebilirsiniz:
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)}")
7. Deneyin
Sunucuyu çalıştırın:
python route_guide_server.py
Farklı bir terminalden sanal ortamı tekrar etkinleştirin ve istemciyi çalıştırın:
python route_guide_client.py
Aşağıdakine benzer bir çıkış görürsünüz. Zaman damgaları, netlik için çıkarılmıştır:
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
8. Sırada ne var?
- gRPC'nin işleyiş şeklini Introduction to gRPC (gRPC'ye Giriş) ve Core concepts (Temel kavramlar) başlıklı makalelerden öğrenebilirsiniz.
- Temel bilgiler eğitimini inceleyin.
- Python API referansını inceleyin.