3grepros library interface. 
    7- {@link grepros.inputs.AppSource AppSource}: produces messages from iterable or pushed data 
    8- {@link grepros.inputs.BagSource BagSource}: produces messages from ROS bagfiles 
    9- {@link grepros.inputs.LiveSource LiveSource}: produces messages from live ROS topics 
   13- {@link grepros.outputs.AppSink AppSink}: provides messages to callback function 
   14- {@link grepros.outputs.BagSink BagSink}: writes messages to bagfile 
   15- {@link grepros.outputs.ConsoleSink ConsoleSink}: prints messages to console 
   16- {@link grepros.plugins.auto.csv.CsvSink CsvSink}: writes messages to CSV files, each topic to a separate file 
   17- {@link grepros.plugins.auto.html.HtmlSink HtmlSink}: writes messages to an HTML file 
   18- {@link grepros.outputs.LiveSink LiveSink}: publishes messages to ROS topics 
   19- {@link grepros.plugins.mcap.McapSink McapSink}: writes messages to MCAP file 
   20- {@link grepros.outputs.MultiSink MultiSink}: combines any number of sinks 
   21- {@link grepros.plugins.parquet.ParquetSink ParquetSink}: writes messages to Apache Parquet files 
   22- {@link grepros.plugins.auto.postgres.PostgresSink PostgresSink}: writes messages to a Postgres database 
   23- {@link grepros.plugins.auto.sqlite.SqliteSink SqliteSink}: writes messages to an SQLite database 
   24- {@link grepros.plugins.sql.SqlSink SqlSink}: writes SQL schema file for message type tables and topic views 
   26{@link grepros.api.BaseBag Bag}: generic bag interface. 
   27{@link grepros.search.Scanner Scanner}: ROS message grepper. 
   29Format-specific bag classes: 
   31- {@link grepros.ros1.ROS1Bag ROS1Bag}: ROS1 bag reader and writer in .bag format 
   32- {@link grepros.ros2.ROS2Bag ROS2Bag}: ROS2 bag reader and writer in .db3 SQLite format 
   33- {@link grepros.plugins.embag.EmbagReader EmbagReader}: ROS1 bag reader 
   34  using the <a href="https://github.com/embarktrucks/embag">embag</a> library
 
   37Output sink `write_options` arguments can be given 
with underscores
 
   38instead of dashes, e.g. `
"rollover_size"` instead of `
"rollover-size"`.
 
   40------------------------------------------------------------------------------
 
   41This file 
is part of grepros - grep 
for ROS bag files 
and live topics.
 
   42Released under the BSD License.
 
   47------------------------------------------------------------------------------
 
   49## @namespace grepros.library 
   50from . plugins.auto.csv      import CsvSink
 
   51from . plugins.auto.html     
import HtmlSink
 
   52from . plugins.auto.postgres 
import PostgresSink
 
   53from . plugins.auto.sqlite   
import SqliteSink
 
   54from . plugins.mcap          
import McapBag, McapSink
 
   55from . plugins.parquet       
import ParquetSink
 
   56from . plugins.sql           
import SqlSink
 
   59from . inputs  
import AppSource, BagSource, LiveSource, Source
 
   60from . outputs 
import AppSink, BagSink, ConsoleSink, LiveSink, MultiSink, Sink
 
   61from . search  
import BooleanResult, ExpressionTree, Scanner
 
   70def grep(args=None, **kwargs):
 
   72    Yields matching messages from specified source.
 
   74    Initializes grepros 
if not already initialized.
 
   76    Read 
from bagfiles: `
grep(file=
"2022-10-*.bag", pattern=
"cpu")`.
 
   78    Read 
from live topics: `
grep(live=
True, pattern=
"cpu")`.
 
   81    @param   args                      arguments 
as namespace 
or dictionary, case-insensitive;
 
   82                                       or a single path 
as the ROS bagfile to read,
 
   85    @param   kwargs                    any 
and all arguments 
as keyword overrides, case-insensitive
 
   89    @param   args.file                 names of ROS bagfiles to read 
if not all 
in directory
 
   90    @param   args.path                 paths to scan 
if not current directory
 
   91    @param   args.recurse              recurse into subdirectories when looking 
for bagfiles
 
   92    @param   args.decompress           decompress archived bags to file directory
 
   93    @param   args.reindex              make a copy of unindexed bags 
and reindex them (ROS1 only)
 
   94    @param   args.orderby              
"topic" or "type" if any to group results by
 
   95    @param   args.timescale            emit messages on original timeline 
from first message
 
   96                                       at given rate, 0 disables
 
   97    @param   args.timescale_emission   start timeline 
from first matched message 
not first 
in bag
 
  102    @param   args.live                 whether reading messages 
from live ROS topics
 
  103    @param   args.queue_size_in        subscriber queue size (default 10)
 
  104    @param   args.ros_time_in          stamp messages 
with ROS time instead of wall time
 
  108    @param   args.app                  whether reading messages 
from iterable 
or pushed data;
 
  109                                       may contain the iterable itself
 
  110    @param   args.iterable             iterable yielding (topic, msg, stamp) 
or (topic, msg);
 
  111                                       yielding `
None` signals end of content
 
  113    @param   args.topic                ROS topics to read 
if not all
 
  114    @param   args.type                 ROS message types to read 
if not all
 
  115    @param   args.skip_topic           ROS topics to skip
 
  116    @param   args.skip_type            ROS message types to skip
 
  117    @param   args.start_time           earliest timestamp of messages to read
 
  118    @param   args.end_time             latest timestamp of messages to read
 
  119    @param   args.start_index          message index within topic to start 
from 
  120    @param   args.end_index            message index within topic to stop at
 
  122    @param   args.nth_message          read every Nth message 
in topic, starting 
from first
 
  123    @param   args.nth_interval         minimum time interval between messages 
in topic,
 
  124                                       as seconds 
or ROS duration
 
  126    @param   args.select_field         message fields to use 
in matching 
if not all
 
  127    @param   args.noselect_field       message fields to skip 
in matching
 
  129    @param   args.unique               emit messages that are unique 
in topic
 
  130                                       (select_field 
and noselect_field apply 
if specified)
 
  131    @param   args.condition            Python expressions that must evaluate 
as true
 
  132                                       for message to be processable, see ConditionMixin
 
  136    @param   args.pattern              pattern(s) to find 
in message field values
 
  137    @param   args.fixed_string         pattern contains ordinary strings, 
not regular expressions
 
  138    @param   args.case                 use case-sensitive matching 
in pattern
 
  139    @param   args.invert               select messages 
not matching pattern
 
  140    @param   args.expression           pattern(s) are a logical expression
 
  141                                       like 
'this AND (this2 OR NOT "skip this")',
 
  142                                       with elements 
as patterns to find 
in message fields
 
  144    @param   args.nth_match            emit every Nth match 
in topic, starting 
from first
 
  145    @param   args.max_count            number of matched messages to emit (per file 
if bag input)
 
  146    @param   args.max_per_topic        number of matched messages to emit 
from each topic
 
  147    @param   args.max_topics           number of topics to 
print matches 
from 
  149    @param   args.before               number of messages of leading context to emit before match
 
  150    @param   args.after                number of messages of trailing context to emit after match
 
  151    @param   args.context              number of messages of leading 
and trailing context
 
  154    @param   args.highlight            highlight matched values
 
  155    @param   args.match_wrapper        string to wrap around matched values,
 
  156                                       both sides 
if one value, start 
and end 
if more than one,
 
  157                                       or no wrapping 
if zero values
 
  159    @return  {
@link grepros.Scanner.GrepMessage GrepMessage} namedtuples
 
  160             of (topic, message, timestamp, match, index)
 
  162    DEFAULT_ARGS = dict(FILE=[], LIVE=False, APP=
False, ITERABLE=
None,
 
  163                        COLOR=
"never", HIGHLIGHT=
False)
 
  166    is_bag = isinstance(args, Bag) 
or \
 
  167             common.is_iterable(args) 
and all(isinstance(x, Bag) 
for x 
in args)
 
  168    args = {
"FILE": str(args)} 
if isinstance(args, common.PATH_TYPES) 
else \
 
  169           {} 
if is_bag 
or isinstance(args, Source) 
else args
 
  170    args = common.ArgumentUtil.validate(common.ensure_namespace(args, DEFAULT_ARGS, **kwargs))
 
  171    if not _inited: 
init(args)
 
  173    if common.is_iterable(args.APP) 
and not common.is_iterable(args.ITERABLE):
 
  174        args.APP, args.ITERABLE = 
True, args.APP
 
  175    src = args0 
if isinstance(args0, Source) 
else \
 
  179    if args 
and isinstance(args0, Source): src.configure(**kwargs)
 
  183        for x 
in Scanner(args).find(src): 
yield x
 
  185        if not isinstance(args0, (Bag, Source)): src.close()
 
  188def source(args=None, **kwargs):
 
  192    Initializes grepros 
if not already initialized.
 
  194    @param   args                      arguments 
as namespace 
or dictionary, case-insensitive;
 
  195                                       or a single path 
as the ROS bagfile to read
 
  196    @param   kwargs                    any 
and all arguments 
as keyword overrides, case-insensitive
 
  197    @param   args.file                 one 
or more names of ROS bagfiles to read 
from 
  198    @param   args.live                 read messages 
from live ROS topics instead
 
  199    @param   args.app                  read messages 
from iterable 
or pushed data instead;
 
  200                                       may contain the iterable itself
 
  204    @param   args.file                 names of ROS bagfiles to read 
if not all 
in directory
 
  205    @param   args.path                 paths to scan 
if not current directory
 
  206    @param   args.recurse              recurse into subdirectories when looking 
for bagfiles
 
  207    @param   args.orderby              
"topic" or "type" if any to group results by
 
  208    @param   args.decompress           decompress archived bags to file directory
 
  209    @param   args.reindex              make a copy of unindexed bags 
and reindex them (ROS1 only)
 
  210    @param   args.timescale            emit messages on original timeline 
from first message
 
  211                                       at given rate, 0 disables
 
  212    @param   args.timescale_emission   start timeline 
from first matched message 
not first 
in bag
 
  213    @param   args.progress             whether to 
print progress bar
 
  217    @param   args.queue_size_in        subscriber queue size (default 10)
 
  218    @param   args.ros_time_in          stamp messages 
with ROS time instead of wall time
 
  219    @param   args.progress             whether to 
print progress bar
 
  223    @param   args.iterable             iterable yielding (topic, msg, stamp) 
or (topic, msg);
 
  224                                       yielding `
None` signals end of content
 
  228    @param   args.topic                ROS topics to read 
if not all
 
  229    @param   args.type                 ROS message types to read 
if not all
 
  230    @param   args.skip_topic           ROS topics to skip
 
  231    @param   args.skip_type            ROS message types to skip
 
  232    @param   args.start_time           earliest timestamp of messages to read
 
  233    @param   args.end_time             latest timestamp of messages to read
 
  234    @param   args.start_index          message index within topic to start 
from 
  235    @param   args.end_index            message index within topic to stop at
 
  236    @param   args.unique               emit messages that are unique 
in topic
 
  237    @param   args.select_field         message fields to use 
for uniqueness 
if not all
 
  238    @param   args.noselect_field       message fields to skip 
for uniqueness
 
  239    @param   args.nth_message          read every Nth message 
in topic, starting 
from first
 
  240    @param   args.nth_interval         minimum time interval between messages 
in topic,
 
  241                                       as seconds 
or ROS duration
 
  242    @param   args.condition            Python expressions that must evaluate 
as true
 
  243                                       for message to be processable, see ConditionMixin
 
  245    DEFAULT_ARGS = dict(FILE=[], LIVE=False, APP=
False, ITERABLE=
None)
 
  246    args = {
"FILE": str(args)} 
if isinstance(args, common.PATH_TYPES) 
else args
 
  247    args = common.ensure_namespace(args, DEFAULT_ARGS, **kwargs)
 
  248    if not _inited: 
init(args)
 
  250    if common.is_iterable(args.APP) 
and not common.is_iterable(args.ITERABLE):
 
  251        args.APP, args.ITERABLE = 
True, args.APP
 
  252    result = (LiveSource 
if args.LIVE 
else AppSource 
if args.APP 
else BagSource)(args)
 
  257def sink(args=None, **kwargs):
 
  262    Initializes grepros 
if not already initialized.
 
  264    @param   args                       arguments 
as namespace 
or dictionary, case-insensitive;
 
  265                                        or a single item 
as sink target like bag filename
 
  266    @param   kwargs                     any 
and all arguments 
as keyword overrides, case-insensitive
 
  267    @param   args.app                   provide messages to given callback function
 
  268    @param   args.console               
print matches to console
 
  269    @param   args.publish               publish matches to live topics
 
  270    @param   args.write                 file 
or other target like Postgres database to write,
 
  271                                        as "target", 
or [
"target", dict(format=
"format", ..)]
 
  272                                        or [[..target1..], [..target2..], ..]
 
  273    @param   args.write_options         format-specific options like
 
  274                                        {
"overwrite": whether to overwrite existing file
 
  279    @param   args.line_prefix           
print source prefix like bag filename on each message line
 
  280    @param   args.max_field_lines       maximum number of lines to 
print per field
 
  281    @param   args.start_line            message line number to start output 
from 
  282    @param   args.end_line              message line number to stop output at
 
  283    @param   args.max_message_lines     maximum number of lines to output per message
 
  284    @param   args.lines_around_match    number of message lines around matched fields to output
 
  285    @param   args.matched_fields_only   output only the fields where match was found
 
  286    @param   args.wrap_width            character width to wrap message YAML output at
 
  287    @param   args.match_wrapper         string to wrap around matched values,
 
  288                                        both sides 
if one value, start 
and end 
if more than one,
 
  289                                        or no wrapping 
if zero values
 
  293    @param   args.color                 
False or "never" for not using colors 
in replacements
 
  294    @param   args.highlight             highlight matched values (default true)
 
  295    @param   args.emit_field            message fields to emit 
if not all
 
  296    @param   args.noemit_field          message fields to skip 
in output
 
  297    @param   args.max_field_lines       maximum number of lines to output per field
 
  298    @param   args.start_line            message line number to start output 
from 
  299    @param   args.end_line              message line number to stop output at
 
  300    @param   args.max_message_lines     maximum number of lines to output per message
 
  301    @param   args.lines_around_match    number of message lines around matched fields to output
 
  302    @param   args.matched_fields_only   output only the fields where match was found
 
  303    @param   args.wrap_width            character width to wrap message YAML output at
 
  304    @param   args.match_wrapper         string to wrap around matched values,
 
  305                                        both sides 
if one value, start 
and end 
if more than one,
 
  306                                        or no wrapping 
if zero values
 
  310    @param   args.queue_size_out        publisher queue size (default 10)
 
  311    @param   args.publish_prefix        output topic prefix, prepended to input topic
 
  312    @param   args.publish_suffix        output topic suffix, appended to output topic
 
  313    @param   args.publish_fixname       single output topic name to publish to,
 
  314                                        overrides prefix 
and suffix 
if given
 
  318    @param   args.emit                  callback(topic, msg, stamp, highlighted msg, index 
in topic)
 
  320    @param   args.metaemit              callback(metadata dict) 
if any,
 
  321                                        invoked before first emit 
from source batch
 
  325    @param   args.meta                  whether to 
print metainfo
 
  326    @param   args.verbose               whether to 
print debug information
 
  328    DEFAULT_ARGS = dict(CONSOLE=False, PUBLISH=
False, WRITE=[], APP=
False, EMIT=
None, METAEMIT=
None)
 
  331    args = {
"WRITE": str(args)} 
if isinstance(args, common.PATH_TYPES) 
else args
 
  332    args = common.ensure_namespace(args, DEFAULT_ARGS, **kwargs)
 
  333    if not _inited: 
init(args)
 
  336        if isinstance(args.WRITE, common.PATH_TYPES):
 
  337            args.WRITE = [[args.WRITE]]  
 
  338        elif isinstance(args.WRITE, (list, tuple)) 
and isinstance(args.WRITE[0], common.PATH_TYPES):
 
  339            args.WRITE = [args.WRITE]  
 
  340    if callable(args.APP) 
and not callable(args.EMIT): args.APP, args.EMIT = 
True, args.APP
 
  344    result = multisink.sinks[0] 
if len(multisink.sinks) == 1 
else multisink
 
  348def init(args=None, **kwargs):
 
  350    Initializes ROS version bindings, loads all built-in plugins 
if dependencies available.
 
  353    @param   args.plugin   one 
or more extra plugins to load,
 
  354                           as full names 
or instances of Python module/
class 
  355    @param   kwargs        any 
and all arguments 
as keyword overrides, case-insensitive
 
  358    args = common.ensure_namespace(args, {
"PLUGIN": []}, **kwargs)
 
  360        if args: plugins.configure(args)
 
  363    common.ConsolePrinter.configure(color=
None, apimode=
True)
 
  366    for x 
in (plugins.mcap, plugins.parquet, plugins.sql):
 
  367        try: plugins.configure(PLUGIN=x)
 
  368        except Exception: 
pass 
  369    Bag.READER_CLASSES.add(McapBag)  
 
  370    Bag.WRITER_CLASSES.add(McapBag)  
 
  371    if args.PLUGIN: plugins.configure(args)
 
  373    api.TypeMeta.LIFETIME, api.TypeMeta.POPULATION = 0, 100
 
  379    "AppSink", 
"AppSource", 
"Bag", 
"BagSink", 
"BagSource", 
"BooleanResult", 
"ConsoleSink",
 
  380    "CsvSink", 
"ExpressionTree", 
"HtmlSink", 
"LiveSink", 
"LiveSource", 
"McapBag", 
"McapSink",
 
  381    "MultiSink", 
"ParquetSink", 
"PostgresSink", 
"Scanner", 
"Sink", 
"Source", 
"SqliteSink",
 
  382    "SqlSink", 
"grep", 
"init", 
"sink", 
"source",
 
Combines any number of sinks.
 
MCAP bag interface, providing most of rosbag.Bag interface.
 
source(args=None, **kwargs)
Convenience for creating a Source instance from arguments.
 
sink(args=None, **kwargs)
Convenience for creating a Sink instance from arguments, MultiSink if several outputs.
 
init(args=None, **kwargs)
Initializes ROS version bindings, loads all built-in plugins if dependencies available.
 
grep(args=None, **kwargs)
Yields matching messages from specified source.