Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: adopt api changes #637

Merged
merged 20 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Adjust Finetuner based on API changes for Jina AI Cloud. ([#637](https://github.com/jina-ai/finetuner/pull/637))

- Change default `experiment_name` from current working dir to `default`. ([#637](https://github.com/jina-ai/finetuner/pull/637))

### Fixed

- Correctly infer the type of models created using `get_model` in the `build_encoding_dataset` function. )[#623](https://github.com/jina-ai/finetuner/pull/623))
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ build-sdist:

# ---------------------------------------------------------------- Test related targets

PYTEST_ARGS = --show-capture no --full-trace --verbose --cov finetuner/ --cov-report term-missing --cov-report html
PYTEST_ARGS = --show-capture no --verbose --cov finetuner/ --cov-report term-missing --cov-report html

## Run tests
test:
Expand Down
22 changes: 13 additions & 9 deletions finetuner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,16 +267,16 @@ def get_run(run_name: str, experiment_name: Optional[str] = None) -> Run:
return ft.get_run(run_name=run_name, experiment_name=experiment_name)


def list_runs(experiment_name: Optional[str] = None) -> List[Run]:
def list_runs(experiment_name: Optional[str] = None, size: int = 50) -> List[Run]:
"""List every run.

If an experiment name is not specified, we'll list every run across all
experiments.

:param experiment_name: Optional name of the experiment.
:return: A list of `Run` objects.
:param size: Number of runs to retrieve.
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""
return ft.list_runs(experiment_name=experiment_name)
return ft.list_runs(experiment_name=experiment_name, size=size)


def delete_run(run_name: str, experiment_name: Optional[str] = None) -> None:
Expand All @@ -303,11 +303,11 @@ def delete_runs(experiment_name: Optional[str] = None) -> None:
ft.delete_runs(experiment_name=experiment_name)


def create_experiment(name: Optional[str] = None) -> Experiment:
def create_experiment(name: str = 'default') -> Experiment:
"""Create an experiment.

:param name: Optional name of the experiment. If `None`,
the experiment is named after the current directory.
:param name: The name of the experiment. If not provided,
the experiment is named as `default`.
:return: An `Experiment` object.
"""
return ft.create_experiment(name=name)
Expand All @@ -322,9 +322,13 @@ def get_experiment(name: str) -> Experiment:
return ft.get_experiment(name=name)


def list_experiments() -> List[Experiment]:
"""List every experiment."""
return ft.list_experiments()
def list_experiments(size: int = 50) -> List[Experiment]:
"""List every experiment.

:param size: The number of experiments to retrieve.
:return: A list of :class:`Experiment`.
"""
return ft.list_experiments(size=size)
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved


def delete_experiment(name: str) -> Experiment:
Expand Down
30 changes: 16 additions & 14 deletions finetuner/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class FinetunerV1Client(_BaseClient):

""" Experiment API """

def create_experiment(self, name: str, description: Optional[str] = '') -> dict:
def create_experiment(
self, name: str = 'default', description: Optional[str] = ''
) -> dict:
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""Create a new experiment.

:param name: The name of the experiment.
Expand All @@ -53,13 +55,15 @@ def get_experiment(self, name: str) -> dict:
url = self._construct_url(self._base_url, API_VERSION, EXPERIMENTS, name)
return self._handle_request(url=url, method=GET)

def list_experiments(self) -> List[dict]:
"""List all available experiments.
def list_experiments(self, size: int = 50) -> List[dict]:
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""List every experiment.

:return: List of all experiments.
:param size: The number of experiments to retrieve.
:return: A list of :class:`Experiment`.
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""
params = {'size': size}
url = self._construct_url(self._base_url, API_VERSION, EXPERIMENTS)
return self._handle_request(url=url, method=GET)
return self._handle_request(url=url, method=GET, params=params)

def delete_experiment(self, name: str) -> dict:
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""Delete an experiment given its name.
Expand Down Expand Up @@ -92,26 +96,24 @@ def get_run(self, experiment_name: str, run_name: str) -> dict:
)
return self._handle_request(url=url, method=GET)

def list_runs(self, experiment_name: Optional[str] = None) -> List[dict]:
def list_runs(
self, experiment_name: Optional[str] = None, size: int = 50
) -> List[dict]:
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""List all created runs inside a given experiment.

If no experiment is specified, list runs for all available experiments.
:param experiment_name: The name of the experiment.
:param size: Number of runs to retrieve.
:return: List of all runs.
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""
if not experiment_name:
target_experiments = [
experiment[NAME] for experiment in self.list_experiments()
]
url = self._construct_url(self._base_url, API_VERSION, RUNS, RUNS)
else:
target_experiments = [experiment_name]
response = []
for experiment_name in target_experiments:
url = self._construct_url(
self._base_url, API_VERSION, EXPERIMENTS, experiment_name, RUNS
)
response.extend(self._handle_request(url=url, method=GET))
return response
params = {'size': size}
return self._handle_request(url=url, method=GET, params=params)

def delete_run(self, experiment_name: str, run_name: str) -> dict:
bwanglzu marked this conversation as resolved.
Show resolved Hide resolved
"""Delete a run by its name and experiment.
Expand Down
35 changes: 18 additions & 17 deletions finetuner/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,33 +78,34 @@ def get_run(self, name: str) -> Run:
:param name: Name of the run.
:return: A `Run` object.
"""
run_info = self._client.get_run(experiment_name=self._name, run_name=name)
run = self._client.get_run(experiment_name=self._name, run_name=name)
run = Run(
name=run_info[NAME],
config=run_info[CONFIG],
created_at=run_info[CREATED_AT],
description=run_info[DESCRIPTION],
name=run[NAME],
config=run[CONFIG],
created_at=run[CREATED_AT],
description=run[DESCRIPTION],
experiment_name=self._name,
client=self._client,
)
return run

def list_runs(self) -> List[Run]:
def list_runs(self, size: int = 50) -> List[Run]:
"""List every run inside the experiment.

:param size: Number of runs to retrieve.
:return: List of `Run` objects.
"""
run_infos = self._client.list_runs(experiment_name=self._name)
runs = self._client.list_runs(experiment_name=self._name, size=size)['items']
return [
Run(
name=run_info[NAME],
config=run_info[CONFIG],
created_at=run_info[CREATED_AT],
description=run_info[DESCRIPTION],
name=run[NAME],
config=run[CONFIG],
created_at=run[CREATED_AT],
description=run[DESCRIPTION],
experiment_name=self._name,
client=self._client,
)
for run_info in run_infos
for run in runs
]

def delete_run(self, name: str):
Expand Down Expand Up @@ -186,7 +187,7 @@ def create_run(
)

num_workers = kwargs.get(NUM_WORKERS, 4)
run_info = self._client.create_run(
run = self._client.create_run(
run_name=run_name,
experiment_name=self._name,
run_config=config,
Expand All @@ -196,11 +197,11 @@ def create_run(
)
run = Run(
client=self._client,
name=run_info[NAME],
name=run[NAME],
experiment_name=self._name,
config=run_info[CONFIG],
created_at=run_info[CREATED_AT],
description=run_info[DESCRIPTION],
config=run[CONFIG],
created_at=run[CREATED_AT],
description=run[DESCRIPTION],
)
return run

Expand Down
89 changes: 46 additions & 43 deletions finetuner/finetuner.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
from typing import Any, Dict, List, Optional, Union

from docarray import DocumentArray
Expand All @@ -7,6 +6,7 @@
from finetuner.client import FinetunerV1Client
from finetuner.constants import CREATED_AT, DESCRIPTION, NAME, STATUS
from finetuner.data import CSVOptions
from finetuner.excepts import FinetunerServerError
from finetuner.experiment import Experiment
from finetuner.run import Run
from hubble import login_required
Expand All @@ -18,6 +18,7 @@ class Finetuner:
def __init__(self):
self._client = None
self._default_experiment = None
self._default_experiment_name = 'default'

def login(self, force: bool = False, interactive: Optional[bool] = None):
"""Login to Hubble account, initialize a client object
Expand All @@ -33,11 +34,6 @@ def login(self, force: bool = False, interactive: Optional[bool] = None):
force=force, post_success=self._init_state, interactive=interactive
)

@staticmethod
def _get_cwd() -> str:
"""Returns current working directory."""
return os.getcwd().split('/')[-1]

@login_required
def _init_state(self):
"""Initialize client and default experiment."""
Expand All @@ -47,29 +43,29 @@ def _init_state(self):
def _get_default_experiment(self) -> Experiment:
"""Create or retrieve (if it already exists) a default experiment
for the current working directory."""
experiment_name = self._get_cwd()
for experiment in self.list_experiments():
if experiment.name == experiment_name:
if experiment.name == self._default_experiment_name:
return experiment
return self.create_experiment(name=experiment_name)
return self.create_experiment(name=self._default_experiment_name)

@login_required
def create_experiment(self, name: Optional[str] = None) -> Experiment:
def create_experiment(self, name: str = 'default') -> Experiment:
"""Create an experiment.

:param name: Optional name of the experiment. If `None`,
the experiment is named after the current directory.
:return: An `Experiment` object.
"""
if not name:
name = self._get_cwd()
experiment_info = self._client.create_experiment(name=name)
try:
experiment = self._client.get_experiment(name=name)
except FinetunerServerError:
experiment = self._client.create_experiment(name=name)
return Experiment(
client=self._client,
name=experiment_info[NAME],
status=experiment_info[STATUS],
created_at=experiment_info[CREATED_AT],
description=experiment_info[DESCRIPTION],
name=experiment[NAME],
status=experiment[STATUS],
created_at=experiment[CREATED_AT],
description=experiment[DESCRIPTION],
)

@login_required
Expand All @@ -79,29 +75,33 @@ def get_experiment(self, name: str) -> Experiment:
:param name: Name of the experiment.
:return: An `Experiment` object.
"""
experiment_info = self._client.get_experiment(name=name)
experiment = self._client.get_experiment(name=name)
return Experiment(
client=self._client,
name=experiment_info[NAME],
status=experiment_info[STATUS],
created_at=experiment_info[CREATED_AT],
description=experiment_info[DESCRIPTION],
name=experiment[NAME],
status=experiment[STATUS],
created_at=experiment[CREATED_AT],
description=experiment[DESCRIPTION],
)

@login_required
def list_experiments(self) -> List[Experiment]:
"""List every experiment."""
experiment_infos = self._client.list_experiments()
def list_experiments(self, size: int = 50) -> List[Experiment]:
"""List every experiment.

:param size: The number of experiments to retrieve.
:return: A list of :class:`Experiment`.
"""
experiments = self._client.list_experiments(size=size)['items']

return [
Experiment(
client=self._client,
name=experiment_info[NAME],
status=experiment_info[STATUS],
created_at=experiment_info[CREATED_AT],
description=experiment_info[DESCRIPTION],
name=experiment[NAME],
status=experiment[STATUS],
created_at=experiment[CREATED_AT],
description=experiment[DESCRIPTION],
)
for experiment_info in experiment_infos
for experiment in experiments
]

@login_required
Expand All @@ -110,30 +110,30 @@ def delete_experiment(self, name: str) -> Experiment:
:param name: Name of the experiment.
:return: Deleted experiment.
"""
experiment_info = self._client.delete_experiment(name=name)
experiment = self._client.delete_experiment(name=name)
return Experiment(
client=self._client,
name=experiment_info[NAME],
status=experiment_info[STATUS],
created_at=experiment_info[CREATED_AT],
description=experiment_info[DESCRIPTION],
name=experiment[NAME],
status=experiment[STATUS],
created_at=experiment[CREATED_AT],
description=experiment[DESCRIPTION],
)

@login_required
def delete_experiments(self) -> List[Experiment]:
"""Delete every experiment.
:return: List of deleted experiments.
"""
experiment_infos = self._client.delete_experiments()
experiments = self._client.delete_experiments()
return [
Experiment(
client=self._client,
name=experiment_info[NAME],
status=experiment_info[STATUS],
created_at=experiment_info[CREATED_AT],
description=experiment_info[DESCRIPTION],
name=experiment[NAME],
status=experiment[STATUS],
created_at=experiment[CREATED_AT],
description=experiment[DESCRIPTION],
)
for experiment_info in experiment_infos
for experiment in experiments
]

@login_required
Expand Down Expand Up @@ -225,13 +225,16 @@ def get_run(self, run_name: str, experiment_name: Optional[str] = None) -> Run:
return experiment.get_run(name=run_name)

@login_required
def list_runs(self, experiment_name: Optional[str] = None) -> List[Run]:
def list_runs(
self, experiment_name: Optional[str] = None, size: int = 50
) -> List[Run]:
"""List every run.

If an experiment name is not specified, we'll list every run across all
experiments.

:param experiment_name: Optional name of the experiment.
:param size: Number of runs to retrieve.
:return: A list of `Run` objects.
"""
if not experiment_name:
Expand All @@ -240,7 +243,7 @@ def list_runs(self, experiment_name: Optional[str] = None) -> List[Run]:
experiments = [self.get_experiment(name=experiment_name)]
runs = []
for experiment in experiments:
runs.extend(experiment.list_runs())
runs.extend(experiment.list_runs(size=size))
return runs

@login_required
Expand Down
Loading