pydantic-rpc 0.6.1__py3-none-any.whl → 0.8.0__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.
- pydantic_rpc/__init__.py +10 -0
- pydantic_rpc/core.py +1829 -469
- pydantic_rpc/mcp/__init__.py +5 -0
- pydantic_rpc/mcp/converter.py +115 -0
- pydantic_rpc/mcp/exporter.py +283 -0
- pydantic_rpc/py.typed +0 -0
- {pydantic_rpc-0.6.1.dist-info → pydantic_rpc-0.8.0.dist-info}/METADATA +353 -18
- pydantic_rpc-0.8.0.dist-info/RECORD +10 -0
- pydantic_rpc-0.8.0.dist-info/WHEEL +4 -0
- {pydantic_rpc-0.6.1.dist-info → pydantic_rpc-0.8.0.dist-info}/entry_points.txt +1 -0
- pydantic_rpc-0.6.1.dist-info/RECORD +0 -8
- pydantic_rpc-0.6.1.dist-info/WHEEL +0 -4
- pydantic_rpc-0.6.1.dist-info/licenses/LICENSE +0 -21
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: pydantic-rpc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: A Python library for building gRPC/ConnectRPC services with Pydantic models.
|
|
5
5
|
Author: Yasushi Itoh
|
|
6
|
-
|
|
7
|
-
Requires-Python: >=3.11
|
|
8
|
-
Requires-Dist: connecpy>=1.4.1
|
|
9
|
-
Requires-Dist: grpcio-health-checking>=1.56.2
|
|
10
|
-
Requires-Dist: grpcio-reflection>=1.56.2
|
|
11
|
-
Requires-Dist: grpcio-tools>=1.56.2
|
|
6
|
+
Requires-Dist: annotated-types>=0.5.0
|
|
12
7
|
Requires-Dist: pydantic>=2.1.1
|
|
8
|
+
Requires-Dist: grpcio>=1.56.2
|
|
9
|
+
Requires-Dist: grpcio-tools>=1.56.2
|
|
10
|
+
Requires-Dist: grpcio-reflection>=1.56.2
|
|
11
|
+
Requires-Dist: grpcio-health-checking>=1.56.2
|
|
13
12
|
Requires-Dist: sonora>=0.2.3
|
|
13
|
+
Requires-Dist: connecpy==2.0.0
|
|
14
|
+
Requires-Dist: mcp>=1.9.4
|
|
15
|
+
Requires-Dist: starlette>=0.27.0
|
|
16
|
+
Requires-Python: >=3.11
|
|
14
17
|
Description-Content-Type: text/markdown
|
|
15
18
|
|
|
16
19
|
# 🚀 PydanticRPC
|
|
@@ -125,6 +128,7 @@ app.mount(OlympicsLocationAgent())
|
|
|
125
128
|
- **For Connect-RPC:**
|
|
126
129
|
- 🌐 **Connecpy Support:** Partially supports Connect-RPC via `Connecpy`.
|
|
127
130
|
- 🛠️ **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.
|
|
131
|
+
- 🤖 **MCP (Model Context Protocol) Support:** Expose your services as tools for AI assistants using the official MCP SDK, supporting both stdio and HTTP/SSE transports.
|
|
128
132
|
|
|
129
133
|
## 📦 Installation
|
|
130
134
|
|
|
@@ -178,12 +182,18 @@ class Greeter:
|
|
|
178
182
|
return HelloReply(message=f"Hello, {request.name}!")
|
|
179
183
|
|
|
180
184
|
|
|
185
|
+
async def main():
|
|
186
|
+
# You can specify a custom port (default is 50051)
|
|
187
|
+
server = AsyncIOServer(port=50052)
|
|
188
|
+
await server.run(Greeter())
|
|
189
|
+
|
|
190
|
+
|
|
181
191
|
if __name__ == "__main__":
|
|
182
|
-
|
|
183
|
-
loop = asyncio.get_event_loop()
|
|
184
|
-
loop.run_until_complete(server.run(Greeter()))
|
|
192
|
+
asyncio.run(main())
|
|
185
193
|
```
|
|
186
194
|
|
|
195
|
+
The AsyncIOServer automatically handles graceful shutdown on SIGTERM and SIGINT signals.
|
|
196
|
+
|
|
187
197
|
### 🌐 ASGI Application Example
|
|
188
198
|
|
|
189
199
|
```python
|
|
@@ -263,7 +273,7 @@ This will launch a Connecpy-based ASGI application that uses the same Pydantic m
|
|
|
263
273
|
> - Please follow the instruction described in https://go.dev/doc/install.
|
|
264
274
|
> 2. Install `protoc-gen-connecpy`:
|
|
265
275
|
> ```bash
|
|
266
|
-
> go install github.com/connecpy/protoc-gen-connecpy@latest
|
|
276
|
+
> go install github.com/i2y/connecpy/v2/protoc-gen-connecpy@latest
|
|
267
277
|
> ```
|
|
268
278
|
|
|
269
279
|
## ♻️ Skipping Protobuf Generation
|
|
@@ -275,6 +285,21 @@ export PYDANTIC_RPC_SKIP_GENERATION=true
|
|
|
275
285
|
|
|
276
286
|
When this variable is set to "true", PydanticRPC will load existing pre-generated modules rather than generating them on the fly.
|
|
277
287
|
|
|
288
|
+
## 🪧 Setting Protobuf and Connecpy/gRPC generation directory
|
|
289
|
+
By default your files will be generated in the current working directory where you ran the code from, but you can set a custom specific directory by setting the environment variable below:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
export PYDANTIC_RPC_PROTO_PATH=/your/path
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## ⚠️ Reserved Fields
|
|
296
|
+
|
|
297
|
+
You can also set an environment variable to reserve a set number of fields for proto generation, for backward and forward compatibility.
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
export PYDANTIC_RPC_RESERVED_FIELDS=1
|
|
301
|
+
```
|
|
302
|
+
|
|
278
303
|
## 💎 Advanced Features
|
|
279
304
|
|
|
280
305
|
### 🌊 Response Streaming
|
|
@@ -648,6 +673,203 @@ buf: * (#2) Call complete
|
|
|
648
673
|
%
|
|
649
674
|
```
|
|
650
675
|
|
|
676
|
+
### 🪶 Empty Messages
|
|
677
|
+
|
|
678
|
+
Empty request/response messages are automatically mapped to `google.protobuf.Empty`:
|
|
679
|
+
|
|
680
|
+
```python
|
|
681
|
+
from pydantic_rpc import AsyncIOServer, Message
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
class EmptyRequest(Message):
|
|
685
|
+
pass # Automatically uses google.protobuf.Empty
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
class GreetingResponse(Message):
|
|
689
|
+
message: str
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
class GreetingService:
|
|
693
|
+
async def say_hello(self, request: EmptyRequest) -> GreetingResponse:
|
|
694
|
+
return GreetingResponse(message="Hello!")
|
|
695
|
+
|
|
696
|
+
async def get_default_greeting(self) -> GreetingResponse:
|
|
697
|
+
# Method with no request parameter (implicitly empty)
|
|
698
|
+
return GreetingResponse(message="Hello, World!")
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
### 🎨 Custom Serialization
|
|
702
|
+
|
|
703
|
+
Pydantic's serialization decorators are fully supported:
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
from typing import Any
|
|
707
|
+
from pydantic import field_serializer, model_serializer
|
|
708
|
+
from pydantic_rpc import Message
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
class UserMessage(Message):
|
|
712
|
+
name: str
|
|
713
|
+
age: int
|
|
714
|
+
|
|
715
|
+
@field_serializer('name')
|
|
716
|
+
def serialize_name(self, name: str) -> str:
|
|
717
|
+
"""Always uppercase the name when serializing."""
|
|
718
|
+
return name.upper()
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
class ComplexMessage(Message):
|
|
722
|
+
value: int
|
|
723
|
+
multiplier: int
|
|
724
|
+
|
|
725
|
+
@model_serializer
|
|
726
|
+
def serialize_model(self) -> dict[str, Any]:
|
|
727
|
+
"""Custom serialization with computed fields."""
|
|
728
|
+
return {
|
|
729
|
+
'value': self.value,
|
|
730
|
+
'multiplier': self.multiplier,
|
|
731
|
+
'result': self.value * self.multiplier # Computed field
|
|
732
|
+
}
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
The serializers are automatically applied when converting between Pydantic models and protobuf messages.
|
|
736
|
+
|
|
737
|
+
#### ⚠️ Limitations and Considerations
|
|
738
|
+
|
|
739
|
+
**1. Nested Message serializers are now supported (v0.8.0+)**
|
|
740
|
+
```python
|
|
741
|
+
class Address(Message):
|
|
742
|
+
city: str
|
|
743
|
+
|
|
744
|
+
@field_serializer("city")
|
|
745
|
+
def serialize_city(self, city: str) -> str:
|
|
746
|
+
return city.upper()
|
|
747
|
+
|
|
748
|
+
class User(Message):
|
|
749
|
+
name: str
|
|
750
|
+
address: Address # ← Address's serializers ARE applied with DEEP strategy
|
|
751
|
+
|
|
752
|
+
@field_serializer("name")
|
|
753
|
+
def serialize_name(self, name: str) -> str:
|
|
754
|
+
return name.upper() # ← This IS applied
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
**Serializer Strategy Control:**
|
|
758
|
+
You can control how nested serializers are applied via environment variable:
|
|
759
|
+
```bash
|
|
760
|
+
# Apply serializers at all nesting levels (default)
|
|
761
|
+
export PYDANTIC_RPC_SERIALIZER_STRATEGY=deep
|
|
762
|
+
|
|
763
|
+
# Apply only top-level serializers
|
|
764
|
+
export PYDANTIC_RPC_SERIALIZER_STRATEGY=shallow
|
|
765
|
+
|
|
766
|
+
# Disable all serializers
|
|
767
|
+
export PYDANTIC_RPC_SERIALIZER_STRATEGY=none
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
**Performance Impact:**
|
|
771
|
+
- DEEP strategy: ~4% overhead for simple nested structures
|
|
772
|
+
- SHALLOW strategy: ~2% overhead (only top-level)
|
|
773
|
+
- NONE strategy: No overhead (serializers disabled)
|
|
774
|
+
|
|
775
|
+
**2. New fields added by serializers are ignored**
|
|
776
|
+
```python
|
|
777
|
+
class ComplexMessage(Message):
|
|
778
|
+
value: int
|
|
779
|
+
multiplier: int
|
|
780
|
+
|
|
781
|
+
@model_serializer
|
|
782
|
+
def serialize_model(self) -> dict[str, Any]:
|
|
783
|
+
return {
|
|
784
|
+
"value": self.value,
|
|
785
|
+
"multiplier": self.multiplier,
|
|
786
|
+
"result": self.value * self.multiplier # ← Won't appear in protobuf
|
|
787
|
+
}
|
|
788
|
+
```
|
|
789
|
+
**Problem**: The `result` field doesn't exist in the Message definition, so it's not in the protobuf schema.
|
|
790
|
+
|
|
791
|
+
**3. Type must remain consistent**
|
|
792
|
+
```python
|
|
793
|
+
class BadExample(Message):
|
|
794
|
+
number: int
|
|
795
|
+
|
|
796
|
+
@field_serializer("number")
|
|
797
|
+
def serialize_number(self, number: int) -> str: # ❌ int → str
|
|
798
|
+
return str(number) # This will cause issues
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
**4. Union/Optional fields have limited support**
|
|
802
|
+
```python
|
|
803
|
+
class UnionExample(Message):
|
|
804
|
+
data: str | int | None # Union type
|
|
805
|
+
|
|
806
|
+
@field_serializer("data")
|
|
807
|
+
def serialize_data(self, data: str | int | None) -> str | int | None:
|
|
808
|
+
# Serializer may not be applied to Union types
|
|
809
|
+
return data
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
**5. Errors fail silently with fallback**
|
|
813
|
+
```python
|
|
814
|
+
class RiskyMessage(Message):
|
|
815
|
+
value: int
|
|
816
|
+
|
|
817
|
+
@field_serializer("value")
|
|
818
|
+
def serialize_value(self, value: int) -> int:
|
|
819
|
+
if value == 0:
|
|
820
|
+
raise ValueError("Cannot serialize zero")
|
|
821
|
+
return value * 2
|
|
822
|
+
|
|
823
|
+
# If error occurs, original value is used (silent fallback)
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
**6. Circular references are handled gracefully**
|
|
827
|
+
```python
|
|
828
|
+
class Node(Message):
|
|
829
|
+
value: str
|
|
830
|
+
child: "Node | None" = None
|
|
831
|
+
|
|
832
|
+
@field_serializer("value")
|
|
833
|
+
def serialize_value(self, v: str) -> str:
|
|
834
|
+
return v.upper()
|
|
835
|
+
|
|
836
|
+
# Circular references are detected and prevented
|
|
837
|
+
node1 = Node(value="first")
|
|
838
|
+
node2 = Node(value="second")
|
|
839
|
+
node1.child = node2
|
|
840
|
+
node2.child = node1 # Circular reference
|
|
841
|
+
|
|
842
|
+
# When converting to protobuf:
|
|
843
|
+
# - Circular references are detected
|
|
844
|
+
# - Empty proto is returned for repeated objects
|
|
845
|
+
# - No infinite recursion occurs
|
|
846
|
+
# Note: Pydantic's model_dump() will fail on circular refs,
|
|
847
|
+
# so serializers won't be applied in this case
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
**✅ Recommended Usage:**
|
|
851
|
+
```python
|
|
852
|
+
class GoodMessage(Message):
|
|
853
|
+
# Use with primitive types
|
|
854
|
+
name: str
|
|
855
|
+
age: int
|
|
856
|
+
|
|
857
|
+
@field_serializer("name")
|
|
858
|
+
def normalize_name(self, name: str) -> str:
|
|
859
|
+
return name.strip().title() # Normalization
|
|
860
|
+
|
|
861
|
+
@field_serializer("age")
|
|
862
|
+
def clamp_age(self, age: int) -> int:
|
|
863
|
+
return max(0, min(age, 150)) # Range limiting
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
**Best Practices:**
|
|
867
|
+
- Use serializers primarily for primitive types (str, int, float, bool)
|
|
868
|
+
- Keep type consistency (int → int, str → str)
|
|
869
|
+
- Avoid complex transformations or side effects
|
|
870
|
+
- Test error cases thoroughly
|
|
871
|
+
- Be aware that errors fail silently
|
|
872
|
+
|
|
651
873
|
### 🔗 Multiple Services with Custom Interceptors
|
|
652
874
|
|
|
653
875
|
PydanticRPC supports defining and running multiple services in a single server:
|
|
@@ -733,6 +955,74 @@ if __name__ == "__main__":
|
|
|
733
955
|
|
|
734
956
|
TODO
|
|
735
957
|
|
|
958
|
+
### 🤖 MCP (Model Context Protocol) Support
|
|
959
|
+
|
|
960
|
+
PydanticRPC can expose your services as MCP tools for AI assistants using FastMCP. This enables seamless integration with any MCP-compatible client.
|
|
961
|
+
|
|
962
|
+
#### Stdio Mode Example
|
|
963
|
+
|
|
964
|
+
```python
|
|
965
|
+
from pydantic_rpc import Message
|
|
966
|
+
from pydantic_rpc.mcp import MCPExporter
|
|
967
|
+
|
|
968
|
+
class CalculateRequest(Message):
|
|
969
|
+
expression: str
|
|
970
|
+
|
|
971
|
+
class CalculateResponse(Message):
|
|
972
|
+
result: float
|
|
973
|
+
|
|
974
|
+
class MathService:
|
|
975
|
+
def calculate(self, req: CalculateRequest) -> CalculateResponse:
|
|
976
|
+
result = eval(req.expression, {"__builtins__": {}}, {})
|
|
977
|
+
return CalculateResponse(result=float(result))
|
|
978
|
+
|
|
979
|
+
# Run as MCP stdio server
|
|
980
|
+
if __name__ == "__main__":
|
|
981
|
+
service = MathService()
|
|
982
|
+
mcp = MCPExporter(service)
|
|
983
|
+
mcp.run_stdio()
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
#### Configuring MCP Clients
|
|
987
|
+
|
|
988
|
+
Any MCP-compatible client can connect to your service. For example, to configure Claude Desktop:
|
|
989
|
+
|
|
990
|
+
```json
|
|
991
|
+
{
|
|
992
|
+
"mcpServers": {
|
|
993
|
+
"my-math-service": {
|
|
994
|
+
"command": "python",
|
|
995
|
+
"args": ["/path/to/math_mcp_server.py"]
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
#### HTTP/ASGI Mode Example
|
|
1002
|
+
|
|
1003
|
+
MCP can also be mounted to existing ASGI applications:
|
|
1004
|
+
|
|
1005
|
+
```python
|
|
1006
|
+
from pydantic_rpc import ConnecpyASGIApp
|
|
1007
|
+
from pydantic_rpc.mcp import MCPExporter
|
|
1008
|
+
|
|
1009
|
+
# Create Connect-RPC ASGI app
|
|
1010
|
+
app = ConnecpyASGIApp()
|
|
1011
|
+
app.mount(MathService())
|
|
1012
|
+
|
|
1013
|
+
# Add MCP support via HTTP/SSE
|
|
1014
|
+
mcp = MCPExporter(MathService())
|
|
1015
|
+
mcp.mount_to_asgi(app, path="/mcp")
|
|
1016
|
+
|
|
1017
|
+
# Run with uvicorn
|
|
1018
|
+
import uvicorn
|
|
1019
|
+
uvicorn.run(app, host="127.0.0.1", port=8000)
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
MCP endpoints will be available at:
|
|
1023
|
+
- SSE: `GET http://localhost:8000/mcp/sse`
|
|
1024
|
+
- Messages: `POST http://localhost:8000/mcp/messages/`
|
|
1025
|
+
|
|
736
1026
|
### 🗄️ Protobuf file and code (Python files) generation using CLI
|
|
737
1027
|
|
|
738
1028
|
You can genereate protobuf files and code for a given module and a specified class using `pydantic-rpc` CLI command:
|
|
@@ -762,16 +1052,61 @@ Using this generated proto file and tools as `protoc`, `buf` and `BSR`, you coul
|
|
|
762
1052
|
| subclass of pydantic.BaseModel | message |
|
|
763
1053
|
|
|
764
1054
|
|
|
1055
|
+
## ⚠️ Known Limitations
|
|
1056
|
+
|
|
1057
|
+
### Union Types with Collections
|
|
1058
|
+
|
|
1059
|
+
Due to protobuf's `oneof` restrictions, you cannot use `Union` types that contain `repeated` (list/tuple) or `map` (dict) fields directly. This is a limitation of the protobuf specification itself.
|
|
1060
|
+
|
|
1061
|
+
**❌ Not Supported:**
|
|
1062
|
+
```python
|
|
1063
|
+
from typing import Union, List, Dict
|
|
1064
|
+
from pydantic_rpc import Message
|
|
1065
|
+
|
|
1066
|
+
# These will fail during proto compilation
|
|
1067
|
+
class MyMessage(Message):
|
|
1068
|
+
# Union with list - NOT SUPPORTED
|
|
1069
|
+
field1: Union[List[int], str]
|
|
1070
|
+
|
|
1071
|
+
# Union with dict - NOT SUPPORTED
|
|
1072
|
+
field2: Union[Dict[str, int], int]
|
|
1073
|
+
|
|
1074
|
+
# Union with nested collections - NOT SUPPORTED
|
|
1075
|
+
field3: Union[List[Dict[str, int]], str]
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
**✅ Workaround - Use Message Wrappers:**
|
|
1079
|
+
```python
|
|
1080
|
+
from typing import Union, List, Dict
|
|
1081
|
+
from pydantic_rpc import Message
|
|
1082
|
+
|
|
1083
|
+
# Wrap collections in Message types
|
|
1084
|
+
class IntList(Message):
|
|
1085
|
+
values: List[int]
|
|
1086
|
+
|
|
1087
|
+
class StringIntMap(Message):
|
|
1088
|
+
values: Dict[str, int]
|
|
1089
|
+
|
|
1090
|
+
class MyMessage(Message):
|
|
1091
|
+
# Now these work!
|
|
1092
|
+
field1: Union[IntList, str]
|
|
1093
|
+
field2: Union[StringIntMap, int]
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
This approach works because protobuf allows message types within `oneof` fields, and the collections are contained within those messages.
|
|
1097
|
+
|
|
1098
|
+
|
|
765
1099
|
## TODO
|
|
766
|
-
- [
|
|
1100
|
+
- [x] Streaming Support
|
|
767
1101
|
- [x] unary-stream
|
|
768
|
-
- [
|
|
769
|
-
- [
|
|
770
|
-
- [
|
|
771
|
-
- [
|
|
1102
|
+
- [x] stream-unary
|
|
1103
|
+
- [x] stream-stream
|
|
1104
|
+
- [x] Empty Message Support (automatic google.protobuf.Empty)
|
|
1105
|
+
- [x] Pydantic Serializer Support (@model_serializer, @field_serializer)
|
|
772
1106
|
- [ ] Custom Health Check Support
|
|
1107
|
+
- [x] MCP (Model Context Protocol) Support via official MCP SDK
|
|
773
1108
|
- [ ] Add more examples
|
|
774
|
-
- [
|
|
1109
|
+
- [x] Add tests
|
|
775
1110
|
|
|
776
1111
|
## 📜 License
|
|
777
1112
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pydantic_rpc/__init__.py,sha256=7dbedaf58742b13e96954afb68ca91f9800a2faf0799f78da6070c9c88511065,440
|
|
2
|
+
pydantic_rpc/core.py,sha256=2e2bce8aaf677ae50fdcdde51507da605ed77efe5e1a522e52b406c416b18318,104265
|
|
3
|
+
pydantic_rpc/mcp/__init__.py,sha256=f05ad62cc38db5c5972e16870c484523c58c5ac650d8454706f1ce4539cc7a52,123
|
|
4
|
+
pydantic_rpc/mcp/converter.py,sha256=b60dcaf82e6bff6be4b2ab8b1e9f2d16e09cb98d8f00182a4f6f73d1a78848a4,4158
|
|
5
|
+
pydantic_rpc/mcp/exporter.py,sha256=20833662f9a973ed9e1a705b9b59aaa2533de6c514ebd87ef66664a430a0d04f,10239
|
|
6
|
+
pydantic_rpc/py.typed,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
|
|
7
|
+
pydantic_rpc-0.8.0.dist-info/WHEEL,sha256=ab6157bc637547491fb4567cd7ddf26b04d63382916ca16c29a5c8e94c9c9ef7,79
|
|
8
|
+
pydantic_rpc-0.8.0.dist-info/entry_points.txt,sha256=72a47b1d2cae3abc045710fe0c2c2e6dfbb051fbf6960c22b62488004e9188ba,57
|
|
9
|
+
pydantic_rpc-0.8.0.dist-info/METADATA,sha256=1cb4d588db71dd052e24c12c63d368c89520279bc9c9a8b10658fdd0d83ee0ec,29803
|
|
10
|
+
pydantic_rpc-0.8.0.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pydantic_rpc/__init__.py,sha256=oomSVGmh_zddQQaphQt1L2xSVh9dD1LVyaAq1cN1FW4,231
|
|
2
|
-
pydantic_rpc/core.py,sha256=SB9GDZRxsMWQFxphinYQUAqrOx10eUn40fPTc7t1xYs,52107
|
|
3
|
-
pydantic_rpc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
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,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Yasushi Itoh
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|