dicom_echo.cli
dicom-echo
Send a C-ECHO message to the given address.
The C-ECHO procedure functions like a ping, serving to test that the peer SCP is accepting associations.
This command will fail if the peer SCP is unreachable or rejects the association request for the given AE titles.
Reference: https://www.dicomstandard.org/standards/view/message-exchange#sect_9.1.5
Usage
$ dicom-echo [OPTIONS] HOST
Arguments
HOST[required]: The socket address of the peer SCP: {host}:{port}Optionally, the AE title may be included: {AE title}@{host}:{port}
Options
-aec, --called, --called-ae-title TEXT: peer AE title of the host SCP [default:ANY-SCP]-aet, --calling, --calling-ae-title TEXT: the AE title of this client [default:ECHOSCU]-id, --id, --message-id INTEGER: the message ID to send [default:1]-V, --version: display the version of this program--install-completion: Install completion for the current shell.--show-completion: Show completion for the current shell, to copy it or customize the installation.--help: Show this message and exit.
1""".. include:: ./cli.md""" # noqa: D415 2 3from __future__ import annotations 4 5import logging 6import sys 7from pathlib import Path 8 9import rich 10import typer 11 12import dicom_echo as echo 13 14try: 15 import typing as t 16 17 _ = t.Annotated, t.TypeAlias # type: ignore[attr-defined] 18except AttributeError: # pragma: no cover 19 # note: for supporting Python 3.8 20 import typing_extensions as t # type: ignore[no-redef] 21 22__all__ = ['main', 'version_callback'] 23 24logger = logging.getLogger(__name__) 25 26app = typer.Typer(context_settings={'help_option_names': ['-h', '--help']}, rich_markup_mode='rich') 27this = Path(sys.argv[0]).resolve() 28command = this.name if this.name != '__main__.py' else this.parent.name 29 30 31def version_callback(value: bool | None) -> None: 32 """Print the version of this program.""" 33 if not value: 34 return 35 36 rich.print(f'[bold bright_black]{command}[/bold bright_black] {echo.__version__}') 37 raise typer.Exit() 38 39 40AEC: t.TypeAlias = t.Annotated[ 41 str, 42 typer.Option( 43 '-aec', '--called', '--called-ae-title', rich_help_panel='DICOM Options', help='peer AE title of the host SCP' 44 ), 45] 46 47AET: t.TypeAlias = t.Annotated[ 48 str, 49 typer.Option( 50 '-aet', '--calling', '--calling-ae-title', rich_help_panel='DICOM Options', help='the AE title of this client' 51 ), 52] 53 54ID: t.TypeAlias = t.Annotated[ 55 int, typer.Option('-id', '--id', '--message-id', rich_help_panel='DICOM Options', help='the message ID to send') 56] 57 58VER: t.TypeAlias = t.Annotated[ 59 bool, 60 typer.Option( 61 '-V', 62 '--version', 63 callback=version_callback, 64 is_eager=True, 65 help='display the version of this program', 66 ), 67] 68 69BLUE_HOST_PURPLE_PORT = r'[blue]{host}[/blue]:[purple]{port}[/purple]' 70GREEN_AET_BLUE_HOST_PURPLE_PORT = r'[green]{AE title}[/green]@' + BLUE_HOST_PURPLE_PORT 71HOST_OPTION_HELP = f"""The socket address of the peer SCP: {BLUE_HOST_PURPLE_PORT} 72 73 Optionally, the AE title may be included: {GREEN_AET_BLUE_HOST_PURPLE_PORT} 74""" 75 76 77@app.command() 78def main( 79 host: t.Annotated[str, typer.Argument(show_default=False, help=HOST_OPTION_HELP)], 80 called_ae_title: AEC = echo.DEFAULT_CALLED_AE_TITLE, 81 calling_ae_title: AET = echo.DEFAULT_CALLING_AE_TITLE, 82 message_id: ID = 1, 83 version: VER = False, 84) -> None: 85 """Send a `C-ECHO` request to the given address. 86 87 The `C-ECHO` procedure functions like a `ping`, serving to test that the peer SCP is accepting associations. 88 89 This command will fail if the peer SCP is unreachable or rejects the association request for the given AE titles. 90 91 Reference: https://www.dicomstandard.org/standards/view/message-exchange#sect_9.1.5 92 """ 93 if '@' in host and called_ae_title == echo.DEFAULT_CALLED_AE_TITLE: 94 called_ae_title, _ = host.split('@') 95 96 if rc := echo.send(host, called_ae_title, calling_ae_title, message_id): 97 rich.print(f':warning: [orange]Warning[/orange]: received non-zero status code: {rc}') 98 raise typer.Exit(rc) 99 100 rich.print(':white_check_mark: [green]Success[/green]') 101 102 103logger.debug('successfully imported %s', __name__)
78@app.command() 79def main( 80 host: t.Annotated[str, typer.Argument(show_default=False, help=HOST_OPTION_HELP)], 81 called_ae_title: AEC = echo.DEFAULT_CALLED_AE_TITLE, 82 calling_ae_title: AET = echo.DEFAULT_CALLING_AE_TITLE, 83 message_id: ID = 1, 84 version: VER = False, 85) -> None: 86 """Send a `C-ECHO` request to the given address. 87 88 The `C-ECHO` procedure functions like a `ping`, serving to test that the peer SCP is accepting associations. 89 90 This command will fail if the peer SCP is unreachable or rejects the association request for the given AE titles. 91 92 Reference: https://www.dicomstandard.org/standards/view/message-exchange#sect_9.1.5 93 """ 94 if '@' in host and called_ae_title == echo.DEFAULT_CALLED_AE_TITLE: 95 called_ae_title, _ = host.split('@') 96 97 if rc := echo.send(host, called_ae_title, calling_ae_title, message_id): 98 rich.print(f':warning: [orange]Warning[/orange]: received non-zero status code: {rc}') 99 raise typer.Exit(rc) 100 101 rich.print(':white_check_mark: [green]Success[/green]')
Send a C-ECHO request to the given address.
The C-ECHO procedure functions like a ping, serving to test that the peer SCP is accepting associations.
This command will fail if the peer SCP is unreachable or rejects the association request for the given AE titles.
Reference: https://www.dicomstandard.org/standards/view/message-exchange#sect_9.1.5
32def version_callback(value: bool | None) -> None: 33 """Print the version of this program.""" 34 if not value: 35 return 36 37 rich.print(f'[bold bright_black]{command}[/bold bright_black] {echo.__version__}') 38 raise typer.Exit()
Print the version of this program.