pydantic-rpc 0.10.0__py3-none-any.whl → 0.11.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 +4 -0
- pydantic_rpc/core.py +46 -8
- pydantic_rpc/decorators.py +72 -1
- {pydantic_rpc-0.10.0.dist-info → pydantic_rpc-0.11.0.dist-info}/METADATA +94 -9
- {pydantic_rpc-0.10.0.dist-info → pydantic_rpc-0.11.0.dist-info}/RECORD +6 -7
- pydantic_rpc-0.10.0.dist-info/entry_points.txt +0 -3
- {pydantic_rpc-0.10.0.dist-info → pydantic_rpc-0.11.0.dist-info}/WHEEL +0 -0
pydantic_rpc/__init__.py
CHANGED
|
@@ -13,6 +13,8 @@ from .decorators import (
|
|
|
13
13
|
proto_option,
|
|
14
14
|
get_method_options,
|
|
15
15
|
has_http_option,
|
|
16
|
+
error_handler,
|
|
17
|
+
get_error_handlers,
|
|
16
18
|
)
|
|
17
19
|
from .tls import (
|
|
18
20
|
GrpcTLSConfig,
|
|
@@ -31,6 +33,8 @@ __all__ = [
|
|
|
31
33
|
"proto_option",
|
|
32
34
|
"get_method_options",
|
|
33
35
|
"has_http_option",
|
|
36
|
+
"error_handler",
|
|
37
|
+
"get_error_handlers",
|
|
34
38
|
"GrpcTLSConfig",
|
|
35
39
|
"extract_peer_identity",
|
|
36
40
|
"extract_peer_certificate_chain",
|
pydantic_rpc/core.py
CHANGED
|
@@ -2606,6 +2606,9 @@ class Server:
|
|
|
2606
2606
|
|
|
2607
2607
|
def __init__(
|
|
2608
2608
|
self,
|
|
2609
|
+
service: Optional[object] = None,
|
|
2610
|
+
port: int = 50051,
|
|
2611
|
+
package_name: str = "",
|
|
2609
2612
|
max_workers: int = 8,
|
|
2610
2613
|
*interceptors: Any,
|
|
2611
2614
|
tls: Optional["GrpcTLSConfig"] = None,
|
|
@@ -2614,9 +2617,10 @@ class Server:
|
|
|
2614
2617
|
futures.ThreadPoolExecutor(max_workers), interceptors=interceptors
|
|
2615
2618
|
)
|
|
2616
2619
|
self._service_names: list[str] = []
|
|
2617
|
-
self._package_name: str =
|
|
2618
|
-
self._port: int =
|
|
2620
|
+
self._package_name: str = package_name
|
|
2621
|
+
self._port: int = port
|
|
2619
2622
|
self._tls_config = tls
|
|
2623
|
+
self._initial_service = service
|
|
2620
2624
|
|
|
2621
2625
|
def set_package_name(self, package_name: str):
|
|
2622
2626
|
"""Set the package name for .proto generation."""
|
|
@@ -2654,6 +2658,11 @@ class Server:
|
|
|
2654
2658
|
Mount multiple services and run the gRPC server with reflection and health check.
|
|
2655
2659
|
Press Ctrl+C or send SIGTERM to stop.
|
|
2656
2660
|
"""
|
|
2661
|
+
# Mount initial service if provided
|
|
2662
|
+
if self._initial_service:
|
|
2663
|
+
self.mount(self._initial_service, self._package_name)
|
|
2664
|
+
|
|
2665
|
+
# Mount additional services
|
|
2657
2666
|
for obj in objs:
|
|
2658
2667
|
self.mount(obj, self._package_name)
|
|
2659
2668
|
|
|
@@ -2699,14 +2708,18 @@ class AsyncIOServer:
|
|
|
2699
2708
|
|
|
2700
2709
|
def __init__(
|
|
2701
2710
|
self,
|
|
2711
|
+
service: Optional[object] = None,
|
|
2712
|
+
port: int = 50051,
|
|
2713
|
+
package_name: str = "",
|
|
2702
2714
|
*interceptors: grpc.ServerInterceptor,
|
|
2703
2715
|
tls: Optional["GrpcTLSConfig"] = None,
|
|
2704
2716
|
) -> None:
|
|
2705
2717
|
self._server: grpc.aio.Server = grpc.aio.server(interceptors=interceptors)
|
|
2706
2718
|
self._service_names: list[str] = []
|
|
2707
|
-
self._package_name: str =
|
|
2708
|
-
self._port: int =
|
|
2719
|
+
self._package_name: str = package_name
|
|
2720
|
+
self._port: int = port
|
|
2709
2721
|
self._tls_config = tls
|
|
2722
|
+
self._initial_service = service
|
|
2710
2723
|
|
|
2711
2724
|
def set_package_name(self, package_name: str):
|
|
2712
2725
|
"""Set the package name for .proto generation."""
|
|
@@ -2746,6 +2759,11 @@ class AsyncIOServer:
|
|
|
2746
2759
|
Mount multiple async services and run the gRPC server with reflection and health check.
|
|
2747
2760
|
Press Ctrl+C or send SIGTERM to stop.
|
|
2748
2761
|
"""
|
|
2762
|
+
# Mount initial service if provided
|
|
2763
|
+
if self._initial_service:
|
|
2764
|
+
self.mount(self._initial_service, self._package_name)
|
|
2765
|
+
|
|
2766
|
+
# Mount additional services
|
|
2749
2767
|
for obj in objs:
|
|
2750
2768
|
self.mount(obj, self._package_name)
|
|
2751
2769
|
|
|
@@ -2802,10 +2820,11 @@ class ASGIApp:
|
|
|
2802
2820
|
An ASGI-compatible application that can serve Connect-RPC via Connecpy.
|
|
2803
2821
|
"""
|
|
2804
2822
|
|
|
2805
|
-
def __init__(self):
|
|
2823
|
+
def __init__(self, service: Optional[object] = None, package_name: str = ""):
|
|
2806
2824
|
self._services: list[tuple[Any, str]] = [] # List of (app, path) tuples
|
|
2807
2825
|
self._service_names: list[str] = []
|
|
2808
|
-
self._package_name: str =
|
|
2826
|
+
self._package_name: str = package_name
|
|
2827
|
+
self._initial_service = service
|
|
2809
2828
|
|
|
2810
2829
|
def mount(self, obj: object, package_name: str = ""):
|
|
2811
2830
|
"""Generate and compile proto files, then mount the async service implementation."""
|
|
@@ -2838,6 +2857,11 @@ class ASGIApp:
|
|
|
2838
2857
|
|
|
2839
2858
|
def mount_objs(self, *objs: object):
|
|
2840
2859
|
"""Mount multiple service objects into this ASGI app."""
|
|
2860
|
+
# Mount initial service if provided
|
|
2861
|
+
if self._initial_service:
|
|
2862
|
+
self.mount(self._initial_service, self._package_name)
|
|
2863
|
+
|
|
2864
|
+
# Mount additional services
|
|
2841
2865
|
for obj in objs:
|
|
2842
2866
|
self.mount(obj, self._package_name)
|
|
2843
2867
|
|
|
@@ -2848,6 +2872,10 @@ class ASGIApp:
|
|
|
2848
2872
|
send: Callable[[dict[str, Any]], Any],
|
|
2849
2873
|
):
|
|
2850
2874
|
"""ASGI entry point with routing for multiple services."""
|
|
2875
|
+
# Mount initial service on first call if not already mounted
|
|
2876
|
+
if self._initial_service and not self._services:
|
|
2877
|
+
self.mount(self._initial_service, self._package_name)
|
|
2878
|
+
|
|
2851
2879
|
if scope["type"] != "http":
|
|
2852
2880
|
await send({"type": "http.response.start", "status": 404})
|
|
2853
2881
|
await send({"type": "http.response.body", "body": b"Not Found"})
|
|
@@ -2874,10 +2902,11 @@ class WSGIApp:
|
|
|
2874
2902
|
A WSGI-compatible application that can serve Connect-RPC via Connecpy.
|
|
2875
2903
|
"""
|
|
2876
2904
|
|
|
2877
|
-
def __init__(self):
|
|
2905
|
+
def __init__(self, service: Optional[object] = None, package_name: str = ""):
|
|
2878
2906
|
self._services: list[tuple[Any, str]] = [] # List of (app, path) tuples
|
|
2879
2907
|
self._service_names: list[str] = []
|
|
2880
|
-
self._package_name: str =
|
|
2908
|
+
self._package_name: str = package_name
|
|
2909
|
+
self._initial_service = service
|
|
2881
2910
|
|
|
2882
2911
|
def mount(self, obj: object, package_name: str = ""):
|
|
2883
2912
|
"""Generate and compile proto files, then mount the sync service implementation."""
|
|
@@ -2910,6 +2939,11 @@ class WSGIApp:
|
|
|
2910
2939
|
|
|
2911
2940
|
def mount_objs(self, *objs: object):
|
|
2912
2941
|
"""Mount multiple service objects into this WSGI app."""
|
|
2942
|
+
# Mount initial service if provided
|
|
2943
|
+
if self._initial_service:
|
|
2944
|
+
self.mount(self._initial_service, self._package_name)
|
|
2945
|
+
|
|
2946
|
+
# Mount additional services
|
|
2913
2947
|
for obj in objs:
|
|
2914
2948
|
self.mount(obj, self._package_name)
|
|
2915
2949
|
|
|
@@ -2921,6 +2955,10 @@ class WSGIApp:
|
|
|
2921
2955
|
],
|
|
2922
2956
|
) -> Iterable[bytes]:
|
|
2923
2957
|
"""WSGI entry point with routing for multiple services."""
|
|
2958
|
+
# Mount initial service on first call if not already mounted
|
|
2959
|
+
if self._initial_service and not self._services:
|
|
2960
|
+
self.mount(self._initial_service, self._package_name)
|
|
2961
|
+
|
|
2924
2962
|
path = environ.get("PATH_INFO", "")
|
|
2925
2963
|
|
|
2926
2964
|
# Route to the appropriate service based on path
|
pydantic_rpc/decorators.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Decorators for adding protobuf options to RPC methods."""
|
|
2
2
|
|
|
3
|
-
from typing import Any, Callable, Dict, List, Optional, TypeVar
|
|
3
|
+
from typing import Any, Callable, Dict, List, Optional, TypeVar, Type
|
|
4
4
|
from functools import wraps
|
|
5
|
+
import grpc
|
|
6
|
+
from connecpy.code import Code as ConnectErrors
|
|
5
7
|
|
|
6
8
|
from .options import OptionMetadata, OPTION_METADATA_ATTR
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
12
|
+
ERROR_HANDLER_ATTR = "__pydantic_rpc_error_handlers__"
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
def http_option(
|
|
@@ -136,3 +139,71 @@ def has_proto_options(method: Callable) -> bool:
|
|
|
136
139
|
"""
|
|
137
140
|
metadata = get_method_options(method)
|
|
138
141
|
return metadata is not None and len(metadata.proto_options) > 0
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def error_handler(
|
|
145
|
+
exception_type: Type[Exception],
|
|
146
|
+
status_code: Optional[grpc.StatusCode] = None,
|
|
147
|
+
connect_code: Optional[ConnectErrors] = None,
|
|
148
|
+
handler: Optional[Callable[[Exception], tuple[str, Any]]] = None,
|
|
149
|
+
) -> Callable[[F], F]:
|
|
150
|
+
"""
|
|
151
|
+
Decorator to add automatic error handling to an RPC method.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
exception_type: The type of exception to handle
|
|
155
|
+
status_code: The gRPC status code to return (for gRPC services)
|
|
156
|
+
connect_code: The Connect error code to return (for Connect services)
|
|
157
|
+
handler: Optional custom handler function that returns (message, details)
|
|
158
|
+
|
|
159
|
+
Example:
|
|
160
|
+
@error_handler(ValidationError, status_code=grpc.StatusCode.INVALID_ARGUMENT)
|
|
161
|
+
@error_handler(KeyError, status_code=grpc.StatusCode.NOT_FOUND)
|
|
162
|
+
async def get_user(self, request: GetUserRequest) -> User:
|
|
163
|
+
...
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
def decorator(func: F) -> F:
|
|
167
|
+
# Get or create error handlers list
|
|
168
|
+
if not hasattr(func, ERROR_HANDLER_ATTR):
|
|
169
|
+
setattr(func, ERROR_HANDLER_ATTR, [])
|
|
170
|
+
|
|
171
|
+
handlers = getattr(func, ERROR_HANDLER_ATTR)
|
|
172
|
+
|
|
173
|
+
# Add this handler to the list
|
|
174
|
+
handlers.append(
|
|
175
|
+
{
|
|
176
|
+
"exception_type": exception_type,
|
|
177
|
+
"status_code": status_code or grpc.StatusCode.INTERNAL,
|
|
178
|
+
"connect_code": connect_code or ConnectErrors.INTERNAL,
|
|
179
|
+
"handler": handler,
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
@wraps(func)
|
|
184
|
+
def wrapper(*args, **kwargs):
|
|
185
|
+
return func(*args, **kwargs)
|
|
186
|
+
|
|
187
|
+
# Preserve the error handlers on the wrapper
|
|
188
|
+
setattr(wrapper, ERROR_HANDLER_ATTR, handlers)
|
|
189
|
+
|
|
190
|
+
# Preserve any existing option metadata
|
|
191
|
+
if hasattr(func, OPTION_METADATA_ATTR):
|
|
192
|
+
setattr(wrapper, OPTION_METADATA_ATTR, getattr(func, OPTION_METADATA_ATTR))
|
|
193
|
+
|
|
194
|
+
return wrapper # type: ignore
|
|
195
|
+
|
|
196
|
+
return decorator
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def get_error_handlers(method: Callable) -> Optional[List[Dict[str, Any]]]:
|
|
200
|
+
"""
|
|
201
|
+
Get error handlers from a method.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
method: The method to get error handlers from
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
List of error handler configurations if present, None otherwise
|
|
208
|
+
"""
|
|
209
|
+
return getattr(method, ERROR_HANDLER_ATTR, None)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pydantic-rpc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: A Python library for building gRPC/ConnectRPC services with Pydantic models.
|
|
5
5
|
Author: Yasushi Itoh
|
|
6
6
|
Requires-Dist: annotated-types==0.7.0
|
|
@@ -62,9 +62,10 @@ class OlympicsLocationAgent:
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
if __name__ == "__main__":
|
|
65
|
-
|
|
65
|
+
# New enhanced initialization API (optional - backward compatible)
|
|
66
|
+
s = AsyncIOServer(service=OlympicsLocationAgent(), port=50051)
|
|
66
67
|
loop = asyncio.get_event_loop()
|
|
67
|
-
loop.run_until_complete(s.run(
|
|
68
|
+
loop.run_until_complete(s.run())
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
And here is an example of a simple Connect RPC service that exposes the same agent as an ASGI application:
|
|
@@ -106,8 +107,8 @@ class OlympicsLocationAgent:
|
|
|
106
107
|
result = await self._agent.run(req.prompt())
|
|
107
108
|
return result.data
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
app
|
|
110
|
+
# New enhanced initialization API (optional - backward compatible)
|
|
111
|
+
app = ASGIApp(service=OlympicsLocationAgent())
|
|
111
112
|
|
|
112
113
|
```
|
|
113
114
|
|
|
@@ -129,6 +130,17 @@ app.mount(OlympicsLocationAgent())
|
|
|
129
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.
|
|
130
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.
|
|
131
132
|
|
|
133
|
+
## ⚠️ Important Notes for Connect-RPC
|
|
134
|
+
|
|
135
|
+
When using Connect-RPC with ASGIApp:
|
|
136
|
+
|
|
137
|
+
- **Endpoint Path Format**: Connect-RPC endpoints use CamelCase method names in the path: `/<package>.<service>/<Method>` (e.g., `/chat.v1.ChatService/SendMessage`)
|
|
138
|
+
- **Content-Type**: Set `Content-Type: application/json` or `application/connect+json` for requests
|
|
139
|
+
- **HTTP/2 Requirement**: Bidirectional streaming requires HTTP/2. Use Hypercorn instead of uvicorn for HTTP/2 support
|
|
140
|
+
- **Testing**: Use [buf curl](https://buf.build/docs/ecosystem/cli/curl) for testing Connect-RPC endpoints with proper streaming support
|
|
141
|
+
|
|
142
|
+
For detailed examples and testing instructions, see the [examples directory](examples/).
|
|
143
|
+
|
|
132
144
|
## 📦 Installation
|
|
133
145
|
|
|
134
146
|
Install PydanticRPC via pip:
|
|
@@ -137,6 +149,54 @@ Install PydanticRPC via pip:
|
|
|
137
149
|
pip install pydantic-rpc
|
|
138
150
|
```
|
|
139
151
|
|
|
152
|
+
For CLI support with built-in server runners:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
pip install pydantic-rpc-cli # Includes hypercorn and gunicorn
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 🆕 Enhanced Features (v0.10.0+)
|
|
159
|
+
|
|
160
|
+
**Note: All new features are fully backward compatible. Existing code continues to work without modification.**
|
|
161
|
+
|
|
162
|
+
### Enhanced Initialization API
|
|
163
|
+
All server classes now support optional initialization with services:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# Traditional API (still works)
|
|
167
|
+
server = AsyncIOServer()
|
|
168
|
+
server.set_port(50051)
|
|
169
|
+
await server.run(MyService())
|
|
170
|
+
|
|
171
|
+
# New enhanced API (optional)
|
|
172
|
+
server = AsyncIOServer(
|
|
173
|
+
service=MyService(),
|
|
174
|
+
port=50051,
|
|
175
|
+
package_name="my.package"
|
|
176
|
+
)
|
|
177
|
+
await server.run()
|
|
178
|
+
|
|
179
|
+
# Same for ASGI/WSGI apps
|
|
180
|
+
app = ASGIApp(service=MyService(), package_name="my.package")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Error Handling with Decorators
|
|
184
|
+
Automatically map exceptions to gRPC/Connect status codes:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from pydantic_rpc import error_handler
|
|
188
|
+
import grpc
|
|
189
|
+
|
|
190
|
+
class MyService:
|
|
191
|
+
@error_handler(ValidationError, status_code=grpc.StatusCode.INVALID_ARGUMENT)
|
|
192
|
+
@error_handler(KeyError, status_code=grpc.StatusCode.NOT_FOUND)
|
|
193
|
+
async def get_user(self, request: GetUserRequest) -> User:
|
|
194
|
+
# Exceptions are automatically converted to proper status codes
|
|
195
|
+
if request.id not in users_db:
|
|
196
|
+
raise KeyError(f"User {request.id} not found")
|
|
197
|
+
return users_db[request.id]
|
|
198
|
+
```
|
|
199
|
+
|
|
140
200
|
## 🚀 Getting Started
|
|
141
201
|
|
|
142
202
|
PydanticRPC supports two main protocols:
|
|
@@ -1090,15 +1150,40 @@ MCP endpoints will be available at:
|
|
|
1090
1150
|
- SSE: `GET http://localhost:8000/mcp/sse`
|
|
1091
1151
|
- Messages: `POST http://localhost:8000/mcp/messages/`
|
|
1092
1152
|
|
|
1093
|
-
### 🗄️
|
|
1153
|
+
### 🗄️ CLI Tool (pydantic-rpc-cli)
|
|
1154
|
+
|
|
1155
|
+
The CLI tool provides powerful features for generating protobuf files and running servers. Install it separately:
|
|
1156
|
+
|
|
1157
|
+
```bash
|
|
1158
|
+
pip install pydantic-rpc-cli
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
#### Generate Protobuf Files
|
|
1094
1162
|
|
|
1095
|
-
|
|
1163
|
+
```bash
|
|
1164
|
+
# Generate .proto file from a service class
|
|
1165
|
+
pydantic-rpc generate myapp.services.UserService --output ./proto/
|
|
1166
|
+
|
|
1167
|
+
# Also compile to Python code
|
|
1168
|
+
pydantic-rpc generate myapp.services.UserService --compile
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
#### Run Servers Directly
|
|
1172
|
+
|
|
1173
|
+
The CLI can run any type of server:
|
|
1096
1174
|
|
|
1097
1175
|
```bash
|
|
1098
|
-
|
|
1176
|
+
# Run as gRPC server (auto-detects async/sync)
|
|
1177
|
+
pydantic-rpc serve myapp.services.UserService --port 50051
|
|
1178
|
+
|
|
1179
|
+
# Run as Connect-RPC with ASGI (HTTP/2, uses Hypercorn)
|
|
1180
|
+
pydantic-rpc serve myapp.services.UserService --asgi --port 8000
|
|
1181
|
+
|
|
1182
|
+
# Run as Connect-RPC with WSGI (HTTP/1.1, uses Gunicorn)
|
|
1183
|
+
pydantic-rpc serve myapp.services.UserService --wsgi --port 8000 --workers 4
|
|
1099
1184
|
```
|
|
1100
1185
|
|
|
1101
|
-
Using
|
|
1186
|
+
Using the generated proto files with tools like `protoc`, `buf` and `BSR`, you can generate code for any desired language.
|
|
1102
1187
|
|
|
1103
1188
|
|
|
1104
1189
|
## 📖 Data Type Mapping
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
pydantic_rpc/__init__.py,sha256=
|
|
2
|
-
pydantic_rpc/core.py,sha256=
|
|
3
|
-
pydantic_rpc/decorators.py,sha256=
|
|
1
|
+
pydantic_rpc/__init__.py,sha256=c5e0b5d4ed6de3e3c7c1ada5389e704ce149ea56ca0930392db6abdf222b4e86,871
|
|
2
|
+
pydantic_rpc/core.py,sha256=9f1a8e669df10d99fea575b83efcb7209c186e461de0ae7050e0592ee675d45c,114131
|
|
3
|
+
pydantic_rpc/decorators.py,sha256=d147eb7c0814043b79ef2f8551947341f32852296467b35b12bc4e63469ef294,6217
|
|
4
4
|
pydantic_rpc/mcp/__init__.py,sha256=f05ad62cc38db5c5972e16870c484523c58c5ac650d8454706f1ce4539cc7a52,123
|
|
5
5
|
pydantic_rpc/mcp/converter.py,sha256=b60dcaf82e6bff6be4b2ab8b1e9f2d16e09cb98d8f00182a4f6f73d1a78848a4,4158
|
|
6
6
|
pydantic_rpc/mcp/exporter.py,sha256=20833662f9a973ed9e1a705b9b59aaa2533de6c514ebd87ef66664a430a0d04f,10239
|
|
7
7
|
pydantic_rpc/options.py,sha256=6094036184a500b92715fd91d31ecc501460a56de47dcf6024c6335ae8e5d6e3,4561
|
|
8
8
|
pydantic_rpc/py.typed,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
|
|
9
9
|
pydantic_rpc/tls.py,sha256=0eb290cc09c8ebedc71e7a97c01736d9675a314f70ebd80a2ce73e3f1689d359,3567
|
|
10
|
-
pydantic_rpc-0.
|
|
11
|
-
pydantic_rpc-0.
|
|
12
|
-
pydantic_rpc-0.
|
|
13
|
-
pydantic_rpc-0.10.0.dist-info/RECORD,,
|
|
10
|
+
pydantic_rpc-0.11.0.dist-info/WHEEL,sha256=ab6157bc637547491fb4567cd7ddf26b04d63382916ca16c29a5c8e94c9c9ef7,79
|
|
11
|
+
pydantic_rpc-0.11.0.dist-info/METADATA,sha256=fae01debdcc0725d6cc2f89180d9dd88cfcb5e05581faee71b75f95b4119b195,34906
|
|
12
|
+
pydantic_rpc-0.11.0.dist-info/RECORD,,
|
|
File without changes
|