Пример #1
0
def project_get_or_create(multi_session_force_recreate=False):
    """
    Return existed or create new project based on environment. Currently supported methods:
    - "fixed": project is based on "project_name" attribute specified by input args when app starts
    - "session": project is based on "project_name" key restored from flask.session object
    :return:
    """
    if input_args.command == 'start-multi-session':
        # get user from session
        if 'user' not in session:
            session['user'] = str(uuid4())
        user = session['user']

        # get project from session
        if 'project' not in session or multi_session_force_recreate:
            session['project'] = str(uuid4())
        project = session['project']

        project_name = user + '/' + project
        return Project.get_or_create(project_name,
                                     input_args,
                                     context={
                                         'multi_session': True,
                                         'user': convert_string_to_hash(user)
                                     })
    else:
        if multi_session_force_recreate:
            raise NotImplementedError(
                '"multi_session_force_recreate" option supported only with "start-multi-session" mode'
            )
        return Project.get_or_create(input_args.project_name,
                                     input_args,
                                     context={'multi_session': False})
Пример #2
0
def main():
    import threading
    import webbrowser

    global input_args

    input_args = parse_input_args()

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        if not input_args.no_browser:
            browser_url = 'http://127.0.0.1:' + str(
                input_args.port) + '/welcome'
            threading.Timer(2.5, lambda: webbrowser.open(browser_url)).start()
            print('Start browser at URL: ' + browser_url)

        app.run(host='0.0.0.0', port=input_args.port, debug=input_args.debug)

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        app.run(host='0.0.0.0', port=input_args.port, debug=input_args.debug)
Пример #3
0
def setup_page():
    """ Setup labeling config
    """
    input_values = {}
    project = g.project
    input_args = current_app.label_studio.input_args

    g.project.description = project.get_config(project.name, input_args).get(
        'description', 'Untitled')

    # evaluate all projects for this user: user_projects + shared_projects
    if project.config.get("show_project_links_in_multisession",
                          True) and hasattr(g, 'user'):
        user = g.user
        project_ids = g.project.get_user_projects(user, input_args.root_dir)

        # own projects
        project_names = [os.path.join(user, uuid) for uuid in project_ids]
        project_desc = [
            Project.get_config(name, input_args).get('description', 'Untitled')
            for name in project_names
        ]
        own_projects = dict(zip(project_ids, project_desc))

        # shared projects
        shared_projects = {}
        for uuid in session.get('shared_projects', []):
            tmp_user = Project.get_user_by_project(uuid, input_args.root_dir)
            project_name = os.path.join(tmp_user, uuid)
            project_desc = Project.get_config(project_name, input_args).get(
                'description', 'Untitled')
            shared_projects[uuid] = project_desc
    else:
        own_projects, shared_projects = {}, {}

    # this is useful for the transfer to playground templates
    template_mode = request.args.get('template_mode')
    page = 'includes/setup_templates.html' if template_mode else 'setup.html'

    templates = get_config_templates(g.project.config)
    return flask.render_template(
        page,
        config=g.project.config,
        project=g.project,
        label_config_full=g.project.label_config_full,
        templates=templates,
        input_values=input_values,
        multi_session=input_args.command == 'start-multi-session',
        own_projects=own_projects,
        shared_projects=shared_projects,
        template_mode=template_mode,
        serialized_project=g.project.serialize())
Пример #4
0
def api_project_switch():
    """ Switch projects in multi-session mode
    """
    input_args = current_app.label_studio.input_args

    if request.args.get('uuid') is None:
        return make_response("Not a valid UUID", 400)

    uuid = request.args.get('uuid')
    user = Project.get_user_by_project(uuid, input_args.root_dir)

    # not owner user tries to open shared project
    if user != g.user:
        # create/append shared projects for user
        if 'shared_projects' not in session:
            session['shared_projects'] = {}
        session['shared_projects'].update({uuid: {}})

    # switch project
    session['project'] = uuid

    output = g.project.serialize()
    output['multi_session_mode'] = input_args.command == 'start-multi-session'
    if request.method == 'GET':
        return redirect(url_for('label_studio.setup_page'))
    else:
        return make_response(jsonify(output), 200)
Пример #5
0
def project_get_or_create():
    """
    Return existed or create new project based on environment. Currently supported methods:
    - "fixed": project is based on "project_name" attribute specified by input args when app starts
    - "session": project is based on "project_name" key restored from flask.session object
    :return:
    """
    if input_args.command == 'start-multi-session':
        if 'project_name' in session:
            project_name = session['project_name']
        else:
            project_name = str(uuid4())
            session['project_name'] = project_name
        return Project.get_or_create(project_name, input_args)
    else:
        return Project.get_or_create(input_args.project_name, input_args)
Пример #6
0
def project_get_or_create(multi_session_force_recreate=False):
    """ Return existed or create new project based on environment. Currently supported methods:
        - "fixed": project is based on "project_name" attribute specified by input args when app starts
        - "session": project is based on "project_name" key restored from flask.session object

        :param multi_session_force_recreate: create a new project if True
        :return: project
    """
    input_args = current_app.label_studio.input_args
    if input_args and input_args.command == 'start-multi-session':
        # get user from session
        if 'user' not in session:
            session['user'] = str(uuid4())
        user = session['user']
        g.user = user

        # get project from session
        if 'project' not in session or multi_session_force_recreate:
            session['project'] = str(uuid4())
        project = session['project']

        # check for shared projects and get owner user
        if project in session.get('shared_projects', []):
            owner = Project.get_user_by_project(project, input_args.root_dir)
            if owner is None:  # owner is None when project doesn't exist
                raise Exception(
                    'No such shared project found: project_uuid = ' + project)
            else:
                user = owner

        project_name = user + '/' + project
        return Project.get_or_create(project_name,
                                     input_args,
                                     context={
                                         'multi_session':
                                         True,
                                         'user':
                                         convert_string_to_hash(user.encode())
                                     })
    else:
        if multi_session_force_recreate:
            raise NotImplementedError(
                '"multi_session_force_recreate" option supported only with "start-multi-session" mode'
            )
        return Project.get_or_create(input_args.project_name,
                                     input_args,
                                     context={'multi_session': False})
Пример #7
0
def main():
    import threading
    import webbrowser

    global input_args

    input_args = parse_input_args()

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    import label_studio.utils.functions
    label_studio.utils.functions.HOSTNAME = 'http://localhost:' + str(
        input_args.port)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(input_args.project_name):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                'Did you miss create it first with `label-studio init {pdir}` ?'
                .format(pdir=input_args.project_name))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        if not input_args.no_browser:
            browser_url = label_studio.utils.functions.HOSTNAME + '/welcome'
            threading.Timer(2.5, lambda: webbrowser.open(browser_url)).start()
            print('Start browser at URL: ' + browser_url)

        app.run(host='0.0.0.0', port=input_args.port, debug=input_args.debug)

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        app.run(host='0.0.0.0', port=input_args.port, debug=input_args.debug)
Пример #8
0
def setup_page():
    """ Setup label config
    """
    input_values = {}
    project = g.project

    g.project.description = project.get_config(project.name, input_args).get(
        'description', 'Untitled')

    # evaluate all projects for this user: user_projects + shared_projects
    if project.config.get("show_project_links_in_multisession",
                          True) and hasattr(g, 'user'):
        user = g.user
        project_ids = g.project.get_user_projects(user, input_args.root_dir)

        # own projects
        project_names = [os.path.join(user, uuid) for uuid in project_ids]
        project_desc = [
            Project.get_config(name, input_args).get('description', 'Untitled')
            for name in project_names
        ]
        own_projects = dict(zip(project_ids, project_desc))

        # shared projects
        shared_projects = {}
        for uuid in session.get('shared_projects', []):
            tmp_user = Project.get_user_by_project(uuid, input_args.root_dir)
            project_name = os.path.join(tmp_user, uuid)
            project_desc = Project.get_config(project_name, input_args).get(
                'description', 'Untitled')
            shared_projects[uuid] = project_desc
    else:
        own_projects, shared_projects = {}, {}

    templates = get_config_templates(g.project.config)
    return flask.render_template(
        'setup.html',
        config=g.project.config,
        project=g.project,
        label_config_full=g.project.label_config_full,
        templates=templates,
        input_values=input_values,
        multi_session=input_args.command == 'start-multi-session',
        own_projects=own_projects,
        shared_projects=shared_projects)
Пример #9
0
def goc_project():
    """monkeypatch for get_or_create_project"""
    project_name = "my_project"
    user = "******"
    input_args_dict = {"root_dir": os.path.join(os.path.dirname(__file__), "../../")}
    input_args = SimpleNamespace(**input_args_dict)
    project = Project.get_or_create(
        project_name, input_args, context={"multi_session": False}
    )
    return project
Пример #10
0
def goc_project():
    """monkeypatch for get_or_create_project"""
    project_name = 'my_project'
    user = '******'
    input_args_dict = {
        'root_dir': os.path.join(os.path.dirname(__file__), '../../')
    }
    input_args = SimpleNamespace(**input_args_dict)
    project = Project.get_or_create(project_name, input_args, context={
            'multi_session': False
    })
    return project
Пример #11
0
def main():
    global input_args

    app.jinja_env.filters['str2datetime'] = str2datetime

    input_args = parse_input_args()

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(Project.get_project_dir(input_args.project_name, input_args)):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                'Did you miss create it first with `label-studio init {pdir}` ?'.format(
                    pdir=Project.get_project_dir(input_args.project_name, input_args)))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        import label_studio.utils.functions

        config = Project.get_config(input_args.project_name, input_args)
        host = input_args.host or config.get('host', 'localhost')
        port = input_args.port or config.get('port', 8080)
        label_studio.utils.functions.HOSTNAME = 'http://localhost:' + str(port)

        try:
            start_browser(label_studio.utils.functions.HOSTNAME, input_args.no_browser)
            app.run(host=host, port=port, debug=input_args.debug)
        except OSError as e:
            # address already is in use
            if e.errno == 98:
                new_port = int(port) + 1
                print('\n*** WARNING! ***\n* Port ' + str(port) + ' is in use.\n'
                      '* Try to start at ' + str(new_port) + '\n****************\n')
                label_studio.utils.functions.HOSTNAME = 'http://localhost:' + str(new_port)
                start_browser(label_studio.utils.functions.HOSTNAME, input_args.no_browser)
                app.run(host=host, port=new_port, debug=input_args.debug)
            else:
                raise e

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        app.run(host=input_args.host or '0.0.0.0', port=input_args.port or 8080, debug=input_args.debug)
Пример #12
0
def project_get_or_create(multi_session_force_recreate=False):
    """
    Return existed or create new project based on environment. Currently supported methods:
    - "fixed": project is based on "project_name" attribute specified by input args when app starts
    - "session": project is based on "project_name" key restored from flask.session object
    :return:
    """
    print("Project get or create")
    if input_args.command == 'start-multi-session':
        # get user from session
        if 'user' not in session:
            session['user'] = str(uuid4())
        user = session['user']

        # get project from session
        if 'project' not in session or multi_session_force_recreate:
            session['project'] = str(uuid4())
        project = session['project']

        project_name = user + '/' + project
        return Project.get_or_create(project_name,
                                     input_args,
                                     context={
                                         'user': user,
                                         'project': project,
                                         'multi_session': True,
                                     })
    else:
        # if multi_session_force_recreate:
        #     raise NotImplementedError(
        #         '"multi_session_force_recreate" option supported only with "start-multi-session" mode')
        user = project = input_args.project_name  # in standalone mode, user and project are singletons and consts
        return Project.get_or_create(input_args.project_name,
                                     input_args,
                                     context={
                                         'user': user,
                                         'project': project,
                                         'multi_session': False
                                     })
Пример #13
0
def main():
    # this will avoid looped imports and will register deprecated endpoints in the blueprint
    import label_studio.deprecated

    input_args = parse_input_args()
    app = create_app(LabelStudioConfig(input_args=input_args))

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == "init":
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == "start":

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(
                Project.get_project_dir(input_args.project_name, input_args)):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                "Did you miss create it first with `label-studio init {pdir}` ?"
                .format(pdir=Project.get_project_dir(input_args.project_name,
                                                     input_args)))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == "start":
        import label_studio.utils.functions
        import label_studio.utils.auth

        config = Project.get_config(input_args.project_name, input_args)

        # set username and password
        label_studio.utils.auth.USERNAME = (input_args.username
                                            or config.get("username") or
                                            label_studio.utils.auth.USERNAME)
        label_studio.utils.auth.PASSWORD = input_args.password or config.get(
            "password", "")

        # set host name
        host = input_args.host or config.get("host", "localhost")
        port = input_args.port or config.get("port", 8080)
        server_host = ("localhost" if host == "localhost" else "0.0.0.0"
                       )  # web server host

        # ssl certificate and key
        cert_file = input_args.cert_file or config.get("cert")
        key_file = input_args.key_file or config.get("key")
        ssl_context = None
        if cert_file and key_file:
            config["protocol"] = "https://"
            ssl_context = (cert_file, key_file)

        # check port is busy
        if not input_args.debug and check_port_in_use("localhost", port):
            old_port = port
            port = int(port) + 1
            print("\n*** WARNING! ***\n* Port " + str(old_port) +
                  " is in use.\n" + "* Trying to start at " + str(port) +
                  "\n****************\n")

        # external hostname is used for data import paths, they must be absolute always,
        # otherwise machine learning backends couldn't access them
        set_web_protocol(input_args.protocol
                         or config.get("protocol", "http://"))
        external_hostname = get_web_protocol() + host.replace(
            "0.0.0.0", "localhost")
        if host in ["0.0.0.0", "localhost", "127.0.0.1"]:
            external_hostname += ":" + str(port)
        set_external_hostname(external_hostname)

        start_browser("http://localhost:" + str(port), input_args.no_browser)
        if input_args.use_gevent:
            app.debug = input_args.debug
            ssl_args = ({
                "keyfile": key_file,
                "certfile": cert_file
            } if ssl_context else {})
            http_server = WSGIServer((server_host, port),
                                     app,
                                     log=app.logger,
                                     **ssl_args)
            http_server.serve_forever()
        else:
            app.run(
                host=server_host,
                port=port,
                debug=input_args.debug,
                ssl_context=ssl_context,
            )

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == "start-multi-session":
        server_host = input_args.host or "0.0.0.0"
        port = input_args.port or 8080

        if input_args.use_gevent:
            app.debug = input_args.debug
            http_server = WSGIServer((server_host, port), app, log=app.logger)
            http_server.serve_forever()
        else:
            app.run(host=server_host, port=port, debug=input_args.debug)
Пример #14
0
def main():
    # this will avoid looped imports and will register deprecated endpoints in the blueprint
    import label_studio.deprecated

    input_args = parse_input_args()
    app = create_app(LabelStudioConfig(input_args=input_args))

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(
                Project.get_project_dir(input_args.project_name, input_args)):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                'Did you miss create it first with `label-studio init {pdir}` ?'
                .format(pdir=Project.get_project_dir(input_args.project_name,
                                                     input_args)))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        import label_studio.utils.functions
        import label_studio.utils.auth
        config = Project.get_config(input_args.project_name, input_args)

        # set username and password
        label_studio.utils.auth.USERNAME = input_args.username or \
            config.get('username') or label_studio.utils.auth.USERNAME
        label_studio.utils.auth.PASSWORD = input_args.password or config.get(
            'password', '')

        # set host name
        host = input_args.host or config.get('host', 'localhost')
        port = input_args.port or config.get('port', 8080)
        server_host = 'localhost' if host == 'localhost' else '0.0.0.0'  # web server host

        # ssl certificate and key
        cert_file = input_args.cert_file or config.get('cert')
        key_file = input_args.key_file or config.get('key')
        ssl_context = None
        if cert_file and key_file:
            config['protocol'] = 'https://'
            ssl_context = (cert_file, key_file)

        # check port is busy
        if not input_args.debug and check_port_in_use('localhost', port):
            old_port = port
            port = int(port) + 1
            print('\n*** WARNING! ***\n* Port ' + str(old_port) +
                  ' is in use.\n' + '* Trying to start at ' + str(port) +
                  '\n****************\n')

        # external hostname is used for data import paths, they must be absolute always,
        # otherwise machine learning backends couldn't access them
        set_web_protocol(input_args.protocol
                         or config.get('protocol', 'http://'))
        external_hostname = get_web_protocol() + host.replace(
            '0.0.0.0', 'localhost')
        if host in ['0.0.0.0', 'localhost', '127.0.0.1']:
            external_hostname += ':' + str(port)
        set_external_hostname(external_hostname)

        start_browser('http://localhost:' + str(port), input_args.no_browser)
        if input_args.use_gevent:
            app.debug = input_args.debug
            ssl_args = {
                'keyfile': key_file,
                'certfile': cert_file
            } if ssl_context else {}
            http_server = WSGIServer((server_host, port),
                                     app,
                                     log=app.logger,
                                     **ssl_args)
            http_server.serve_forever()
        else:
            app.run(host=server_host,
                    port=port,
                    debug=input_args.debug,
                    ssl_context=ssl_context)

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        server_host = input_args.host or '0.0.0.0'
        port = input_args.port or 8080

        if input_args.use_gevent:
            app.debug = input_args.debug
            http_server = WSGIServer((server_host, port), app, log=app.logger)
            http_server.serve_forever()
        else:
            app.run(host=server_host, port=port, debug=input_args.debug)
Пример #15
0
def main():
    global input_args

    app.jinja_env.filters['str2datetime'] = str2datetime

    input_args = parse_input_args()

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(
                Project.get_project_dir(input_args.project_name, input_args)):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                'Did you miss create it first with `label-studio init {pdir}` ?'
                .format(pdir=Project.get_project_dir(input_args.project_name,
                                                     input_args)))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        import label_studio.utils.functions
        import label_studio.utils.auth
        config = Project.get_config(input_args.project_name, input_args)

        # set username and password
        label_studio.utils.auth.USERNAME = input_args.username or \
            config.get('username') or label_studio.utils.auth.USERNAME
        label_studio.utils.auth.PASSWORD = input_args.password or config.get(
            'password', '')

        # set host name
        host = input_args.host or config.get(
            'host', 'localhost')  # name for external links generation
        port = input_args.port or config.get('port', 8080)
        server_host = 'localhost' if host == 'localhost' else '0.0.0.0'  # web server host

        # ssl certificate and key
        cert_file = input_args.cert_file or config.get('cert')
        key_file = input_args.key_file or config.get('key')
        ssl_context = None
        if cert_file and key_file:
            config['protocol'] = 'https://'
            ssl_context = (cert_file, key_file)

        # check port is busy
        if not input_args.debug and check_port_in_use('localhost', port):
            old_port = port
            port = int(port) + 1
            print('\n*** WARNING! ***\n* Port ' + str(old_port) +
                  ' is in use.\n' + '* Trying to start at ' + str(port) +
                  '\n****************\n')

        set_web_protocol(input_args.protocol
                         or config.get('protocol', 'http://'))
        set_full_hostname(get_web_protocol() +
                          host.replace('0.0.0.0', 'localhost') + ':' +
                          str(port))

        start_browser('http://localhost:' + str(port), input_args.no_browser)
        if input_args.use_gevent:
            app.debug = input_args.debug
            ssl_args = {
                'keyfile': key_file,
                'certfile': cert_file
            } if ssl_context else {}
            http_server = WSGIServer((server_host, port),
                                     app,
                                     log=app.logger,
                                     **ssl_args)
            http_server.serve_forever()
        else:
            app.run(host=server_host,
                    port=port,
                    debug=input_args.debug,
                    ssl_context=ssl_context)

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        server_host = input_args.host or '0.0.0.0'
        port = input_args.port or 8080

        if input_args.use_gevent:
            app.debug = input_args.debug
            http_server = WSGIServer((server_host, port), app, log=app.logger)
            http_server.serve_forever()
        else:
            app.run(host=server_host, port=port, debug=input_args.debug)
Пример #16
0
def parse_input_args():
    """ Combine args with json config

    :return: config dict
    """
    import sys
    import argparse
    from label_studio.project import Project

    if len(sys.argv) == 1:
        print('\nQuick start usage: label-studio start my_project --init\n')

    available_templates = [
        os.path.basename(os.path.dirname(f)) for f in iter_config_templates()
    ]

    def valid_filepath(filepath):
        path = os.path.abspath(os.path.expanduser(filepath))
        if os.path.exists(path):
            return path
        raise FileNotFoundError(filepath)

    root_parser = argparse.ArgumentParser(add_help=False)
    root_parser.add_argument('--version',
                             dest='version',
                             action='store_true',
                             help='Show Label Studio version')
    root_parser.add_argument('-b',
                             '--no-browser',
                             dest='no_browser',
                             action='store_true',
                             help='Do not open browser at label studio start')
    root_parser.add_argument('-d',
                             '--debug',
                             dest='debug',
                             action='store_true',
                             help='Debug mode for Flask',
                             default=None)
    root_parser.add_argument('--force',
                             dest='force',
                             action='store_true',
                             help='Force overwrite existing files')
    root_parser.add_argument('--root-dir',
                             dest='root_dir',
                             default='.',
                             help='Project root directory')
    root_parser.add_argument('-v',
                             '--verbose',
                             dest='verbose',
                             action='store_true',
                             help='Increase output verbosity')
    root_parser.add_argument('--template',
                             dest='template',
                             choices=available_templates,
                             help='Choose from predefined project templates')
    root_parser.add_argument('-c',
                             '--config',
                             dest='config_path',
                             type=valid_filepath,
                             help='Server config')
    root_parser.add_argument('-l',
                             '--label-config',
                             dest='label_config',
                             type=valid_filepath,
                             help='Label config path')
    root_parser.add_argument(
        '-i',
        '--input-path',
        dest='input_path',
        type=valid_filepath,
        help='Input path for task file or directory with tasks')
    root_parser.add_argument('-s',
                             '--source',
                             dest='source',
                             choices=Project.get_available_source_storages(),
                             help='Source data storage type')
    root_parser.add_argument('--source-path',
                             dest='source_path',
                             help='Source bucket name')
    root_parser.add_argument('--source-params',
                             dest='source_params',
                             type=json.loads,
                             default={},
                             help='JSON string representing source parameters')
    root_parser.add_argument('-t',
                             '--target',
                             dest='target',
                             choices=Project.get_available_target_storages(),
                             help='Target data storage type')
    root_parser.add_argument('--target-path',
                             dest='target_path',
                             help='Target bucket name')
    root_parser.add_argument('--target-params',
                             dest='target_params',
                             type=json.loads,
                             default={},
                             help='JSON string representing target parameters')
    root_parser.add_argument(
        '--input-format',
        dest='input_format',
        choices=('json', 'json-dir', 'text', 'text-dir', 'image-dir',
                 'audio-dir'),
        default='json',
        help=
        'Input tasks format. Unless you are using "json" or "json-dir" format, --label-config option is required'
    )
    root_parser.add_argument(
        '-o',
        '--output-dir',
        dest='output_dir',
        type=valid_filepath,
        help='Output directory for completions (unless cloud storage is used)')
    root_parser.add_argument('--ml-backends',
                             dest='ml_backends',
                             nargs='+',
                             help='Machine learning backends URLs')
    root_parser.add_argument('--sampling',
                             dest='sampling',
                             choices=['sequential', 'uniform'],
                             default='sequential',
                             help='Sampling type that defines tasks order')
    root_parser.add_argument('--log-level',
                             dest='log_level',
                             choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'],
                             default=None,
                             help='Logging level')
    root_parser.add_argument(
        '--host',
        dest='host',
        type=str,
        help=
        'Server hostname for LS internal usage like import task urls generation, sample task urls, etc. '
        'If you need to start server on localhost instead of 0.0.0.0, just make it "localhost". '
        'Otherwise web-server host will be 0.0.0.0 always independent of this parameter.'
    )
    root_parser.add_argument('--protocol',
                             dest='protocol',
                             type=str,
                             help='Web protocol http:// or https://')
    root_parser.add_argument('-p',
                             '--port',
                             dest='port',
                             type=int,
                             help='Server port')
    root_parser.add_argument('--cert',
                             dest='cert_file',
                             type=valid_filepath,
                             help='Certificate file for HTTPS (in PEM format)')
    root_parser.add_argument('--key',
                             dest='key_file',
                             type=valid_filepath,
                             help='Private key file for HTTPS (in PEM format)')
    root_parser.add_argument(
        '--allow-serving-local-files',
        dest='allow_serving_local_files',
        action='store_true',
        help=
        'Allow serving local files (Warning! use this option only for your local runs)'
    )
    root_parser.add_argument('--use-gevent',
                             dest='use_gevent',
                             action='store_true',
                             help='Use gevent for better concurrency',
                             default=False)

    parser = argparse.ArgumentParser(description='Label studio')

    subparsers = parser.add_subparsers(dest='command',
                                       help='Available commands')
    subparsers.required = True

    # init sub-command parser

    parser_version = subparsers.add_parser('version',
                                           help='Print version info',
                                           parents=[root_parser])

    parser_init = subparsers.add_parser('init',
                                        help='Initialize Label Studio',
                                        parents=[root_parser])
    parser_init.add_argument(
        'project_name',
        help='Path to directory where project state will be initialized')

    # start sub-command parser

    parser_start = subparsers.add_parser('start',
                                         help='Start Label Studio server',
                                         parents=[root_parser])
    parser_start.add_argument(
        'project_name',
        help='Path to directory where project state has been initialized')
    parser_start.add_argument(
        '--init',
        dest='init',
        action='store_true',
        help='Initialize if project is not initialized yet')
    parser_start.add_argument('--password',
                              dest='password',
                              default='',
                              help='Password for web access')
    parser_start.add_argument('--username',
                              dest='username',
                              default='',
                              help='Username for web access')

    # start-multi-session sub-command parser

    parser_start_ms = subparsers.add_parser('start-multi-session',
                                            help='Start Label Studio server',
                                            parents=[root_parser])

    args = parser.parse_args()

    # print version
    if args.version or args.command == 'version':
        from label_studio import __version__
        print('\nLabel Studio version:', __version__, '\n')

    if args.output_dir is not None:
        raise RuntimeError(
            '"--output-dir" option is deprecated and has no effect.\n'
            'All output results are saved to project_name/completions directory'
        )

    label_config_explicitly_specified = hasattr(
        args, 'label_config') and args.label_config
    if args.template and not label_config_explicitly_specified:
        args.label_config = os.path.join(find_dir('examples'), args.template,
                                         'config.xml')
    if not hasattr(args, 'label_config'):
        args.label_config = None
    return args
Пример #17
0
def main():
    global input_args

    app.jinja_env.filters['str2datetime'] = str2datetime

    input_args = parse_input_args()

    # setup logging level
    if input_args.log_level:
        logging.root.setLevel(input_args.log_level)

    # On `init` command, create directory args.project_name with initial project state and exit
    if input_args.command == 'init':
        Project.create_project_dir(input_args.project_name, input_args)
        return

    elif input_args.command == 'start':

        # If `start --init` option is specified, do the same as with `init` command, but continue to run app
        if input_args.init:
            Project.create_project_dir(input_args.project_name, input_args)

        if not os.path.exists(
                Project.get_project_dir(input_args.project_name, input_args)):
            raise FileNotFoundError(
                'Project directory "{pdir}" not found. '
                'Did you miss create it first with `label-studio init {pdir}` ?'
                .format(pdir=Project.get_project_dir(input_args.project_name,
                                                     input_args)))

    # On `start` command, launch browser if --no-browser is not specified and start label studio server
    if input_args.command == 'start':
        import label_studio.utils.functions
        import label_studio.utils.auth
        config = Project.get_config(input_args.project_name, input_args)

        # set username and password
        label_studio.utils.auth.USERNAME = input_args.username or \
            config.get('username') or label_studio.utils.auth.USERNAME
        label_studio.utils.auth.PASSWORD = input_args.password or config.get(
            'password', '')

        # set host name
        host = input_args.host or config.get('host', 'localhost')
        port = input_args.port or config.get('port', 8080)

        if not input_args.debug and check_port_in_use('localhost', port):
            old_port = port
            port = int(port) + 1
            print('\n*** WARNING! ***\n* Port ' + str(old_port) +
                  ' is in use.\n' + '* Trying to start at ' + str(port) +
                  '\n****************\n')

        set_web_protocol(config.get('protocol', 'http://'))
        set_full_hostname(get_web_protocol() +
                          host.replace('0.0.0.0', 'localhost') + ':' +
                          str(port))

        start_browser('http://localhost:' + str(port), input_args.no_browser)
        app.run(host=host, port=port, debug=input_args.debug)

    # On `start-multi-session` command, server creates one project per each browser sessions
    elif input_args.command == 'start-multi-session':
        app.run(host=input_args.host or '0.0.0.0',
                port=input_args.port or 8080,
                debug=input_args.debug)
Пример #18
0
def parse_input_args():
    """Combine args with json config

    :return: config dict
    """
    import sys
    import argparse
    from label_studio.project import Project

    if len(sys.argv) == 1:
        print("\nQuick start usage: label-studio start my_project --init\n")

    available_templates = [
        os.path.basename(os.path.dirname(f)) for f in iter_config_templates()
    ]

    def valid_filepath(filepath):
        path = os.path.abspath(os.path.expanduser(filepath))
        if os.path.exists(path):
            return path
        raise FileNotFoundError(filepath)

    root_parser = argparse.ArgumentParser(add_help=False)
    root_parser.add_argument(
        "--version",
        dest="version",
        action="store_true",
        help="Show Label Studio version",
    )
    root_parser.add_argument(
        "-b",
        "--no-browser",
        dest="no_browser",
        action="store_true",
        help="Do not open browser at label studio start",
    )
    root_parser.add_argument(
        "-d",
        "--debug",
        dest="debug",
        action="store_true",
        help="Debug mode for Flask",
        default=None,
    )
    root_parser.add_argument(
        "--force",
        dest="force",
        action="store_true",
        help="Force overwrite existing files",
    )
    root_parser.add_argument("--root-dir",
                             dest="root_dir",
                             default=".",
                             help="Project root directory")
    root_parser.add_argument(
        "-v",
        "--verbose",
        dest="verbose",
        action="store_true",
        help="Increase output verbosity",
    )
    root_parser.add_argument(
        "--template",
        dest="template",
        choices=available_templates,
        help="Choose from predefined project templates",
    )
    root_parser.add_argument("-c",
                             "--config",
                             dest="config_path",
                             type=valid_filepath,
                             help="Server config")
    root_parser.add_argument(
        "-l",
        "--label-config",
        dest="label_config",
        type=valid_filepath,
        help="Label config path",
    )
    root_parser.add_argument(
        "-i",
        "--input-path",
        dest="input_path",
        type=valid_filepath,
        help="Input path for task file or directory with tasks",
    )
    root_parser.add_argument(
        "-s",
        "--source",
        dest="source",
        choices=Project.get_available_source_storages(),
        help="Source data storage type",
    )
    root_parser.add_argument("--source-path",
                             dest="source_path",
                             help="Source bucket name")
    root_parser.add_argument(
        "--source-params",
        dest="source_params",
        type=json.loads,
        default={},
        help="JSON string representing source parameters",
    )
    root_parser.add_argument(
        "-t",
        "--target",
        dest="target",
        choices=Project.get_available_target_storages(),
        help="Target data storage type",
    )
    root_parser.add_argument("--target-path",
                             dest="target_path",
                             help="Target bucket name")
    root_parser.add_argument(
        "--target-params",
        dest="target_params",
        type=json.loads,
        default={},
        help="JSON string representing target parameters",
    )
    root_parser.add_argument(
        "--input-format",
        dest="input_format",
        choices=("json", "json-dir", "text", "text-dir", "image-dir",
                 "audio-dir"),
        default="json",
        help=
        'Input tasks format. Unless you are using "json" or "json-dir" format, --label-config option is required',
    )
    root_parser.add_argument(
        "-o",
        "--output-dir",
        dest="output_dir",
        type=valid_filepath,
        help="Output directory for completions (unless cloud storage is used)",
    )
    root_parser.add_argument(
        "--ml-backends",
        dest="ml_backends",
        nargs="+",
        help="Machine learning backends URLs",
    )
    root_parser.add_argument(
        "--sampling",
        dest="sampling",
        choices=["sequential", "uniform"],
        default="sequential",
        help="Sampling type that defines tasks order",
    )
    root_parser.add_argument(
        "--log-level",
        dest="log_level",
        choices=["DEBUG", "INFO", "WARNING", "ERROR"],
        default=None,
        help="Logging level",
    )
    root_parser.add_argument(
        "--host",
        dest="host",
        type=str,
        help=
        "Server hostname for LS internal usage like import task urls generation, sample task urls, etc. "
        'If you need to start server on localhost instead of 0.0.0.0, just make it "localhost". '
        "Otherwise web-server host will be 0.0.0.0 always independent of this parameter.",
    )
    root_parser.add_argument("--protocol",
                             dest="protocol",
                             type=str,
                             help="Web protocol http:// or https://")
    root_parser.add_argument("-p",
                             "--port",
                             dest="port",
                             type=int,
                             help="Server port")
    root_parser.add_argument(
        "--cert",
        dest="cert_file",
        type=valid_filepath,
        help="Certificate file for HTTPS (in PEM format)",
    )
    root_parser.add_argument(
        "--key",
        dest="key_file",
        type=valid_filepath,
        help="Private key file for HTTPS (in PEM format)",
    )
    root_parser.add_argument(
        "--allow-serving-local-files",
        dest="allow_serving_local_files",
        action="store_true",
        help=
        "Allow serving local files (Warning! use this option only for your local runs)",
    )
    root_parser.add_argument(
        "--use-gevent",
        dest="use_gevent",
        action="store_true",
        help="Use gevent for better concurrency",
        default=False,
    )
    root_parser.add_argument(
        "--initial-project-description",
        dest="project_desc",
        help="Project description to identify project",
    )

    parser = argparse.ArgumentParser(description="Label studio")

    subparsers = parser.add_subparsers(dest="command",
                                       help="Available commands")
    subparsers.required = True

    # init sub-command parser

    parser_version = subparsers.add_parser("version",
                                           help="Print version info",
                                           parents=[root_parser])

    parser_init = subparsers.add_parser("init",
                                        help="Initialize Label Studio",
                                        parents=[root_parser])
    parser_init.add_argument(
        "project_name",
        help="Path to directory where project state will be initialized")

    # start sub-command parser

    parser_start = subparsers.add_parser("start",
                                         help="Start Label Studio server",
                                         parents=[root_parser])
    parser_start.add_argument(
        "project_name",
        help="Path to directory where project state has been initialized",
    )
    parser_start.add_argument(
        "--init",
        dest="init",
        action="store_true",
        help="Initialize if project is not initialized yet",
    )
    parser_start.add_argument("--password",
                              dest="password",
                              default="",
                              help="Password for web access")
    parser_start.add_argument("--username",
                              dest="username",
                              default="",
                              help="Username for web access")

    # start-multi-session sub-command parser

    parser_start_ms = subparsers.add_parser("start-multi-session",
                                            help="Start Label Studio server",
                                            parents=[root_parser])

    args = parser.parse_args()

    # print version
    if args.version or args.command == "version":
        from label_studio import __version__

        print("\nLabel Studio version:", __version__, "\n")

    if args.output_dir is not None:
        raise RuntimeError(
            '"--output-dir" option is deprecated and has no effect.\n'
            "All output results are saved to project_name/completions directory"
        )

    label_config_explicitly_specified = (hasattr(args, "label_config")
                                         and args.label_config)
    if args.template and not label_config_explicitly_specified:
        args.label_config = os.path.join(find_dir("examples"), args.template,
                                         "config.xml")
    if not hasattr(args, "label_config"):
        args.label_config = None
    return args