This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git

commit 097918420205ac6697b46b1a3455b23e8b1c1c3d
Author: chaokunyang <[email protected]>
AuthorDate: Wed Jun 17 06:04:00 2026 +0000

    🔄 synced local 'docs/guide/' with remote 'docs/guide/'
---
 docs/guide/csharp/grpc-support.md     |   2 +-
 docs/guide/go/grpc-support.md         |   2 +-
 docs/guide/java/grpc-support.md       |   2 +-
 docs/guide/javascript/grpc-support.md |   2 +-
 docs/guide/kotlin/grpc-support.md     |   2 +-
 docs/guide/python/grpc-support.md     | 167 ++++++++++++++++++++++------------
 docs/guide/rust/grpc-support.md       |   2 +-
 docs/guide/scala/grpc-support.md      |   2 +-
 8 files changed, 118 insertions(+), 63 deletions(-)

diff --git a/docs/guide/csharp/grpc-support.md 
b/docs/guide/csharp/grpc-support.md
index 485900d829..e017664c46 100644
--- a/docs/guide/csharp/grpc-support.md
+++ b/docs/guide/csharp/grpc-support.md
@@ -284,7 +284,7 @@ A gRPC service named `Greeter` still generates the service 
companion
 schema files target the same C# namespace without colliding. No
 namespace-derived or service-derived module alias is generated.
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service code only replaces request and response serialization.
 All normal gRPC operational features still belong to your gRPC stack:
diff --git a/docs/guide/go/grpc-support.md b/docs/guide/go/grpc-support.md
index 02418eba1c..4c221dc90e 100644
--- a/docs/guide/go/grpc-support.md
+++ b/docs/guide/go/grpc-support.md
@@ -201,7 +201,7 @@ Generated Go code follows grpc-go conventions:
 - The generated codec is used for every message frame, including streaming
   frames.
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service companion only supplies Fory serialization. Operational
 behavior remains standard grpc-go behavior:
diff --git a/docs/guide/java/grpc-support.md b/docs/guide/java/grpc-support.md
index d1c899329a..2239444fa1 100644
--- a/docs/guide/java/grpc-support.md
+++ b/docs/guide/java/grpc-support.md
@@ -366,7 +366,7 @@ final class StreamingClient {
 The generated descriptors preserve the exact IDL service and method names for
 the gRPC path.
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service code only replaces request and response serialization.
 All normal gRPC operational features still belong to grpc-java:
diff --git a/docs/guide/javascript/grpc-support.md 
b/docs/guide/javascript/grpc-support.md
index 696ecef24a..2cbc68dbee 100644
--- a/docs/guide/javascript/grpc-support.md
+++ b/docs/guide/javascript/grpc-support.md
@@ -291,7 +291,7 @@ stream.on("end", () => {
 });
 ```
 
-## Operations
+## gRPC Runtime Behavior
 
 Generated service code only replaces request and response serialization. Normal
 gRPC operational features still belong to the transport package:
diff --git a/docs/guide/kotlin/grpc-support.md 
b/docs/guide/kotlin/grpc-support.md
index cf517df443..c18eabebfa 100644
--- a/docs/guide/kotlin/grpc-support.md
+++ b/docs/guide/kotlin/grpc-support.md
@@ -230,7 +230,7 @@ stub.chat(
 }
 ```
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service code only replaces request and response serialization.
 All normal gRPC operational features still belong to grpc-java and
diff --git a/docs/guide/python/grpc-support.md 
b/docs/guide/python/grpc-support.md
index cdcff92243..0c5921cc67 100644
--- a/docs/guide/python/grpc-support.md
+++ b/docs/guide/python/grpc-support.md
@@ -28,19 +28,16 @@ IDL, or FlatBuffers IDL and you want gRPC transport 
semantics with Fory payload
 encoding. Use standard protobuf gRPC code generation when clients or tools must
 consume protobuf message bytes directly.
 
-Generated Python companions currently target the synchronous `grpcio` API. Use
-regular `def` servicer methods, `grpc.server(...)`, standard `grpc.Channel`
-instances, and Python iterators or generators for streaming RPCs. The generated
-stub accepts any channel configured by your application. The compiler does not
-generate `grpc.aio` stubs or service bases, so do not implement generated
-servicer methods as `async def` unless you add a custom adapter outside the
-generated companion. Python gRPC async support based on `grpc.aio` will be
-available in the next Fory release.
+Python gRPC generation defaults to the `grpc.aio` AsyncIO API. Generated
+servicer bases use `async def` methods, generated stubs are used with
+`grpc.aio.Channel` instances, and streaming RPCs use async iterables. 
Synchronous
+`grpcio` companions are still available with `--grpc-python-mode=sync`.
 
 ## Install Dependencies
 
-Install `grpcio` alongside `pyfory`. The generated companion imports `grpc`, 
but
-`pyfory` does not add gRPC as a hard dependency.
+Install `grpcio` alongside `pyfory`. The generated companion imports `grpc` 
and,
+in the default mode, `grpc.aio`, but `pyfory` does not add gRPC as a hard
+dependency.
 
 ```bash
 pip install pyfory grpcio
@@ -75,79 +72,82 @@ foryc service.fdl --python_out=./generated/python --grpc
 
 For this schema, the Python generator emits:
 
-| File                   | Purpose                                     |
-| ---------------------- | ------------------------------------------- |
-| `demo_greeter.py`      | Fory dataclasses and registration helpers   |
-| `demo_greeter_grpc.py` | `grpcio` stub, servicer base, and registrar |
+| File                   | Purpose                                       |
+| ---------------------- | --------------------------------------------- |
+| `demo_greeter.py`      | Fory dataclasses and registration helpers     |
+| `demo_greeter_grpc.py` | `grpc.aio` stub, servicer base, and registrar |
 
 The module name is derived from the Fory package by replacing dots with
 underscores. A schema with no package uses `generated.py` and
 `generated_grpc.py`.
 
-## Implement a Server
+## Implement an Async Server
 
-Subclass the generated servicer and register it with a normal `grpcio` server.
+Subclass the generated servicer and register it with a `grpc.aio` server.
 Generated Python method names use snake_case, while the gRPC wire path keeps 
the
 original IDL method name.
 
 ```python
-from concurrent import futures
+import asyncio
 
-import grpc
+import grpc.aio
 
 import demo_greeter
 import demo_greeter_grpc
 
 
 class Greeter(demo_greeter_grpc.GreeterServicer):
-    def say_hello(self, request, context):
+    async def say_hello(self, request, context):
         return demo_greeter.HelloReply(reply=f"Hello, {request.name}")
 
 
-def serve():
-    server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
+async def serve():
+    server = grpc.aio.server()
     demo_greeter_grpc.add_servicer(Greeter(), server)
     server.add_insecure_port("[::]:50051")
-    server.start()
-    server.wait_for_termination()
+    await server.start()
+    await server.wait_for_termination()
 
 
 if __name__ == "__main__":
-    serve()
+    asyncio.run(serve())
 ```
 
 Generated request and response types are serialized by the generated companion,
 so service implementations do not perform manual Fory registration.
 
-## Create a Client
+## Create an Async Client
 
-Use the generated stub with a normal `grpcio` channel. Production clients
-usually pass a TLS/auth-configured channel:
+Use the generated stub with a `grpc.aio` channel. Production clients usually
+pass a TLS/auth-configured channel:
 
 ```python
+import asyncio
+
 import grpc
+import grpc.aio
 
 import demo_greeter
 import demo_greeter_grpc
 
 
-def main():
+async def main():
     credentials = grpc.ssl_channel_credentials()
-    with grpc.secure_channel("api.example.com:443", credentials) as channel:
+    async with grpc.aio.secure_channel("api.example.com:443", credentials) as 
channel:
         stub = demo_greeter_grpc.GreeterStub(channel)
-        reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory"))
+        reply = await stub.say_hello(demo_greeter.HelloRequest(name="Fory"))
         print(reply.reply)
 
 
 if __name__ == "__main__":
-    main()
+    asyncio.run(main())
 ```
 
 For local tests and development, an insecure channel can be used explicitly:
 
 ```python
-# Test-only channel. Use a TLS/auth-configured grpc.Channel in production.
-with grpc.insecure_channel("localhost:50051") as channel:
+# Test-only channel. Use a TLS/auth-configured grpc.aio.Channel in production.
+async with grpc.aio.insecure_channel("localhost:50051") as channel:
     stub = demo_greeter_grpc.GreeterStub(channel)
 ```
 
@@ -168,63 +168,118 @@ service Greeter {
 }
 ```
 
-Generated Python code follows `grpcio` conventions:
+Default Python gRPC output follows `grpc.aio` conventions:
 
-| IDL shape                                 | Servicer method shape            
           | Stub method shape                |
-| ----------------------------------------- | 
------------------------------------------- | -------------------------------- |
-| `rpc A (Req) returns (Res)`               | returns one response object      
           | returns one response object      |
-| `rpc A (Req) returns (stream Res)`        | yields response objects          
           | returns an iterator of responses |
-| `rpc A (stream Req) returns (Res)`        | consumes an iterator and returns 
a response | accepts an iterator of requests  |
-| `rpc A (stream Req) returns (stream Res)` | consumes and yields iterators    
           | accepts and returns iterators    |
+| IDL shape                                 | Servicer method shape            
               | Stub method shape                      |
+| ----------------------------------------- | 
----------------------------------------------- | 
-------------------------------------- |
+| `rpc A (Req) returns (Res)`               | `async def` returns one response 
object         | awaitable returns one response object  |
+| `rpc A (Req) returns (stream Res)`        | `async def` yields response 
objects             | returns an async iterator of responses |
+| `rpc A (stream Req) returns (Res)`        | consumes an async iterator and 
returns response | accepts an async iterator of requests  |
+| `rpc A (stream Req) returns (stream Res)` | consumes and yields async 
iterators             | accepts and returns async iterators    |
 
 Servicer methods use snake_case names, while generated descriptors preserve the
 exact IDL service and method names for the gRPC path.
 
-Server implementations can use Python iterators directly:
+Server implementations use async methods and async iteration:
 
 ```python
 class Greeter(demo_greeter_grpc.GreeterServicer):
-    def lots_of_replies(self, request, context):
+    async def lots_of_replies(self, request, context):
         yield demo_greeter.HelloReply(reply=f"Hello, {request.name}")
         yield demo_greeter.HelloReply(reply=f"Welcome, {request.name}")
 
-    def lots_of_greetings(self, request_iterator, context):
-        names = [request.name for request in request_iterator]
+    async def lots_of_greetings(self, request_iterator, context):
+        names = []
+        async for request in request_iterator:
+            names.append(request.name)
         return demo_greeter.HelloReply(reply=", ".join(names))
 
-    def chat(self, request_iterator, context):
-        for request in request_iterator:
+    async def chat(self, request_iterator, context):
+        async for request in request_iterator:
             yield demo_greeter.HelloReply(reply=f"Hello, {request.name}")
 ```
 
-Generated clients use the standard `grpcio` streaming call shapes:
+Generated clients use `grpc.aio` streaming call shapes:
 
 ```python
 credentials = grpc.ssl_channel_credentials()
-with grpc.secure_channel("api.example.com:443", credentials) as channel:
+async with grpc.aio.secure_channel("api.example.com:443", credentials) as 
channel:
     stub = demo_greeter_grpc.GreeterStub(channel)
 
-    for reply in stub.lots_of_replies(
+    async for reply in stub.lots_of_replies(
         demo_greeter.HelloRequest(name="Fory")
     ):
         print(reply.reply)
 
-    def greeting_requests():
+    async def greeting_requests():
         yield demo_greeter.HelloRequest(name="Ada")
         yield demo_greeter.HelloRequest(name="Grace")
 
-    summary = stub.lots_of_greetings(greeting_requests())
+    summary = await stub.lots_of_greetings(greeting_requests())
     print(summary.reply)
 
-    def chat_requests():
+    async def chat_requests():
         yield demo_greeter.HelloRequest(name="Fory")
         yield demo_greeter.HelloRequest(name="RPC")
 
-    for reply in stub.chat(chat_requests()):
+    async for reply in stub.chat(chat_requests()):
         print(reply.reply)
 ```
 
-## Operations
+## Sync Mode
+
+Use sync mode for existing synchronous `grpcio` applications or environments
+that do not run an asyncio event loop. Generate sync companions explicitly:
+
+```bash
+foryc service.fdl --python_out=./generated/python --grpc 
--grpc-python-mode=sync
+```
+
+Sync mode emits the same `<module>_grpc.py` filename and public names, but the
+servicer methods use regular `def`, and applications use `grpc.server(...)` and
+standard `grpc.Channel` instances.
+
+Unary sync server example:
+
+```python
+from concurrent import futures
+
+import grpc
+
+import demo_greeter
+import demo_greeter_grpc
+
+
+class Greeter(demo_greeter_grpc.GreeterServicer):
+    def say_hello(self, request, context):
+        return demo_greeter.HelloReply(reply=f"Hello, {request.name}")
+
+
+server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
+demo_greeter_grpc.add_servicer(Greeter(), server)
+server.add_insecure_port("[::]:50051")
+server.start()
+server.wait_for_termination()
+```
+
+Unary sync client example:
+
+```python
+import grpc
+
+import demo_greeter
+import demo_greeter_grpc
+
+
+with grpc.insecure_channel("localhost:50051") as channel:
+    stub = demo_greeter_grpc.GreeterStub(channel)
+    reply = stub.say_hello(demo_greeter.HelloRequest(name="Fory"))
+    print(reply.reply)
+```
+
+Sync streaming follows the normal `grpcio` iterator and generator conventions.
+
+## gRPC Runtime Behavior
 
 The generated service companion only supplies Fory serialization callbacks.
 Operational behavior remains standard `grpcio` behavior:
@@ -233,8 +288,8 @@ Operational behavior remains standard `grpcio` behavior:
 - TLS and authentication credentials
 - Client and server interceptors
 - Status codes, details, and metadata
-- Channel and server lifecycle
-- Thread pool sizing for synchronous servers
+- Async event loop, channel, and server lifecycle in default mode
+- Thread pool sizing for synchronous servers in sync mode
 
 ## Troubleshooting
 
diff --git a/docs/guide/rust/grpc-support.md b/docs/guide/rust/grpc-support.md
index 4c9ca55f6c..d60989f879 100644
--- a/docs/guide/rust/grpc-support.md
+++ b/docs/guide/rust/grpc-support.md
@@ -300,7 +300,7 @@ reference metadata for a request or response type, Rust 
gRPC generation rejects
 that service. Use thread-safe reference shapes for gRPC payloads, or keep the
 non-thread-safe type out of the RPC boundary.
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service companion only supplies Fory serialization and tonic
 bindings. Operational behavior remains standard tonic behavior:
diff --git a/docs/guide/scala/grpc-support.md b/docs/guide/scala/grpc-support.md
index 0b97929db0..f89f47d689 100644
--- a/docs/guide/scala/grpc-support.md
+++ b/docs/guide/scala/grpc-support.md
@@ -371,7 +371,7 @@ Server-streaming, client-streaming, and bidirectional 
server methods use
 grpc-java `StreamObserver` APIs because streaming completion, request flow
 control, cancellation, and backpressure follow grpc-java behavior.
 
-## Operations
+## gRPC Runtime Behavior
 
 The generated service code only replaces request and response serialization.
 All normal gRPC operational features still belong to grpc-java:


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to