pydantic-rpc 0.5.0__tar.gz → 0.6.1__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.5.0 → pydantic_rpc-0.6.1}/PKG-INFO +337 -8
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/README.md +335 -6
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/README.md +1 -1
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/agent_aio_grpc.py +11 -8
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/agent_connecpy.py +11 -8
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_connecpy.py +30 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeting_connecpy.py +44 -46
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicslocationagent_connecpy.py +30 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/pyproject.toml +10 -3
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/src/pydantic_rpc/core.py +108 -1
- pydantic_rpc-0.6.1/tests/asyncechoservice.proto +33 -0
- pydantic_rpc-0.6.1/tests/asyncechoservice_connecpy.py +109 -0
- pydantic_rpc-0.6.1/tests/asyncechoservice_pb2.py +37 -0
- pydantic_rpc-0.6.1/tests/asyncechoservice_pb2.pyi +17 -0
- pydantic_rpc-0.6.1/tests/asyncechoservice_pb2_grpc.py +121 -0
- pydantic_rpc-0.6.1/tests/echoservice.proto +33 -0
- pydantic_rpc-0.6.1/tests/echoservice_connecpy.py +109 -0
- pydantic_rpc-0.6.1/tests/echoservice_pb2.py +37 -0
- pydantic_rpc-0.6.1/tests/echoservice_pb2.pyi +17 -0
- pydantic_rpc-0.6.1/tests/echoservice_pb2_grpc.py +119 -0
- pydantic_rpc-0.6.1/tests/test_apps.py +190 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/uv.lock +69 -19
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/.gitignore +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/.python-version +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/LICENSE +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/asyncio_greeting.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/barservice.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/barservice_pb2.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/barservice_pb2.pyi +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/barservice_pb2_grpc.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/foobar.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/foobar_client.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/fooservice.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/fooservice_pb2.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/fooservice_pb2.pyi +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/fooservice_pb2_grpc.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/google/protobuf/duration.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/google/protobuf/timestamp.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_client.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_connecpy_client.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_pb2.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_pb2.pyi +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_pb2_grpc.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeter_sonora_client.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeting.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeting_asgi.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeting_using_exsiting_pb2_modules.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/greeting_wsgi.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicsagent.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicsagent_pb2.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicsagent_pb2.pyi +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicsagent_pb2_grpc.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicslocationagent.proto +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicslocationagent_pb2.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicslocationagent_pb2.pyi +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/examples/olympicslocationagent_pb2_grpc.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/src/pydantic_rpc/__init__.py +0 -0
- {pydantic_rpc-0.5.0 → pydantic_rpc-0.6.1}/src/pydantic_rpc/py.typed +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydantic-rpc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: A Python library for building gRPC/ConnectRPC services with Pydantic models.
|
|
5
5
|
Author: Yasushi Itoh
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Python: >=3.11
|
|
8
|
-
Requires-Dist: connecpy>=1.
|
|
8
|
+
Requires-Dist: connecpy>=1.4.1
|
|
9
9
|
Requires-Dist: grpcio-health-checking>=1.56.2
|
|
10
10
|
Requires-Dist: grpcio-reflection>=1.56.2
|
|
11
11
|
Requires-Dist: grpcio-tools>=1.56.2
|
|
@@ -23,7 +23,9 @@ Below is an example of a simple gRPC service that exposes a [PydanticAI](https:/
|
|
|
23
23
|
```python
|
|
24
24
|
import asyncio
|
|
25
25
|
|
|
26
|
+
from openai import AsyncOpenAI
|
|
26
27
|
from pydantic_ai import Agent
|
|
28
|
+
from pydantic_ai.models.openai import OpenAIModel
|
|
27
29
|
from pydantic_rpc import AsyncIOServer, Message
|
|
28
30
|
|
|
29
31
|
|
|
@@ -42,7 +44,15 @@ class Olympics(Message):
|
|
|
42
44
|
|
|
43
45
|
class OlympicsLocationAgent:
|
|
44
46
|
def __init__(self):
|
|
45
|
-
|
|
47
|
+
client = AsyncOpenAI(
|
|
48
|
+
base_url="http://localhost:11434/v1",
|
|
49
|
+
api_key="ollama_api_key",
|
|
50
|
+
)
|
|
51
|
+
ollama_model = OpenAIModel(
|
|
52
|
+
model_name="llama3.2",
|
|
53
|
+
openai_client=client,
|
|
54
|
+
)
|
|
55
|
+
self._agent = Agent(ollama_model)
|
|
46
56
|
|
|
47
57
|
async def ask(self, req: Olympics) -> CityLocation:
|
|
48
58
|
result = await self._agent.run(req.prompt())
|
|
@@ -60,7 +70,9 @@ And here is an example of a simple Connect RPC service that exposes the same age
|
|
|
60
70
|
```python
|
|
61
71
|
import asyncio
|
|
62
72
|
|
|
73
|
+
from openai import AsyncOpenAI
|
|
63
74
|
from pydantic_ai import Agent
|
|
75
|
+
from pydantic_ai.models.openai import OpenAIModel
|
|
64
76
|
from pydantic_rpc import ConnecpyASGIApp, Message
|
|
65
77
|
|
|
66
78
|
|
|
@@ -78,7 +90,15 @@ class Olympics(Message):
|
|
|
78
90
|
|
|
79
91
|
class OlympicsLocationAgent:
|
|
80
92
|
def __init__(self):
|
|
81
|
-
|
|
93
|
+
client = AsyncOpenAI(
|
|
94
|
+
base_url="http://localhost:11434/v1",
|
|
95
|
+
api_key="ollama_api_key",
|
|
96
|
+
)
|
|
97
|
+
ollama_model = OpenAIModel(
|
|
98
|
+
model_name="llama3.2",
|
|
99
|
+
openai_client=client,
|
|
100
|
+
)
|
|
101
|
+
self._agent = Agent(ollama_model, result_type=CityLocation)
|
|
82
102
|
|
|
83
103
|
async def ask(self, req: Olympics) -> CityLocation:
|
|
84
104
|
result = await self._agent.run(req.prompt())
|
|
@@ -104,6 +124,7 @@ app.mount(OlympicsLocationAgent())
|
|
|
104
124
|
- 🌐 **WSGI/ASGI Support:** Create gRPC-Web services that can run as WSGI or ASGI applications powered by `Sonora`.
|
|
105
125
|
- **For Connect-RPC:**
|
|
106
126
|
- 🌐 **Connecpy Support:** Partially supports Connect-RPC via `Connecpy`.
|
|
127
|
+
- 🛠️ **Pre-generated Protobuf Files and Code:** Pre-generate proto files and corresponding code via the CLI. By setting the environment variable (PYDANTIC_RPC_SKIP_GENERATION), you can skip runtime generation.
|
|
107
128
|
|
|
108
129
|
## 📦 Installation
|
|
109
130
|
|
|
@@ -257,7 +278,9 @@ When this variable is set to "true", PydanticRPC will load existing pre-generate
|
|
|
257
278
|
## 💎 Advanced Features
|
|
258
279
|
|
|
259
280
|
### 🌊 Response Streaming
|
|
260
|
-
PydanticRPC supports streaming
|
|
281
|
+
PydanticRPC supports streaming responses only for asynchronous gRPC and gRPC-Web services.
|
|
282
|
+
If a service class method’s return type is `typing.AsyncIterator[T]`, the method is considered a streaming method.
|
|
283
|
+
|
|
261
284
|
|
|
262
285
|
Please see the sample code below:
|
|
263
286
|
|
|
@@ -265,8 +288,10 @@ Please see the sample code below:
|
|
|
265
288
|
import asyncio
|
|
266
289
|
from typing import Annotated, AsyncIterator
|
|
267
290
|
|
|
291
|
+
from openai import AsyncOpenAI
|
|
268
292
|
from pydantic import Field
|
|
269
293
|
from pydantic_ai import Agent
|
|
294
|
+
from pydantic_ai.models.openai import OpenAIModel
|
|
270
295
|
from pydantic_rpc import AsyncIOServer, Message
|
|
271
296
|
|
|
272
297
|
|
|
@@ -299,7 +324,15 @@ class StreamingResult(Message):
|
|
|
299
324
|
|
|
300
325
|
class OlympicsAgent:
|
|
301
326
|
def __init__(self):
|
|
302
|
-
|
|
327
|
+
client = AsyncOpenAI(
|
|
328
|
+
base_url='http://localhost:11434/v1',
|
|
329
|
+
api_key='ollama_api_key',
|
|
330
|
+
)
|
|
331
|
+
ollama_model = OpenAIModel(
|
|
332
|
+
model_name='llama3.2',
|
|
333
|
+
openai_client=client,
|
|
334
|
+
)
|
|
335
|
+
self._agent = Agent(ollama_model)
|
|
303
336
|
|
|
304
337
|
async def ask(self, req: OlympicsQuery) -> CityLocation:
|
|
305
338
|
result = await self._agent.run(req.prompt(), result_type=CityLocation)
|
|
@@ -319,6 +352,302 @@ if __name__ == "__main__":
|
|
|
319
352
|
loop.run_until_complete(s.run(OlympicsAgent()))
|
|
320
353
|
```
|
|
321
354
|
|
|
355
|
+
In the example above, the `ask_stream` method returns an `AsyncIterator[StreamingResult]` object, which is considered a streaming method. The `StreamingResult` class is a Pydantic model that defines the response type of the streaming method. You can use any Pydantic model as the response type.
|
|
356
|
+
|
|
357
|
+
Now, you can call the `ask_stream` method of the server described above using your preferred gRPC client tool. The example below uses `buf curl`.
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
```console
|
|
361
|
+
% buf curl --data '{"start": 1980, "end": 2024}' -v http://localhost:50051/olympicsagent.v1.OlympicsAgent/AskStream --protocol grpc --http2-prior-knowledge
|
|
362
|
+
|
|
363
|
+
buf: * Using server reflection to resolve "olympicsagent.v1.OlympicsAgent"
|
|
364
|
+
buf: * Dialing (tcp) localhost:50051...
|
|
365
|
+
buf: * Connected to [::1]:50051
|
|
366
|
+
buf: > (#1) POST /grpc.reflection.v1.ServerReflection/ServerReflectionInfo
|
|
367
|
+
buf: > (#1) Accept-Encoding: identity
|
|
368
|
+
buf: > (#1) Content-Type: application/grpc+proto
|
|
369
|
+
buf: > (#1) Grpc-Accept-Encoding: gzip
|
|
370
|
+
buf: > (#1) Grpc-Timeout: 119997m
|
|
371
|
+
buf: > (#1) Te: trailers
|
|
372
|
+
buf: > (#1) User-Agent: grpc-go-connect/1.12.0 (go1.21.4) buf/1.28.1
|
|
373
|
+
buf: > (#1)
|
|
374
|
+
buf: } (#1) [5 bytes data]
|
|
375
|
+
buf: } (#1) [32 bytes data]
|
|
376
|
+
buf: < (#1) HTTP/2.0 200 OK
|
|
377
|
+
buf: < (#1) Content-Type: application/grpc
|
|
378
|
+
buf: < (#1) Grpc-Message: Method not found!
|
|
379
|
+
buf: < (#1) Grpc-Status: 12
|
|
380
|
+
buf: < (#1)
|
|
381
|
+
buf: * (#1) Call complete
|
|
382
|
+
buf: > (#2) POST /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo
|
|
383
|
+
buf: > (#2) Accept-Encoding: identity
|
|
384
|
+
buf: > (#2) Content-Type: application/grpc+proto
|
|
385
|
+
buf: > (#2) Grpc-Accept-Encoding: gzip
|
|
386
|
+
buf: > (#2) Grpc-Timeout: 119967m
|
|
387
|
+
buf: > (#2) Te: trailers
|
|
388
|
+
buf: > (#2) User-Agent: grpc-go-connect/1.12.0 (go1.21.4) buf/1.28.1
|
|
389
|
+
buf: > (#2)
|
|
390
|
+
buf: } (#2) [5 bytes data]
|
|
391
|
+
buf: } (#2) [32 bytes data]
|
|
392
|
+
buf: < (#2) HTTP/2.0 200 OK
|
|
393
|
+
buf: < (#2) Content-Type: application/grpc
|
|
394
|
+
buf: < (#2) Grpc-Accept-Encoding: identity, deflate, gzip
|
|
395
|
+
buf: < (#2)
|
|
396
|
+
buf: { (#2) [5 bytes data]
|
|
397
|
+
buf: { (#2) [434 bytes data]
|
|
398
|
+
buf: * Server reflection has resolved file "olympicsagent.proto"
|
|
399
|
+
buf: * Invoking RPC olympicsagent.v1.OlympicsAgent.AskStream
|
|
400
|
+
buf: > (#3) POST /olympicsagent.v1.OlympicsAgent/AskStream
|
|
401
|
+
buf: > (#3) Accept-Encoding: identity
|
|
402
|
+
buf: > (#3) Content-Type: application/grpc+proto
|
|
403
|
+
buf: > (#3) Grpc-Accept-Encoding: gzip
|
|
404
|
+
buf: > (#3) Grpc-Timeout: 119947m
|
|
405
|
+
buf: > (#3) Te: trailers
|
|
406
|
+
buf: > (#3) User-Agent: grpc-go-connect/1.12.0 (go1.21.4) buf/1.28.1
|
|
407
|
+
buf: > (#3)
|
|
408
|
+
buf: } (#3) [5 bytes data]
|
|
409
|
+
buf: } (#3) [6 bytes data]
|
|
410
|
+
buf: * (#3) Finished upload
|
|
411
|
+
buf: < (#3) HTTP/2.0 200 OK
|
|
412
|
+
buf: < (#3) Content-Type: application/grpc
|
|
413
|
+
buf: < (#3) Grpc-Accept-Encoding: identity, deflate, gzip
|
|
414
|
+
buf: < (#3)
|
|
415
|
+
buf: { (#3) [5 bytes data]
|
|
416
|
+
buf: { (#3) [25 bytes data]
|
|
417
|
+
{
|
|
418
|
+
"answer": "Here's a list of Summer"
|
|
419
|
+
}
|
|
420
|
+
buf: { (#3) [5 bytes data]
|
|
421
|
+
buf: { (#3) [31 bytes data]
|
|
422
|
+
{
|
|
423
|
+
"answer": " and Winter Olympics from 198"
|
|
424
|
+
}
|
|
425
|
+
buf: { (#3) [5 bytes data]
|
|
426
|
+
buf: { (#3) [29 bytes data]
|
|
427
|
+
{
|
|
428
|
+
"answer": "0 to 2024:\n\nSummer Olympics"
|
|
429
|
+
}
|
|
430
|
+
buf: { (#3) [5 bytes data]
|
|
431
|
+
buf: { (#3) [20 bytes data]
|
|
432
|
+
{
|
|
433
|
+
"answer": ":\n1. 1980 - Moscow"
|
|
434
|
+
}
|
|
435
|
+
buf: { (#3) [5 bytes data]
|
|
436
|
+
buf: { (#3) [20 bytes data]
|
|
437
|
+
{
|
|
438
|
+
"answer": ", Soviet Union\n2. "
|
|
439
|
+
}
|
|
440
|
+
buf: { (#3) [5 bytes data]
|
|
441
|
+
buf: { (#3) [32 bytes data]
|
|
442
|
+
{
|
|
443
|
+
"answer": "1984 - Los Angeles, California"
|
|
444
|
+
}
|
|
445
|
+
buf: { (#3) [5 bytes data]
|
|
446
|
+
buf: { (#3) [15 bytes data]
|
|
447
|
+
{
|
|
448
|
+
"answer": ", USA\n3. 1988"
|
|
449
|
+
}
|
|
450
|
+
buf: { (#3) [5 bytes data]
|
|
451
|
+
buf: { (#3) [26 bytes data]
|
|
452
|
+
{
|
|
453
|
+
"answer": " - Seoul, South Korea\n4."
|
|
454
|
+
}
|
|
455
|
+
buf: { (#3) [5 bytes data]
|
|
456
|
+
buf: { (#3) [27 bytes data]
|
|
457
|
+
{
|
|
458
|
+
"answer": " 1992 - Barcelona, Spain\n"
|
|
459
|
+
}
|
|
460
|
+
buf: { (#3) [5 bytes data]
|
|
461
|
+
buf: { (#3) [20 bytes data]
|
|
462
|
+
{
|
|
463
|
+
"answer": "5. 1996 - Atlanta,"
|
|
464
|
+
}
|
|
465
|
+
buf: { (#3) [5 bytes data]
|
|
466
|
+
buf: { (#3) [22 bytes data]
|
|
467
|
+
{
|
|
468
|
+
"answer": " Georgia, USA\n6. 200"
|
|
469
|
+
}
|
|
470
|
+
buf: { (#3) [5 bytes data]
|
|
471
|
+
buf: { (#3) [26 bytes data]
|
|
472
|
+
{
|
|
473
|
+
"answer": "0 - Sydney, Australia\n7."
|
|
474
|
+
}
|
|
475
|
+
buf: { (#3) [5 bytes data]
|
|
476
|
+
buf: { (#3) [25 bytes data]
|
|
477
|
+
{
|
|
478
|
+
"answer": " 2004 - Athens, Greece\n"
|
|
479
|
+
}
|
|
480
|
+
buf: { (#3) [5 bytes data]
|
|
481
|
+
buf: { (#3) [20 bytes data]
|
|
482
|
+
{
|
|
483
|
+
"answer": "8. 2008 - Beijing,"
|
|
484
|
+
}
|
|
485
|
+
buf: { (#3) [5 bytes data]
|
|
486
|
+
buf: { (#3) [18 bytes data]
|
|
487
|
+
{
|
|
488
|
+
"answer": " China\n9. 2012 -"
|
|
489
|
+
}
|
|
490
|
+
buf: { (#3) [5 bytes data]
|
|
491
|
+
buf: { (#3) [29 bytes data]
|
|
492
|
+
{
|
|
493
|
+
"answer": " London, United Kingdom\n10."
|
|
494
|
+
}
|
|
495
|
+
buf: { (#3) [5 bytes data]
|
|
496
|
+
buf: { (#3) [24 bytes data]
|
|
497
|
+
{
|
|
498
|
+
"answer": " 2016 - Rio de Janeiro"
|
|
499
|
+
}
|
|
500
|
+
buf: { (#3) [5 bytes data]
|
|
501
|
+
buf: { (#3) [18 bytes data]
|
|
502
|
+
{
|
|
503
|
+
"answer": ", Brazil\n11. 202"
|
|
504
|
+
}
|
|
505
|
+
buf: { (#3) [5 bytes data]
|
|
506
|
+
buf: { (#3) [24 bytes data]
|
|
507
|
+
{
|
|
508
|
+
"answer": "0 - Tokyo, Japan (held"
|
|
509
|
+
}
|
|
510
|
+
buf: { (#3) [5 bytes data]
|
|
511
|
+
buf: { (#3) [21 bytes data]
|
|
512
|
+
{
|
|
513
|
+
"answer": " in 2021 due to the"
|
|
514
|
+
}
|
|
515
|
+
buf: { (#3) [5 bytes data]
|
|
516
|
+
buf: { (#3) [26 bytes data]
|
|
517
|
+
{
|
|
518
|
+
"answer": " COVID-19 pandemic)\n12. "
|
|
519
|
+
}
|
|
520
|
+
buf: { (#3) [5 bytes data]
|
|
521
|
+
buf: { (#3) [28 bytes data]
|
|
522
|
+
{
|
|
523
|
+
"answer": "2024 - Paris, France\n\nNote"
|
|
524
|
+
}
|
|
525
|
+
buf: { (#3) [5 bytes data]
|
|
526
|
+
buf: { (#3) [41 bytes data]
|
|
527
|
+
{
|
|
528
|
+
"answer": ": The Olympics were held without a host"
|
|
529
|
+
}
|
|
530
|
+
buf: { (#3) [5 bytes data]
|
|
531
|
+
buf: { (#3) [26 bytes data]
|
|
532
|
+
{
|
|
533
|
+
"answer": " city for one year (2022"
|
|
534
|
+
}
|
|
535
|
+
buf: { (#3) [5 bytes data]
|
|
536
|
+
buf: { (#3) [42 bytes data]
|
|
537
|
+
{
|
|
538
|
+
"answer": ", due to the Russian invasion of Ukraine"
|
|
539
|
+
}
|
|
540
|
+
buf: { (#3) [5 bytes data]
|
|
541
|
+
buf: { (#3) [29 bytes data]
|
|
542
|
+
{
|
|
543
|
+
"answer": ").\n\nWinter Olympics:\n1. 198"
|
|
544
|
+
}
|
|
545
|
+
buf: { (#3) [5 bytes data]
|
|
546
|
+
buf: { (#3) [27 bytes data]
|
|
547
|
+
{
|
|
548
|
+
"answer": "0 - Lake Placid, New York"
|
|
549
|
+
}
|
|
550
|
+
buf: { (#3) [5 bytes data]
|
|
551
|
+
buf: { (#3) [15 bytes data]
|
|
552
|
+
{
|
|
553
|
+
"answer": ", USA\n2. 1984"
|
|
554
|
+
}
|
|
555
|
+
buf: { (#3) [5 bytes data]
|
|
556
|
+
buf: { (#3) [27 bytes data]
|
|
557
|
+
{
|
|
558
|
+
"answer": " - Sarajevo, Yugoslavia ("
|
|
559
|
+
}
|
|
560
|
+
buf: { (#3) [5 bytes data]
|
|
561
|
+
buf: { (#3) [30 bytes data]
|
|
562
|
+
{
|
|
563
|
+
"answer": "now Bosnia and Herzegovina)\n"
|
|
564
|
+
}
|
|
565
|
+
buf: { (#3) [5 bytes data]
|
|
566
|
+
buf: { (#3) [20 bytes data]
|
|
567
|
+
{
|
|
568
|
+
"answer": "3. 1988 - Calgary,"
|
|
569
|
+
}
|
|
570
|
+
buf: { (#3) [5 bytes data]
|
|
571
|
+
buf: { (#3) [25 bytes data]
|
|
572
|
+
{
|
|
573
|
+
"answer": " Alberta, Canada\n4. 199"
|
|
574
|
+
}
|
|
575
|
+
buf: { (#3) [5 bytes data]
|
|
576
|
+
buf: { (#3) [26 bytes data]
|
|
577
|
+
{
|
|
578
|
+
"answer": "2 - Albertville, France\n"
|
|
579
|
+
}
|
|
580
|
+
buf: { (#3) [5 bytes data]
|
|
581
|
+
buf: { (#3) [13 bytes data]
|
|
582
|
+
{
|
|
583
|
+
"answer": "5. 1994 - L"
|
|
584
|
+
}
|
|
585
|
+
buf: { (#3) [5 bytes data]
|
|
586
|
+
buf: { (#3) [24 bytes data]
|
|
587
|
+
{
|
|
588
|
+
"answer": "illehammer, Norway\n6. "
|
|
589
|
+
}
|
|
590
|
+
buf: { (#3) [5 bytes data]
|
|
591
|
+
buf: { (#3) [23 bytes data]
|
|
592
|
+
{
|
|
593
|
+
"answer": "1998 - Nagano, Japan\n"
|
|
594
|
+
}
|
|
595
|
+
buf: { (#3) [5 bytes data]
|
|
596
|
+
buf: { (#3) [16 bytes data]
|
|
597
|
+
{
|
|
598
|
+
"answer": "7. 2002 - Salt"
|
|
599
|
+
}
|
|
600
|
+
buf: { (#3) [5 bytes data]
|
|
601
|
+
buf: { (#3) [24 bytes data]
|
|
602
|
+
{
|
|
603
|
+
"answer": " Lake City, Utah, USA\n"
|
|
604
|
+
}
|
|
605
|
+
buf: { (#3) [5 bytes data]
|
|
606
|
+
buf: { (#3) [18 bytes data]
|
|
607
|
+
{
|
|
608
|
+
"answer": "8. 2006 - Torino"
|
|
609
|
+
}
|
|
610
|
+
buf: { (#3) [5 bytes data]
|
|
611
|
+
buf: { (#3) [17 bytes data]
|
|
612
|
+
{
|
|
613
|
+
"answer": ", Italy\n9. 2010"
|
|
614
|
+
}
|
|
615
|
+
buf: { (#3) [5 bytes data]
|
|
616
|
+
buf: { (#3) [40 bytes data]
|
|
617
|
+
{
|
|
618
|
+
"answer": " - Vancouver, British Columbia, Canada"
|
|
619
|
+
}
|
|
620
|
+
buf: { (#3) [5 bytes data]
|
|
621
|
+
buf: { (#3) [13 bytes data]
|
|
622
|
+
{
|
|
623
|
+
"answer": "\n10. 2014 -"
|
|
624
|
+
}
|
|
625
|
+
buf: { (#3) [5 bytes data]
|
|
626
|
+
buf: { (#3) [20 bytes data]
|
|
627
|
+
{
|
|
628
|
+
"answer": " Sochi, Russia\n11."
|
|
629
|
+
}
|
|
630
|
+
buf: { (#3) [5 bytes data]
|
|
631
|
+
buf: { (#3) [16 bytes data]
|
|
632
|
+
{
|
|
633
|
+
"answer": " 2018 - Pyeong"
|
|
634
|
+
}
|
|
635
|
+
buf: { (#3) [5 bytes data]
|
|
636
|
+
buf: { (#3) [24 bytes data]
|
|
637
|
+
{
|
|
638
|
+
"answer": "chang, South Korea\n12."
|
|
639
|
+
}
|
|
640
|
+
buf: < (#3)
|
|
641
|
+
buf: < (#3) Grpc-Message:
|
|
642
|
+
buf: < (#3) Grpc-Status: 0
|
|
643
|
+
buf: * (#3) Call complete
|
|
644
|
+
buf: < (#2)
|
|
645
|
+
buf: < (#2) Grpc-Message:
|
|
646
|
+
buf: < (#2) Grpc-Status: 0
|
|
647
|
+
buf: * (#2) Call complete
|
|
648
|
+
%
|
|
649
|
+
```
|
|
650
|
+
|
|
322
651
|
### 🔗 Multiple Services with Custom Interceptors
|
|
323
652
|
|
|
324
653
|
PydanticRPC supports defining and running multiple services in a single server:
|
|
@@ -404,9 +733,9 @@ if __name__ == "__main__":
|
|
|
404
733
|
|
|
405
734
|
TODO
|
|
406
735
|
|
|
407
|
-
### 🗄️ Protobuf file and code (Python files) generation
|
|
736
|
+
### 🗄️ Protobuf file and code (Python files) generation using CLI
|
|
408
737
|
|
|
409
|
-
|
|
738
|
+
You can genereate protobuf files and code for a given module and a specified class using `pydantic-rpc` CLI command:
|
|
410
739
|
|
|
411
740
|
```bash
|
|
412
741
|
pydantic-rpc a_module.py aClassName
|