Skip to content

Commit 3899875

Browse files
authored
Python Getting Started: point README.md to the codelabs site (#55)
Link the interactive codelab in place of README.md.
1 parent a6b9941 commit 3899875

File tree

1 file changed

+5
-331
lines changed
  • codelabs/grpc-python-getting-started

1 file changed

+5
-331
lines changed
Lines changed: 5 additions & 331 deletions
Original file line numberDiff line numberDiff line change
@@ -1,343 +1,17 @@
11
# Getting Started with gRPC-Python
22

3-
Get hands-on with gRPC for Python in this interactive codelab!
3+
Get hands-on with gRPC for Python in this interactive codelab!
44

55
Perfect for Python developers new to gRPC, those seeking a refresher, or anyone building distributed
66
systems. No prior gRPC experience needed!
77

8-
**Build a complete gRPC service from scratch, learning:**
9-
10-
- Protocol Buffers (protobuf): Define service contracts & data.
11-
- gRPC Code Generation: Auto-generate Python code.
12-
- Client/Server Communication: Implement seamless interactions.
13-
14-
**You'll gain:**
15-
16-
- A working gRPC service in Python.
17-
- Hands-on experience with Protocol Buffers and code generation.
18-
- Skills to design, build, & test gRPC clients and servers.
19-
- A strong foundation in gRPC for real-world projects.
20-
218
### How to use this directory
229

23-
- [start_here](./start_here/) directory serves as a starting point for the codelab.
10+
- [start_here](./start_here/) directory serves as a starting point for the codelab.
2411
- [completed](./completed/) directory showcases the finished code, giving you a peak of how the
2512
final implementation should look like.
2613

27-
## Prerequisites
28-
29-
### This codelab
30-
31-
```sh
32-
cd ~/your-dev-dir
33-
git clone https://github.com/grpc-ecosystem/grpc-codelabs.git
34-
cd grpc-codelabs/
35-
```
36-
37-
### Python3
38-
39-
For this codelab, we require python 3.9 or higher, but recommend python 3.11. System-specific
40-
instructions can be found in Python documentation: [Python Setup and Usage](https://docs.python.org/3/using/index.html).
41-
42-
### Pip3
43-
44-
We recommend using the latest pip, see [Installation - pip](https://pip.pypa.io/en/stable/installation/).
45-
In some OS distributions, `ensurepip` is not available out-of-box. On Debian/Ubuntu, you may need
46-
to run.
47-
48-
```sh
49-
sudo apt-get install python3-pip
50-
```
51-
52-
If necessary, upgrade your version of pip:
53-
54-
```sh
55-
python3 -m ensurepip --upgrade
56-
```
57-
58-
If your python installation is owned by the system, pip will be installed in the user directory. If
59-
you may see a warning like this, ensure the pip directory is in `$PATH`:
60-
61-
```
62-
WARNING: The scripts pip3 and pip3.9 are installed in '/Users/sergiitk/Library/Python/3.9/bin' which is not on PATH.
63-
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
64-
```
65-
66-
### Venv
67-
68-
[venv](https://docs.python.org/3/library/venv.html) is a built-in tool to create python virtual
69-
environments. However, some OS distributions choose to exclude it. You can check if it's available
70-
on your system with
71-
72-
```sh
73-
python3 -m venv --help
74-
```
75-
76-
In debian/ubuntu, this also will advise you on what package to install. You may need to run
77-
something like this:
78-
79-
```sh
80-
sudo apt-get install python3-venv
81-
```
82-
83-
Once `venv` is installed, create a virtual environment:
84-
85-
```sh
86-
cd codelabs/grpc-python-getting-started
87-
python3 -m venv .venv
88-
```
89-
90-
#### Activate virtual environment
91-
92-
```sh
93-
cd "$(git rev-parse --show-toplevel || echo .)" && cd codelabs/grpc-python-getting-started
94-
source ./.venv/bin/activate
95-
```
96-
97-
## Define proto
98-
99-
Your working directory will be `codelabs/grpc-python-getting-started/start_here`. Assuming you
100-
followed `venv` activation section, you can cd into the start folder with:
101-
102-
```sh
103-
cd start_here/
104-
```
105-
106-
Our first step is to define the gRPC *service* and the method *request* and *response* types using
107-
[protocol buffers](https://protobuf.dev/overview).
108-
109-
Let’s start by defining the messages and service in `route_guide.proto`.
110-
111-
### Define Proto Messages
112-
113-
Our `.proto` file contains protocol buffer message type definitions for all the request and response
114-
types used in our service methods.
115-
116-
Let’s define the `Point` message type:
117-
118-
```proto
119-
message Point {
120-
int32 latitude = 1;
121-
int32 longitude = 2;
122-
}
123-
```
124-
125-
Let’s also define the `Feature` message type:
126-
127-
```proto
128-
message Feature {
129-
// The name of the feature.
130-
string name = 1;
131-
132-
// The point where the feature is detected.
133-
Point location = 2;
134-
}
135-
```
136-
137-
### Define RouteGuide Service
138-
139-
To define a service, you specify a named `service` in your `.proto` file:
140-
141-
```proto
142-
service RouteGuide {
143-
// Definition of the service goes here
144-
}
145-
```
146-
147-
### Define RPC Method
148-
149-
Then you define `rpc` methods inside your service definition, specifying their request and response
150-
types. In this section of the codelab, let’s define a Unary RPC method.
151-
152-
> Unary RPC method - A *simple RPC* where the client sends a request to the server using the stub
153-
and waits for a response to come back, just like a normal function call.
154-
155-
```proto
156-
// Obtains the feature at a given position.
157-
rpc GetFeature(Point) returns (Feature) {}
158-
```
159-
160-
> [!TIP]
161-
> For the complete .proto file, see
162-
> [`completed/protos/route_guide.proto`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/completed/protos/route_guide.proto)
163-
164-
## Generating client and server code
165-
166-
Next you need to generate the gRPC client and server interfaces from your .proto service definition.
167-
168-
First, install the grpcio-tools package:
169-
170-
```sh
171-
pip install --require-virtualenv grpcio-tools
172-
```
173-
174-
If you see `ERROR: Could not find an activated virtualenv (required)`, please
175-
[activate virtual environment](#activate-virtual-environment), then cd into `start_here`.
176-
177-
Use the following command to generate the Python code:
178-
179-
```sh
180-
python -m grpc_tools.protoc --proto_path=./protos \
181-
--python_out=. --pyi_out=. --grpc_python_out=. \
182-
./protos/route_guide.proto
183-
```
184-
185-
Note that as we’ve already provided a version of the generated code in the `completed` directory,
186-
running this command regenerates the appropriate file rather than creating a new one. The generated
187-
code files are called `route_guide_pb2.py` and `route_guide_pb2_grpc.py` and contain:
188-
189-
* classes for the messages defined in `route_guide.proto`
190-
* classes for the service defined in `route_guide.proto`
191-
* `RouteGuideStub`, which can be used by clients to invoke RouteGuide RPCs
192-
* `RouteGuideServicer`, which defines the interface for implementations of the RouteGuide service
193-
* a function for the service defined in `route_guide.proto`
194-
* `add_RouteGuideServicer_to_server`, which adds a RouteGuideServicer to a `grpc.Server`.
195-
196-
> [!Note]
197-
> The `2` in pb2 indicates that the generated code is following Protocol Buffers Python API version
198-
> 2. Version 1 is obsolete. It has no relation to the Protocol Buffers Language version, which is
199-
> the one indicated by `syntax = "proto3"` or `syntax = "proto2"` in a `.proto` file.
200-
201-
202-
## Creating the server
203-
204-
First let’s look at how you create a `RouteGuide` server. Creating and running a `RouteGuide` server
205-
breaks down into two work items:
206-
207-
* Implementing the servicer interface generated from our service definition with functions that
208-
perform the actual “work” of the service.
209-
* Running a gRPC server to listen for requests from clients and transmit responses.
210-
211-
You can find the initial `RouteGuide` server in [`start_here/route_guide_server.py`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/start_here/route_guide_server.py).
212-
213-
### Implementing RouteGuide
214-
215-
`route_guide_server.py` has a `RouteGuideServicer` class that subclasses the generated class
216-
`route_guide_pb2_grpc.RouteGuideServicer`:
217-
218-
```py
219-
# RouteGuideServicer provides an implementation
220-
# of the methods of the RouteGuide service.
221-
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
222-
```
223-
224-
`RouteGuideServicer` implements all the `RouteGuide` service methods.
225-
226-
Let us look into a simple RPC implementation in detail. Method `GetFeature` gets a `Point` from the
227-
client and returns the corresponding feature information from its database in `Feature`.
228-
229-
```py
230-
def GetFeature(self, request, context):
231-
feature = get_feature(self.db, request)
232-
if feature is None:
233-
return route_guide_pb2.Feature(name="", location=request)
234-
else:
235-
return feature
236-
```
237-
238-
The method is passed a `route_guide_pb2.Point` request for the RPC, and a `grpc.ServicerContext`
239-
object that provides RPC-specific information such as timeout limits. It returns a
240-
`route_guide_pb2.Feature` response.
241-
242-
> [!TIP]
243-
> For the completed route guide server, see
244-
> [`completed/route_guide_server.py`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/completed/route_guide_server.py).
245-
246-
## Starting the server
247-
248-
Once you have implemented all the `RouteGuide` methods, the next step is to start up a gRPC server
249-
so that clients can actually use your service:
250-
251-
```py
252-
def serve():
253-
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
254-
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(RouteGuideServicer(), server)
255-
listen_addr = "localhost:50051"
256-
server.add_insecure_port(listen_addr)
257-
print(f"Starting server on {listen_addr}")
258-
server.start()
259-
server.wait_for_termination()
260-
```
261-
262-
The server `start()` method is non-blocking. A new thread will be instantiated to handle requests.
263-
The thread calling `server.start()` will often not have any other work to do in the meantime. In
264-
this case, you can call `server.wait_for_termination()` to cleanly block the calling thread until
265-
the server terminates.
266-
267-
> [!TIP]
268-
> For the completed route guide server, see
269-
> [`completed/route_guide_server.py`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/completed/route_guide_server.py).
270-
271-
## Creating the client
272-
273-
In this section, we’ll look at creating a client for our `RouteGuide` service. You can see the
274-
initial client code in [`start_here/route_guide_client.py`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/start_here/route_guide_client.py).
275-
276-
### Creating a stub
277-
278-
To call service methods, we first need to create a *stub*.
279-
280-
We instantiate the `RouteGuideStub` class of the `route_guide_pb2_grpc` module, generated from our
281-
`.proto` inside of the `route_guide_client.py` file.
282-
283-
```py
284-
channel = grpc.insecure_channel('localhost:50051')
285-
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
286-
```
287-
288-
### Calling service methods
289-
290-
For RPC methods that return a single response (“response-unary” methods), gRPC Python supports both
291-
synchronous (blocking) and asynchronous (non-blocking) control flow semantics.
292-
293-
### Simple RPC
294-
295-
First, let's define a `Point` to call the service with. This should be as simple as instantiating an
296-
object from the `route_guide_pb2` package with some properties:
297-
298-
```py
299-
point = route_guide_pb2.Point(latitude=412346009, longitude=-744026814)
300-
```
301-
302-
A synchronous call to the simple RPC `GetFeature` is nearly as straightforward as calling a local
303-
method. The RPC call waits for the server to respond, and will either return a response or raise an
304-
exception. We can call the method and see the response like this:
305-
306-
```py
307-
feature = stub.GetFeature(point)
308-
print(feature)
309-
```
310-
311-
You can inspect the fields of the Feature object and output the result of the request:
312-
313-
```py
314-
if feature.name:
315-
print(f"Feature called '{feature.name}' at {format_point(feature.location)}")
316-
else:
317-
print(f"Found no feature at at {format_point(feature.location)}")
318-
```
319-
320-
> [!TIP]
321-
> For the completed route guide client, see
322-
> [`completed/route_guide_client.py`](https://github.com/grpc-ecosystem/grpc-codelabs/blob/main/codelabs/grpc-python-getting-started/completed/route_guide_client.py).
323-
324-
## Try it out!
325-
326-
Run the server:
327-
328-
```sh
329-
python route_guide_server.py
330-
```
331-
332-
From a different terminal, [activate virtual environment](#activate-virtual-environment), then run
333-
the client:
334-
335-
```sh
336-
python route_guide_client.py
337-
```
338-
339-
## What’s next
14+
## Codelab
34015

341-
* Learn how gRPC works in [Introduction to gRPC](https://grpc.io/docs/what-is-grpc/introduction/)
342-
and [Core concepts](https://grpc.io/docs/what-is-grpc/core-concepts/).
343-
* Explore the [Python API reference](https://grpc.github.io/grpc/python/).
16+
Follow the codelab at:
17+
https://codelabs.developers.google.com/grpc/getting-started-grpc-python

0 commit comments

Comments
 (0)