openrvdas.logger.transforms.format_transform
Sample config file for using for FormatTransform. To run, copy the config below to a file, say 's330_format.yaml', then run
logger/listener/listen.py --config_file s330_format.yaml
Sample config:
# Read from stored logfile
readers:
class: LogfileReader
kwargs:
filebase: test//NBP1406/s330/raw/NBP1406_s330-2014-08-01
# Logfile reader already has a timestamp, so we don't need to
# timestamp. Just add the instrument prefix and parse it.
transforms:
- class: PrefixTransform
kwargs:
prefix: s330
- class: ParseTransform
kwargs:
definition_path: local/usap/nbp/devices/nbp_devices.yaml
# Output a string showing course and speed. We only provide a default
# for course, so if course is missing, we will still output a string, but
# if speed is missing, we will output None instead of a string.
- class: FormatTransform
module: logger.transforms.format_transform # where the definition is
kwargs:
format_str: 'Course: {S330CourseTrue}, Speed: {S330SpeedKt}'
defaults: {'S330CourseTrue': '-'}
# Output to stdout
writers:
- class: TextFileWriter
1#!/usr/bin/env python3 2""" 3Sample config file for using for FormatTransform. To run, copy the config 4below to a file, say 's330_format.yaml', then run 5 6 logger/listener/listen.py --config_file s330_format.yaml 7 8Sample config: 9 10 # Read from stored logfile 11 readers: 12 class: LogfileReader 13 kwargs: 14 filebase: test//NBP1406/s330/raw/NBP1406_s330-2014-08-01 15 16 # Logfile reader already has a timestamp, so we don't need to 17 # timestamp. Just add the instrument prefix and parse it. 18 transforms: 19 - class: PrefixTransform 20 kwargs: 21 prefix: s330 22 - class: ParseTransform 23 kwargs: 24 definition_path: local/usap/nbp/devices/nbp_devices.yaml 25 26 # Output a string showing course and speed. We only provide a default 27 # for course, so if course is missing, we will still output a string, but 28 # if speed is missing, we will output None instead of a string. 29 - class: FormatTransform 30 module: logger.transforms.format_transform # where the definition is 31 kwargs: 32 format_str: 'Course: {S330CourseTrue}, Speed: {S330SpeedKt}' 33 defaults: {'S330CourseTrue': '-'} 34 35 # Output to stdout 36 writers: 37 - class: TextFileWriter 38""" 39 40from typing import Union 41 42from logger.utils.das_record import DASRecord # noqa: E402 43from logger.utils.timestamp import time_str # noqa: E402 44from logger.transforms.transform import Transform # noqa: E402 45 46 47################################################################################ 48class FormatTransform(Transform): 49 def __init__(self, format_str, defaults=None, use_iso_timestamp=False, **kwargs): 50 """ 51 Output a formatted string in which field values from a DASRecord or field 52 dict have been substituted. An optional default_dict may be provided to 53 indicate what value should be substituted in if the relevant record is 54 missing any of the requested values. 55 56 format_str - A format string, as described 57 https://www.w3schools.com/python/ref_string_format.asp 58 59 E.g. format_str='Course: {S330CourseTrue}, Speed: {S330SpeedKt}kt', 60 would output 'Course: 227.3, Speed 7.3kt' 61 62 63 default_dict - If omitted, transform will emit None if any of the fields 64 requested in the format string are missing. 65 66 If not None, should be a dict of field:value pairs 67 specifying the value that should be substituted in 68 for any missing fields. If a field:value pair is missing 69 from this dict, return None for the relevant record. 70 71 E.g. default_dict={'S330CourseTrue': '-'} would output 72 'Course: -, Speed 7.3kt' if S330CourseTrue were missing 73 from the input record, but would output None if S330SpeedKt 74 were missing (because no default was provided for 75 S330SpeedKt). 76 77 use_iso_timestamp - If True, ISO 8601 format timestamps when the {timestamp} 78 tag is present. Otherwise use Unix numerical timestamps. 79 """ 80 super().__init__(**kwargs) # processes 'quiet' and type hints 81 82 self.format_str = format_str 83 self.defaults = defaults or {} 84 self.use_uso_timestamp = use_iso_timestamp 85 86 def transform(self, record: Union[DASRecord, dict]) -> str: 87 # See if it's something we can process, and if not, try digesting 88 if not self.can_process_record(record): # BaseModule 89 return self.digest_record(record) # BaseModule 90 91 if type(record) is DASRecord: 92 record_fields = record.fields 93 elif type(record) is dict: 94 if 'fields' in record: 95 record_fields = record['fields'] 96 else: 97 record_fields = record 98 else: 99 return ('Record passed to FormatTransform was neither a dict nor a ' 100 'DASRecord. Type was %s: %s' % (type(record), str(record)[:80])) 101 102 fields = self.defaults.copy() 103 104 for field, value in record_fields.items(): 105 fields[field] = value 106 107 # Add the timestamp as a field as well. 108 if type(record) is DASRecord: 109 fields['timestamp'] = record.timestamp 110 else: 111 fields['timestamp'] = record.get('timestamp', 0) 112 113 # If we're supposed to be outputting USO 8601 timestamps, 114 # convert to appropriate format 115 if self.use_uso_timestamp: 116 fields['timestamp'] = time_str(fields['timestamp']) 117 118 try: 119 result = self.format_str.format(**fields) 120 121 except KeyError: 122 result = None 123 124 if result: 125 return result 126 return None
49class FormatTransform(Transform): 50 def __init__(self, format_str, defaults=None, use_iso_timestamp=False, **kwargs): 51 """ 52 Output a formatted string in which field values from a DASRecord or field 53 dict have been substituted. An optional default_dict may be provided to 54 indicate what value should be substituted in if the relevant record is 55 missing any of the requested values. 56 57 format_str - A format string, as described 58 https://www.w3schools.com/python/ref_string_format.asp 59 60 E.g. format_str='Course: {S330CourseTrue}, Speed: {S330SpeedKt}kt', 61 would output 'Course: 227.3, Speed 7.3kt' 62 63 64 default_dict - If omitted, transform will emit None if any of the fields 65 requested in the format string are missing. 66 67 If not None, should be a dict of field:value pairs 68 specifying the value that should be substituted in 69 for any missing fields. If a field:value pair is missing 70 from this dict, return None for the relevant record. 71 72 E.g. default_dict={'S330CourseTrue': '-'} would output 73 'Course: -, Speed 7.3kt' if S330CourseTrue were missing 74 from the input record, but would output None if S330SpeedKt 75 were missing (because no default was provided for 76 S330SpeedKt). 77 78 use_iso_timestamp - If True, ISO 8601 format timestamps when the {timestamp} 79 tag is present. Otherwise use Unix numerical timestamps. 80 """ 81 super().__init__(**kwargs) # processes 'quiet' and type hints 82 83 self.format_str = format_str 84 self.defaults = defaults or {} 85 self.use_uso_timestamp = use_iso_timestamp 86 87 def transform(self, record: Union[DASRecord, dict]) -> str: 88 # See if it's something we can process, and if not, try digesting 89 if not self.can_process_record(record): # BaseModule 90 return self.digest_record(record) # BaseModule 91 92 if type(record) is DASRecord: 93 record_fields = record.fields 94 elif type(record) is dict: 95 if 'fields' in record: 96 record_fields = record['fields'] 97 else: 98 record_fields = record 99 else: 100 return ('Record passed to FormatTransform was neither a dict nor a ' 101 'DASRecord. Type was %s: %s' % (type(record), str(record)[:80])) 102 103 fields = self.defaults.copy() 104 105 for field, value in record_fields.items(): 106 fields[field] = value 107 108 # Add the timestamp as a field as well. 109 if type(record) is DASRecord: 110 fields['timestamp'] = record.timestamp 111 else: 112 fields['timestamp'] = record.get('timestamp', 0) 113 114 # If we're supposed to be outputting USO 8601 timestamps, 115 # convert to appropriate format 116 if self.use_uso_timestamp: 117 fields['timestamp'] = time_str(fields['timestamp']) 118 119 try: 120 result = self.format_str.format(**fields) 121 122 except KeyError: 123 result = None 124 125 if result: 126 return result 127 return None
Base class Transform about which we know nothing else.
Passes arguments quiet, encoding and encoding_errors up to BaseModule
50 def __init__(self, format_str, defaults=None, use_iso_timestamp=False, **kwargs): 51 """ 52 Output a formatted string in which field values from a DASRecord or field 53 dict have been substituted. An optional default_dict may be provided to 54 indicate what value should be substituted in if the relevant record is 55 missing any of the requested values. 56 57 format_str - A format string, as described 58 https://www.w3schools.com/python/ref_string_format.asp 59 60 E.g. format_str='Course: {S330CourseTrue}, Speed: {S330SpeedKt}kt', 61 would output 'Course: 227.3, Speed 7.3kt' 62 63 64 default_dict - If omitted, transform will emit None if any of the fields 65 requested in the format string are missing. 66 67 If not None, should be a dict of field:value pairs 68 specifying the value that should be substituted in 69 for any missing fields. If a field:value pair is missing 70 from this dict, return None for the relevant record. 71 72 E.g. default_dict={'S330CourseTrue': '-'} would output 73 'Course: -, Speed 7.3kt' if S330CourseTrue were missing 74 from the input record, but would output None if S330SpeedKt 75 were missing (because no default was provided for 76 S330SpeedKt). 77 78 use_iso_timestamp - If True, ISO 8601 format timestamps when the {timestamp} 79 tag is present. Otherwise use Unix numerical timestamps. 80 """ 81 super().__init__(**kwargs) # processes 'quiet' and type hints 82 83 self.format_str = format_str 84 self.defaults = defaults or {} 85 self.use_uso_timestamp = use_iso_timestamp
Output a formatted string in which field values from a DASRecord or field dict have been substituted. An optional default_dict may be provided to indicate what value should be substituted in if the relevant record is missing any of the requested values.
format_str - A format string, as described https://www.w3schools.com/python/ref_string_format.asp
E.g. format_str='Course: {S330CourseTrue}, Speed: {S330SpeedKt}kt',
would output 'Course: 227.3, Speed 7.3kt'
default_dict - If omitted, transform will emit None if any of the fields requested in the format string are missing.
If not None, should be a dict of field:value pairs
specifying the value that should be substituted in
for any missing fields. If a field:value pair is missing
from this dict, return None for the relevant record.
E.g. default_dict={'S330CourseTrue': '-'} would output
'Course: -, Speed 7.3kt' if S330CourseTrue were missing
from the input record, but would output None if S330SpeedKt
were missing (because no default was provided for
S330SpeedKt).
use_iso_timestamp - If True, ISO 8601 format timestamps when the {timestamp} tag is present. Otherwise use Unix numerical timestamps.
87 def transform(self, record: Union[DASRecord, dict]) -> str: 88 # See if it's something we can process, and if not, try digesting 89 if not self.can_process_record(record): # BaseModule 90 return self.digest_record(record) # BaseModule 91 92 if type(record) is DASRecord: 93 record_fields = record.fields 94 elif type(record) is dict: 95 if 'fields' in record: 96 record_fields = record['fields'] 97 else: 98 record_fields = record 99 else: 100 return ('Record passed to FormatTransform was neither a dict nor a ' 101 'DASRecord. Type was %s: %s' % (type(record), str(record)[:80])) 102 103 fields = self.defaults.copy() 104 105 for field, value in record_fields.items(): 106 fields[field] = value 107 108 # Add the timestamp as a field as well. 109 if type(record) is DASRecord: 110 fields['timestamp'] = record.timestamp 111 else: 112 fields['timestamp'] = record.get('timestamp', 0) 113 114 # If we're supposed to be outputting USO 8601 timestamps, 115 # convert to appropriate format 116 if self.use_uso_timestamp: 117 fields['timestamp'] = time_str(fields['timestamp']) 118 119 try: 120 result = self.format_str.format(**fields) 121 122 except KeyError: 123 result = None 124 125 if result: 126 return result 127 return None