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

Feat/api todos (solves #31) #35

Merged
merged 8 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
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:
flowolf marked this conversation as resolved.
Show resolved Hide resolved
"""
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 == {}