diff --git a/CHANGELOG.md b/CHANGELOG.md index e94ab667d..a6e0cf810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ - Added support for `airflow` integration ([#1466](https://github.com/neptune-ai/neptune-client/pull/1466)) ### Changes -- Add handling of project limits [#1456](https://github.com/neptune-ai/neptune-client/pull/1456) +- Add handling of project limits ([#1456](https://github.com/neptune-ai/neptune-client/pull/1456)) +- Language and style improvements ([#1465](https://github.com/neptune-ai/neptune-client/pull/1465)) ### Fixes - Fix exception handling in `ApiMethodWrapper.handle_neptune_http_errors` ([#1469](https://github.com/neptune-ai/neptune-client/pull/1469)) diff --git a/src/neptune/__init__.py b/src/neptune/__init__.py index 2df8e25cf..bbefe37b5 100644 --- a/src/neptune/__init__.py +++ b/src/neptune/__init__.py @@ -15,8 +15,8 @@ # """Log and organize all your ML model metadata with neptune.ai. -There are four kinds of Neptune object: run, model, model version, and project. -These help you track, store, and visualize metadata related to your model-training experiments. +There are four kinds of Neptune objects: run, model, model version, and project. +They help you track, store, and visualize metadata related to your model-training experiments. The package contains the functions and constructors needed to initialize the objects. You can either create new objects or connect to existing ones (to, for example, fetch or add more metadata). diff --git a/src/neptune/cli/__main__.py b/src/neptune/cli/__main__.py index 134166132..27477a6a5 100644 --- a/src/neptune/cli/__main__.py +++ b/src/neptune/cli/__main__.py @@ -44,5 +44,5 @@ def main(): try: loaded_plugin = entry_point.load() except Exception as e: - warnings.warn(f"Failed loading neptune plug-in `{name}` with exception: {e}") + warnings.warn(f"Failed to load neptune plug-in `{name}` with exception: {e}") main.add_command(loaded_plugin, name) diff --git a/src/neptune/cli/clear.py b/src/neptune/cli/clear.py index 91998b0aa..5015614f8 100644 --- a/src/neptune/cli/clear.py +++ b/src/neptune/cli/clear.py @@ -51,7 +51,7 @@ def clear(self, path: Path, force: bool = False, clear_eventual: bool = True): @staticmethod def remove_sync_containers(path: Path): """ - Function can remove SYNC_DIRECTORY safely, Neptune client stores only files to upload in this location. + Function can remove SYNC_DIRECTORY safely, Neptune client only stores files to upload in this location. """ shutil.rmtree(path / SYNC_DIRECTORY, ignore_errors=True) diff --git a/src/neptune/cli/commands.py b/src/neptune/cli/commands.py index 687653f58..5d7d944d4 100644 --- a/src/neptune/cli/commands.py +++ b/src/neptune/cli/commands.py @@ -50,8 +50,8 @@ def status(path: Path) -> None: """List synchronized and unsynchronized objects in the given directory. Trashed objects are not listed. - Neptune stores object data on disk in '.neptune' directories. In case an object executes offline - or network is unavailable as the object executes, object data can be synchronized + Neptune stores object data on disk in the '.neptune' directory. If an object executes offline + or if the network is unavailable as the object executes, the object data can be synchronized with the server with this command line utility. Examples: @@ -100,10 +100,10 @@ def sync( project_name: Optional[str], offline_only: Optional[bool], ): - """Synchronizes objects with unsent data with the server. + """Synchronizes objects with unsent data to the server. - Neptune stores object data on disk in '.neptune' directories. In case an object executes offline - or network is unavailable as the run executes, object data can be synchronized + Neptune stores object data on disk in the '.neptune' directory. If an object executes offline + or if the network is unavailable as the run executes, the object data can be synchronized with the server with this command line utility. You can list unsynchronized runs with `neptune status` diff --git a/src/neptune/cli/status.py b/src/neptune/cli/status.py index 9a4c511a4..1f356802e 100644 --- a/src/neptune/cli/status.py +++ b/src/neptune/cli/status.py @@ -36,9 +36,9 @@ from neptune.internal.utils.logger import logger offline_run_explainer = """ -Runs which execute offline are not created on the server and they are not assigned to projects; +Runs that execute offline are not created on the server and are not assigned to projects; instead, they are identified by UUIDs like the ones above. -When synchronizing offline runs, please specify the workspace and project using the "--project" +When synchronizing offline runs, specify the workspace and project using the "--project" flag. Alternatively, you can set the environment variable {} to the target workspace/project. See the examples below. """.format( diff --git a/src/neptune/cli/utils.py b/src/neptune/cli/utils.py index a872f4295..948417c94 100644 --- a/src/neptune/cli/utils.py +++ b/src/neptune/cli/utils.py @@ -78,7 +78,7 @@ def get_metadata_container( _project_name_missing_message = ( "Project name not provided. Could not synchronize offline runs." - " To synchronize offline run, specify the project name with the --project flag" + " To synchronize an offline run, specify the project name with the --project flag" f" or by setting the {PROJECT_ENV_NAME} environment variable." ) @@ -113,7 +113,7 @@ def is_container_synced_and_remove_junk(experiment_path: Path) -> bool: def _is_execution_synced_and_remove_junk(execution_path: Path) -> bool: """ - The DiskQueue.close() method remove junk metadata from disk when queue is empty. + The DiskQueue.close() method removes junk metadata from the disk when the queue is empty. """ with DiskQueue(execution_path, lambda x: x.to_dict(), Operation.from_dict, threading.RLock()) as disk_queue: return disk_queue.is_empty() diff --git a/src/neptune/common/exceptions.py b/src/neptune/common/exceptions.py index 9ee3f57a6..6c79fff3e 100644 --- a/src/neptune/common/exceptions.py +++ b/src/neptune/common/exceptions.py @@ -93,7 +93,7 @@ def __init__(self): There are two options to add it: - specify it in your code - - set as an environment variable in your operating system. + - set it as an environment variable in your operating system. {h2}CODE{end} Pass the token to the {bold}init_run(){end} function via the {bold}api_token{end} argument: @@ -183,7 +183,7 @@ def __init__(self): - {correct}WORKSPACE_NAME{end}: can be your username or your organization name - {correct}PROJECT_NAME{end}: the name specified for the project - - Ask your organization administrator to grant you necessary privileges to the project. + - Ask your organization administrator to grant you the necessary privileges to the project. {correct}Need help?{end}-> https://docs.neptune.ai/getting_help """ @@ -207,7 +207,7 @@ def __init__(self, msg=None): - {correct}WORKSPACE_NAME{end}: can be your username or your organization name - {correct}PROJECT_NAME{end}: the name specified for the project - - Ask your organization administrator to grant you necessary privileges to the project. + - Ask your organization administrator to grant you the necessary privileges to the project. {correct}Need help?{end}-> https://docs.neptune.ai/getting_help """ diff --git a/src/neptune/common/utils.py b/src/neptune/common/utils.py index f5d6a201e..5883e233a 100644 --- a/src/neptune/common/utils.py +++ b/src/neptune/common/utils.py @@ -81,7 +81,7 @@ def validate_notebook_path(path): def assure_directory_exists(destination_dir): - """Check if `destination_dir` DIRECTORY exists, or creates one""" + """Checks if `destination_dir` DIRECTORY exists, or creates one""" if not destination_dir: destination_dir = os.getcwd() @@ -159,7 +159,7 @@ def update_session_proxies(session, proxies): def get_git_info(repo_path=None): """Retrieve information about git repository. - If attempt fails, ``None`` will be returned. + If the attempt fails, ``None`` will be returned. Args: repo_path (:obj:`str`, optional, default is ``None``): diff --git a/src/neptune/exceptions.py b/src/neptune/exceptions.py index 0d8ec28d0..380a2a00a 100644 --- a/src/neptune/exceptions.py +++ b/src/neptune/exceptions.py @@ -146,7 +146,7 @@ def __init__(self, field_path): The field "{field_path}" was not found. There are two possible reasons: - - There is a typo in a path. Double-check your code for typos. + - There is a typo in the path. Double-check your code for typos. - You are fetching a field that another process created, but the local representation is not synchronized. If you are sending metadata from multiple processes at the same time, synchronize the local representation before fetching values: {python}run.sync(){end} @@ -365,7 +365,7 @@ def __init__( {end} The Neptune client couldn't find your project name. {available_projects_message}{available_workspaces_message} -There are two options two add it: +There are two options to add it: - specify it in your code - set an environment variable in your operating system. diff --git a/src/neptune/handler.py b/src/neptune/handler.py index 5a6031f5a..331f53001 100644 --- a/src/neptune/handler.py +++ b/src/neptune/handler.py @@ -127,7 +127,7 @@ def __getattr__(self, item: str): For example: You're trying run[{self._path}].{item}() but you probably want run.{item}(). - To obtain the root object of the namespace handler, you can do: + To obtain the root object of the namespace handler, you can do the following: root_run = run[{self._path}].get_root_object() root_run.{item}() """, @@ -136,7 +136,7 @@ def __getattr__(self, item: str): return object.__getattribute__(self, item) def _get_attribute(self): - """Returns Attribute defined in `self._path` or throws MissingFieldException""" + """Returns an attribute defined in `self._path` or throws MissingFieldException.""" attr = self._container.get_attribute(self._path) if attr is None: raise MissingFieldException(self._path) @@ -144,7 +144,7 @@ def _get_attribute(self): @property def container(self) -> "MetadataContainer": - """Returns the container that the attribute is attached to""" + """Returns the container that the attribute is attached to.""" return self._container def get_root_object(self) -> "NeptuneObject": @@ -159,7 +159,7 @@ def get_root_object(self) -> "NeptuneObject": >>> pretraining_run = pretraining.get_root_object() >>> pretraining_run.stop() # The root run is stopped - For more, see the docs: + For more information, see the docs: https://docs.neptune.ai/api/field_types/#get_root_object """ return self._container @@ -168,7 +168,7 @@ def get_root_object(self) -> "NeptuneObject": def assign(self, value, *, wait: bool = False) -> None: """Assigns the provided value to the field. - Available for following field types (`Field types docs page`_): + Available for the following field types: * `Integer` * `Float` * `Boolean` @@ -186,7 +186,7 @@ def assign(self, value, *, wait: bool = False) -> None: >>> import neptune >>> run = neptune.init_run() - >>> # You can both use the Python assign operator (=) + >>> # You can use both the Python assign operator (=) ... run['parameters/max_epochs'] = 5 >>> # as well as directly use the .assign method ... run['parameters/max_epochs'].assign(5) @@ -203,7 +203,7 @@ def assign(self, value, *, wait: bool = False) -> None: >>> params = {'max_epochs': 5, 'lr': 0.4} >>> run['parameters'] = params - .. _Field types docs page: + For more information, see the docs: https://docs.neptune.ai/api-reference/field-types """ with self._container.lock(): @@ -217,7 +217,7 @@ def assign(self, value, *, wait: bool = False) -> None: @check_protected_paths def upload(self, value, *, wait: bool = False) -> None: - """Uploads provided file under specified field path. + """Uploads the provided file under the specified field path. Args: value (str or File): Path to the file to be uploaded or `File` value object. @@ -236,14 +236,12 @@ def upload(self, value, *, wait: bool = False) -> None: ... # When downloaded the filename is a combination of path and the extension ... run["dataset/data_sample"].download() # data_sample.csv - Explicitely create File value object + Explicitly create File value object >>> from neptune.types import File >>> run["dataset/data_sample"].upload(File("sample_data.csv")) - You may also want to check `upload docs page`_. - - .. _upload docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#upload """ @@ -282,7 +280,8 @@ def log( ) -> None: """Logs the provided value or a collection of values. - Available for following field types (`Field types docs page`_): + Available for the following field types: + * `FloatSeries` * `StringSeries` * `FileSeries` @@ -300,7 +299,7 @@ def log( This makes the call synchronous. Defaults to `False`. - .. _Field types docs page: + For more information, see the docs: https://docs.neptune.ai/api-reference/field-types """ @@ -362,7 +361,7 @@ def append( * `FileSeries` - series of files When you log the first value, the type of the value determines what type of field is created. - For more, see the field types documentation: https://docs.neptune.ai/api/field_types + To learn more about field types, see the docs: https://docs.neptune.ai/api/field_types Args: value: Value to be added to the series field. @@ -370,7 +369,7 @@ def append( timestamp: Optional time index of the log entry being appended, in Unix time format. If None, the current time (obtained with `time.time()`) is used. wait: If True, the client sends all tracked metadata to the server before executing the call. - For details, see https://docs.neptune.ai/api/universal/#wait + For more information, see: https://docs.neptune.ai/api/universal/#wait Examples: >>> import neptune @@ -404,14 +403,14 @@ def extend( ) -> None: """Logs a series of values by appending the provided collection of values to the end of the series. - Available for following series field types: + Available for the following series field types: * `FloatSeries` - series of float values * `StringSeries` - series of strings * `FileSeries` - series of files When you log the first value, the type of the value determines what type of field is created. - For more, see the field types documentation: https://docs.neptune.ai/api/field_types + To learn more about field types, see the docs: https://docs.neptune.ai/api/field_types Args: values: Values to be added to the series field, as a dictionary or collection. @@ -423,7 +422,7 @@ def extend( Example: The following example reads a CSV file into a pandas DataFrame and extracts the values - to create a Neptune series. + to create a Neptune series: >>> import neptune >>> run = neptune.init_run() >>> for epoch in range(n_epochs): @@ -449,19 +448,17 @@ def extend( @check_protected_paths def add(self, values: Union[str, Iterable[str]], *, wait: bool = False) -> None: - """Adds the provided tag or tags to the run's tags. + """Adds the provided tags to the run. Args: values (str or collection of str): Tag or tags to be added. .. note:: - If you want you can use emojis in your tags eg. "Exploration 🧪" - wait (bool, optional): If `True` the client will wait to send all tracked metadata to the server first. + You can use emojis in your tags. For example, "Exploration 🧪" + wait (bool, optional): If `True`, the client will wait to send all tracked metadata to the server first. This makes the call synchronous. Defaults to `False`. - You may also want to check `add docs page`_. - - .. _add types docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#add """ verify_type("values", values, (str, Iterable)) @@ -494,17 +491,15 @@ def pop(self, path: str = None, *, wait: bool = False) -> None: @check_protected_paths def remove(self, values: Union[str, Iterable[str]], *, wait: bool = False) -> None: - """Removes the provided tag or tags from the set. + """Removes the provided tags from the set. Args: - values (str or collection of str): Tag or tags to be removed. - wait (bool, optional): If `True` the client will wait to send all tracked metadata to the server first. + values (str or collection of str): Tags to be removed. + wait (bool, optional): If `True`, the client will wait to send all tracked metadata to the server first. This makes the call synchronous. Defaults to `False`. - You may also want to check `remove docs page`_. - - .. _remove docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#remove """ return self._pass_call_to_attr(function_name="remove", values=values, wait=wait) @@ -514,21 +509,20 @@ def clear(self, *, wait: bool = False): """Removes all tags from the `StringSet`. Args: - wait (bool, optional): If `True` the client will wait to send all tracked metadata to the server first. + wait (bool, optional): If `True`, the client will wait to send all tracked metadata to the server first. This makes the call synchronous. Defaults to `False`. - You may also want to check `clear docs page`_. - - .. _clear docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#clear """ return self._pass_call_to_attr(function_name="clear", wait=wait) def fetch(self): - """Fetches fields value or in case of a namespace fetches values of all non-File Atom fields as a dictionary. + """Fetches fields value or, in case of a namespace, fetches values of all non-File Atom fields as a dictionary. + + Available for the following field types: - Available for following field types (`Field types docs page`_): * `Integer` * `Float` * `Boolean` @@ -538,32 +532,35 @@ def fetch(self): * `Namespace handler` Returns: - Value stored in the field or in case of a namespace a dictionary containing all non-Atom fields values. + If called on a field, returns the stored value. + If called on a namespace, returns a dictionary containing the values of all non-Atom fields. - .. _Field types docs page: + For more information on field types, see the docs: https://docs.neptune.ai/api-reference/field-types """ return self._pass_call_to_attr(function_name="fetch") def fetch_last(self): - """Fetches last value stored in the series from Neptune servers. + """Fetches the last value stored in the series from Neptune. + + Available for the following field types: - Available for following field types (`Field types docs page`_): * `FloatSeries` * `StringSeries` Returns: - Fetches last value stored in the series from Neptune servers. + Fetches the last value stored in the series from Neptune. - .. _Field types docs page: + For more information on field types, see the docs: https://docs.neptune.ai/api-reference/field-types """ return self._pass_call_to_attr(function_name="fetch_last") def fetch_values(self, *, include_timestamp: Optional[bool] = True): - """Fetches all values stored in the series from Neptune servers. + """Fetches all values stored in the series from Neptune. + + Available for the following field types: - Available for following field types (`Field types docs page`_): * `FloatSeries` * `StringSeries` @@ -574,36 +571,35 @@ def fetch_values(self, *, include_timestamp: Optional[bool] = True): Returns: ``Pandas.DataFrame``: containing all the values and their indexes stored in the series field. - .. _Field types docs page: + For more information on field types, see the docs: https://docs.neptune.ai/api-reference/field-types """ return self._pass_call_to_attr(function_name="fetch_values", include_timestamp=include_timestamp) @check_protected_paths def delete_files(self, paths: Union[str, Iterable[str]], *, wait: bool = False) -> None: - """Delete the file or files specified by paths from the `FileSet` stored on the Neptune servers. + """Deletes the files specified by the paths from the `FileSet` stored on the Neptune servers. Args: paths (str or collection of str): `Path` or paths to files or folders to be deleted. - Note that these are paths relative to the FileSet itself e.g. if the `FileSet` contains - file `example.txt`, `varia/notes.txt`, `varia/data.csv` to delete whole subfolder you would pass - varia as the argument. - wait (bool, optional): If `True` the client will wait to send all tracked metadata to the server. + Note that the paths are relative to the FileSet itself. For example, if the `FileSet` contains + the files `example.txt`, `varia/notes.txt`, `varia/data.csv`, to delete the entire varia subfolder, + you would pass varia as the argument. + wait (bool, optional): If `True`, the client will wait to send all tracked metadata to the server. This makes the call synchronous. Defaults to `None`. - You may also want to check `delete_files docs page`_. - - .. _delete_files docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#delete_files """ return self._pass_call_to_attr(function_name="delete_files", paths=paths, wait=wait) @check_protected_paths def download(self, destination: str = None) -> None: - """Downloads the stored file or files to the working directory or specified destination. + """Downloads the stored files to the working directory or to the specified destination. + + Available for the following field types: - Available for following field types (`Field types docs page`_): * `File` * `FileSeries` * `FileSet` @@ -617,13 +613,13 @@ def download(self, destination: str = None) -> None: If `destination` is a path to a file, the file will be downloaded under the specified name. Defaults to `None`. - .. _Field types docs page: + For more information, see the docs: https://docs.neptune.ai/api-reference/field-types """ return self._pass_call_to_attr(function_name="download", destination=destination) def download_last(self, destination: str = None) -> None: - """Downloads the stored file or files to the working directory or specified destination. + """Downloads the stored files to the working directory or to the specified destination. Args: destination (str, optional): Path to where the file(s) should be downloaded. @@ -633,9 +629,7 @@ def download_last(self, destination: str = None) -> None: If `destination` is a path to a file, the file will be downloaded under the specified name. Defaults to `None`. - You may also want to check `download_last docs page`_. - - .. _download_last docs page: + For more information, see the docs: https://docs.neptune.ai/api/field_types#download_last """ return self._pass_call_to_attr(function_name="download_last", destination=destination) @@ -643,7 +637,7 @@ def download_last(self, destination: str = None) -> None: def fetch_hash(self) -> str: """Fetches the hash of an artifact. - You may also want to check `fetch_hash docs page`_. + You may also want to check the docs: https://docs.neptune.ai/api/field_types#fetch_hash """ return self._pass_call_to_attr(function_name="fetch_hash") @@ -651,7 +645,7 @@ def fetch_hash(self) -> str: def fetch_extension(self) -> str: """Fetches the extension of a file. - You may also want to check `fetch_extension docs page`_. + You may also want to check the docs: https://docs.neptune.ai/api/field_types#fetch_extension """ return self._pass_call_to_attr(function_name="fetch_extension") @@ -659,26 +653,26 @@ def fetch_extension(self) -> str: def fetch_files_list(self) -> List[ArtifactFileData]: """Fetches the list of files in an artifact and their metadata. - You may also want to check `fetch_files_list docs page`_. + You may also want to check the docs: https://docs.neptune.ai/api/field_types#fetch_files_list """ return self._pass_call_to_attr(function_name="fetch_files_list") def list_fileset_files(self, path: Optional[str] = None) -> List[FileEntry]: - """Fetches metadata about the file set. + """Fetches metadata of the file set. - If the top-level artifact of the field is a directory, only metadata about this directory is returned. - You can use the `path` argument to list metadata about files contained inside the directory or subdirectories. + If the top-level artifact of the field is a directory, only the metadata of this directory is returned. + You can use the `path` argument to list metadata of the files contained inside the directory or subdirectories. Args: - path: Path to a nested directory, to get metadata about files contained within the directory. + path: Path to a nested directory, to get metadata of the files contained within the directory. Returns: List of FileEntry items with the following metadata: name, size (bytes), mtime (last modification time), and file type (file or directory). Examples: - In this example, a Neptune run (RUN-100) has a FileSet field "dataset" containing a directory called "data" + In this example, a Neptune run (RUN-100) has a FileSet field "dataset" containing a directory called "data", which has a subdirectory "samples" and a file "dataset.csv". The code for logging this would be: `run["dataset"].upload_files("data")` @@ -696,7 +690,7 @@ def list_fileset_files(self, path: Optional[str] = None) -> List[FileEntry]: tzinfo=tzutc()), file_type='file'), FileEntry(name='sample_v3.csv', size=215, mtime=datetime.datetime(2023, 8, 17, 10, 31, 26, 338000, tzinfo=tzutc()), file_type='file'), ...] - For more, see the API reference: + For more information, see the API reference: https://docs.neptune.ai/api/field_types#list_fileset_files """ return self._pass_call_to_attr(function_name="list_fileset_files", path=path) @@ -708,7 +702,7 @@ def _pass_call_to_attr(self, function_name, **kwargs): def track_files(self, path: str, *, destination: str = None, wait: bool = False) -> None: """Creates an artifact tracking some files. - You may also want to check `track_files docs page`_. + You may also want to check the docs: https://docs.neptune.ai/api/field_types#track_files """ with self._container.lock(): @@ -726,9 +720,9 @@ def __delitem__(self, path) -> None: class ExtendUtils: @staticmethod def transform_to_extend_format(value): - """Preserve nested structure created by `Namespaces` and `dict_like` objects, - but replace all other values with single-element lists, - so work can be delegated to `extend` method.""" + """Preserves the nested structure created by `Namespaces` and `dict_like` objects, + but replaces all other values with single-element lists, + so the work can be delegated to `extend` method.""" if isinstance(value, Namespace) or is_dict_like(value): return {k: ExtendUtils.transform_to_extend_format(v) for k, v in value.items()} @@ -739,21 +733,21 @@ def transform_to_extend_format(value): @staticmethod def validate_values_for_extend(values, steps, timestamps): - """Validates if input data is a collection or Namespace with collections leafs. + """Validates if the input data is a collection or a namespace with collections leafs. If steps or timestamps are passed, check if its length is equal to all given values.""" collections_lengths = set(ExtendUtils.generate_leaf_collection_lengths(values)) if len(collections_lengths) > 1: if steps is not None: - raise NeptuneUserApiInputException("Number of steps must be equal to number of values") + raise NeptuneUserApiInputException("Number of steps must be equal to the number of values") if timestamps is not None: - raise NeptuneUserApiInputException("Number of timestamps must be equal to number of values") + raise NeptuneUserApiInputException("Number of timestamps must be equal to the number of values") else: common_collections_length = next(iter(collections_lengths)) if steps is not None and common_collections_length != len(steps): - raise NeptuneUserApiInputException("Number of steps must be equal to number of values") + raise NeptuneUserApiInputException("Number of steps must be equal to the number of values") if timestamps is not None and common_collections_length != len(timestamps): - raise NeptuneUserApiInputException("Number of timestamps must be equal to number of values") + raise NeptuneUserApiInputException("Number of timestamps must be equal to the number of values") @staticmethod def generate_leaf_collection_lengths(values) -> Iterator[int]: @@ -766,4 +760,4 @@ def generate_leaf_collection_lengths(values) -> Iterator[int]: elif is_collection(values): yield len(values) else: - raise NeptuneUserApiInputException("Values must be a collection or Namespace leafs must be collections") + raise NeptuneUserApiInputException("Values must be a collection or namespace leafs must be collections") diff --git a/src/neptune/version.py b/src/neptune/version.py index 942b1ced5..53a43925f 100644 --- a/src/neptune/version.py +++ b/src/neptune/version.py @@ -45,7 +45,7 @@ def detect_version() -> str: if neptune_version is not None and neptune_client_version is not None: raise RuntimeError( "We've detected that the 'neptune' and 'neptune-client' packages are both installed. " - "Uninstall each of them and then install only the new 'neptune' package. For more, " + "Uninstall each of them and then install only the new 'neptune' package. For more information, " "see https://docs.neptune.ai/setup/upgrading/" ) elif neptune_version is not None: