def main():
    """
    Wrapper for OGR
    """
    parser = argparse.ArgumentParser(description='Wrapper for obographs library'
                                                 """
                                                 By default, ontologies are cached locally and synced from a remote sparql endpoint
                                                 """,
                                     formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('-r', '--resource', type=str, required=False,
                        help='Handle of ontology. See doc on inputs in RTD')
    parser.add_argument('-R', '--resources', type=str, nargs='*', required=False,
                        help='List of handles of ontologies (see -r)')
    parser.add_argument('-o', '--outfile', type=str, required=False,
                        help='Path to output file')
    parser.add_argument('-t', '--to', type=str, required=False,
                        help='Output to (tree, dot, ...)')
    parser.add_argument('-d', '--direction', type=str, default='', required=False,
                        help='u = up, d = down, ud = up and down')
    parser.add_argument('-p', '--properties', nargs='*', type=str, required=False,
                        help='Properties')
    parser.add_argument('-P', '--prefix', type=str, required=False,
                        help='Prefix to constrain traversal on, e.g. PATO, ENVO')
    parser.add_argument('-Q', '--query', type=str, required=False,
                        help='SPARQL query body (only works with sparql handle)')
    parser.add_argument('-s', '--search', type=str, default='', required=False,
                        help='Search type. p=partial, r=regex')
    parser.add_argument('-S', '--slim', type=str, default='', required=False,
                        help='Slim type. m=minimal')
    parser.add_argument('--insubset', type=str, default='', required=False,
                        help='Name of subset to use as seed set of terms. For multiple subsets use comma for intersection and pipe for union')
    parser.add_argument('-L', '--level', type=int, required=False,
                        help='Query all nodes at level L in graph')
    parser.add_argument('-c', '--container_properties', nargs='*', type=str, required=False,
                        help='Properties to nest in graph')
    parser.add_argument('-x', '--render', type=str, required=False,
                        help='renderer settings.')
    parser.add_argument('-X', '--xrefs-as-edges', dest='xrefs_as_edges', action='store_true',
                        help='render xrefs as edges.')
    parser.add_argument('--showdefs', dest='showdefs', action='store_true',
                        help='show text definitions.')
    parser.add_argument('-v', '--verbosity', default=0, action='count',
                        help='Increase output verbosity')

    parser.add_argument('ids',nargs='*')

    args = parser.parse_args()

    if args.verbosity >= 2:
        logging.basicConfig(level=logging.DEBUG)
    elif args.verbosity == 1:
        logging.basicConfig(level=logging.INFO)
    else:
        logging.basicConfig(level=logging.WARNING)
        
    logging.info("Welcome!")

    if args.resource is None and args.resources is None:
        logging.error("You must specify -r or -R")
    handle = args.resource
    handles = args.resources

    factory = OntologyFactory()
    logging.info("Creating ont object from: {} {}".format(handle, factory))
    ont = None
    if handle:
        ont = factory.create(handle)
    else:
        ont = factory.create(handles.pop())
    if handles:
        ont.merge([factory.create(h) for h in handles])
        
    logging.info("ont: {}".format(ont))

    if args.xrefs_as_edges:
        xu.materialize_xrefs_as_edges(ont)
    
    qids = []
    dirn = args.direction
    if dirn == '' and args.to is not None:
        dirn = 'u'
    searchp = args.search

    if args.level is not None:
        logging.info("Query for level: {}".format(args.level))
        qids = qids + ont.get_level(args.level, relations=args.properties, prefix=args.prefix)

    if args.insubset is not None and args.insubset != "":
        disjs = args.insubset.split("|")
        dset = set()
        for i in disjs:
            cset = None
            conjs = i.split(",")
            for j in conjs:
                terms = set(ont.extract_subset(j))
                if cset is None:
                    cset = terms
                else:
                    cset = cset.intersection(terms)
            dset = dset.union(cset)
        qids = qids + list(dset)


    if args.query is not None:
        qids = qids + ont.sparql(select='*',
                                 body=args.query,
                                 inject_prefixes = ont.prefixes(),
                                 single_column=True)

    # TODO: make syns optional
    logging.info("Main query terms: {}".format(args.ids))
    for id in ont.resolve_names(args.ids,
                                synonyms=True,
                                is_remote = searchp.find('x') > -1,
                                is_partial_match = searchp.find('p') > -1,
                                is_regex = searchp.find('r') > -1):
        qids.append(id)
    logging.info("Query IDs: {} Rels: {}".format(qids, args.properties))

    nodes = ont.traverse_nodes(qids, up=dirn.find("u") > -1, down=dirn.find("d") > -1,
                               relations=args.properties)

    # deprecated
    #g = ont.get_filtered_graph(relations=args.properties)
    subont = ont.subontology(nodes, relations=args.properties)
    render(subont, qids, args)
Wrapper for OGR