Skip to content

Commit

Permalink
Feat/api todos (solves #31) (#35)
Browse files Browse the repository at this point in the history
* create Todos class

* added test

* renamed test file

* moved publicApiV2 impelemntation to publicV2 folder

* fixed imports after moving publicAPIV2 class

* added docstrings

* docstring v2

* improved naming
  • Loading branch information
Mopsgeschwindigkeit authored Oct 24, 2023
1 parent 96623c2 commit e9656db
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 35 deletions.
15 changes: 0 additions & 15 deletions src/sxapi/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import requests

PUBLIC_API_V2_BASE_URL = "https://api.smaxtec.com/api/v2"
INTEGRATION_API_V2_BASE_URL = "https://api.smaxtec.com/integration/v2"


Expand Down Expand Up @@ -93,20 +92,6 @@ def delete(self, path, *args, **kwargs):
return r.json()


class PublicAPIV2(BaseAPI):
def __init__(self, base_url=None, email=None, password=None, api_token=None):
"""Initialize a new public api client instance."""
base_url = base_url or PUBLIC_API_V2_BASE_URL
api_type = ApiTypes.PUBLIC
super().__init__(
base_url,
email=email,
password=password,
api_token=api_token,
api_type=api_type,
)


class IntegrationAPIV2(BaseAPI):
def __init__(self, base_url=None, email=None, password=None, api_token=None):
"""Initialize a new integration api client instance."""
Expand Down
6 changes: 2 additions & 4 deletions src/sxapi/cli/cli_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import keyring

from sxapi.base import (
IntegrationAPIV2,
PublicAPIV2,
)
from sxapi.base import IntegrationAPIV2
from sxapi.publicV2 import PublicAPIV2


class CliUser:
Expand Down
2 changes: 1 addition & 1 deletion src/sxapi/cli/subparser/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import requests

from sxapi.base import PublicAPIV2
from sxapi.cli import cli_user
from sxapi.publicV2 import PublicAPIV2


def create_token_parser(subparsers):
Expand Down
24 changes: 24 additions & 0 deletions src/sxapi/publicV2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from sxapi.base import (
ApiTypes,
BaseAPI,
)
from sxapi.publicV2.todos import Todos

PUBLIC_API_V2_BASE_URL = "https://api.smaxtec.com/api/v2"


class PublicAPIV2(BaseAPI):
def __init__(self, base_url=None, email=None, password=None, api_token=None):
"""Initialize a new public api client instance."""
base_url = base_url or PUBLIC_API_V2_BASE_URL
api_type = ApiTypes.PUBLIC

self.todos = Todos(api=self)

super().__init__(
base_url,
email=email,
password=password,
api_token=api_token,
api_type=api_type,
)
2 changes: 1 addition & 1 deletion src/sxapi/publicV2/sensordata.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
)
from urllib.parse import urlencode

from ..base import PublicAPIV2
from sxapi.publicV2 import PublicAPIV2


def get_sensor_data_from_animal(api, animal_id, *args, **kwargs):
Expand Down
114 changes: 114 additions & 0 deletions src/sxapi/publicV2/todos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
class Todos:
"""
This Class represents the /todos endpoint of the PublicAPIV2.
https://api.smaxtec.com/api/v2/
"""

def __init__(self, api=None):
self.api = api
self.path_suffix = "/todos"

def post(self, todo_type, organisation_id, **kwargs):
"""Creates a new todo.
Args:
todo_type (str): Type of the todo to be created
organisation_id (str): Id of organisation the todo should be created for
**kwargs: Optional parameters of the API call.
Find supported parameters under
https://api.smaxtec.com/api/v2/
Returns:
dict: Response of API call. Created todo on success, error message else.
"""
params = {
"todo_type": todo_type,
"organisation_id": organisation_id,
}

for k, v in kwargs.items():
params[k] = v

self.api.post(self.path_suffix, json=params)

def put(self, todo_id, **kwargs):
"""Updates an existing todo.
Args:
todo_id (str): Id of the todo which should be updated.
**kwargs: Optional parameters of the API call.
Find supported parameters under
https://api.smaxtec.com/api/v2/
Returns:
dict: Response of API call. Updated todo on success, error message else.
"""
params = {}
for k, v in kwargs.items():
params[k] = v

url_suffix = self.path_suffix + f"/{todo_id}"
return self.api.put(url_suffix, json=params)

def get(self, todo_id):
"""Get one todo.
Args:
todo_id (str): Id of the desired todo
Returns:
dict: Response of API call. Queried todo on success, error message else.
"""
return self.api.get(self.path_suffix + f"/{todo_id}")

def post_comment(self, todo_id, content):
"""Create a comment for a todo.
Args:
todo_id (str): Id of the todo a comment is to be created.
content (str): Content of the comment
Returns:
dict: Response of API call. Updated todo on success, error message else.
"""
params = {
"content": content,
}

url_suffix = self.path_suffix + f"/{todo_id}/comments"
return self.api.post(url_suffix, json=params)

def delete_comment(self, todo_id, comment_id):
"""Delete a comment from a todo.
Args:
todo_id (str): Id of the todo a comment is to be deleted.
comment_id (str): Id of the comment to delete.
Returns:
dict: Response of API call. Updated todo on success, error message else.
"""

url_suffix = self.path_suffix + f"/{todo_id}/comments/{comment_id}"
return self.api.delete(url_suffix)

def put_comment(self, todo_id, comment_id, content):
"""Update a comment from a todo.
Args:
todo_id (str): Id of the todo a comment is to be updated.
comment_id (str): Id of the comment to be updated.
content (str): Updated content of the Id.
Returns:
dict: Response of API call. Updated todo on success, error message else.
"""
params = {
"content": content,
}

url_suffix = self.path_suffix + f"/{todo_id}/comments/{comment_id}"
return self.api.put(url_suffix, json=params)
4 changes: 2 additions & 2 deletions tests/cli_tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@mock.patch("sxapi.cli.cli.Cli.version_info")
@mock.patch("builtins.print")
@mock.patch("sxapi.cli.cli_user.get_token_keyring", return_value="keyring-token")
@mock.patch("sxapi.base.PublicAPIV2.get_token", return_value="keyring-token")
@mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="keyring-token")
def test_func(get_token_mock, keyring_mock, print_mock, version_mock):
with mock.patch("sys.argv", ["sx_api", "--version"]):
assert version_mock.call_count == 0
Expand Down Expand Up @@ -86,7 +86,7 @@ def test_config(keyring_mock, version_mock):

@mock.patch("sxapi.cli.cli.Cli.version_info")
@mock.patch("sxapi.cli.cli_user.get_token_keyring", return_value="keyring-token")
@mock.patch("sxapi.base.PublicAPIV2.get_token", return_value="api-token")
@mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api-token")
def test_init_user(api_mock, k_mock, version_mock):
with mock.patch(
"sys.argv",
Expand Down
2 changes: 1 addition & 1 deletion tests/cli_tests/test_gsd_subparser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mock

from sxapi.base import PublicAPIV2
from sxapi.cli.cli import Cli
from sxapi.publicV2 import PublicAPIV2

args_parser = Cli.parse_args

Expand Down
4 changes: 2 additions & 2 deletions tests/cli_tests/test_token_subparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


@mock.patch("builtins.print")
@mock.patch("sxapi.base.PublicAPIV2.get_token", return_value="api_token")
@mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api_token")
def test_handle_print_token(api_mock, print_mock):
namespace = args_parser(["token", "-p"])
assert namespace.print_token == "ek"
Expand Down Expand Up @@ -118,7 +118,7 @@ def test_handle_new_token(creds_mock, getpass_mock, print_mock):
assert call_args.args[0] == "Username or Password is wrong!"
print_mock.reset_mock()

with mock.patch("sxapi.base.PublicAPIV2.get_token", return_value="api_token"):
with mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api_token"):
namespace = args_parser(["token", "-n", "marco@test", "pwd"])
assert namespace.new_token == ["marco@test", "pwd"]
handle_new_token(namespace)
Expand Down
6 changes: 2 additions & 4 deletions tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import mock

from sxapi.base import (
IntegrationAPIV2,
PublicAPIV2,
)
from sxapi.base import IntegrationAPIV2
from sxapi.publicV2 import PublicAPIV2


@mock.patch("requests.Session.delete")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import mock

from sxapi.base import (
IntegrationAPIV2,
PublicAPIV2,
)
from sxapi.base import IntegrationAPIV2
from sxapi.publicV2 import PublicAPIV2
from sxapi.publicV2.sensordata import get_sensor_data_from_animal


@mock.patch("builtins.print")
@mock.patch("sxapi.base.PublicAPIV2.get")
@mock.patch("sxapi.publicV2.PublicAPIV2.get")
def test_get_sensor_data(get_mock, print_mock):
get_sensor_data_from_animal(IntegrationAPIV2(), "animal_id")
call_args = print_mock.call_args_list[0]
Expand Down
88 changes: 88 additions & 0 deletions tests/test_publicV2/test_todos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import mock

from sxapi.publicV2 import PublicAPIV2


@mock.patch("sxapi.publicV2.PublicAPIV2.post")
def test_post_todos(post_mock):
test_api = PublicAPIV2()
test_api.todos.post(
"test_todo_type", "test_orga_id", kwarg1="kwarg1", optional2="optional2"
)

call_args = post_mock.call_args_list[0]

assert post_mock.call_count == 1
assert call_args.args[0] == "/todos"
assert call_args.kwargs["json"] == {
"todo_type": "test_todo_type",
"organisation_id": "test_orga_id",
"kwarg1": "kwarg1",
"optional2": "optional2",
}


@mock.patch("sxapi.publicV2.PublicAPIV2.post")
def test_post_todo_comment(post_mock):
test_api = PublicAPIV2()
test_api.todos.post_comment("test_todo_id", content="comment_content")

call_args = post_mock.call_args_list[0]

assert post_mock.call_count == 1
assert call_args.args[0] == "/todos/test_todo_id/comments"
assert call_args.kwargs["json"] == {
"content": "comment_content",
}


@mock.patch("sxapi.publicV2.PublicAPIV2.put")
def test_put_todos(put_mock):
test_api = PublicAPIV2()
test_api.todos.put("test_todo_id", kwarg1="1", kwarg2="2", kwarg3=3)

call_args = put_mock.call_args_list[0]

assert put_mock.call_count == 1
assert call_args.args[0] == "/todos/test_todo_id"
assert call_args.kwargs["json"] == {
"kwarg1": "1",
"kwarg2": "2",
"kwarg3": 3,
}


@mock.patch("sxapi.publicV2.PublicAPIV2.put")
def test_put_todo_comments(get_mock):
test_api = PublicAPIV2()
test_api.todos.put_comment("test_todo_id", "test_comment_id", "updated_content")

call_args = get_mock.call_args_list[0]

assert get_mock.call_count == 1
assert call_args.args[0] == "/todos/test_todo_id/comments/test_comment_id"
assert call_args.kwargs["json"] == {"content": "updated_content"}


@mock.patch("sxapi.publicV2.PublicAPIV2.get")
def test_get_todos(get_mock):
test_api = PublicAPIV2()
test_api.todos.get("test_todo_id")

call_args = get_mock.call_args_list[0]

assert get_mock.call_count == 1
assert call_args.args[0] == "/todos/test_todo_id"
assert call_args.kwargs == {}


@mock.patch("sxapi.publicV2.PublicAPIV2.delete")
def test_delete_todo_comments(get_mock):
test_api = PublicAPIV2()
test_api.todos.delete_comment("test_todo_id", "test_comment_id")

call_args = get_mock.call_args_list[0]

assert get_mock.call_count == 1
assert call_args.args[0] == "/todos/test_todo_id/comments/test_comment_id"
assert call_args.kwargs == {}

0 comments on commit e9656db

Please sign in to comment.