def main(importer_class=None, args=None):
    """Entry point for import program.

    If the ``args`` are provided, these should be a list of strings that will
    be used instead of ``sys.argv[1:]``. This is mostly useful for testing.
    """
    parser = argparse.ArgumentParser(
        description='Import from external model formats')
    parser.add_argument('--source', metavar='path', default='.',
                        help='Source directory or file')
    parser.add_argument('--dest', metavar='path', default='.',
                        help='Destination directory (default is ".")')
    parser.add_argument('--no-exchange', action='store_true',
                        help=('Disable importing exchange reactions as'
                              ' exchange compound file.'))
    parser.add_argument('--split-subsystem', action='store_true',
                        help='Enable splitting reaction files by subsystem')
    parser.add_argument('--merge-compounds', action='store_true',
                        help=('Merge identical compounds occuring in various'
                              ' compartments.'))
    parser.add_argument('--force', action='store_true',
                        help='Enable overwriting model files')

    if importer_class is None:
        parser.add_argument(
            'format', help='Format to import ("list" to see all)')

    args = parser.parse_args(args)

    # Set up logging for the command line interface
    if 'PSAMM_DEBUG' in os.environ:
        level = getattr(logging, os.environ['PSAMM_DEBUG'].upper(), None)
        if level is not None:
            logging.basicConfig(level=level)
    else:
        logging.basicConfig(
            level=logging.INFO, format='%(levelname)s: %(message)s')

    if importer_class is None:
        # Discover all available model importers
        importers = {}
        for importer_entry in pkg_resources.iter_entry_points(
                'psamm.importer'):
            canonical = importer_entry.name.lower()
            if canonical not in importers:
                importers[canonical] = importer_entry
            else:
                logger.warning('Importer {} was found more than once!'.format(
                    importer_entry.name))

        # Print list of importers
        if args.format in ('list', 'help'):
            if len(importers) == 0:
                logger.error('No importers found!')
            else:
                importer_classes = []
                for name, entry in iteritems(importers):
                    importer_class = entry.load()
                    title = getattr(importer_class, 'title', None)
                    generic = getattr(importer_class, 'generic', False)
                    if title is not None:
                        importer_classes.append(
                            (title, generic, name, importer_class))

                print('Generic importers:')
                for title, _, name, importer_class in sorted(
                        c for c in importer_classes if c[1]):
                    print('{:<12}  {}'.format(name, title))

                print()
                print('Model-specific importers:')
                for title, _, name, importer_class in sorted(
                        c for c in importer_classes if not c[1]):
                    print('{:<12}  {}'.format(name, title))
            sys.exit(0)

        importer_name = args.format.lower()
        if importer_name not in importers:
            logger.error('Importer {} not found!'.format(importer_name))
            logger.info('Use "list" to see available importers.')
            sys.exit(-1)

        importer_class = importers[importer_name].load()

    importer = importer_class()

    try:
        model = importer.import_model(args.source)
    except ModelLoadError as e:
        logger.error('Failed to load model!', exc_info=True)
        importer.help()
        parser.error(text_type(e))
    except ParseError as e:
        logger.error('Failed to parse model!', exc_info=True)
        logger.error(text_type(e))
        sys.exit(-1)

    if args.merge_compounds:
        compounds_before = len(model.compounds)
        sbml.merge_equivalent_compounds(model)
        if len(model.compounds) < compounds_before:
            logger.info(
                'Merged {} compound entries into {} entries by'
                ' removing duplicates in various compartments'.format(
                    compounds_before, len(model.compounds)))

    print('Model: {}'.format(model.name))
    print('- Biomass reaction: {}'.format(model.biomass_reaction))
    print('- Compartments: {}'.format(len(model.compartments)))
    print('- Compounds: {}'.format(len(model.compounds)))
    print('- Reactions: {}'.format(len(model.reactions)))
    print('- Genes: {}'.format(count_genes(model)))

    # Check if dest directory is empty. If we get an error assume that the
    # directory does not exist.
    dest_is_empty = False
    try:
        dest_is_empty = len(os.listdir(args.dest)) == 0
    except OSError:
        dest_is_empty = True

    if not dest_is_empty:
        if not args.force:
            logger.error('Destination directory is not empty. Use --force'
                         ' option to proceed anyway, overwriting any existing'
                         ' files in {}'.format(args.dest))
            return 1
        else:
            logger.warning('Destination directory is not empty, overwriting'
                           ' existing files in {}'.format(args.dest))

    # Create destination directory if not exists
    dest = args.dest
    mkdir_p(dest)

    convert_exchange = not args.no_exchange
    write_yaml_model(model, dest, convert_exchange=convert_exchange,
                     split_subsystem=args.split_subsystem)
def main ( importer_class = None , args = None ) : parser = argparse . ArgumentParser ( description = 'Import from external model formats' ) parser . add_argument ( '--source' , metavar = 'path' , default = '.' , help = 'Source directory or file' ) parser . add_argument ( '--dest' , metavar = 'path' , default = '.' , help = 'Destination directory (default is ".")' ) parser . add_argument ( '--no-exchange' , action = 'store_true' , help = ( 'Disable importing exchange reactions as' ' exchange compound file.' ) ) parser . add_argument ( '--split-subsystem' , action = 'store_true' , help = 'Enable splitting reaction files by subsystem' ) parser . add_argument ( '--merge-compounds' , action = 'store_true' , help = ( 'Merge identical compounds occuring in various' ' compartments.' ) ) parser . add_argument ( '--force' , action = 'store_true' , help = 'Enable overwriting model files' ) if importer_class is None : parser . add_argument ( 'format' , help = 'Format to import ("list" to see all)' ) args = parser . parse_args ( args ) if 'PSAMM_DEBUG' in os . environ : level = getattr ( logging , os . environ [ 'PSAMM_DEBUG' ] . upper ( ) , None ) if level is not None : logging . basicConfig ( level = level ) else : logging . basicConfig ( level = logging . INFO , format = '%(levelname)s: %(message)s' ) if importer_class is None : importers = { } for importer_entry in pkg_resources . iter_entry_points ( 'psamm.importer' ) : canonical = importer_entry . name . lower ( ) if canonical not in importers : importers [ canonical ] = importer_entry else : logger . warning ( 'Importer {} was found more than once!' . format ( importer_entry . name ) ) if args . format in ( 'list' , 'help' ) : if len ( importers ) == 0 : logger . error ( 'No importers found!' ) else : importer_classes = [ ] for name , entry in iteritems ( importers ) : importer_class = entry . load ( ) title = getattr ( importer_class , 'title' , None ) generic = getattr ( importer_class , 'generic' , False ) if title is not None : importer_classes . append ( ( title , generic , name , importer_class ) ) print ( 'Generic importers:' ) for title , _ , name , importer_class in sorted ( c for c in importer_classes if c [ 1 ] ) : print ( '{:<12}  {}' . format ( name , title ) ) print ( ) print ( 'Model-specific importers:' ) for title , _ , name , importer_class in sorted ( c for c in importer_classes if not c [ 1 ] ) : print ( '{:<12}  {}' . format ( name , title ) ) sys . exit ( 0 ) importer_name = args . format . lower ( ) if importer_name not in importers : logger . error ( 'Importer {} not found!' . format ( importer_name ) ) logger . info ( 'Use "list" to see available importers.' ) sys . exit ( - 1 ) importer_class = importers [ importer_name ] . load ( ) importer = importer_class ( ) try : model = importer . import_model ( args . source ) except ModelLoadError as e : logger . error ( 'Failed to load model!' , exc_info = True ) importer . help ( ) parser . error ( text_type ( e ) ) except ParseError as e : logger . error ( 'Failed to parse model!' , exc_info = True ) logger . error ( text_type ( e ) ) sys . exit ( - 1 ) if args . merge_compounds : compounds_before = len ( model . compounds ) sbml . merge_equivalent_compounds ( model ) if len ( model . compounds ) < compounds_before : logger . info ( 'Merged {} compound entries into {} entries by' ' removing duplicates in various compartments' . format ( compounds_before , len ( model . compounds ) ) ) print ( 'Model: {}' . format ( model . name ) ) print ( '- Biomass reaction: {}' . format ( model . biomass_reaction ) ) print ( '- Compartments: {}' . format ( len ( model . compartments ) ) ) print ( '- Compounds: {}' . format ( len ( model . compounds ) ) ) print ( '- Reactions: {}' . format ( len ( model . reactions ) ) ) print ( '- Genes: {}' . format ( count_genes ( model ) ) ) dest_is_empty = False try : dest_is_empty = len ( os . listdir ( args . dest ) ) == 0 except OSError : dest_is_empty = True if not dest_is_empty : if not args . force : logger . error ( 'Destination directory is not empty. Use --force' ' option to proceed anyway, overwriting any existing' ' files in {}' . format ( args . dest ) ) return 1 else : logger . warning ( 'Destination directory is not empty, overwriting' ' existing files in {}' . format ( args . dest ) ) dest = args . dest mkdir_p ( dest ) convert_exchange = not args . no_exchange write_yaml_model ( model , dest , convert_exchange = convert_exchange , split_subsystem = args . split_subsystem )
Entry point for import program.

    If the ``args`` are provided, these should be a list of strings that will
    be used instead of ``sys.argv[1:]``. This is mostly useful for testing.