Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions python/Ice/customError/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*_ice.py
VisitorCenter
91 changes: 91 additions & 0 deletions python/Ice/customError/README.md
Original file line number Diff line number Diff line change
@@ -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
45 changes: 45 additions & 0 deletions python/Ice/customError/client/main.py
Original file line number Diff line number Diff line change
@@ -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())
11 changes: 11 additions & 0 deletions python/Ice/customError/client/requirements.txt
Original file line number Diff line number Diff line change
@@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not commit this file

Binary file not shown.
47 changes: 47 additions & 0 deletions python/Ice/customError/server/chatbot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) ZeroC, Inc.

from datetime import datetime, timedelta

import Ice

# Slice module VisitorCenter in Greeter.ice maps to Python module VisitorCenter.
import VisitorCenter

MAX_LENGTH = 7


class Chatbot(VisitorCenter.Greeter):
"""
Chatbot is an Ice servant that implements Slice interface Greeter.
"""

# Implements the method greet from the Greeter class generated by the Slice compiler.
def greet(self, name: str, current: Ice.Current) -> 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}!"
31 changes: 31 additions & 0 deletions python/Ice/customError/server/main.py
Original file line number Diff line number Diff line change
@@ -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()
11 changes: 11 additions & 0 deletions python/Ice/customError/server/requirements.txt
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions python/Ice/customError/slice/Greeter.ice
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 1 addition & 0 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
Loading