def test_convert_to_api_parameters(self, uuid4, swagger_client_factory):
        # given
        swagger_client = MagicMock()
        swagger_client.get_model.return_value = ApiParameter
        swagger_client_factory.return_value = swagger_client

        # and
        some_uuid = str(uuid.uuid4())
        uuid4.return_value = some_uuid

        # and
        backend = HostedNeptuneBackend(api_token=API_TOKEN)

        # and
        some_object = SomeClass()

        # when
        api_params = backend._convert_to_api_parameters({
            'str':
            'text',
            'bool':
            False,
            'float':
            1.23,
            'int':
            int(12),
            'list': [123, 'abc', ['def']],
            'obj':
            some_object
        })

        # then
        expected_api_params = {
            ApiParameter(id=some_uuid,
                         name='str',
                         parameterType='string',
                         value='text'),
            ApiParameter(id=some_uuid,
                         name='bool',
                         parameterType='string',
                         value='False'),
            ApiParameter(id=some_uuid,
                         name='float',
                         parameterType='double',
                         value='1.23'),
            ApiParameter(id=some_uuid,
                         name='int',
                         parameterType='double',
                         value='12'),
            ApiParameter(id=some_uuid,
                         name='list',
                         parameterType='string',
                         value="[123, 'abc', ['def']]"),
            ApiParameter(id=some_uuid,
                         name='obj',
                         parameterType='string',
                         value=str(some_object))
        }
        self.assertEqual(expected_api_params, set(api_params))
Esempio n. 2
0
    def __init__(self, api_token=None, proxies=None, backend=None):
        self._backend = backend

        if self._backend is None:
            _logger.warning('WARNING: Instantiating Session without specifying a backend is deprecated '
                            'and will be removed in future versions. For current behaviour '
                            'use `neptune.init(...)` or `Session.with_default_backend(...)')

            self._backend = HostedNeptuneBackend(api_token, proxies)
Esempio n. 3
0
    def test_max_compatible_version_ok(self, swagger_client_factory):
        # given
        self._get_swagger_client_mock(swagger_client_factory,
                                      max_compatible='0.5.13')

        # expect
        HostedNeptuneBackend(api_token=API_TOKEN)
    def test_should_take_default_credentials_from_env(self, env,
                                                      swagger_client_factory):
        # when
        backend = HostedNeptuneBackend()

        # then
        self.assertEqual(API_TOKEN, backend.credentials.api_token)
Esempio n. 5
0
    def test_should_accept_given_api_token(self, swagger_client_factory):
        # given
        self._get_swagger_client_mock(swagger_client_factory)

        # when
        session = HostedNeptuneBackend(API_TOKEN)

        # then
        self.assertEqual(API_TOKEN, session.credentials.api_token)
Esempio n. 6
0
    def test_cannot_resolve_host(self, gethostname_mock):
        # given
        token = 'eyJhcGlfYWRkcmVzcyI6Imh0dHBzOi8vdWkuc3RhZ2UubmVwdHVuZS5tbCIsImFwaV91cmwiOiJodHRwczovL3VpLn' \
                'N0YWdlLm5lcHR1bmUuYWkiLCJhcGlfa2V5IjoiOTgzOGQ5NTQtNDAwMy0xMWU5LWJmNTAtMjMxOTgzNTVkYTY2In0='

        gethostname_mock.side_effect = socket.gaierror

        # expect
        with self.assertRaises(CannotResolveHostname):
            HostedNeptuneBackend(token)
Esempio n. 7
0
    def test_depracted_token(self, gethostname_mock):
        # given
        token = 'eyJhcGlfYWRkcmVzcyI6Imh0dHBzOi8vdWkuc3RhZ2UubmVwdHVuZS5tbCIsImF' \
                'waV9rZXkiOiI5ODM4ZDk1NC00MDAzLTExZTktYmY1MC0yMzE5ODM1NWRhNjYifQ=='

        gethostname_mock.side_effect = socket.gaierror

        # expect
        with self.assertRaises(DeprecatedApiToken):
            HostedNeptuneBackend(token)
Esempio n. 8
0
    def test_max_compatible_version_fail(self, swagger_client_factory):
        # given
        self._get_swagger_client_mock(swagger_client_factory,
                                      max_compatible='0.5.12')

        # expect
        with self.assertRaises(UnsupportedClientVersion) as ex:
            HostedNeptuneBackend(api_token=API_TOKEN)

        self.assertTrue(
            "Please install neptune-client==0.5.12" in str(ex.exception))
Esempio n. 9
0
    def with_default_backend(cls, api_token=None):
        """The simplest way to instantiate a ``Session``.

        Args:
            api_token (:obj:`str`):
                User's API token.
                If ``None``, the value of ``NEPTUNE_API_TOKEN`` environment variable will be taken.

        Examples:

            .. code :: python3

                from neptune import Session
                session = Session.with_default_backend()

        """
        return cls(backend=HostedNeptuneBackend(api_token))
Esempio n. 10
0
class Session(object):
    """A class for running communication with Neptune.

    In order to query Neptune experiments you need to instantiate this object first.

    Args:
        backend (:class:`~neptune.backend.Backend`, optional, default is ``None``):
            By default, Neptune client library sends logs, metrics, images, etc to Neptune servers:
            either publicly available SaaS, or an on-premises installation.

            You can pass the default backend instance explicitly to specify its parameters:

            .. code :: python3

                from neptune import Session, HostedNeptuneBackend
                session = Session(backend=HostedNeptuneBackend(...))

            Passing an instance of :class:`~neptune.OfflineBackend` makes your code run without communicating
            with Neptune servers.

            .. code :: python3

                from neptune import Session, OfflineBackend
                session = Session(backend=OfflineBackend())

        api_token (:obj:`str`, optional, default is ``None``):
            User's API token. If ``None``, the value of ``NEPTUNE_API_TOKEN`` environment variable will be taken.
            Parameter is ignored if ``backend`` is passed.

            .. deprecated :: 0.4.4

            Instead, use:

            .. code :: python3

                from neptune import Session
                session = Session.with_default_backend(api_token='...')

        proxies (:obj:`str`, optional, default is ``None``):
            Argument passed to HTTP calls made via the `Requests <https://2.python-requests.org/en/master/>`_ library.
            For more information see their proxies
            `section <https://2.python-requests.org/en/master/user/advanced/#proxies>`_.
            Parameter is ignored if ``backend`` is passed.

            .. deprecated :: 0.4.4

            Instead, use:

            .. code :: python3

                from neptune import Session, HostedNeptuneBackend
                session = Session(backend=HostedNeptuneBackend(proxies=...))

    Examples:

        Create session, assuming you have created an environment variable ``NEPTUNE_API_TOKEN``

        .. code:: python3

            from neptune import Session
            session = Session.with_default_backend()

        Create session and pass ``api_token``

        .. code:: python3

            from neptune import Session
            session = Session.with_default_backend(api_token='...')

        Create an offline session

        .. code:: python3

            from neptune import Session, OfflineBackend
            session = Session(backend=OfflineBackend())

    """
    def __init__(self, api_token=None, proxies=None, backend=None):
        self._backend = backend

        if self._backend is None:
            _logger.warning(
                'WARNING: Instantiating Session without specifying a backend is deprecated '
                'and will be removed in future versions. For current behaviour '
                'use `neptune.init(...)` or `Session.with_default_backend(...)'
            )

            self._backend = HostedNeptuneBackend(api_token, proxies)

    @classmethod
    def with_default_backend(cls, api_token=None):
        """The simplest way to instantiate a ``Session``.

        Args:
            api_token (:obj:`str`):
                User's API token.
                If ``None``, the value of ``NEPTUNE_API_TOKEN`` environment variable will be taken.

        Examples:

            .. code :: python3

                from neptune import Session
                session = Session.with_default_backend()

        """
        return cls(backend=HostedNeptuneBackend(api_token))

    def get_project(self, project_qualified_name):
        """Get a project with given ``project_qualified_name``.

        In order to access experiments data one needs to get a :class:`~neptune.projects.Project` object first.
        This method gives you the ability to do that.

        Args:
            project_qualified_name (:obj:`str`):
                Qualified name of a project in a form of ``namespace/project_name``.

        Returns:
            :class:`~neptune.projects.Project` object.

        Raise:
            :class:`~neptune.api_exceptions.ProjectNotFound`: When a project with given name does not exist.

        Examples:

            .. code:: python3

                # Create a Session instance
                from neptune.sessions import Session
                session = Session()

                # Get a project by it's ``project_qualified_name``:
                my_project = session.get_project('namespace/project_name')

        """
        if not project_qualified_name:
            raise ProjectNotFound(project_qualified_name)

        if not re.match(PROJECT_QUALIFIED_NAME_PATTERN,
                        project_qualified_name):
            raise IncorrectProjectQualifiedName(project_qualified_name)

        return self._backend.get_project(project_qualified_name)

    def get_projects(self, namespace):
        """Get all projects that you have permissions to see in given organization

        | This method gets you all available projects names and their
          corresponding :class:`~neptune.projects.Project` objects.
        | Both private and public projects may be returned for the organization.
          If you have role in private project, it is included.
        | You can retrieve all the public projects that belong to any user or organization,
          as long as you know their username or organization name.

        Args:
            namespace (:obj:`str`): It can either be name of the organization or username.

        Returns:
            :obj:`OrderedDict`
                | **keys** are ``project_qualified_name`` that is: *'organization/project_name'*
                | **values** are corresponding :class:`~neptune.projects.Project` objects.

        Raises:
            `NamespaceNotFound`: When the given namespace does not exist.

        Examples:

            .. code:: python3

                # create Session
                from neptune.sessions import Session
                session = Session()

                # Now, you can list all the projects available for a selected namespace.
                # You can use `YOUR_NAMESPACE` which is your organization or user name.
                # You can also list public projects created by other organizations.
                # For example you can use the `neptune-ml` namespace.

                session.get_projects('neptune-ml')

                # Example output:
                # OrderedDict([('neptune-ml/credit-default-prediction',
                #               Project(neptune-ml/credit-default-prediction)),
                #              ('neptune-ml/GStore-Customer-Revenue-Prediction',
                #               Project(neptune-ml/GStore-Customer-Revenue-Prediction)),
                #              ('neptune-ml/human-protein-atlas',
                #               Project(neptune-ml/human-protein-atlas)),
                #              ('neptune-ml/Ships',
                #               Project(neptune-ml/Ships)),
                #              ('neptune-ml/Mapping-Challenge',
                #               Project(neptune-ml/Mapping-Challenge))
                #              ])
        """

        projects = [
            Project(self._backend, p.id, namespace, p.name)
            for p in self._backend.get_projects(namespace)
        ]
        return OrderedDict((p.full_id, p) for p in projects)
Esempio n. 11
0
def init(project_qualified_name=None,
         api_token=None,
         proxies=None,
         backend=None):
    """Initialize `Neptune client library <https://github.com/neptune-ai/neptune-client>`_ to work with
    specific project.

    Authorize user, sets value of global variable ``project`` to :class:`~neptune.projects.Project` object
    that can be used to create or list experiments, notebooks, etc.

    Args:
        project_qualified_name (:obj:`str`, optional, default is ``None``):
            Qualified name of a project in a form of ``namespace/project_name``.
            If ``None``, the value of ``NEPTUNE_PROJECT`` environment variable will be taken.

        api_token (:obj:`str`, optional, default is ``None``):
            User's API token. If ``None``, the value of ``NEPTUNE_API_TOKEN`` environment variable will be taken.

            .. note::

                It is strongly recommended to use ``NEPTUNE_API_TOKEN`` environment variable rather than
                placing your API token in plain text in your source code.

        proxies (:obj:`dict`, optional, default is ``None``):
            Argument passed to HTTP calls made via the `Requests <https://2.python-requests.org/en/master/>`_ library.
            For more information see their proxies
            `section <https://2.python-requests.org/en/master/user/advanced/#proxies>`_.

            .. note::

                Only `http` and `https` keys are supported by all features.

            .. deprecated :: 0.4.4

            Instead, use:

            .. code :: python3

                from neptune import HostedNeptuneBackend
                neptune.init(backend=HostedNeptuneBackend(proxies=...))

        backend (:class:`~neptune.Backend`, optional, default is ``None``):
            By default, Neptune client library sends logs, metrics, images, etc to Neptune servers:
            either publicly available SaaS, or an on-premises installation.

            You can also pass the default backend instance explicitly to specify its parameters:

            .. code :: python3

                from neptune import HostedNeptuneBackend
                neptune.init(backend=HostedNeptuneBackend(...))

            Passing an instance of :class:`~neptune.OfflineBackend` makes your code run without communicating
            with Neptune servers.

            .. code :: python3

                from neptune import OfflineBackend
                neptune.init(backend=OfflineBackend())

            .. note::
                Instead of passing a ``neptune.OfflineBackend`` instance as ``backend``, you can set an
                environment variable ``NEPTUNE_BACKEND=offline`` to override the default behaviour.

    Returns:
        :class:`~neptune.projects.Project` object that is used to create or list experiments, notebooks, etc.

    Raises:
        `MissingApiToken`: When ``api_token`` is None and ``NEPTUNE_API_TOKEN`` environment variable was not set.
        `MissingProjectQualifiedName`: When ``project_qualified_name`` is None
            and ``NEPTUNE_PROJECT`` environment variable was not set.
        `InvalidApiKey`: When given ``api_token`` is malformed.
        `Unauthorized`: When given ``api_token`` is invalid.

    Examples:

        .. code:: python3

            # minimal invoke
            neptune.init()

            # specifying project name
            neptune.init('jack/sandbox')

            # running offline
            neptune.init(backend=neptune.OfflineBackend())
    """

    if project_qualified_name is None:
        project_qualified_name = os.getenv(envs.PROJECT_ENV_NAME)

    # pylint: disable=global-statement
    with __lock:
        global session, project

        if backend is None:
            backend_name = os.getenv(envs.BACKEND)
            if backend_name == 'offline':
                backend = OfflineBackend()

            elif backend_name is None:
                backend = HostedNeptuneBackend(api_token, proxies)

            else:
                raise InvalidNeptuneBackend(backend_name)

        session = Session(backend=backend)

        if project_qualified_name is None:
            raise MissingProjectQualifiedName()

        project = session.get_project(project_qualified_name)

        return project
    def test_should_accept_given_api_token(self, _):
        # when
        session = HostedNeptuneBackend(API_TOKEN)

        # then
        self.assertEqual(API_TOKEN, session.credentials.api_token)