Ejemplo n.º 1
0
def delete_experiment(request: Request, experiment_id: Text,
                      project_id: int) -> JSONResponse:
    """Delete experiment.
    Args:
        experiment_id {Text}: experiment id
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {
        'project_id': project_id,
        'experiment_id': experiment_id
    })

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    experiment_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/experiments/delete',
        json={'experiment_id': experiment_id})

    if experiment_resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=experiment_resp.status_code,
                              message=experiment_resp.json().get('message'))

    return JSONResponse({'experiment_id': experiment_id})
Ejemplo n.º 2
0
def get_model(request: Request, model_id: Text, project_id: int) -> JSONResponse:
    """Get model.

    Args:
        model_id {Text}: model id (name)
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    model_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/get-details',
        json={'registered_model': {'name': model_id}}
    )

    if model_resp.status_code != HTTPStatus.OK:
        return error_response(
            http_response_code=model_resp.status_code,
            message=model_resp.json().get('message')
        )

    registered_model_detailed = model_resp.json().get('registered_model_detailed', {})
    model = {
        'id': registered_model_detailed.get('registered_model', {}).get('name'),
        'project_id': project_id,
        'creation_timestamp': registered_model_detailed.get('creation_timestamp'),
        'last_updated_timestamp': registered_model_detailed.get('last_updated_timestamp')
    }

    return JSONResponse(model)
Ejemplo n.º 3
0
def get_model_version_uri(project_id: int, model_id: Text,
                          version: Text) -> Text:
    """Get model version URI.
    Args:
        project_id {int}: project id
        model_id {Text}: model id (name)
        version {Text}: model version
    Returns:
        Text: path to model package for model version
    """

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    model_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/get-details',
        json={'registered_model': {
            'name': model_id
        }})

    if model_resp.status_code != HTTPStatus.OK:

        if model_resp.status_code == HTTPStatus.NOT_FOUND:
            raise RegisteredModelNotFoundError(f'Model {model_id} not found')

        raise Exception(model_resp.text)

    this_model_versions = filter_model_versions(get_model_versions(project_id),
                                                model_id)

    for ver in this_model_versions:
        if ver.get('model_version', {}).get('version') == version:
            return ver.get('source')

    raise RegisteredModelNotFoundError(
        f'Version {version} of {model_id} not found')
Ejemplo n.º 4
0
def delete_model(request: Request, model_id: Text, project_id: int) -> JSONResponse:
    """Delete model.
    Args:
        model_id {Text}: model id (name)
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {
        'project_id': project_id,
        'model_id': model_id
    })

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    model_resp = requests.delete(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/delete',
        json={'registered_model': {'name': model_id}}
    )

    if model_resp.status_code != HTTPStatus.OK:
        return error_response(
            http_response_code=model_resp.status_code,
            message=model_resp.json().get('message')
        )

    return JSONResponse({'model_id': model_id})
Ejemplo n.º 5
0
def list_models(request: Request, project_id: int) -> JSONResponse:
    """Get models list.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    resp = requests.get(f'{url}/api/2.0/preview/mlflow/registered-models/list')
    registered_models = []

    for model in resp.json().get('registered_models_detailed', []):

        registered_models.append({
            'id': model.get('registered_model', {}).get('name'),
            'project_id': project_id,
            'creation_timestamp': model.get('creation_timestamp'),
            'last_updated_timestamp': model.get('last_updated_timestamp')
        })

    return JSONResponse(registered_models)
Ejemplo n.º 6
0
def list_runs(request: Request, project_id: int,
              experiment_id: Text) -> JSONResponse:
    """Get runs list.
    Args:
        project_id {int}: project id
        experiment_id {Text}: experiment id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    resp = requests.post(url=f'{url}/api/2.0/preview/mlflow/runs/search',
                         json={'experiment_ids': [experiment_id]})

    if resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=resp.status_code,
                              message=resp.json().get('message'))

    runs = resp.json().get('runs', [])

    for run in runs:
        run['id'] = run.get('info', {}).get('run_id')

    return JSONResponse(runs)
Ejemplo n.º 7
0
def list_experiments(request: Request, project_id: int) -> JSONResponse:
    """Get experiments list.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """
    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    resp = requests.get(url=f'{url}/api/2.0/preview/mlflow/experiments/list')
    experiments = []

    for exp in resp.json().get('experiments'):

        experiment_id = exp.get('experiment_id')
        runs_resp = requests.get(
            f'{url}/api/2.0/preview/mlflow/runs/search?experiment_ids=[{experiment_id}]'
        )
        runs = runs_resp.json().get('runs', [])
        creation_time = ''
        last_update_time = ''
        """
        if corresponding tags are empty then fields:
            * creation_time = start_time of the first run;
            * last_update_time = end_time of the last run.
        """
        if len(runs) > 0:
            creation_time = runs[len(runs) - 1].get('info',
                                                    {}).get('start_time')
            last_update_time = runs[0].get('info', {}).get('end_time')

        tags = {tag['key']: tag['value'] for tag in exp.get('tags', [])}
        experiments.append({
            'id':
            experiment_id,
            'user_id':
            tags.get('user_id', ''),
            'name':
            exp.get('name'),
            'artifact_location':
            exp.get('artifact_location'),
            'lifecycle_stage':
            exp.get('lifecycle_stage'),
            'last_update_time':
            tags.get('last_update_time', last_update_time),
            'creation_time':
            tags.get('creation_time', creation_time),
            'description':
            tags.get('mlflow.note.content', ''),
            'project_id':
            tags.get('project_id', project_id)
        })

    return JSONResponse(experiments)
Ejemplo n.º 8
0
def list_projects(request: Request) -> JSONResponse:
    """Get projects list.
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    projects = project_manager.list_projects()
    return JSONResponse(projects)
Ejemplo n.º 9
0
def register_model(
        request: Request,
        project_id: int,
        name: Text = Form(...),
        source: Text = Form(...),
        run_id: Text = Form(...)
) -> JSONResponse:
    """Register model.
    Args:
        project_id {int}: project id
        name {Text}: model name
        source {Text}: path to model package
        run_id {Text}: run id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {
        'project_id': project_id,
        'name': name,
        'source': source,
        'run_id': run_id
    })

    project_manager = ProjectManager()
    if not is_model(source):
        raise ModelDoesNotExistError(f'Model {source} does not exist or is not MLflow model')

    url = project_manager.get_internal_tracking_uri(project_id)
    requests.post(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/create',
        json={'name': name}
    )
    requests.post(
        url=f'{url}/api/2.0/preview/mlflow/model-versions/create',
        json={
            'name': name,
            'source': source,
            'run_id': run_id
        }
    )
    model_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/get-details',
        json={'registered_model': {'name': name}}
    )
    registered_model_detailed = model_resp.json().get('registered_model_detailed', {})
    model = {
        'id': name,
        'project_id': project_id,
        'creation_timestamp': registered_model_detailed.get('creation_timestamp'),
        'last_updated_timestamp': registered_model_detailed.get('last_updated_timestamp')
    }

    return JSONResponse(model, HTTPStatus.CREATED)
Ejemplo n.º 10
0
def get_project(request: Request, project_id: int) -> JSONResponse:  # pylint: disable=invalid-name,redefined-builtin
    """Get project.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    project = project_manager.get_project(project_id)
    return JSONResponse(project)
Ejemplo n.º 11
0
def stat(request: Request) -> JSONResponse:
    """Get statistics of resources usage.
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()

    return JSONResponse(
        dict(projects=project_manager.running_projects_stat(),
             system=system_stat()))
Ejemplo n.º 12
0
def get_experiment(request: Request, experiment_id: Text,
                   project_id: int) -> JSONResponse:
    """Get experiment.
    Args:
        experiment_id {Text}: experiment id
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    experiment_resp = requests.get(
        url=
        f'{url}/api/2.0/preview/mlflow/experiments/get?experiment_id={experiment_id}'
    )

    if experiment_resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=experiment_resp.status_code,
                              message=experiment_resp.json().get('message'))

    experiment = experiment_resp.json().get('experiment')
    experiment_id = experiment.get('experiment_id')
    runs_resp = requests.get(
        f'{url}/api/2.0/preview/mlflow/runs/search?experiment_ids=[{experiment_id}]'
    )
    runs = runs_resp.json().get('runs', [])
    creation_time = ''
    last_update_time = ''
    """
    if corresponding tags are empty then fields:
        * creation_time = start_time of the first run;
        * last_update_time = end_time of the last run.
    """
    if len(runs) > 0:
        creation_time = runs[len(runs) - 1].get('info', {}).get('start_time')
        last_update_time = runs[0].get('info', {}).get('end_time')

    experiment['id'] = experiment.pop('experiment_id')
    tags = {tag['key']: tag['value'] for tag in experiment.pop('tags', [])}
    experiment['description'] = tags.get('mlflow.note.content', '')
    experiment['user_id'] = tags.get('user_id', '')
    experiment['project_id'] = tags.get('project_id', project_id)
    experiment['creation_time'] = tags.get('creation_time', creation_time)
    experiment['last_update_time'] = tags.get('last_update_time',
                                              last_update_time)

    return JSONResponse(experiment)
Ejemplo n.º 13
0
def restore(request: Request, project_id: int) -> JSONResponse:  # pylint: disable=invalid-name,redefined-builtin
    """Restore project.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {'project_id': project_id})

    project_manager = ProjectManager()
    project_manager.restore(project_id)
    project = project_manager.get_project(project_id)

    return JSONResponse(project, HTTPStatus.OK)
Ejemplo n.º 14
0
def get_model_versions(project_id: int) -> List[Dict]:
    """Get all model versions by tracking server uri
    Args:
        project_id {int}: project id
    Returns:
        List[Dict]: list of model versions
    """

    project_manager = ProjectManager()
    tracking_uri = project_manager.get_internal_tracking_uri(project_id)
    model_versions_resp = requests.get(
        url=f'{tracking_uri}/api/2.0/preview/mlflow/model-versions/search')
    model_versions = model_versions_resp.json().get('model_versions_detailed')

    return model_versions
Ejemplo n.º 15
0
def list_artifacts(request: Request, project_id: int,
                   run_id: Text) -> JSONResponse:
    """Get artifacts list.
    Args:
        project_id {int}: project id
        run_id {int}: run_id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {'project_id': project_id, 'run_id': run_id})

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    runs_resp = requests.get(
        url=f'{url}/api/2.0/preview/mlflow/artifacts/list?run_id={run_id}')

    if runs_resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=runs_resp.status_code,
                              message=runs_resp.json().get('message'))

    runs = runs_resp.json()
    root_uri = runs.get('root_uri')
    files = runs.get('files', [])

    runs_list = []

    for i, file in enumerate(files):

        runs_resp = requests.get(
            url=f'{url}/api/2.0/preview/mlflow/runs/get?run_id={run_id}', )

        run = runs_resp.json()
        run_info = run.get('run', {}).get('info', {})
        experiment_id = run_info.get('experiment_id')

        runs_list.append({
            'id': f'{project_id}{experiment_id}{run_id}{i}',
            'project_id': project_id,
            'experiment_id': experiment_id,
            'run_id': run_id,
            'type': str(get_artifact_type(root_uri, file)),
            'creation_timestamp': run_info.get('start_time'),
            'root_uri': root_uri,
            'path': file.get('path')
        })

    return JSONResponse(runs_list)
Ejemplo n.º 16
0
def update_project(
    request: Request,
    project_id: int,
    name: Text = Form(None),
    description: Text = Form(None)
) -> JSONResponse:
    """Update project.
    Args:
        project_id {int}: project id
        name {Text}: project name
        description {Text}: project description
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {
        'project_id': project_id,
        'name': name,
        'description': description
    })

    project_manager = ProjectManager()
    if name is not None:
        project_manager.update_project_name(project_id, name)

    if description is not None:
        project_manager.update_project_description(project_id, description)

    project = project_manager.get_project(project_id)

    return JSONResponse(project)
Ejemplo n.º 17
0
def project_healthcheck(request: Request, project_id: int) -> JSONResponse:  # pylint: disable=invalid-name,redefined-builtin
    """Get project healthcheck (check if project's tracking server process was started).
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    project = project_manager.get_project(project_id)
    is_running = project_manager._is_running(project_id)

    if is_running:
        return JSONResponse(project, HTTPStatus.OK)
    else:
        return JSONResponse(project, HTTPStatus.BAD_REQUEST)
Ejemplo n.º 18
0
def create_project(
    request: Request, name: Text = Form(...), description: Text = Form('')
) -> JSONResponse:
    """Create project.
    Args:
        name {Text}: project name
        description {Text}: project description
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {'name': name, 'description': description})

    project_manager = ProjectManager()
    project_id = project_manager.create_project(name, description)
    project = project_manager.get_project(project_id)

    return JSONResponse(project, HTTPStatus.CREATED)
Ejemplo n.º 19
0
def ping(request: Request, project_id: int) -> JSONResponse:
    """Ping project's tracking server.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    project = project_manager.get_project(project_id)

    try:
        requests.get(url)
        return JSONResponse(project, HTTPStatus.OK)
    except requests.exceptions.ConnectionError:
        return JSONResponse(project, HTTPStatus.BAD_REQUEST)
Ejemplo n.º 20
0
def run_project(request: Request, project_id: int) -> JSONResponse:  # pylint: disable=invalid-name,redefined-builtin
    """Run project's tracking server.
    Args:
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request, {'project_id': project_id})

    project_manager = ProjectManager()
    running = project_manager.run(project_id)

    if not running:
        return error_response(
            http_response_code=HTTPStatus.INTERNAL_SERVER_ERROR,
            message='Internal error, tracking server has terminated')

    project = project_manager.get_project(project_id)
    return JSONResponse(project, HTTPStatus.OK)
Ejemplo n.º 21
0
def get_run(request: Request, run_id: Text, project_id: int) -> JSONResponse:
    """Get run.
    Args:
        run_id {Text}: run id
        project_id {int}: project id
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(request)

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    resp = requests.get(
        url=f'{url}/api/2.0/preview/mlflow/runs/get?run_id={run_id}', )

    if resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=resp.status_code,
                              message=resp.json().get('message'))

    run = resp.json().get('run')
    run['id'] = run.get('info', {}).get('run_id')
    return JSONResponse(run)
Ejemplo n.º 22
0
def check_if_project_and_model_exist(project_id: int, model_id: Text) -> None:
    """Check if project and model are exist.
    Args:
        project_id {int}: project id
        model_id {Text}: model id (name)
    Raises:
        ProjectNotFoundError: if project does not exists;
        RegisteredModelNotFoundError: if project exists, but model does not exist
    """

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)

    if url is None:
        raise ProjectNotFoundError(f'Project with ID {project_id} not found')

    model_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/registered-models/get-details',
        json={'registered_model': {
            'name': model_id
        }})

    if model_resp.status_code != HTTPStatus.OK:
        raise RegisteredModelNotFoundError(f'Model {model_id} not found')
Ejemplo n.º 23
0
def create_experiment(
    request: Request,
    project_id: int,
    user_id: Text = Form(''),
    name: Text = Form(''),
    description: Text = Form('')
) -> JSONResponse:
    """Create experiment
    Args:
        project_id {int}: project id
        user_id {Text}: user id (name)
        name {Text}: experiment name
        description {Text}: experiment description
    Returns:
        starlette.responses.JSONResponse
    """

    log_request(
        request, {
            'project_id': project_id,
            'user_id': user_id,
            'name': name,
            'description': description
        })

    project_manager = ProjectManager()
    url = project_manager.get_internal_tracking_uri(project_id)
    creation_resp = requests.post(
        url=f'{url}/api/2.0/preview/mlflow/experiments/create',
        json={'name': name})
    creation_json = creation_resp.json()
    experiment_id = creation_json.get('experiment_id')

    if creation_resp.status_code != HTTPStatus.OK:
        return error_response(http_response_code=creation_resp.status_code,
                              message=creation_json.get('message'))

    utc_timestamp = get_utc_timestamp()
    tags = {
        'mlflow.note.content': description,
        'user_id': user_id,
        'project_id': str(project_id),
        'creation_time': utc_timestamp,
        'last_update_time': utc_timestamp
    }

    for key, value in tags.items():
        requests.post(
            url=f'{url}/api/2.0/preview/mlflow/experiments/set-experiment-tag',
            json={
                'experiment_id': experiment_id,
                'key': key,
                'value': value
            })

    experiment_request = requests.get(
        url=
        f'{url}/api/2.0/preview/mlflow/experiments/get?experiment_id={experiment_id}'
    )

    experiment = experiment_request.json().get('experiment')
    tags = {tag['key']: tag['value'] for tag in experiment.pop('tags', [])}
    experiment['description'] = tags.get('mlflow.note.content', '')
    experiment['user_id'] = tags.get('user_id', '')
    experiment['project_id'] = tags.get('project_id', '')
    experiment['creation_time'] = tags.get('creation_time', '')
    experiment['last_update_time'] = tags.get('last_update_time', '')

    return JSONResponse(experiment, HTTPStatus.CREATED)