pydantic-rpc 0.3.1__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/PKG-INFO +29 -38
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/README.md +28 -37
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/agent_aio_grpc.py +10 -29
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/agent_connecpy.py +10 -14
- pydantic_rpc-0.4.0/examples/olympicsagent.proto +40 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicslocationagent.proto +6 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/pyproject.toml +1 -1
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/src/pydantic_rpc/core.py +1343 -1308
- pydantic_rpc-0.3.1/examples/olympicsagent.proto +0 -144
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/.gitignore +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/.python-version +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/LICENSE +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/README.md +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/asyncio_greeting.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/barservice.proto +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/barservice_pb2.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/barservice_pb2.pyi +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/barservice_pb2_grpc.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/foobar.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/foobar_client.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/fooservice.proto +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/fooservice_pb2.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/fooservice_pb2.pyi +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/fooservice_pb2_grpc.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/google/protobuf/duration.proto +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/google/protobuf/timestamp.proto +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter.proto +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_client.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_connecpy.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_connecpy_client.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_pb2.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_pb2.pyi +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_pb2_grpc.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeter_sonora_client.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeting.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeting_asgi.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeting_connecpy.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeting_using_exsiting_pb2_modules.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/greeting_wsgi.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicsagent_pb2.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicsagent_pb2.pyi +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicsagent_pb2_grpc.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicslocationagent_connecpy.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicslocationagent_pb2.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicslocationagent_pb2.pyi +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/examples/olympicslocationagent_pb2_grpc.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/requirements-dev.lock +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/requirements.lock +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/src/pydantic_rpc/__init__.py +0 -0
- {pydantic_rpc-0.3.1 → pydantic_rpc-0.4.0}/src/pydantic_rpc/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pydantic-rpc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Python library for building gRPC/ConnectRPC services with Pydantic models.
|
|
5
5
|
Author: Yasushi Itoh
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -94,6 +94,7 @@ app.mount(OlympicsLocationAgent())
|
|
|
94
94
|
- 🔄 **Automatic Protobuf Generation:** Automatically creates protobuf files matching the method signatures of your Python objects.
|
|
95
95
|
- ⚙️ **Dynamic Code Generation:** Generates server and client stubs using `grpcio-tools`.
|
|
96
96
|
- ✅ **Pydantic Integration:** Uses `pydantic` for robust type validation and serialization.
|
|
97
|
+
- 📄 **Pprotobuf File Export:** Exports the generated protobuf files for use in other languages.
|
|
97
98
|
- **For gRPC:**
|
|
98
99
|
- 💚 **Health Checking:** Built-in support for gRPC health checks using `grpc_health.v1`.
|
|
99
100
|
- 🔎 **Server Reflection:** Built-in support for gRPC server reflection.
|
|
@@ -261,57 +262,38 @@ Please see the sample code below:
|
|
|
261
262
|
|
|
262
263
|
```python
|
|
263
264
|
import asyncio
|
|
264
|
-
from typing import AsyncIterator
|
|
265
|
+
from typing import Annotated, AsyncIterator
|
|
265
266
|
|
|
266
|
-
from pydantic import
|
|
267
|
+
from pydantic import Field
|
|
267
268
|
from pydantic_ai import Agent
|
|
268
269
|
from pydantic_rpc import AsyncIOServer, Message
|
|
269
270
|
|
|
270
271
|
|
|
271
272
|
# `Message` is just a pydantic BaseModel alias
|
|
272
273
|
class CityLocation(Message):
|
|
273
|
-
city: str
|
|
274
|
-
country:
|
|
274
|
+
city: Annotated[str, Field(description="The city where the Olympics were held")]
|
|
275
|
+
country: Annotated[
|
|
276
|
+
str, Field(description="The country where the Olympics were held")
|
|
277
|
+
]
|
|
275
278
|
|
|
276
279
|
|
|
277
280
|
class OlympicsQuery(Message):
|
|
278
|
-
year: int
|
|
281
|
+
year: Annotated[int, Field(description="The year of the Olympics", ge=1896)]
|
|
279
282
|
|
|
280
283
|
def prompt(self):
|
|
281
284
|
return f"Where were the Olympics held in {self.year}?"
|
|
282
285
|
|
|
283
|
-
@field_validator("year")
|
|
284
|
-
def validate_year(cls, value):
|
|
285
|
-
if value < 1896:
|
|
286
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
287
|
-
|
|
288
|
-
return value
|
|
289
|
-
|
|
290
286
|
|
|
291
287
|
class OlympicsDurationQuery(Message):
|
|
292
|
-
start: int
|
|
293
|
-
end: int
|
|
288
|
+
start: Annotated[int, Field(description="The start year of the Olympics", ge=1896)]
|
|
289
|
+
end: Annotated[int, Field(description="The end year of the Olympics", ge=1896)]
|
|
294
290
|
|
|
295
291
|
def prompt(self):
|
|
296
292
|
return f"From {self.start} to {self.end}, how many Olympics were held? Please provide the list of countries and cities."
|
|
297
293
|
|
|
298
|
-
@field_validator("start")
|
|
299
|
-
def validate_start(cls, value):
|
|
300
|
-
if value < 1896:
|
|
301
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
302
|
-
|
|
303
|
-
return value
|
|
304
|
-
|
|
305
|
-
@field_validator("end")
|
|
306
|
-
def validate_end(cls, value):
|
|
307
|
-
if value < 1896:
|
|
308
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
309
|
-
|
|
310
|
-
return value
|
|
311
|
-
|
|
312
294
|
|
|
313
295
|
class StreamingResult(Message):
|
|
314
|
-
answer: str
|
|
296
|
+
answer: Annotated[str, Field(description="The answer to the query")]
|
|
315
297
|
|
|
316
298
|
|
|
317
299
|
class OlympicsAgent:
|
|
@@ -433,18 +415,27 @@ Using this generated proto file and tools as `protoc`, `buf` and `BSR`, you coul
|
|
|
433
415
|
|
|
434
416
|
## 📖 Data Type Mapping
|
|
435
417
|
|
|
436
|
-
| Python Type
|
|
437
|
-
|
|
438
|
-
| str
|
|
439
|
-
|
|
|
440
|
-
|
|
|
441
|
-
|
|
|
442
|
-
|
|
|
443
|
-
|
|
|
418
|
+
| Python Type | Protobuf Type |
|
|
419
|
+
|--------------------------------|---------------------------|
|
|
420
|
+
| str | string |
|
|
421
|
+
| bytes | bytes |
|
|
422
|
+
| bool | bool |
|
|
423
|
+
| int | int32 |
|
|
424
|
+
| float | float, double |
|
|
425
|
+
| list[T], tuple[T] | repeated T |
|
|
426
|
+
| dict[K, V] | map<K, V> |
|
|
427
|
+
| datetime.datetime | google.protobuf.Timestamp |
|
|
428
|
+
| datetime.timedelta | google.protobuf.Duration |
|
|
429
|
+
| typing.Union[A, B] | oneof A, B |
|
|
430
|
+
| subclass of enum.Enum | enum |
|
|
431
|
+
| subclass of pydantic.BaseModel | message |
|
|
444
432
|
|
|
445
433
|
|
|
446
434
|
## TODO
|
|
447
435
|
- [ ] Streaming Support
|
|
436
|
+
- [x] unary-stream
|
|
437
|
+
- [ ] stream-unary
|
|
438
|
+
- [ ] stream-stream
|
|
448
439
|
- [ ] Betterproto Support
|
|
449
440
|
- [ ] Sonora-connect Support
|
|
450
441
|
- [ ] Custom Health Check Support
|
|
@@ -80,6 +80,7 @@ app.mount(OlympicsLocationAgent())
|
|
|
80
80
|
- 🔄 **Automatic Protobuf Generation:** Automatically creates protobuf files matching the method signatures of your Python objects.
|
|
81
81
|
- ⚙️ **Dynamic Code Generation:** Generates server and client stubs using `grpcio-tools`.
|
|
82
82
|
- ✅ **Pydantic Integration:** Uses `pydantic` for robust type validation and serialization.
|
|
83
|
+
- 📄 **Pprotobuf File Export:** Exports the generated protobuf files for use in other languages.
|
|
83
84
|
- **For gRPC:**
|
|
84
85
|
- 💚 **Health Checking:** Built-in support for gRPC health checks using `grpc_health.v1`.
|
|
85
86
|
- 🔎 **Server Reflection:** Built-in support for gRPC server reflection.
|
|
@@ -247,57 +248,38 @@ Please see the sample code below:
|
|
|
247
248
|
|
|
248
249
|
```python
|
|
249
250
|
import asyncio
|
|
250
|
-
from typing import AsyncIterator
|
|
251
|
+
from typing import Annotated, AsyncIterator
|
|
251
252
|
|
|
252
|
-
from pydantic import
|
|
253
|
+
from pydantic import Field
|
|
253
254
|
from pydantic_ai import Agent
|
|
254
255
|
from pydantic_rpc import AsyncIOServer, Message
|
|
255
256
|
|
|
256
257
|
|
|
257
258
|
# `Message` is just a pydantic BaseModel alias
|
|
258
259
|
class CityLocation(Message):
|
|
259
|
-
city: str
|
|
260
|
-
country:
|
|
260
|
+
city: Annotated[str, Field(description="The city where the Olympics were held")]
|
|
261
|
+
country: Annotated[
|
|
262
|
+
str, Field(description="The country where the Olympics were held")
|
|
263
|
+
]
|
|
261
264
|
|
|
262
265
|
|
|
263
266
|
class OlympicsQuery(Message):
|
|
264
|
-
year: int
|
|
267
|
+
year: Annotated[int, Field(description="The year of the Olympics", ge=1896)]
|
|
265
268
|
|
|
266
269
|
def prompt(self):
|
|
267
270
|
return f"Where were the Olympics held in {self.year}?"
|
|
268
271
|
|
|
269
|
-
@field_validator("year")
|
|
270
|
-
def validate_year(cls, value):
|
|
271
|
-
if value < 1896:
|
|
272
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
273
|
-
|
|
274
|
-
return value
|
|
275
|
-
|
|
276
272
|
|
|
277
273
|
class OlympicsDurationQuery(Message):
|
|
278
|
-
start: int
|
|
279
|
-
end: int
|
|
274
|
+
start: Annotated[int, Field(description="The start year of the Olympics", ge=1896)]
|
|
275
|
+
end: Annotated[int, Field(description="The end year of the Olympics", ge=1896)]
|
|
280
276
|
|
|
281
277
|
def prompt(self):
|
|
282
278
|
return f"From {self.start} to {self.end}, how many Olympics were held? Please provide the list of countries and cities."
|
|
283
279
|
|
|
284
|
-
@field_validator("start")
|
|
285
|
-
def validate_start(cls, value):
|
|
286
|
-
if value < 1896:
|
|
287
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
288
|
-
|
|
289
|
-
return value
|
|
290
|
-
|
|
291
|
-
@field_validator("end")
|
|
292
|
-
def validate_end(cls, value):
|
|
293
|
-
if value < 1896:
|
|
294
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
295
|
-
|
|
296
|
-
return value
|
|
297
|
-
|
|
298
280
|
|
|
299
281
|
class StreamingResult(Message):
|
|
300
|
-
answer: str
|
|
282
|
+
answer: Annotated[str, Field(description="The answer to the query")]
|
|
301
283
|
|
|
302
284
|
|
|
303
285
|
class OlympicsAgent:
|
|
@@ -419,18 +401,27 @@ Using this generated proto file and tools as `protoc`, `buf` and `BSR`, you coul
|
|
|
419
401
|
|
|
420
402
|
## 📖 Data Type Mapping
|
|
421
403
|
|
|
422
|
-
| Python Type
|
|
423
|
-
|
|
424
|
-
| str
|
|
425
|
-
|
|
|
426
|
-
|
|
|
427
|
-
|
|
|
428
|
-
|
|
|
429
|
-
|
|
|
404
|
+
| Python Type | Protobuf Type |
|
|
405
|
+
|--------------------------------|---------------------------|
|
|
406
|
+
| str | string |
|
|
407
|
+
| bytes | bytes |
|
|
408
|
+
| bool | bool |
|
|
409
|
+
| int | int32 |
|
|
410
|
+
| float | float, double |
|
|
411
|
+
| list[T], tuple[T] | repeated T |
|
|
412
|
+
| dict[K, V] | map<K, V> |
|
|
413
|
+
| datetime.datetime | google.protobuf.Timestamp |
|
|
414
|
+
| datetime.timedelta | google.protobuf.Duration |
|
|
415
|
+
| typing.Union[A, B] | oneof A, B |
|
|
416
|
+
| subclass of enum.Enum | enum |
|
|
417
|
+
| subclass of pydantic.BaseModel | message |
|
|
430
418
|
|
|
431
419
|
|
|
432
420
|
## TODO
|
|
433
421
|
- [ ] Streaming Support
|
|
422
|
+
- [x] unary-stream
|
|
423
|
+
- [ ] stream-unary
|
|
424
|
+
- [ ] stream-stream
|
|
434
425
|
- [ ] Betterproto Support
|
|
435
426
|
- [ ] Sonora-connect Support
|
|
436
427
|
- [ ] Custom Health Check Support
|
|
@@ -1,55 +1,36 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import AsyncIterator
|
|
2
|
+
from typing import Annotated, AsyncIterator
|
|
3
3
|
|
|
4
|
-
from pydantic import
|
|
4
|
+
from pydantic import Field
|
|
5
5
|
from pydantic_ai import Agent
|
|
6
6
|
from pydantic_rpc import AsyncIOServer, Message
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
# `Message` is just a pydantic BaseModel alias
|
|
10
10
|
class CityLocation(Message):
|
|
11
|
-
city: str
|
|
12
|
-
country:
|
|
11
|
+
city: Annotated[str, Field(description="The city where the Olympics were held")]
|
|
12
|
+
country: Annotated[
|
|
13
|
+
str, Field(description="The country where the Olympics were held")
|
|
14
|
+
]
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class OlympicsQuery(Message):
|
|
16
|
-
year: int
|
|
18
|
+
year: Annotated[int, Field(description="The year of the Olympics", ge=1896)]
|
|
17
19
|
|
|
18
20
|
def prompt(self):
|
|
19
21
|
return f"Where were the Olympics held in {self.year}?"
|
|
20
22
|
|
|
21
|
-
@field_validator("year")
|
|
22
|
-
def validate_year(cls, value):
|
|
23
|
-
if value < 1896:
|
|
24
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
25
|
-
|
|
26
|
-
return value
|
|
27
|
-
|
|
28
23
|
|
|
29
24
|
class OlympicsDurationQuery(Message):
|
|
30
|
-
start: int
|
|
31
|
-
end: int
|
|
25
|
+
start: Annotated[int, Field(description="The start year of the Olympics", ge=1896)]
|
|
26
|
+
end: Annotated[int, Field(description="The end year of the Olympics", ge=1896)]
|
|
32
27
|
|
|
33
28
|
def prompt(self):
|
|
34
29
|
return f"From {self.start} to {self.end}, how many Olympics were held? Please provide the list of countries and cities."
|
|
35
30
|
|
|
36
|
-
@field_validator("start")
|
|
37
|
-
def validate_start(cls, value):
|
|
38
|
-
if value < 1896:
|
|
39
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
40
|
-
|
|
41
|
-
return value
|
|
42
|
-
|
|
43
|
-
@field_validator("end")
|
|
44
|
-
def validate_end(cls, value):
|
|
45
|
-
if value < 1896:
|
|
46
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
47
|
-
|
|
48
|
-
return value
|
|
49
|
-
|
|
50
31
|
|
|
51
32
|
class StreamingResult(Message):
|
|
52
|
-
answer: str
|
|
33
|
+
answer: Annotated[str, Field(description="The answer to the query")]
|
|
53
34
|
|
|
54
35
|
|
|
55
36
|
class OlympicsAgent:
|
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
3
5
|
from hypercorn.asyncio import serve
|
|
4
6
|
from hypercorn.config import Config
|
|
5
|
-
from pydantic import
|
|
7
|
+
from pydantic import Field
|
|
6
8
|
from pydantic_ai import Agent
|
|
7
9
|
from pydantic_rpc import ConnecpyASGIApp, Message
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class CityLocation(Message):
|
|
11
|
-
city: str
|
|
12
|
-
country:
|
|
13
|
+
city: Annotated[str, Field(description="The city where the Olympics were held")]
|
|
14
|
+
country: Annotated[
|
|
15
|
+
str, Field(description="The country where the Olympics were held")
|
|
16
|
+
]
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
class Olympics(Message):
|
|
16
|
-
year:
|
|
20
|
+
year: Annotated[
|
|
21
|
+
int, Field(description="The year of the Olympics", ge=1896, multiple_of=4)
|
|
22
|
+
]
|
|
17
23
|
|
|
18
24
|
def prompt(self):
|
|
19
25
|
return f"Where were the Olympics held in {self.year}?"
|
|
20
26
|
|
|
21
|
-
@field_validator("year")
|
|
22
|
-
def validate_year(cls, value):
|
|
23
|
-
if value < 1896:
|
|
24
|
-
raise ValueError("The first modern Olympics was held in 1896.")
|
|
25
|
-
|
|
26
|
-
if value % 4 != 0:
|
|
27
|
-
raise ValueError("The Olympics are held every 4 years.")
|
|
28
|
-
|
|
29
|
-
return value
|
|
30
|
-
|
|
31
27
|
|
|
32
28
|
class OlympicsLocationAgent:
|
|
33
29
|
def __init__(self):
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package olympicsagent.v1;
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
service OlympicsAgent {
|
|
7
|
+
rpc Ask (OlympicsQuery) returns (CityLocation);
|
|
8
|
+
rpc AskStream (OlympicsDurationQuery) returns (stream StreamingResult);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
message CityLocation {
|
|
12
|
+
// The city where the Olympics were held
|
|
13
|
+
string city = 1;
|
|
14
|
+
// The country where the Olympics were held
|
|
15
|
+
string country = 2;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
message OlympicsQuery {
|
|
19
|
+
// The year of the Olympics
|
|
20
|
+
// Constraint:
|
|
21
|
+
// greater than or equal to 1896
|
|
22
|
+
int32 year = 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
message StreamingResult {
|
|
26
|
+
// The answer to the query
|
|
27
|
+
string answer = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
message OlympicsDurationQuery {
|
|
31
|
+
// The start year of the Olympics
|
|
32
|
+
// Constraint:
|
|
33
|
+
// greater than or equal to 1896
|
|
34
|
+
int32 start = 1;
|
|
35
|
+
// The end year of the Olympics
|
|
36
|
+
// Constraint:
|
|
37
|
+
// greater than or equal to 1896
|
|
38
|
+
int32 end = 2;
|
|
39
|
+
}
|
|
40
|
+
|
|
@@ -8,11 +8,17 @@ service OlympicsLocationAgent {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
message CityLocation {
|
|
11
|
+
// The city where the Olympics were held
|
|
11
12
|
string city = 1;
|
|
13
|
+
// The country where the Olympics were held
|
|
12
14
|
string country = 2;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
message Olympics {
|
|
18
|
+
// The year of the Olympics
|
|
19
|
+
// Constraint:
|
|
20
|
+
// greater than or equal to 1896
|
|
21
|
+
// multiple of 4
|
|
16
22
|
int32 year = 1;
|
|
17
23
|
}
|
|
18
24
|
|