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})
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)
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())
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)
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)
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})
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)
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)
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
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
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)
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 })
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)
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)
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)
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
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)
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