pydantic-rpc 0.6.0__py3-none-any.whl → 0.6.1__py3-none-any.whl

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.
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydantic-rpc
3
- Version: 0.6.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.3.2
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
- self._agent = Agent("ollama:llama3.2", result_type=CityLocation)
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
- self._agent = Agent("ollama:llama3.2", result_type=CityLocation)
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())
@@ -268,8 +288,10 @@ Please see the sample code below:
268
288
  import asyncio
269
289
  from typing import Annotated, AsyncIterator
270
290
 
291
+ from openai import AsyncOpenAI
271
292
  from pydantic import Field
272
293
  from pydantic_ai import Agent
294
+ from pydantic_ai.models.openai import OpenAIModel
273
295
  from pydantic_rpc import AsyncIOServer, Message
274
296
 
275
297
 
@@ -302,7 +324,15 @@ class StreamingResult(Message):
302
324
 
303
325
  class OlympicsAgent:
304
326
  def __init__(self):
305
- self._agent = Agent("ollama:llama3.2")
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)
306
336
 
307
337
  async def ask(self, req: OlympicsQuery) -> CityLocation:
308
338
  result = await self._agent.run(req.prompt(), result_type=CityLocation)
@@ -324,6 +354,299 @@ if __name__ == "__main__":
324
354
 
325
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.
326
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
+ ```
327
650
 
328
651
  ### 🔗 Multiple Services with Custom Interceptors
329
652
 
@@ -1,8 +1,8 @@
1
1
  pydantic_rpc/__init__.py,sha256=oomSVGmh_zddQQaphQt1L2xSVh9dD1LVyaAq1cN1FW4,231
2
2
  pydantic_rpc/core.py,sha256=SB9GDZRxsMWQFxphinYQUAqrOx10eUn40fPTc7t1xYs,52107
3
3
  pydantic_rpc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pydantic_rpc-0.6.0.dist-info/METADATA,sha256=oTCJJH4yB2VW-eVGXN3EoGtinuC9kllMQFThk2QuPlo,12698
5
- pydantic_rpc-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- pydantic_rpc-0.6.0.dist-info/entry_points.txt,sha256=LeZJ6UN-fhjKrEGkcmsAAKuA-fIe7MpvzKMPSZfi0NE,56
7
- pydantic_rpc-0.6.0.dist-info/licenses/LICENSE,sha256=Y6jkAm2VqPqoGIGQ-mEQCecNfteQ2LwdpYhC5XiH_cA,1069
8
- pydantic_rpc-0.6.0.dist-info/RECORD,,
4
+ pydantic_rpc-0.6.1.dist-info/METADATA,sha256=Vi8bU0-HjPnhI0ETt9ReRhmMfJxBqPuf9gnAYQjTx4c,20481
5
+ pydantic_rpc-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ pydantic_rpc-0.6.1.dist-info/entry_points.txt,sha256=LeZJ6UN-fhjKrEGkcmsAAKuA-fIe7MpvzKMPSZfi0NE,56
7
+ pydantic_rpc-0.6.1.dist-info/licenses/LICENSE,sha256=Y6jkAm2VqPqoGIGQ-mEQCecNfteQ2LwdpYhC5XiH_cA,1069
8
+ pydantic_rpc-0.6.1.dist-info/RECORD,,