def test_shutdown(self): """Test trying to shutdown a socket that's already closed.""" ae = AE() ae.add_supported_context('1.2.840.10008.1.1') server = ae.start_server(('', 11112), block=False) server.socket.close() server.shutdown()
class SCP: def __init__(self, host: str, port: int, ae_title: str): self.address = (host, port) self.ae = AE(ae_title=ae_title) self.create_context() self.handlers: List[Tuple] = [] def create_context(self) -> None: for storage_class in list(_STORAGE_CLASSES.values()) + list( _VERIFICATION_CLASSES.values()): self.ae.add_supported_context( abstract_syntax=storage_class, transfer_syntax=ALL_TRANSFER_SYNTAXES, ) def add_handler(self, event_type: InterventionEvent, func: Callable, args: Tuple) -> None: handler = (event_type, func, args) self.handlers.append(handler) def start(self, block: bool = True) -> None: self.ae.start_server( address=self.address, block=block, evt_handlers=self.handlers, ) def stop(self) -> None: self.ae.shutdown()
class DummyVerificationSCP(DummyBaseSCP): """A threaded dummy verification SCP used for testing""" def __init__(self, port=11112): self.ae = AE() self.port = port self.ae.supported_contexts = VerificationPresentationContexts self.ae.add_supported_context('1.2.3.4') DummyBaseSCP.__init__(self) self.status = 0x0000 def on_c_echo(self, context, info): """Callback for ae.on_c_echo Parameters ---------- delay : int or float Wait `delay` seconds before sending a response """ self.context = context self.info = info time.sleep(self.delay) if self.send_abort: self.ae.active_associations[0].abort() return self.status
class DummyStorageSCP(threading.Thread): def __init__(self, port=11112): """Initialise the class""" self.ae = AE(b'DUMMY_SCP', port) self.ae.add_supported_context(CTImageStorage) self.ae.add_supported_context(RTImageStorage) #self.ae.on_c_echo = self.on_c_echo self.ae.on_c_store = self.on_c_store #self.ae.on_c_find = self.on_c_find #self.ae.on_c_get = self.on_c_get #self.ae.on_c_move = self.on_c_move threading.Thread.__init__(self) self.daemon = True self.RECEIVED_DS = 0 def run(self): """The thread run method""" self.ae.start() def start(self): """The thread run method""" self.ae.start() def stop(self): """Stop the SCP thread""" self.ae.stop() def on_c_store(self, ds, context, info): """Callback for ae.on_c_store""" return 0x0000
def FnStoreScp(): # Implement a handler for evt.EVT_C_STORE def handle_store(event): """Handle a C-STORE request event.""" # Decode the C-STORE request's *Data Set* parameter to a pydicom Dataset ds = event.dataset # Add the File Meta Information ds.file_meta = event.file_meta # Save the dataset using the SOP Instance UID as the filename ds.save_as(ds.SOPInstanceUID, write_like_original=False) # Return a 'Success' status return 0x0000 handlers = [(evt.EVT_C_STORE, handle_store)] # Initialise the Application Entity ae = AE() # Support presentation contexts for all storage SOP Classes ae.add_supported_context('1.2.840.10008.5.1.4.1.1.2', transfer_syntax='1.2.840.10008.1.2.4.91') # Start listening for incoming association requests ae.start_server(('', 11112), evt_handlers=handlers)
def receive_store_simultaneous(test_ds, nr_assoc, ds_per_assoc, use_yappi=False): """Run a Storage SCP and transfer datasets with simultaneous storescu's. Parameters ---------- test_ds : pydicom.dataset.Dataset The test dataset to use nr_assoc : int The number of simultaneous associations that will be made. ds_per_assoc : int The number of C-STORE requests sent per successful association. use_yappi : bool, optional True to use the yappi profiler, False otherwise (default). """ if use_yappi: init_yappi() def handle(event): return 0x0000 ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.maximum_associations = 15 ae.add_supported_context(test_ds.SOPClassUID, ImplicitVRLittleEndian) server = ae.start_server( ("localhost", 11112), block=False, evt_handlers=[(evt.EVT_C_STORE, handle)] ) time.sleep(0.5) start_time = time.time() is_successful = True processes = [] for ii in range(nr_assoc): processes.append(start_storescu(test_ds, ds_per_assoc)) while None in [pp.poll() for pp in processes]: pass returncodes = list(set([pp.returncode for pp in processes])) if len(returncodes) != 1 or returncodes[0] != 0: is_successful = False if is_successful: print( f"C-STORE SCP transferred {nr_assoc * ds_per_assoc} total " f"{os.path.basename(test_ds.filename)} datasets over " f"{nr_assoc} association{'' if nr_assoc == 1 else 's'} " f"in {time.time() - start_time:.2f} s" ) else: print("C-STORE SCP benchmark failed") server.shutdown()
def receive_store_simultaneous(nr_assoc, ds_per_assoc, use_yappi=False): """Run a Storage SCP and transfer datasets with simultaneous storescu's. Parameters ---------- nr_assoc : int The number of simultaneous associations that will be made. ds_per_assoc : int The number of C-STORE requests sent per successful association. use_yappi : bool, optional True to use the yappi profiler, False otherwise (default). """ if use_yappi: init_yappi() def handle(event): return 0x0000 ae = AE() ae.acse_timeout = 5 ae.dimse_timeout = 5 ae.network_timeout = 5 ae.maximum_associations = 15 ae.add_supported_context(DATASET.SOPClassUID, ImplicitVRLittleEndian) server = ae.start_server( ('', 11112), block=False, evt_handlers=[(evt.EVT_C_STORE, handle)] ) time.sleep(0.5) start_time = time.time() run_times = [] is_successful = True processes = [] for ii in range(nr_assoc): processes.append(start_storescu(ds_per_assoc)) while None in [pp.poll() for pp in processes]: pass returncodes = list(set([pp.returncode for pp in processes])) if len(returncodes) != 1 or returncodes[0] != 0: is_successful = False if is_successful: print( "C-STORE SCP transferred {} total datasets over {} " "association(s) in {:.2f} s" .format(nr_assoc * ds_per_assoc, nr_assoc, time.time() - start_time) ) else: print("C-STORE SCP benchmark failed") server.shutdown()
def test_tls_not_server_yes_client(self, client_context): """Test wrapping the requestor socket with TLS (but not server).""" ae = AE() ae.add_supported_context('1.2.840.10008.1.1') server = ae.start_server(('', 11112), block=False) ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('', 11112, tls_args=(client_context, None)) assert assoc.is_aborted server.shutdown()
def create_application_entity(self, allow_echo: bool = True, maximum_pdu_size: int = 0) -> AE: """ Returns an :class:`~pynetdicom.ae.ApplicationEntity` instance. Parameters ---------- allow_echo : bool Whether to enable C-ECHO request handling or not, default is True maximum_pdu_size : int Maximal PDU size. By default, overrides pynetdicom's default setting to 0 (unlimited) Returns ------- AE DICOM networking application entity """ from django_dicom.models.networking import ( messages as networking_messages, ) logger = logging.getLogger("data.dicom.networking") # Get application entity title from the application settings and log # start. ae_title = get_application_entity_title() start_message = networking_messages.APPLICATION_ENTITY_START.format( title=ae_title) logger.info(start_message) # Create application entity instance. application_entity = AE(ae_title=ae_title) # Log end. end_message = networking_messages.APPLICATION_ENTITY_SUCCESS logger.info(end_message) # Add C-ECHO request handling if *allow_echo=True*. if allow_echo: application_entity.add_supported_context(VerificationSOPClass, ALL_TRANSFER_SYNTAXES[:]) logger.debug(networking_messages.C_ECHO_ENABLED) # Modify the maximal PDU size to optimize throughput. application_entity.maximum_pdu_size = maximum_pdu_size if maximum_pdu_size != 0: message = networking_messages.PDU_LIMIT_CONFIGURATION.format( maximum_pdu_size=maximum_pdu_size) logger.debug(message) return application_entity
def start(self): """ Start the server and listen to specified address and port """ ae = AE(self._server_config.ae_title) ae.add_supported_context(ModalityWorklistInformationFind) self._logger.info( 'Running worklist server with AE title {}, ip: {}, listening to port: {}' .format(self._server_config.ae_title, self._server_config.network_address.address, self._server_config.network_address.port)) self._server = ae.start_server(self._server_config.network_address, evt_handlers=self._handlers, block=self._blocking)
def test_tls_not_server_not_client(self): """Test associating with no TLS on either end.""" ae = AE() ae.add_supported_context('1.2.840.10008.1.1') server = ae.start_server(('', 11112), block=False) ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('', 11112) assert assoc.is_established assoc.release() assert assoc.is_released server.shutdown()
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print('storescp.py v{}'.format(__version__)) sys.exit() APP_LOGGER = setup_logging(args, 'storescp') APP_LOGGER.debug('storescp.py v{0!s}'.format(__version__)) APP_LOGGER.debug('') # Set Transfer Syntax options transfer_syntax = ALL_TRANSFER_SYNTAXES[:] if args.prefer_uncompr: transfer_syntax.remove(ImplicitVRLittleEndian) transfer_syntax.append(ImplicitVRLittleEndian) elif args.prefer_little: transfer_syntax.remove(ExplicitVRLittleEndian) transfer_syntax.insert(0, ExplicitVRLittleEndian) elif args.prefer_big: transfer_syntax.remove(ExplicitVRBigEndian) transfer_syntax.insert(0, ExplicitVRBigEndian) elif args.implicit: transfer_syntax = [ImplicitVRLittleEndian] handlers = [(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])] # Create application entity ae = AE(ae_title=args.ae_title) # Add presentation contexts with specified transfer syntaxes for context in AllStoragePresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) if not args.no_echo: for context in VerificationPresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) ae.maximum_pdu_size = args.max_pdu # Set timeouts ae.network_timeout = args.network_timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.start_server((args.bind_address, args.port), evt_handlers=handlers)
class ServiceClassProvider: def __init__(self, aet: str, config: ServiceClassProviderConfig) -> None: self.config = config self.address = ("127.0.0.1", config.port) self.ae = AE(ae_title=aet) self.ae.implementation_class_uid = config.implementation_class_uid self.ae.implementation_version_name = f'{aet}_{config.implementation_class_uid.split(".")[-1]}'[: 16] self.SUPPORTED_ABSTRACT_SYNTAXES: List[str] = [ _STORAGE_CLASSES.get('CTImageStorage'), _STORAGE_CLASSES.get('EnhancedCTImageStorage'), _STORAGE_CLASSES.get('LegacyConvertedEnhancedCTImageStorage') ] for abstract_syntax in self.SUPPORTED_ABSTRACT_SYNTAXES: self.ae.add_supported_context(abstract_syntax, ALL_TRANSFER_SYNTAXES) self.ae.add_supported_context( _VERIFICATION_CLASSES.get("VerificationSOPClass"), DEFAULT_TRANSFER_SYNTAXES) self.ae.require_calling_aet = ["PYNETDICOM"] def handle_c_store(self, event: Event) -> int: ds = event.dataset ds.file_meta = event.file_meta metadata: Dict[str, Optional[ParsedElementValue]] = { "CallingAET": cast(str, event.assoc.requestor.ae_title.strip()), "SopInstanceUID": safe_get(ds, 0x00080018), "StudyInstanceUID": safe_get(ds, 0x0020000D), "Modality": safe_get(ds, 0x00080060), } log_message_meta = " - ".join( [f"{k}={v}" for k, v in metadata.items() if v]) logger.info(f"Processed C-STORE {log_message_meta}") ds.save_as(metadata, write_like_original=False) return 0x0000 def start(self) -> None: logger.info( f"Starting DIMSE C-STORE AE on address={self.address} aet={self.ae.ae_title}" ) self.handlers = [(events.EVT_C_STORE, self.handle_c_store)] self.ae.start_server(self.address, block=True, evt_handlers=self.handlers)
def test_tls_yes_server_not_client(self, server_context): """Test wrapping the requestor socket with TLS (and server).""" ae = AE() ae.add_supported_context('1.2.840.10008.1.1') server = ae.start_server( ('', 11112), block=False, ssl_context=server_context, ) ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('', 11112) assert assoc.is_aborted server.shutdown()
class DicomSCP: def __init__(self): self.ae = AE() self.ae.ae_title = "BPPACS" self.ae.add_supported_context(OphthalmicPhotography8BitImageStorage, SYNTAX_UIDS) def start(self): self.ae.start_server(('', 11112), evt_handlers=[(evt.EVT_C_ECHO, self.handle_echo), (evt.EVT_C_STORE, self.handle_store)]) def handle_echo(self, event): log.info("Echo called") return 0x0000 def handle_store(self, event): log.info("Store received for patient %s" % event.dataset.PatientID) return 0x0000
def test_tls_yes_server_yes_client(self, server_context, client_context): """Test associating with no TLS on either end.""" ae = AE() ae.add_supported_context('1.2.840.10008.1.1') server = ae.start_server( ('', 11112), block=False, ssl_context=server_context, ) ae.add_requested_context('1.2.840.10008.1.1') assoc = ae.associate('', 11112, tls_args=(client_context, None)) assert assoc.is_established assoc.release() assert assoc.is_released server.shutdown()
class DummyDeleteSCP(DummyBaseSCP): """A threaded dummy delete SCP used for testing""" def __init__(self, port=11112): self.ae = AE(port=port) # Print Job SOP Class self.ae.add_supported_context(PrintJobSOPClass) self.ae.add_supported_context(VerificationSOPClass) DummyBaseSCP.__init__(self) self.status = 0x0000 def on_n_delete(self, context, info): """Callback for ae.on_n_delete""" self.context = context self.info = info time.sleep(self.delay) return self.status
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"echoscp.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "echoscp") APP_LOGGER.debug(f"echoscp.py v{__version__}") APP_LOGGER.debug("") # Set Transfer Syntax options transfer_syntax = ALL_TRANSFER_SYNTAXES[:] if args.prefer_uncompr: transfer_syntax.remove(str(ImplicitVRLittleEndian)) transfer_syntax.append(ImplicitVRLittleEndian) elif args.prefer_little: transfer_syntax.remove(str(ExplicitVRLittleEndian)) transfer_syntax.insert(0, ExplicitVRLittleEndian) elif args.prefer_big: transfer_syntax.remove(str(ExplicitVRBigEndian)) transfer_syntax.insert(0, ExplicitVRBigEndian) elif args.implicit: transfer_syntax = [ImplicitVRLittleEndian] handlers = [(evt.EVT_C_ECHO, handle_echo)] # Create application entity ae = AE(ae_title=args.ae_title) ae.add_supported_context(Verification, transfer_syntax) ae.maximum_pdu_size = args.max_pdu ae.network_timeout = args.network_timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.start_server((args.bind_address, args.port), evt_handlers=handlers)
class DummySetSCP(DummyBaseSCP): """A threaded dummy get SCP used for testing""" def __init__(self, port=11112): self.ae = AE(port=port) self.ae.add_supported_context(PrintJobSOPClass) self.ae.add_supported_context(VerificationSOPClass) DummyBaseSCP.__init__(self) self.status = 0x0000 ds = Dataset() ds.PatientName = 'Test' ds.SOPClassUID = PrintJobSOPClass ds.SOPInstanceUID = '1.2.3.4' self.dataset = ds def on_n_set(self, ds, context, info): """Callback for ae.on_n_get""" self.context = context self.info = info time.sleep(self.delay) return self.status, self.dataset
class ServiceClassProvider: def __init__(self, aet: str, config: ServiceClassProviderConfig) -> None: self.config = config self.address = ("0.0.0.0", config.port) self.ae = AE(ae_title=aet) self.ae.implementation_class_uid = config.implementation_class_uid self.ae.implementation_version_name = f'{aet}_{config.implementation_class_uid.split(".")[-1]}'[:16] self.SUPPORTED_ABSTRACT_SYNTAXES: List[str] = [ sop_class.DigitalXRayImagePresentationStorage, sop_class.DigitalXRayImageProcessingStorage, sop_class.CTImageStorage, ] for abstract_syntax in self.SUPPORTED_ABSTRACT_SYNTAXES: self.ae.add_supported_context(abstract_syntax, ALL_TRANSFER_SYNTAXES) self.ae.add_supported_context(VerificationSOPClass, DEFAULT_TRANSFER_SYNTAXES) self.ae.require_calling_aet = ["SAMPLESCU"] def handle_c_store(self, event: Event) -> int: ds = event.dataset ds.file_meta = event.file_meta metadata: Dict[str, Optional[ParsedElementValue]] = { "CallingAET": cast(str, event.assoc.requestor.ae_title.strip()), "SopInstanceUID": safe_get(ds, 0x00080018), "StudyInstanceUID": safe_get(ds, 0x0020000D), "Modality": safe_get(ds, 0x00080060), } log_message_meta = " - ".join([f"{k}={v}" for k, v in metadata.items() if v]) logger.info(f"Processed C-STORE {log_message_meta}") return 0x0000 def start(self) -> None: logger.info(f"Starting DIMSE C-STORE AE on address={self.address} aet={self.ae.ae_title}") self.handlers = [(events.EVT_C_STORE, self.handle_c_store)] self.ae.start_server(self.address, block=True, evt_handlers=self.handlers)
def listen(self, recieved_callback, ae_title="PYNETDICOM"): self.recieved_callback = recieved_callback # Initialise the Application Entity and specify the listen port ae = AE(ae_title=ae_title) # Add the supported presentation context ae.add_supported_context(VerificationSOPClass) for context in StoragePresentationContexts: ae.add_supported_context(context.abstract_syntax) handlers = [ (evt.EVT_C_MOVE, self.on_c_store), (evt.EVT_C_STORE, self.on_c_store), (evt.EVT_C_ECHO, self.on_c_echo), (evt.EVT_ACCEPTED, self.on_association_accepted), (evt.EVT_RELEASED, self.on_association_released), ] # Start listening for incoming association requests ae.start_server(("", self.port), evt_handlers=handlers)
def main(): global inference_queue inference_queue = deque() global dicom_store dicom_store = {} # Parent folder to all storage requests os_helpers.make_directory(config.SCP_STORAGE_PATH) ae = AE() ae.network_timeout = None ae.acse_timeout = None ae.dimse_timeout = None ae.maximum_pdu_size = 0 ae.maximum_associations = 14 # Tested with 14 threads handlers = [ (evt.EVT_ACCEPTED, handle_accepted), (evt.EVT_C_STORE, handle_store), (evt.EVT_RELEASED, handle_release), ] storage_sop_classes = [ cx.abstract_syntax for cx in AllStoragePresentationContexts ] for uid in storage_sop_classes: ae.add_supported_context(uid, ALL_TRANSFER_SYNTAXES) ae.start_server((config.SCP_IP, config.SCP_PORT), block=False, evt_handlers=handlers) print_listening() inference_loop()
def main(): handlers = [(evt.EVT_C_STORE, handle_store), (evt.EVT_RELEASED, handle_release)] ae = AE() ae.network_timeout = None ae.acse_timeout = None ae.dimse_timeout = None ae.maximum_pdu_size = 0 ae.maximum_associations = 1 # TODO Handle more than one storage_sop_classes = [ cx.abstract_syntax for cx in AllStoragePresentationContexts ] for uid in storage_sop_classes: ae.add_supported_context(uid, ALL_TRANSFER_SYNTAXES) print("\nListening for association request on port:", config.SCP_PORT) ae.start_server((config.SCP_IP, config.SCP_PORT), block=True, evt_handlers=handlers)
class SCP: _handlers = [ (evt.EVT_REQUESTED, handle_association_request), (evt.EVT_RELEASED, handle_association_release), (evt.EVT_C_STORE, handle_store), ] def __init__(self, ae_title='PICOM_SCP', host='localhost', port=11112, debug=False): self.ae_title = ae_title self.host = host self.port = port self._ae = AE(ae_title) self._ae.supported_contexts = AllStoragePresentationContexts self._ae.add_supported_context(VerificationSOPClass) # if debug: # debug_logger() def start_server(self, blocking=False): msg = f"Starting DICOM SCP {self.ae_title} on port {self.port}" logger.info(msg) print(msg) self._ae.start_server((self.host, self.port), block=blocking, evt_handlers=self._handlers) def stop_server(self): self._ae.shutdown() def get_ae(self) -> AE: return self._ae
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"qrscp.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "qrscp") APP_LOGGER.debug(f"qrscp.py v{__version__}") APP_LOGGER.debug("") APP_LOGGER.debug("Using configuration from:") APP_LOGGER.debug(f" {args.config}") APP_LOGGER.debug("") config = ConfigParser() config.read(args.config) if args.ae_title: config["DEFAULT"]["ae_title"] = args.ae_title if args.port: config["DEFAULT"]["port"] = args.port if args.max_pdu: config["DEFAULT"]["max_pdu"] = args.max_pdu if args.acse_timeout: config["DEFAULT"]["acse_timeout"] = args.acse_timeout if args.dimse_timeout: config["DEFAULT"]["dimse_timeout"] = args.dimse_timeout if args.network_timeout: config["DEFAULT"]["network_timeout"] = args.network_timeout if args.bind_address: config["DEFAULT"]["bind_address"] = args.bind_address if args.database_location: config["DEFAULT"]["database_location"] = args.database_location if args.instance_location: config["DEFAULT"]["instance_location"] = args.instance_location # Log configuration settings _log_config(config, APP_LOGGER) app_config = config["DEFAULT"] dests = {} for ae_title in config.sections(): dest = config[ae_title] # Convert to bytes and validate the AE title ae_title = set_ae(ae_title, "ae_title", False, False) dests[ae_title] = (dest["address"], dest.getint("port")) # Use default or specified configuration file current_dir = os.path.abspath(os.path.dirname(__file__)) instance_dir = os.path.join(current_dir, app_config["instance_location"]) db_path = os.path.join(current_dir, app_config["database_location"]) # The path to the database db_path = f"sqlite:///{db_path}" db.create(db_path) # Clean up the database and storage directory if args.clean: response = input( "This will delete all instances from both the storage directory " "and the database. Are you sure you wish to continue? [yes/no]: ") if response != "yes": sys.exit() if clean(db_path, instance_dir, APP_LOGGER): sys.exit() else: sys.exit(1) # Try to create the instance storage directory os.makedirs(instance_dir, exist_ok=True) ae = AE(app_config["ae_title"]) ae.maximum_pdu_size = app_config.getint("max_pdu") ae.acse_timeout = app_config.getfloat("acse_timeout") ae.dimse_timeout = app_config.getfloat("dimse_timeout") ae.network_timeout = app_config.getfloat("network_timeout") ## Add supported presentation contexts # Verification SCP ae.add_supported_context(Verification, ALL_TRANSFER_SYNTAXES) # Storage SCP - support all transfer syntaxes for cx in AllStoragePresentationContexts: ae.add_supported_context(cx.abstract_syntax, ALL_TRANSFER_SYNTAXES, scp_role=True, scu_role=False) # Query/Retrieve SCP ae.add_supported_context(PatientRootQueryRetrieveInformationModelFind) ae.add_supported_context(PatientRootQueryRetrieveInformationModelMove) ae.add_supported_context(PatientRootQueryRetrieveInformationModelGet) ae.add_supported_context(StudyRootQueryRetrieveInformationModelFind) ae.add_supported_context(StudyRootQueryRetrieveInformationModelMove) ae.add_supported_context(StudyRootQueryRetrieveInformationModelGet) # Set our handler bindings handlers = [ (evt.EVT_C_ECHO, handle_echo, [args, APP_LOGGER]), (evt.EVT_C_FIND, handle_find, [db_path, args, APP_LOGGER]), (evt.EVT_C_GET, handle_get, [db_path, args, APP_LOGGER]), (evt.EVT_C_MOVE, handle_move, [dests, db_path, args, APP_LOGGER]), (evt.EVT_C_STORE, handle_store, [instance_dir, db_path, args, APP_LOGGER]), ] # Listen for incoming association requests ae.start_server((app_config["bind_address"], app_config.getint("port")), evt_handlers=handlers)
if ds.PatientName not in ['*', '', '?']: matching = [ inst for inst in instances if inst.PatientName == ds.PatientName ] for instance in matching: # Check if C-CANCEL has been received if event.is_cancelled: yield (0XFE00, None) return identifier = Dataset() identifier.PatientName = instance.PatientName identifier.QueryRetrieveLevel = ds.QueryRetrieveLevel # Pending yield (0XFF00, identifier) handlers = [(evt.EVT_C_FIND, handle_find)] # Initialise the Application Entity and specify the listen port ae = AE() # Add the supported presentation context ae.add_supported_context(PatientRootQueryRetrieveInformationModelFind) # Start listening for incoming association requests ae.start_server(('', 11112), evt_handlers=handlers)
except: dcm_files = [] yield 0 for dcm in dcm_files: ds = dcmread(dcm, force=True) yield 0xFF00, ds handlers = [(evt.EVT_C_GET, handle_get)] # Create application entity ae = AE(ae_title=args.aetitle) for context in StoragePresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax, scp_role=True, scu_role=False) for context in QueryRetrievePresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) ae.maximum_pdu_size = args.max_pdu # Set timeouts ae.network_timeout = args.timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.start_server(('', args.port), evt_handlers=handlers)
dcm_files = [os.path.join(basedir, x) for x in dcm_files] for dcm in dcm_files: data = dcmread(dcm, force=True) ds = Dataset() if 'QueryRetrieveLevel' in dataset: ds.QueryRetrieveLevel = dataset.QueryRetrieveLevel ds.RetrieveAETitle = args.aetitle ds.PatientName = data.PatientName status_ds = Dataset() status_ds.Status = 0xFF00 yield status_ds, ds # Create application entity ae = AE(ae_title=args.aetitle) for context in QueryRetrievePresentationContexts: ae.add_supported_context(context.abstract_syntax, transfer_syntax) ae.maximum_pdu_size = args.max_pdu # Set timeouts ae.network_timeout = args.timeout ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.on_c_find = on_c_find ae.start_server(('', args.port))
log = (f"{datetime.datetime.now():%Y-%m-%d|%H:%M:%S} " f"| {ds.AccessionNumber} " f"| {ds.SeriesDescription} \n") with open(logfile, 'a') as f: f.write(log) except Exception as e: with open(logfile, 'a') as f: f.write(traceback.format_exc()) return 0x0000 #get the storage path storage_dir = os.environ['storage'] logfile = os.environ['log'] aetitle = os.environ['aetitle'] aeport = int(os.environ['aeport']) handlers = [(evt.EVT_C_STORE, handle_store, [storage_dir])] # Initialise the Application Entity ae = AE(ae_title=bytes(aetitle, encoding='UTF-8')) # Add the supported presentation contexts ae.supported_contexts = StoragePresentationContexts ae.add_supported_context(VerificationSOPClass) ae.add_supported_context(MRImageStorage, JPEG2000Lossless) # Start listening for incoming association requests ae.start_server(('0.0.0.0', aeport), evt_handlers=handlers)
host = "192.168.8.177" port = "4242" arg0 = '-ds' #-ds all files under dir, '' single file arg1 = '-q' #--v verbose q quick, d debug arg2 = '-cx' #require context file = fname storescu.main([arg0, host, port, file, arg1, arg2]) print("file send!", file) os.remove(file) return 0x0000 handlers = [(evt.EVT_C_STORE, handle_store, ['out'])] #context_a = _build_context(CTImageStorage, JPEGLossless) #context_b = _build_context(CTImageStorage, JPEG2000Lossless) ae = AE() #ae.add_requested_context(context_a) #ae.add_requested_context(context_b) storage_sop_classes = [ cx.abstract_syntax for cx in AllStoragePresentationContexts ] + [JPEGLossless] + [JPEG2000Lossless] + [VerificationSOPClass] + [ CTImageStorage ] + [VerificationSOPClass] for uid in storage_sop_classes: ae.add_supported_context(uid, ALL_TRANSFER_SYNTAXES) n = 0 #ae.add_supported_context(CTImageStorage, VerificationSOPClass) ae.start_server(('', 11112), block=True, evt_handlers=handlers)