6. ASTM protocol implementation¶
6.1. astm.protocol
:: Common protocol routines¶
-
class
astm.protocol.
ASTMProtocol
(sock=None, map=None, timeout=None)¶ Common ASTM protocol routines.
-
dispatch
(data)¶ Dispatcher of received data.
-
on_ack
()¶ Calls on <ACK> message receiving.
-
on_enq
()¶ Calls on <ENQ> message receiving.
-
on_eot
()¶ Calls on <EOT> message receiving.
-
on_message
()¶ Calls on ASTM message receiving.
-
on_nak
()¶ Calls on <NAK> message receiving.
-
on_timeout
()¶ Calls when timeout event occurs. Used to limit waiting time for response data.
-
6.2. astm.server
:: ASTM Server¶
-
class
astm.server.
BaseRecordsDispatcher
(encoding=None)¶ Abstract dispatcher of received ASTM records by
RequestHandler
. You need to override his handlers or extend dispatcher for your needs. For instance:class Dispatcher(BaseRecordsDispatcher): def __init__(self, encoding=None): super(Dispatcher, self).__init__(encoding) # extend it for your needs self.dispatch['M'] = self.my_handler # map custom wrappers for ASTM records to their type if you # don't like to work with raw data. self.wrapper['M'] = MyWrapper def on_header(self, record): # initialize state for this session ... def on_patient(self, record): # handle patient info ... # etc handlers def my_handler(self, record): # handle custom record that wasn't implemented yet by # python-astm due to some reasons ...
After defining our dispatcher, we left only to let
Server
use it:server = Server(dispatcher=Dispatcher)
-
on_comment
(record)¶ Comment record handler.
-
on_header
(record)¶ Header record handler.
-
on_order
(record)¶ Order record handler.
-
on_patient
(record)¶ Patient record handler.
-
on_result
(record)¶ Result record handler.
-
on_terminator
(record)¶ Terminator record handler.
-
on_unknown
(record)¶ Fallback handler for dispatcher.
-
-
class
astm.server.
RequestHandler
(sock, dispatcher, timeout=None)¶ ASTM protocol request handler.
Parameters: - sock – Socket object.
- dispatcher (
BaseRecordsDispatcher
) – Request handler records dispatcher instance. - timeout (int) – Number of seconds to wait for incoming data before connection closing.
-
on_timeout
()¶ Closes connection on timeout.
-
class
astm.server.
Server
(host='localhost', port=15200, request=None, dispatcher=None, timeout=None, encoding=None)¶ Asyncore driven ASTM server.
Parameters: - host (str) – Server IP address or hostname.
- port (int) – Server port number.
- request – Custom server request handler. If omitted the
RequestHandler
will be used by default. - dispatcher – Custom request handler records dispatcher. If omitted the
BaseRecordsDispatcher
will be used by default. - timeout (int) –
RequestHandler
connection timeout. IfNone
request handler will wait for data before connection closing. - encoding (str) –
Dispatcher
‘s encoding.
-
dispatcher
¶ alias of
BaseRecordsDispatcher
-
request
¶ alias of
RequestHandler
-
serve_forever
(*args, **kwargs)¶ Enters into the
polling loop
to let server handle incoming requests.
6.3. astm.client
:: ASTM Client¶
-
class
astm.client.
Client
(emitter, host='localhost', port=15200, encoding=None, timeout=20, flow_map={'C': ['*'], None: ['H'], 'H': ['C', 'P', 'L'], 'L': ['H'], 'O': ['C', 'P', 'O', 'R', 'L'], 'P': ['C', 'O', 'L'], 'R': ['C', 'P', 'O', 'R', 'L']}, chunk_size=None, bulk_mode=False)¶ Common ASTM client implementation.
Parameters: - emitter (function) – Generator function that will produce ASTM records.
- host (str) – Server IP address or hostname.
- port (int) – Server port number.
- timeout (int) – Time to wait for response from server. If response wasn’t
received, the
on_timeout()
will be called. IfNone
this timer will be disabled. - flow_map – Records flow map. Used by
RecordsStateMachine
. - chunk_size (int) – Chunk size in bytes.
None
value prevents records chunking. - bulk_mode (bool) – Sends all records for single session (starts from Header
and ends with Terminator records) via single message
instead of sending each record separately. If result
message is too long, it may be split by chunks if
chunk_size is not
None
. Keep in mind, that collecting all records for single session may take some time and server may reject data by timeout reason.
Type: dict
Base emitter is a generator that yield ASTM records one by one preserving their order:
from astm.records import ( HeaderRecord, PatientRecord, OrderRecord, TerminatorRecord ) def emitter(): assert (yield HeaderRecord()), 'header was rejected' ok = yield PatientRecord(name={'last': 'foo', 'first': 'bar'}) if ok: # you also can decide what to do in case of record rejection assert (yield OrderRecord()) yield TerminatorRecord() # we may do not care about rejection
Client
thoughtRecordsStateMachine
keep track on this order, raisingAssertionError
if it is broken.When emitter terminates with
StopIteration
orGeneratorExit
exception client connection to server closing too. You may provide endless emitter by wrapping function body withwhile True: ...
loop polling data from source from time to time. Note, that server may have communication timeouts control and may close session after some time of inactivity, so be sure that you’re able to send whole session (started by Header record and ended by Terminator one) within limited time frame (commonly 10-15 sec.).-
handle_connect
()¶ Initiates ASTM communication session.
-
on_ack
()¶ Handles ACK response from server.
Provides callback value
True
to the emitter and sends next message to server.
-
on_enq
()¶ Raises
NotAccepted
exception.
-
on_eot
()¶ Raises
NotAccepted
exception.
-
on_message
()¶ Raises
NotAccepted
exception.
-
on_nak
()¶ Handles NAK response from server.
If it was received on ENQ request, the client tries to repeat last request for allowed amount of attempts. For others it send callback value
False
to the emitter.
-
on_timeout
()¶ Sends final EOT message and closes connection after his receiving.
-
run
(timeout=1.0, *args, **kwargs)¶ Enters into the
polling loop
to let client send outgoing requests.
-
class
astm.client.
Emitter
(emitter, flow_map, encoding, chunk_size=None, bulk_mode=False)¶ ASTM records emitter for
Client
.Used as wrapper for user provided one to provide proper routines around for sending Header and Terminator records.
Parameters: - emitter – Generator/coroutine.
- encoding (str) – Data encoding.
- flow_map – Records flow map. Used by
RecordsStateMachine
. - chunk_size (int) – Chunk size in bytes. If
None
, emitter record wouldn’t be split into chunks. - bulk_mode (bool) – Sends all records for single session (starts from Header
and ends with Terminator records) via single message
instead of sending each record separately. If result
message is too long, it may be split by chunks if
chunk_size is not
None
. Keep in mind, that collecting all records for single session may take some time and server may reject data by timeout reason.
Type: dict
-
send
(value=None)¶ Passes value to the emitter. Semantically acts in same way as
send()
for generators.If the emitter has any value within local buffer the returned value will be extracted from it unless value is
False
.Parameters: value (bool) – Callback value. True
indicates that previous record was successfully received and accepted by server,False
signs about his rejection.Returns: Next record data to send to server. Return type: bytes
-
state_machine
¶ alias of
RecordsStateMachine