From 71b8e221865032b56ce3cc86290e19512ab706bd Mon Sep 17 00:00:00 2001 From: Jose Date: Sat, 27 Sep 2025 19:11:06 +0200 Subject: [PATCH 1/2] Python Ice/customError demo --- python/Ice/customError/.gitignore | 2 + python/Ice/customError/README.md | 91 ++++++++++++++++++ python/Ice/customError/client/main.py | 45 +++++++++ .../Ice/customError/client/requirements.txt | 11 +++ .../__pycache__/chatbot.cpython-313.pyc | Bin 0 -> 2250 bytes python/Ice/customError/server/chatbot.py | 47 +++++++++ python/Ice/customError/server/main.py | 31 ++++++ .../Ice/customError/server/requirements.txt | 11 +++ python/Ice/customError/slice/Greeter.ice | 28 ++++++ python/README.md | 1 + 10 files changed, 267 insertions(+) create mode 100644 python/Ice/customError/.gitignore create mode 100644 python/Ice/customError/README.md create mode 100755 python/Ice/customError/client/main.py create mode 100644 python/Ice/customError/client/requirements.txt create mode 100644 python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc create mode 100644 python/Ice/customError/server/chatbot.py create mode 100755 python/Ice/customError/server/main.py create mode 100644 python/Ice/customError/server/requirements.txt create mode 100644 python/Ice/customError/slice/Greeter.ice diff --git a/python/Ice/customError/.gitignore b/python/Ice/customError/.gitignore new file mode 100644 index 0000000000..0533745cab --- /dev/null +++ b/python/Ice/customError/.gitignore @@ -0,0 +1,2 @@ +*_ice.py +VisitorCenter diff --git a/python/Ice/customError/README.md b/python/Ice/customError/README.md new file mode 100644 index 0000000000..4233b0600b --- /dev/null +++ b/python/Ice/customError/README.md @@ -0,0 +1,91 @@ +# Ice Custom Error + +The Custom error demo shows how to define an exception in Slice, and how to throw and catch this exception. + +A Slice-defined exception should be seen as a custom error carried by the response instead of the expected return +value--there is naturally no throwing across the network. + +We recommend running each program in a separate Python virtual environment. If you are new to Python virtual environments, +see [Python Virtual Environments]. + +## Running the server + +Navigate to the `server` directory. + +### 1. Create and activate a Python virtual environment + +#### macOS and Linux + +```bash +python3 -m venv venv +source venv/bin/activate +``` + +#### Windows (PowerShell) + +```powershell +python -m venv venv +venv\Scripts\activate +``` + +### 2. Install program dependencies + +```bash +pip install -r requirements.txt +``` + +### 3. Compile the Slice definitions + +Use the Slice-to-Python compiler to generate Python code from the `Greeter.ice` file: + +```bash +slice2py ../slice/Greeter.ice +``` + +### 4. Run the server + +```bash +python main.py +``` + +## Running the client + +In a separate terminal, navigate to the `client` directory. + +### 1. Create and activate a Python virtual environment + +#### macOS and Linux + +```bash +python3 -m venv venv +source venv/bin/activate +``` + +#### Windows (PowerShell) + +```powershell +python -m venv venv +venv\Scripts\activate +``` + +### 2. Install program dependencies + +```bash +pip install -r requirements.txt +``` + +### 3. Compile the Slice definitions + +Use the Slice-to-Python compiler to generate Python code from the `Greeter.ice` file: + +```bash +slice2py ../slice/Greeter.ice +``` + +### 4. Run the client + +```bash +python main.py +``` + +[Python Virtual Environments]: https://docs.python.org/3/tutorial/venv.html diff --git a/python/Ice/customError/client/main.py b/python/Ice/customError/client/main.py new file mode 100755 index 0000000000..bf31688ba9 --- /dev/null +++ b/python/Ice/customError/client/main.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# Copyright (c) ZeroC, Inc. + +import asyncio +import getpass +import sys + +import Ice + +# Slice module VisitorCenter in Greeter.ice maps to Python module VisitorCenter. +import VisitorCenter + + +async def main(): + # Create an Ice communicator. We'll use this communicator to create proxies, and manage outgoing connections. We + # enable asyncio support by passing the current event loop to initialize. + async with Ice.initialize(sys.argv, eventLoop=asyncio.get_running_loop()) as communicator: + # GreeterPrx is a class generated by the Slice compiler. We create a proxy from a communicator and a "stringified + # proxy" with the address of the target object. + # If you run the server on a different computer, replace localhost in the string below with the server's hostname + # or IP address. + greeter = VisitorCenter.GreeterPrx(communicator, "greeter:tcp -h localhost -p 4061") + + names = [getpass.getuser(), "", "alice", "bob", "carol", "dave", "billy bob"] + + for name in names: + # Send a request to the remote object and get the response. The response from the server can carry: + # - a greeting (success) + # - a dispatch exception (the base class for marshallable system exceptions), or + # - a GreeterException (the custom exception we've defined in the Slice definitions) + try: + greeting = await greeter.greetAsync(name) + print(greeting) + except Ice.DispatchException as exception: + print( + f"Failed to create a greeting for '{name}': DispatchException {{ message = '{exception.args}', replyStatus = {exception.replyStatus} }}" + ) + except VisitorCenter.GreeterException as exception: + print( + f"Failed to create a greeting for '{name}': GreeterException {{ message = '{exception.message}', error = {exception.error} }}" + ) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/python/Ice/customError/client/requirements.txt b/python/Ice/customError/client/requirements.txt new file mode 100644 index 0000000000..5fdf3aa17f --- /dev/null +++ b/python/Ice/customError/client/requirements.txt @@ -0,0 +1,11 @@ +# Use ZeroC Nightly repository as the main index for pip. +--index-url https://download.zeroc.com/nexus/repository/pypi-nightly/simple/ + +# Allow installing additional packages from PyPI main index if not found in the ZeroC repository. +--extra-index-url https://pypi.org/simple/ + +# Allow installing pre-release versions (required for zeroc-ice nightly builds). +--pre + +# Add the zeroc-ice package (latest nightly version). This package includes the Slice to Python compiler (slice2py). +zeroc-ice diff --git a/python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc b/python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40f3c15435920bdb2a7b96e2a0b206d62b3db72e GIT binary patch literal 2250 zcma(SO>YxNbk^&y*s)2R#R(CVNkR&S#x`;ykqA&JL`?!D!b>8mMA~lbNxac|H_VP9 zaa9SaQiarBDuLP~YAdyz%7FvN{scQzax{vnN}x))r7|tozFFHiO)Jqkym@cteb0Mu z>XAqY!TKz^T{s;;=!GC!%hyEeSwJ2l6{*ryG=nIbk*I_P?YZiq9(R|itjg5ehX#@A z?MJF_NzS^OTgn>ynB3T@f7O%l?+PN};laGl2s4U=cL}#Ct{J%NP7t7=>tA|AAd8ZF3P6?Sr6{B|Bab!DFj{;gIWM(N7riZs zi3bSjDTEeV$w676{lJ1pk@s=@$HQbr1`ez-@J=iOUR{t>@5C*z6-NksdXwU8SA%Ci z97JPHk_b7UE0;bX7uzqTi1qwgRrLk6l}D%Sdpsuca;9-@@8^ zJBr0)ty8r_4UJ19KxU7(&f2>gZoLn@VQ1!T8OLqO7S@hMjkuBgpO=lkRTt)|ispCE_sr2^O`DFW{49`6T|dd~{Zj z&@85Htr9Al#KJ{=!zh-D0~~RmF1n;VK5g9rERS;(dfQ@#ZaPVPvp}$(FB+ENFsd_~ z;)3qrWkM`$+00lmNIuEsWqY|CzI0dL#3c|k@vaz335f?lu*8T{?jHVVWVkpooX5jc z6T{ahhE*;lxi6RicPAIi04~xv)wC!t< z7%syg;k|RqYb3{JZ8o_95w``qTlsDug|lSc+*Fy)N)GRwxAYP#*wiSKJQc%$%a(nY ziV?trkh>Lka(YFQxZ-*NG0w39p-rC?GWR;fT%jExLPhgCLJh{4UrWuygmY4BwnI`^ z>|Dv6ZmCT2Tnb)pBu|RAlUm;d^HvI?Naacnvx}1=#*`S1gr;(h5t>}zwfNbs_}S<2Or{)zPWy&{S&EE}!^nwGb7fXGk`^e8BUf35NR(365XtZ5F^ zl9AJN#;CC@`bN{}X}F^a0p1lre77zTKY=q0;B)kc$Kwm`g^u|W-wf>`*nX6M3O^3J z=rj4XIB94Q!ij)eoo->eZcs5_X)gdCXm&@#%0Dgh;Q2aZXFtuu13 str: + print(f"Dispatching greet request {{ name = '{name}' }}") + + if len(name) > MAX_LENGTH: + raise VisitorCenter.GreeterException("Name is longer than maximum!", VisitorCenter.GreeterError.NameTooLong) + + match name: + case "": + # ObjectNotExistException is a dispatch exception with a reply status of 'ObjectNotExist'. + raise Ice.ObjectNotExistException() + + case "alice": + # Simulate an authentication error by throwing a dispatch exception with the Unauthorized error code. + # Note: This is a demo; no real authentication logic is implemented. + raise Ice.DispatchException( + Ice.ReplyStatus.Unauthorized, "Invalid credentials. The administrator has been notified." + ) + case "bob": + raise VisitorCenter.GreeterException( + f"Away until {(datetime.now() + timedelta(minutes=5)).strftime('%Y-%m-%d %H:%M:%S')}.", + VisitorCenter.GreeterError.Away, + ) + case "carol": + raise VisitorCenter.GreeterException( + "I am already greeting someone else.", VisitorCenter.GreeterError.GreetingOtherVisitor + ) + + case _: + return f"Hello, {name}!" diff --git a/python/Ice/customError/server/main.py b/python/Ice/customError/server/main.py new file mode 100755 index 0000000000..0ffdbd6281 --- /dev/null +++ b/python/Ice/customError/server/main.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# Copyright (c) ZeroC, Inc. + +import sys + +import chatbot +import Ice + + +def main(): + # Create an Ice communicator. We'll use this communicator to create an object adapter. + with Ice.initialize(sys.argv) as communicator: + # Create an object adapter that listens for incoming requests and dispatches them to servants. + adapter = communicator.createObjectAdapterWithEndpoints("GreeterAdapter", "tcp -p 4061") + + # Register the Chatbot servant with the adapter. + adapter.add(chatbot.Chatbot(), Ice.Identity(name="greeter")) + + # Start dispatching requests. + adapter.activate() + print("Listening on port 4061...") + + try: + # Wait until communicator.shutdown() is called, which never occurs in this demo. + communicator.waitForShutdown() + except KeyboardInterrupt: + print("Caught Ctrl+C, exiting...") + + +if __name__ == "__main__": + main() diff --git a/python/Ice/customError/server/requirements.txt b/python/Ice/customError/server/requirements.txt new file mode 100644 index 0000000000..5fdf3aa17f --- /dev/null +++ b/python/Ice/customError/server/requirements.txt @@ -0,0 +1,11 @@ +# Use ZeroC Nightly repository as the main index for pip. +--index-url https://download.zeroc.com/nexus/repository/pypi-nightly/simple/ + +# Allow installing additional packages from PyPI main index if not found in the ZeroC repository. +--extra-index-url https://pypi.org/simple/ + +# Allow installing pre-release versions (required for zeroc-ice nightly builds). +--pre + +# Add the zeroc-ice package (latest nightly version). This package includes the Slice to Python compiler (slice2py). +zeroc-ice diff --git a/python/Ice/customError/slice/Greeter.ice b/python/Ice/customError/slice/Greeter.ice new file mode 100644 index 0000000000..94e30e1a64 --- /dev/null +++ b/python/Ice/customError/slice/Greeter.ice @@ -0,0 +1,28 @@ +// Copyright (c) ZeroC, Inc. + +module VisitorCenter +{ + /// Represents the error code carried by GreeterException. + enum GreeterError { NameTooLong, Away, GreetingOtherVisitor } + + /// Represents the custom error returned by the Greeter when it cannot create a greeting. This exception is thrown + /// by the implementation of the greet operation and caught by the caller. + exception GreeterException + { + /// Describes the exception in a human-readable way. + string message; + + /// Provides an error code that can be used to handle this exception programmatically. + GreeterError error; + } + + /// Represents a simple greeter. + interface Greeter + { + /// Creates a personalized greeting. + /// @param name The name of the person to greet. + /// @return The greeting. + /// @throws GreeterException Thrown when the greeter cannot create a greeting. + string greet(string name) throws GreeterException; + } +} diff --git a/python/README.md b/python/README.md index dfbbfb3ea1..69d72c84b4 100644 --- a/python/README.md +++ b/python/README.md @@ -11,6 +11,7 @@ demonstrates a specific feature or programming technique. | [Ice Callback](./Ice/callback/) | Shows how to implement callbacks in a client application. | | [Ice Config](./Ice/config/) | Shows how to configure client and server applications using Ice configuration files. | | [Ice Context](./Ice/context/) | Shows how to set and retrieve request contexts. | +| [Ice Custom Error](./Ice/customError/) | Shows how to define a new exception in Slice and return this exception from a Slice operation. | | [Ice Greeter](./Ice/greeter/) | Shows how to call and implement a canonical Greeter application with Ice. **Start with this demo!** | | [Ice Inheritance](./Ice/inheritance/) | Shows the power of interface inheritance in Slice. | | [Ice Invocation Timeout](./Ice/invocation_timeout/) | Shows how to use invocation timeouts | From 23114155a989c8536404652ffa6ef211184bc005 Mon Sep 17 00:00:00 2001 From: Jose Date: Tue, 30 Sep 2025 18:39:39 +0200 Subject: [PATCH 2/2] Review fix --- .../server/__pycache__/chatbot.cpython-313.pyc | Bin 2250 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc diff --git a/python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc b/python/Ice/customError/server/__pycache__/chatbot.cpython-313.pyc deleted file mode 100644 index 40f3c15435920bdb2a7b96e2a0b206d62b3db72e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2250 zcma(SO>YxNbk^&y*s)2R#R(CVNkR&S#x`;ykqA&JL`?!D!b>8mMA~lbNxac|H_VP9 zaa9SaQiarBDuLP~YAdyz%7FvN{scQzax{vnN}x))r7|tozFFHiO)Jqkym@cteb0Mu z>XAqY!TKz^T{s;;=!GC!%hyEeSwJ2l6{*ryG=nIbk*I_P?YZiq9(R|itjg5ehX#@A z?MJF_NzS^OTgn>ynB3T@f7O%l?+PN};laGl2s4U=cL}#Ct{J%NP7t7=>tA|AAd8ZF3P6?Sr6{B|Bab!DFj{;gIWM(N7riZs zi3bSjDTEeV$w676{lJ1pk@s=@$HQbr1`ez-@J=iOUR{t>@5C*z6-NksdXwU8SA%Ci z97JPHk_b7UE0;bX7uzqTi1qwgRrLk6l}D%Sdpsuca;9-@@8^ zJBr0)ty8r_4UJ19KxU7(&f2>gZoLn@VQ1!T8OLqO7S@hMjkuBgpO=lkRTt)|ispCE_sr2^O`DFW{49`6T|dd~{Zj z&@85Htr9Al#KJ{=!zh-D0~~RmF1n;VK5g9rERS;(dfQ@#ZaPVPvp}$(FB+ENFsd_~ z;)3qrWkM`$+00lmNIuEsWqY|CzI0dL#3c|k@vaz335f?lu*8T{?jHVVWVkpooX5jc z6T{ahhE*;lxi6RicPAIi04~xv)wC!t< z7%syg;k|RqYb3{JZ8o_95w``qTlsDug|lSc+*Fy)N)GRwxAYP#*wiSKJQc%$%a(nY ziV?trkh>Lka(YFQxZ-*NG0w39p-rC?GWR;fT%jExLPhgCLJh{4UrWuygmY4BwnI`^ z>|Dv6ZmCT2Tnb)pBu|RAlUm;d^HvI?Naacnvx}1=#*`S1gr;(h5t>}zwfNbs_}S<2Or{)zPWy&{S&EE}!^nwGb7fXGk`^e8BUf35NR(365XtZ5F^ zl9AJN#;CC@`bN{}X}F^a0p1lre77zTKY=q0;B)kc$Kwm`g^u|W-wf>`*nX6M3O^3J z=rj4XIB94Q!ij)eoo->eZcs5_X)gdCXm&@#%0Dgh;Q2aZXFtuu13