Skip to content

Commit

Permalink
PT-5054 Adding session and workspace descriptors (#615)
Browse files Browse the repository at this point in the history
* Adding session and workspace descriptors (no tests)
* Adding tests to session descriptor
* Adding tests to WorkspaceId descriptor
* Renaming main to base module
* Removing non-authenticated tests for WorkspaceId and Session
* Finalize the test coverage
* Removing unnecessary auth tests in initialization
---------

Co-authored-by: Javid Gafar-zada <[email protected]>
  • Loading branch information
andher1802 and javidq authored May 29, 2024
1 parent c3cdf51 commit 6af95b7
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 35 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ You can check your current version with the following command:
```

For more information, see [UP42 Python package description](https://pypi.org/project/up42-py/).

## 1.0.4a3

**May 27, 2024**

- Added `Session` and `WorkspaceId` descriptors to provide access to session and workspace_id from other classes.
- Renaming `main` module to `base`.


## 1.0.4a2

**May 24, 2024**
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "up42-py"
version = "1.0.4a2"
version = "1.0.4a3"
description = "Python SDK for UP42, the geospatial marketplace and developer platform."
authors = ["UP42 GmbH <[email protected]>"]
license = "https://github.com/up42/up42-py/blob/master/LICENSE"
Expand Down
56 changes: 45 additions & 11 deletions tests/test_main.py → tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
import dataclasses
from typing import Union
from unittest import mock

import pytest

from up42 import main
from up42 import base

from .fixtures import fixtures_globals as constants


class TestWorkspace:
def test_fails_to_provide_properties_if_not_authenticated(self):
with pytest.raises(main.UserNotAuthenticated):
_ = main.workspace.auth
with pytest.raises(main.UserNotAuthenticated):
_ = main.workspace.id
with pytest.raises(base.UserNotAuthenticated):
_ = base.workspace.auth
with pytest.raises(base.UserNotAuthenticated):
_ = base.workspace.id

def test_should_authenticate(self, requests_mock):
requests_mock.post("https://api.up42.com/oauth/token", json={"access_token": constants.TOKEN})
requests_mock.get(
url="https://api.up42.com/users/me",
json={"data": {"id": constants.WORKSPACE_ID}},
)
main.workspace.authenticate(username=constants.USER_EMAIL, password=constants.PASSWORD)
assert main.workspace.id == constants.WORKSPACE_ID
base.workspace.authenticate(username=constants.USER_EMAIL, password=constants.PASSWORD)
assert base.workspace.id == constants.WORKSPACE_ID


# TODO: these tests to be moved to test_initialization
class TestNonWorkspace:
@pytest.fixture(autouse=True)
def workspace(self, auth_mock):
with mock.patch("up42.main.workspace") as workspace_mock:
with mock.patch("up42.base.workspace") as workspace_mock:
workspace_mock.auth = auth_mock
workspace_mock.id = constants.WORKSPACE_ID
yield
Expand All @@ -43,11 +45,11 @@ def test_get_webhook_events(self, requests_mock):
"error": {},
},
)
assert main.get_webhook_events() == events
assert base.get_webhook_events() == events

@pytest.mark.parametrize("return_json", [False, True])
def test_get_webhooks(self, webhooks_mock, return_json):
webhooks = main.get_webhooks(return_json=return_json)
webhooks = base.get_webhooks(return_json=return_json)
expected = webhooks_mock.get_webhooks(return_json=return_json)
if return_json:
assert webhooks == expected
Expand All @@ -63,4 +65,36 @@ def test_get_credits_balance(self, requests_mock):
url=balance_url,
json={"data": balance},
)
assert main.get_credits_balance() == balance
assert base.get_credits_balance() == balance


@dataclasses.dataclass(eq=True)
class ActiveRecord:
session = base.Session()
workspace_id: Union[str, base.WorkspaceId] = dataclasses.field(default=base.WorkspaceId())


class TestDescriptors:
@pytest.fixture(autouse=True)
def workspace(self, auth_mock):
with mock.patch("up42.base.workspace") as workspace_mock:
workspace_mock.auth = auth_mock
workspace_mock.id = constants.WORKSPACE_ID
yield

def test_should_provide_session(self):
record = ActiveRecord()
assert record.session == base.workspace.auth.session

def test_session_should_not_be_represented(self):
assert "session" not in repr(ActiveRecord())

def test_should_allow_to_set_workspace_id(self):
record = ActiveRecord(workspace_id="custom_workspace_id")
assert record.workspace_id == "custom_workspace_id"
assert "custom_workspace_id" in repr(record)

def test_should_provide_default_workspace_id(self):
record = ActiveRecord()
assert record.workspace_id == constants.WORKSPACE_ID
assert constants.WORKSPACE_ID in repr(record)
17 changes: 2 additions & 15 deletions tests/test_initialization.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
from unittest import mock

import pytest

import up42
from up42 import catalog, main, storage, tasking
from up42 import catalog, storage, tasking

from .fixtures import fixtures_globals as constants


def test_fails_to_initialize_if_not_authenticated():
with pytest.raises(main.UserNotAuthenticated):
up42.initialize_catalog()
with pytest.raises(main.UserNotAuthenticated):
up42.initialize_storage()
with pytest.raises(main.UserNotAuthenticated):
up42.initialize_order(order_id=constants.ORDER_ID)
with pytest.raises(main.UserNotAuthenticated):
up42.initialize_asset(asset_id=constants.ASSET_ID)


def test_should_initialize_objects(
auth_mock,
order_mock,
asset_mock,
):
with mock.patch("up42.main.workspace") as workspace_mock:
with mock.patch("up42.base.workspace") as workspace_mock:
workspace_mock.id = constants.WORKSPACE_ID
workspace_mock.auth = auth_mock

Expand Down
2 changes: 1 addition & 1 deletion up42/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# pylint: disable=only-importing-modules-is-allowed
from up42.asset import Asset
from up42.auth import Auth
from up42.base import authenticate, create_webhook, get_credits_balance, get_webhook_events, get_webhooks
from up42.catalog import Catalog
from up42.initialization import (
initialize_asset,
Expand All @@ -31,7 +32,6 @@
initialize_tasking,
initialize_webhook,
)
from up42.main import authenticate, create_webhook, get_credits_balance, get_webhook_events, get_webhooks
from up42.order import Order
from up42.storage import Storage
from up42.tasking import Tasking
Expand Down
17 changes: 17 additions & 0 deletions up42/main.py → up42/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import warnings
from typing import Any, List, Optional, Union

import requests

from up42 import auth as up42_auth
from up42 import host, utils, webhooks

Expand Down Expand Up @@ -63,6 +65,21 @@ def authenticate(
authenticate = workspace.authenticate


class Session:
def __get__(self, obj, obj_type=None) -> requests.Session:
return workspace.auth.session


class WorkspaceId:
def __get__(self, obj, obj_type=None) -> str:
return obj.__dict__.get("workspace_id", workspace.id)

def __set__(self, obj, value: str) -> None:
if value == self:
value = workspace.id
obj.__dict__["workspace_id"] = value


def get_webhooks(return_json: bool = False) -> List[webhooks.Webhook]:
"""
Gets all registered webhooks for this workspace.
Expand Down
14 changes: 7 additions & 7 deletions up42/initialization.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from up42 import asset, catalog, main, order, storage, tasking, utils, webhooks
from up42 import asset, base, catalog, order, storage, tasking, utils, webhooks

logger = utils.get_logger(__name__, level=logging.INFO)

Expand All @@ -12,21 +12,21 @@ def initialize_catalog() -> catalog.Catalog:
"""
Returns a Catalog object for using the catalog search.
"""
return catalog.Catalog(auth=main.workspace.auth, workspace_id=main.workspace.id)
return catalog.Catalog(auth=base.workspace.auth, workspace_id=base.workspace.id)


def initialize_tasking() -> "tasking.Tasking":
"""
Returns a Tasking object for creating satellite tasking orders.
"""
return tasking.Tasking(auth=main.workspace.auth, workspace_id=main.workspace.id)
return tasking.Tasking(auth=base.workspace.auth, workspace_id=base.workspace.id)


def initialize_storage() -> storage.Storage:
"""
Returns a Storage object to list orders and assets.
"""
return storage.Storage(auth=main.workspace.auth, workspace_id=main.workspace.id)
return storage.Storage(auth=base.workspace.auth, workspace_id=base.workspace.id)


def initialize_order(order_id: str) -> order.Order:
Expand All @@ -35,7 +35,7 @@ def initialize_order(order_id: str) -> order.Order:
Args:
order_id: The UP42 order_id
"""
up42_order = order.Order(auth=main.workspace.auth, order_id=order_id)
up42_order = order.Order(auth=base.workspace.auth, order_id=order_id)
logger.info(INITIALIZED_MSG, up42_order)
return up42_order

Expand All @@ -46,7 +46,7 @@ def initialize_asset(asset_id: str) -> asset.Asset:
Args:
asset_id: The UP42 asset_id
"""
up42_asset = asset.Asset(auth=main.workspace.auth, asset_id=asset_id)
up42_asset = asset.Asset(auth=base.workspace.auth, asset_id=asset_id)
logger.info(INITIALIZED_MSG, up42_asset)
return up42_asset

Expand All @@ -57,6 +57,6 @@ def initialize_webhook(webhook_id: str) -> webhooks.Webhook:
Args:
webhook_id: The UP42 webhook_id
"""
webhook = webhooks.Webhook(auth=main.workspace.auth, workspace_id=main.workspace.id, webhook_id=webhook_id)
webhook = webhooks.Webhook(auth=base.workspace.auth, workspace_id=base.workspace.id, webhook_id=webhook_id)
logger.info(INITIALIZED_MSG, webhook)
return webhook

0 comments on commit 6af95b7

Please sign in to comment.