From 0bd40973e07eb41276f18fb7a3aa1ba87e408c10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 28 Oct 2023 12:50:30 +0000 Subject: [PATCH] Deploy to GitHub pages --- .buildinfo | 4 + .nojekyll | 0 _modules/index.html | 114 ++ _modules/sxapi/base.html | 236 +++ _modules/sxapi/cli/cli.html | 320 ++++ _modules/sxapi/cli/cli_user.html | 233 +++ .../sxapi/cli/subparser/get_sensor_data.html | 192 +++ _modules/sxapi/cli/subparser/token.html | 299 ++++ _modules/sxapi/publicV2.html | 140 ++ _modules/sxapi/publicV2/alarms.html | 242 +++ _modules/sxapi/publicV2/data.html | 510 ++++++ _modules/sxapi/publicV2/feedrations.html | 223 +++ _modules/sxapi/publicV2/groups.html | 190 +++ _modules/sxapi/publicV2/sensordata.html | 150 ++ _modules/sxapi/publicV2/todos.html | 240 +++ _modules/sxapi/publicV2/users.html | 560 +++++++ _sources/api/modules.rst.txt | 7 + _sources/api/sxapi.cli.rst.txt | 37 + _sources/api/sxapi.cli.subparser.rst.txt | 23 + _sources/api/sxapi.publicV2.rst.txt | 69 + _sources/api/sxapi.rst.txt | 30 + _sources/authors.rst.txt | 2 + _sources/changelog.rst.txt | 2 + _sources/contributing.rst.txt | 1 + _sources/index.rst.txt | 61 + _sources/license.rst.txt | 7 + _sources/readme.rst.txt | 2 + _static/alabaster.css | 703 +++++++++ _static/basic.css | 925 +++++++++++ _static/custom.css | 1 + _static/doctools.js | 156 ++ _static/documentation_options.js | 13 + _static/file.png | Bin 0 -> 286 bytes _static/language_data.js | 199 +++ _static/minus.png | Bin 0 -> 90 bytes _static/plus.png | Bin 0 -> 90 bytes _static/pygments.css | 75 + _static/searchtools.js | 574 +++++++ _static/sphinx_highlight.js | 154 ++ api/modules.html | 165 ++ api/sxapi.cli.html | 254 +++ api/sxapi.cli.subparser.html | 213 +++ api/sxapi.html | 333 ++++ api/sxapi.publicV2.html | 1376 +++++++++++++++++ authors.html | 116 ++ changelog.html | 120 ++ contributing.html | 367 +++++ genindex.html | 574 +++++++ index.html | 162 ++ license.html | 298 ++++ objects.inv | Bin 0 -> 1314 bytes py-modindex.html | 196 +++ readme.html | 129 ++ search.html | 125 ++ searchindex.js | 1 + 55 files changed, 11123 insertions(+) create mode 100644 .buildinfo create mode 100644 .nojekyll create mode 100644 _modules/index.html create mode 100644 _modules/sxapi/base.html create mode 100644 _modules/sxapi/cli/cli.html create mode 100644 _modules/sxapi/cli/cli_user.html create mode 100644 _modules/sxapi/cli/subparser/get_sensor_data.html create mode 100644 _modules/sxapi/cli/subparser/token.html create mode 100644 _modules/sxapi/publicV2.html create mode 100644 _modules/sxapi/publicV2/alarms.html create mode 100644 _modules/sxapi/publicV2/data.html create mode 100644 _modules/sxapi/publicV2/feedrations.html create mode 100644 _modules/sxapi/publicV2/groups.html create mode 100644 _modules/sxapi/publicV2/sensordata.html create mode 100644 _modules/sxapi/publicV2/todos.html create mode 100644 _modules/sxapi/publicV2/users.html create mode 100644 _sources/api/modules.rst.txt create mode 100644 _sources/api/sxapi.cli.rst.txt create mode 100644 _sources/api/sxapi.cli.subparser.rst.txt create mode 100644 _sources/api/sxapi.publicV2.rst.txt create mode 100644 _sources/api/sxapi.rst.txt create mode 100644 _sources/authors.rst.txt create mode 100644 _sources/changelog.rst.txt create mode 100644 _sources/contributing.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/license.rst.txt create mode 100644 _sources/readme.rst.txt create mode 100644 _static/alabaster.css create mode 100644 _static/basic.css create mode 100644 _static/custom.css create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/file.png create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/plus.png create mode 100644 _static/pygments.css create mode 100644 _static/searchtools.js create mode 100644 _static/sphinx_highlight.js create mode 100644 api/modules.html create mode 100644 api/sxapi.cli.html create mode 100644 api/sxapi.cli.subparser.html create mode 100644 api/sxapi.html create mode 100644 api/sxapi.publicV2.html create mode 100644 authors.html create mode 100644 changelog.html create mode 100644 contributing.html create mode 100644 genindex.html create mode 100644 index.html create mode 100644 license.html create mode 100644 objects.inv create mode 100644 py-modindex.html create mode 100644 readme.html create mode 100644 search.html create mode 100644 searchindex.js diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 0000000..097f75c --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 959aa8e1cbad269255e4be71235447d9 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 0000000..94964e5 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,114 @@ + + + +
+ + +
+#!/usr/bin/python
+# coding: utf8
+
+from enum import Enum
+
+import requests
+
+INTEGRATION_API_V2_BASE_URL = "https://api.smaxtec.com/integration/v2"
+
+
+
+
+
+
+
+[docs]
+class BaseAPI(object):
+ def __init__(
+ self,
+ base_url,
+ email=None,
+ password=None,
+ api_token=None,
+ api_type=None,
+ ):
+ """Initialize a new base low level API client instance."""
+ self.api_base_url = base_url.rstrip("/")
+ self.email = email
+ self.password = password
+ self.api_token = api_token
+ self.api_type = api_type
+ self._session = None
+
+
+
+
+ @property
+ def session(self):
+ """
+ Geneates a new HTTP session on the fly and logs in if no session exists.
+ """
+ if self._session is None:
+ self._session = requests.Session()
+ self._login()
+ return self._session
+
+
+
+
+ def _login(self):
+ """
+ Login to the api with api key or the given credentials.
+ """
+ if self.api_token is not None:
+ self._session.headers.update({"Authorization": f"Bearer {self.api_token}"})
+ else:
+ params = {"user": self.email, "password": self.password}
+ response = requests.Response
+ if self.api_type == ApiTypes.PUBLIC:
+ response = self._session.post(
+ self.to_url("/users/credentials"), params=params
+ )
+ self.api_token = response.json().get("api_token", None)
+ elif self.api_type == ApiTypes.INTEGRATION:
+ response = self._session.post(
+ self.to_url("/users/session_token"), params=params
+ )
+ self.api_token = response.json().get("token", None)
+ if self.api_token is None:
+ raise requests.HTTPError(response.status_code, response.reason)
+ self._session.headers.update({"Authorization": f"Bearer {self.api_token}"})
+
+
+[docs]
+ def get(self, path, *args, **kwargs):
+ url = self.to_url(path)
+ r = self.session.get(url, *args, **kwargs)
+ return r.json()
+
+
+
+[docs]
+ def post(self, path, *args, **kwargs):
+ url = self.to_url(path)
+ r = self.session.post(url, *args, allow_redirects=False, **kwargs)
+ return r.json()
+
+
+
+[docs]
+ def put(self, path, *args, **kwargs):
+ url = self.to_url(path)
+ r = self.session.put(url, *args, allow_redirects=False, **kwargs)
+ return r.json()
+
+
+
+[docs]
+ def delete(self, path, *args, **kwargs):
+ url = self.to_url(path)
+ r = self.session.delete(url, *args, **kwargs)
+ return r.json()
+
+
+
+
+
+[docs]
+class IntegrationAPIV2(BaseAPI):
+ def __init__(self, base_url=None, email=None, password=None, api_token=None):
+ """Initialize a new integration api client instance."""
+ base_url = base_url or INTEGRATION_API_V2_BASE_URL
+ api_type = ApiTypes.INTEGRATION
+ super().__init__(
+ base_url,
+ email=email,
+ password=password,
+ api_token=api_token,
+ api_type=api_type,
+ )
+
+
+import argparse
+import configparser
+import os
+import sys
+from os.path import (
+ abspath,
+ expanduser,
+)
+
+from setuptools import setup
+
+from sxapi.cli import cli_user
+from sxapi.cli.subparser.get_sensor_data import create_gsd_parser
+from sxapi.cli.subparser.token import create_token_parser
+
+
+
+[docs]
+class Cli:
+ """CLI class for handling arguments and calling the API."""
+
+ def __init__(self):
+ self.config_file_paths = ["/etc/sxapi.conf", "~/.config/sxapi.conf"]
+
+
+[docs]
+ @staticmethod
+ def update_config_with_env(config_dict):
+ config_dict["user"] = os.getenv("SXAPI_USER", config_dict["user"])
+ config_dict["pwd"] = os.getenv("SXAPI_PASSWORD", config_dict["pwd"])
+ config_dict["orga"] = os.getenv("SXAPI_ORGA", config_dict["orga"])
+ config_dict["api_public_v2_path"] = os.getenv(
+ "SXAPI_API_PUBLIC_V2_PATH", config_dict["api_public_v2_path"]
+ )
+ config_dict["api_integration_v2_path"] = os.getenv(
+ "SXAPI_API_INTEGRATION_V2_PATH", config_dict["api_integration_v2_path"]
+ )
+
+
+
+[docs]
+ def read_config_from_file(self, config_file_path):
+ config_dict = {
+ "user": None,
+ "pwd": None,
+ "orga": None,
+ "api_public_v2_path": None,
+ "api_integration_v2_path": None,
+ }
+
+ if config_file_path:
+ self.config_file_paths.append(config_file_path)
+
+ parsable_files = []
+ for config_file in self.config_file_paths:
+ config_file = expanduser(config_file)
+ config_file = abspath(config_file)
+ parsable_files.append(config_file)
+
+ try:
+ config = configparser.ConfigParser(interpolation=None)
+ config.read(parsable_files)
+
+ config_dict["user"] = config.get("SXAPI", "USER")
+ config_dict["pwd"] = config.get("SXAPI", "PASSWORD")
+ config_dict["orga"] = config.get("SXAPI", "ORGA")
+ config_dict["api_public_v2_path"] = config.get(
+ "SXAPI", "API_PUBLIC_V2_PATH"
+ )
+ config_dict["api_integration_v2_path"] = config.get(
+ "SXAPI", "API_INTEGRATION_V2_PATH"
+ )
+ except (
+ KeyError,
+ configparser.NoSectionError,
+ configparser.MissingSectionHeaderError,
+ ) as e:
+ if config_file_path:
+ print(f"Error while reading config file: {e}")
+ return
+ # we should raise custom exception here
+
+ return config_dict
+
+
+
+[docs]
+ @staticmethod
+ def api_status():
+ """
+ Print online status of api/v2 and integration/v2
+ """
+
+ if not cli_user.api_access_token:
+ print("No credentials set. Use --help for more information.")
+ return
+
+ pub_resp = cli_user.public_v2_api.get("/service/status")
+ int_resp = cli_user.integration_v2_api.get("/service/status")
+
+ exit_code = 0
+
+ if not (pub_resp["result"] == "ok" and int_resp["result"] == "ok"):
+ exit_code = 1
+
+ print(f"PublicV2 status: {pub_resp['result']}")
+ print(f"IntegrationV2 status: {int_resp['result']}")
+
+ exit(exit_code)
+
+
+
+[docs]
+ @staticmethod
+ def version_info():
+ """Print version info."""
+ setup(use_scm_version={"version_scheme": "no-guess-dev"})
+
+
+
+[docs]
+ @staticmethod
+ def parse_args(args):
+ """
+ Parse arguments from the CLI and initializes subparsers.
+ """
+ main_parser = argparse.ArgumentParser(
+ description=(
+ "Issue calls to the smaXtec system API to import and export data."
+ )
+ )
+ main_parser.add_argument(
+ "--version",
+ action="store_true",
+ default=False,
+ help="print version info and exit.",
+ )
+ main_parser.add_argument(
+ "--status",
+ action="store_true",
+ default=False,
+ help="prints status of api/V2 and integration/v2",
+ )
+ main_parser.add_argument(
+ "-t",
+ "--arg_token",
+ type=str,
+ help="Access Token",
+ )
+ main_parser.add_argument(
+ "-k",
+ "--use_keyring",
+ action="store_true",
+ help="Use keyring as token source!",
+ )
+ main_parser.add_argument(
+ "-c", "--configfile", type=str, help="Path to config file"
+ )
+ main_parser.add_argument(
+ "--print-configfile",
+ action="store_true",
+ help="Print example config file and exits",
+ )
+
+ # gsd_parser
+ subparsers = main_parser.add_subparsers(help="sub-command help")
+ create_gsd_parser(subparsers)
+ create_token_parser(subparsers)
+
+ if not args:
+ main_parser.print_help()
+ return
+ return main_parser.parse_args(args)
+
+
+
+[docs]
+ def run(self):
+ """Call sxapi functions based on passed arguments."""
+ args = self.parse_args(sys.argv[1:])
+ if not args:
+ return 0
+
+ if args.print_configfile:
+ with open("./src/sxapi/cli/example-config.conf", "r") as f:
+ print(f.read())
+ return
+
+ config_dict = self.read_config_from_file(args.configfile or None)
+
+ self.update_config_with_env(config_dict)
+
+ cli_user.init_user(config_dict, args.arg_token, args.use_keyring)
+
+ if args.status:
+ self.api_status()
+
+ if args.version:
+ self.version_info()
+
+ if args.use_keyring and args.arg_token:
+ print("Choose either -k (keyring), -t (argument) or no flag (environment)!")
+ return
+
+ # run set_defaults for subparser
+ if hasattr(args, "func"):
+ args.func(args)
+
+
+
+
+
+
+
+import os
+
+import keyring
+
+from sxapi.base import IntegrationAPIV2
+from sxapi.publicV2 import PublicAPIV2
+
+
+
+[docs]
+class CliUser:
+ """
+ CliUser class used for initializing, storing, retrieving and deleting
+ credentials and creating/holding Instances of supported API
+ Client.
+
+ This class should only be used in the cli package.
+ """
+
+ def __init__(self):
+ """
+ Basic User Credentials Constructor
+
+ calls self._init_creds() to set available credentials on startup.
+ """
+
+ self.api_access_token = None
+ self.public_v2_api = None
+ self.integration_v2_api = None
+
+
+[docs]
+ @staticmethod
+ def get_token_environment():
+ """
+ Gets token named 'SMAXTEC_API_ACCESS_TOKEN' from the systems' environment.
+ """
+
+ return os.environ.get("SMAXTEC_API_ACCESS_TOKEN", None)
+
+
+
+[docs]
+ def set_token_keyring(self, token):
+ """
+ Store the given token in keyring.
+ """
+ keyring.set_password("sxapi", "SMAXTEC_API_ACCESS_TOKEN", token)
+ self.api_access_token = token
+
+
+
+[docs]
+ @staticmethod
+ def get_token_keyring():
+ """
+ Gets the token stored in the keyring.
+ """
+ return keyring.get_password("sxapi", "SMAXTEC_API_ACCESS_TOKEN")
+
+
+
+[docs]
+ @staticmethod
+ def clear_token_keyring():
+ """
+ Deletes the token from the keyring.
+ """
+ keyring.delete_password("sxapi", "SMAXTEC_API_ACCESS_TOKEN")
+
+
+ # general functions
+
+[docs]
+ def check_credentials_set(self):
+ """
+ Checks if token is already set.
+ """
+ if self.api_access_token is not None:
+ return True
+ return False
+
+
+
+[docs]
+ def init_user(self, config_dict, args_token, args_keyring):
+ """
+ This function retrieves the token from the specified resource
+ (keyring, environment or args) and initializes clients
+ of the supported APIs (PublicV2, IntegrationV2).
+
+ If no token can be found the token is retrieved via
+ the username and password.
+
+ If username and password are also missing, no credentials get
+ stored and not API clients are created.
+ """
+ if args_token:
+ self.api_access_token = args_token
+ elif args_keyring:
+ self.api_access_token = self.get_token_keyring()
+ else:
+ self.api_access_token = self.get_token_environment()
+
+ if self.api_access_token is None and config_dict["user"] and config_dict["pwd"]:
+ self.public_v2_api = PublicAPIV2(
+ base_url=config_dict["api_public_v2_path"],
+ email=config_dict["user"],
+ password=config_dict["pwd"],
+ )
+ self.integration_v2_api = IntegrationAPIV2(
+ base_url=config_dict["api_integration_v2_path"],
+ email=config_dict["user"],
+ password=config_dict["pwd"],
+ )
+
+ self.api_access_token = self.public_v2_api.get_token()
+
+ elif self.api_access_token:
+ self.public_v2_api = PublicAPIV2(
+ base_url=config_dict["api_public_v2_path"],
+ api_token=self.api_access_token,
+ )
+
+ self.integration_v2_api = IntegrationAPIV2(
+ base_url=config_dict["api_integration_v2_path"],
+ api_token=self.api_access_token,
+ )
+
+
+
+import json
+
+from sxapi.cli import cli_user
+from sxapi.publicV2.sensordata import get_sensor_data_from_animal
+
+
+
+[docs]
+def create_gsd_parser(subparsers):
+ """
+ get_sensor_data subparser for cli_tests.
+ Responsible for performing api-call to get the sensor data for a given animal.
+
+ The 'animals_id' is mandatory argument 'animal_id'.
+ It represents the animal you want to get data from.
+
+ The following flag are only optional.
+ The --metrics/-m Flag defines the metrics you want to get from the animal sensor.
+ It expects at most two arguments 'temp', 'act' or both together. Where 'temp' means
+ getting the temperature metric and 'act' means the activity metric.
+
+
+ The --from_date Flag defines the start-date of window you want to get data from.
+ It expects exactly one argument, a datetime in the format 'YYYY-MM-DD'
+ (e.g. 2022.01.12).
+
+ The --to_date Flag defines the end-date of window you want to get data from.
+ It expects exactly one argument, a datetime in the format 'YYYY-MM-DD'
+ (e.g. 2022.01.12).
+ """
+ gsd_parser = subparsers.add_parser(
+ "get_sensor_data",
+ aliases=["gsd"],
+ help="Get sensor data from animal(by its ID)",
+ )
+ gsd_parser.add_argument(
+ "animal_id",
+ help="Animal you want get data from",
+ )
+ gsd_parser.add_argument(
+ "--metrics",
+ "-m",
+ nargs="*",
+ default=None,
+ help="metrics for sensordata",
+ )
+ gsd_parser.add_argument(
+ "--from_date",
+ default=None,
+ nargs=1,
+ help="from_date format: YYYY-MM-DD",
+ )
+ gsd_parser.add_argument(
+ "--to_date",
+ default=None,
+ nargs=1,
+ help="to_date format: YYYY-MM-DD",
+ )
+
+ gsd_parser.set_defaults(func=gsd_sub_function)
+
+
+
+
+[docs]
+def gsd_sub_function(args):
+ """
+ The get_sensor_data subparser default function.
+ This function gets called if you get_sensor_data subparser is used.
+
+ Pares the given arguments and calls a function which
+ performs the desired api call.
+ """
+ if not cli_user.check_credentials_set():
+ print("No credentials set. Use --help for more information.")
+ return
+
+ api = cli_user.public_v2_api
+
+ id = args.animal_id
+ metrics = args.metrics
+ from_date = args.from_date
+ to_date = args.to_date
+ resp = get_sensor_data_from_animal(
+ api=api, animal_id=id, metrics=metrics, from_date=from_date, to_date=to_date
+ )
+ if resp is not None:
+ print(json.dumps(resp, indent=0))
+
+
+import getpass
+
+import requests
+
+from sxapi.cli import cli_user
+from sxapi.publicV2 import PublicAPIV2
+
+
+
+[docs]
+def create_token_parser(subparsers):
+ """
+ Token subparser for cli_tests.
+ Responsible for managing tokens/credentials.
+
+ The --print_token/-p Flag prints the token, stored in keyring or in
+ environment, to stdout. It expects exactly only one argument -> 'e'
+ for printing the token stored in the environment, 'k' for printing
+ the token stored in keyring and 'ek' for printing both at the same time.
+
+ The --set_keyring/-s flag stores the token (given as argument) in the keyring.
+ It expects exactly one argument -> the token you want to store.
+
+ The --clear_keyring/-c Flag deletes the token from the keyring.
+ This flag doesn't expect any argument.
+
+ The --new_token/-n Flag calls api to get new token and prints it to stdout.
+ It expects exactly two arguments -> smaxtec-username and smaxtec-password.
+
+ It is not possible to use more than one of those flags at the same time
+ """
+ token_parser = subparsers.add_parser(
+ "token",
+ help="Get/Set credentials aka 'SMAXTEC_API_ACCESS_TOKEN' from/to specified "
+ "storage location or create new one",
+ )
+
+ token_parser.add_argument(
+ "--print_token",
+ "-p",
+ nargs="?",
+ const="ek",
+ help="Print the current token stored in keyring/environment to stdout. "
+ "One argument required. Possible args 'e' environment | "
+ "'k' keyring | ek for printing both.",
+ )
+ token_parser.add_argument(
+ "--set_keyring",
+ "-s",
+ nargs=1,
+ help="Store the given token in keyring! Requires one argument <token>",
+ )
+ token_parser.add_argument(
+ "--new_token",
+ "-n",
+ nargs="+",
+ help="Reqeust new token. Requires one argument <username>, "
+ "second argument <password> is optional!",
+ )
+ token_parser.add_argument(
+ "--clear_keyring",
+ "-c",
+ action="store_true",
+ default=False,
+ help="Remove the token from keyring!",
+ )
+
+ token_parser.set_defaults(func=token_sub_function)
+
+
+
+
+[docs]
+def token_sub_function(args):
+ """
+ The token subparser default function.
+ This function gets called if token subparser is used.
+
+ Checks args and calls the specific helper function (see below) according to
+ the present flag.
+ """
+ number_op = (
+ bool(args.print_token)
+ + bool(args.set_keyring)
+ + bool(args.new_token)
+ + bool(args.clear_keyring)
+ )
+
+ if number_op > 1:
+ print(
+ "Invalid Combination! Please use just one out of these parameters "
+ "[--print_token, --set_keyring, --new_token, --clear_keyring]"
+ )
+ return
+
+ if args.print_token:
+ handle_print_token(args)
+ elif args.set_keyring:
+ handle_set_token(args)
+ elif args.clear_keyring:
+ handle_clear_token()
+ elif args.new_token:
+ handle_new_token(args)
+
+
+
+# Flag helper functions
+
+[docs]
+def handle_print_token(args):
+ """
+ Logic behind the token subparser --print_token flag.
+
+ Prints the token from the desired source (environment or keyring) to stdout.
+ """
+ keyring = str(cli_user.get_token_keyring())
+ env = str(cli_user.get_token_environment())
+
+ if args.print_token == "ek":
+ print(f"\nKeyring: {keyring}\n\nEnvironment: {env}")
+ return
+ elif len(args.print_token) > 2:
+ print("Invalid number of arguments. Use --help for usage information.")
+ return
+
+ if "e" != args.print_token and "k" != args.print_token:
+ print(
+ "Invalid arguments. Only use 'e' for environment, 'k' for keyring "
+ "or 'ek' for both."
+ )
+ return
+
+ if "e" == args.print_token:
+ print(f"\nEnvironment Token: {env}\n")
+ elif "k" == args.print_token:
+ print(f"\nKeyring Token: {keyring}\n")
+
+
+
+
+[docs]
+def handle_set_token(args):
+ """
+ Logic behind the token subparser --set_keyring flag.
+
+ Parses the args and stores the token in the keyring.
+ """
+ token = args.set_keyring[0]
+ cli_user.set_token_keyring(token=token)
+ print("Token is stored in keyring!")
+
+
+
+
+[docs]
+def handle_clear_token():
+ """
+ Logic behind the token subparser --clear_keyring flag.
+
+ Deletes the token from the keyring.
+ """
+ cli_user.clear_token_keyring()
+ print("Token was deleted from keyring!")
+
+
+
+
+[docs]
+def handle_new_token(args):
+ """
+ Logic behind the token subparser --new_token flag.
+
+ Parses the args, creates an PublicAPIV2 instance to get new token and
+ print the new token to stdout.
+ """
+ if len(args.new_token) == 2:
+ username = args.new_token[0] if "@" in args.new_token[0] else args.new_token[1]
+ pwd = args.new_token[1] if "@" not in args.new_token[1] else args.new_token[0]
+
+ if len(args.new_token) == 1:
+ username = args.new_token[0]
+ pwd = getpass.getpass()
+
+ if "@" not in username:
+ print("Username must be a email!")
+ return
+
+ try:
+ token = str(PublicAPIV2(email=username, password=pwd).get_token())
+ print("SMAXTEC_API_ACCESS_TOKEN=" + token)
+ except requests.HTTPError as e:
+ if "401" in str(e) or "422" in str(e):
+ print("Username or Password is wrong!")
+ except Exception as e:
+ print(e)
+
+
+from sxapi.base import (
+ ApiTypes,
+ BaseAPI,
+)
+from sxapi.publicV2.alarms import Alarms
+from sxapi.publicV2.data import Data
+from sxapi.publicV2.feedrations import Feedrations
+from sxapi.publicV2.groups import Groups
+from sxapi.publicV2.todos import Todos
+from sxapi.publicV2.users import Users
+
+PUBLIC_API_V2_BASE_URL = "https://api.smaxtec.com/api/v2"
+
+
+
+[docs]
+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)
+ self.users = Users(api=self)
+ self.alarms = Alarms(api=self)
+ self.data = Data(api=self)
+ self.groups = Groups(api=self)
+ self.feedrations = Feedrations(api=self)
+
+ super().__init__(
+ base_url,
+ email=email,
+ password=password,
+ api_token=api_token,
+ api_type=api_type,
+ )
+
+
+
+[docs]
+class Alarms:
+ """
+ This class represents the /alarms API endpoint of the PublicAPIV2.
+ https://api.smaxtec.com/api/v2/
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/alarms"
+
+
+[docs]
+ def post(self, organisation_id, title, **kwargs):
+ """Creates a new alarm.
+
+ Args:
+ organisation_id (str): ID of organisation the alarm should be created for
+ title (str): Title of the alarm
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Created alarm on success, error message else.
+
+ """
+ params = {
+ "organisation_id": organisation_id,
+ "title": title,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ return self.api.post(self.path_suffix, json=params)
+
+
+
+[docs]
+ def get_categories(self, **kwargs):
+ """Get all alarms categories for a user or organisation.
+ If no user or organisation is given, this
+ function return a BadRequestError
+
+ Args:
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. List of alarms on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/categories"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def put(self, alarm_id, organisation_id, **kwargs):
+ """Updates an existing alarm.
+
+ Args:
+ alarm_id (str): ID of the alarm which should be updated.
+ organisation_id (str): ID of organisation the alarm should be updated for
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Updated alarm on success, error message else.
+
+ """
+ params = {
+ "organisation_id": organisation_id,
+ }
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{alarm_id}"
+ return self.api.put(url_suffix, json=params)
+
+
+
+[docs]
+ def get(self, alarm_id, **kwargs):
+ """Get one alarm.
+
+ Args:
+ alarm_id (str): ID of the desired alarm
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Queried alarm on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{alarm_id}"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def delete(self, alarm_id, **kwargs):
+ """Delete one alarm.
+
+ Args:
+ alarm_id (str): ID of the alarm to delete
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Deleted alarm on success, error message else.
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{alarm_id}"
+ return self.api.delete(url_suffix, json=params)
+
+
+
+
+[docs]
+class Data:
+ """
+ This Class represents the /data endpoint fo the PublicAPIV2
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/data"
+
+
+[docs]
+ def get_data_animals(self, animal_id, metrics, from_date, to_date, **kwargs):
+ """Query sensordata for an animal.
+
+ Args:
+ animal_id (str): ID of the animal
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {"metrics": metrics, "from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/animals/{animal_id}.json"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_metrics_animals(self, animal_id, **kwargs):
+ """List available metrics for an animal.
+
+ Args:
+ animal_id (str): ID of the animal
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. List of available metrics on success,
+ error message else.
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/animals/{animal_id}/metrics"
+ self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_data_devices(self, device_id, metrics, from_date, to_date, **kwargs):
+ """Query sensordata for a device.
+
+ Args:
+ device_id (str): ID of the device
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {"metrics": metrics, "from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/devices/{device_id}.json"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_metrics_devices(self, device_id, **kwargs):
+ """List available metrics for a device.
+
+ Args:
+ device_id (str): ID of the device
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. List of available metrics on success,
+ error message else.
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/devices/{device_id}/metrics"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_download_animal_data(
+ self, animal_ids, metrics, from_date, to_date, **kwargs
+ ):
+ """Download sensordata for animals.
+
+ Args:
+ animal_ids (list(str)): List of animal IDs
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {
+ "animal_ids": animal_ids,
+ "metrics": metrics,
+ "from_date": from_date,
+ "to_date": to_date,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/download_animal_data"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_download_device_data(
+ self, device_ids, metrics, from_date, to_date, **kwargs
+ ):
+ """Download sensordata for devices.
+
+ Args:
+ device_ids (list(str)): List of device IDs
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {
+ "device_ids": device_ids,
+ "metrics": metrics,
+ "from_date": from_date,
+ "to_date": to_date,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/download_device_data"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_download_group_data(self, group_ids, metrics, from_date, to_date, **kwargs):
+ """Download sensordata for groups.
+
+ Args:
+ group_ids (list(str)): List of group IDs
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {
+ "group_ids": group_ids,
+ "metrics": metrics,
+ "from_date": from_date,
+ "to_date": to_date,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/download_group_data"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def post_downloads_excel_report(self, from_date, to_date, **kwargs):
+ """Generates an Excel report and sends an email
+ containing a download link for the Excel report to the user.
+
+ Args:
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Empty dict on success, error message else.
+
+ """
+ params = {"from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/downloads/generate_excel_report"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def post_downloads_messages_excel_report(self, from_date, to_date, **kwargs):
+ """Generates an Excel report and sends an email
+ containing a download link for the Excel report to the user.
+
+ Args:
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Empty dict on success, error message else.
+
+ """
+ params = {"from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/downloads/generate_messages_excel_report"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def post_downloads_organisation_messages_excel_report(
+ self, organisation_id, from_date, to_date, **kwargs
+ ):
+ """Generates an Excel report and sends an email
+ containing a download link for the Excel report to the user.
+
+ Args:
+ organisation_id (str): ID of organisation the report should be created for
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Empty dict on success, error message else.
+
+ """
+ params = {
+ "organisation_id": organisation_id,
+ "from_date": from_date,
+ "to_date": to_date,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = (
+ self.path_suffix + "/downloads/generate_organisation_messages_excel_report"
+ )
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def get_downloads(self, download_id, **kwargs):
+ """Download a generated Excel report.
+
+ Args:
+ download_id (str): ID of the download
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/downloads/{download_id}"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_data_feedrations(
+ self, feedration_id, metrics, from_date, to_date, **kwargs
+ ):
+ """Query feedration data.
+
+ Args:
+ feedration_id (str): ID of the feedration group
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+
+ """
+ params = {"metrics": metrics, "from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/feedrations/{feedration_id}.json"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_data_groups(self, group_id, metrics, from_date, to_date, **kwargs):
+ """Query group data.
+
+ Args:
+ group_id (str): ID of the group
+ metrics (list(str)): List of metrics to query
+ from_date (str): Query from date
+ to_date (str): Query end date
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+ Returns:
+ dict: Response from the API. Requested Metric values on success,
+ error message else.
+ """
+ params = {"metrics": metrics, "from_date": from_date, "to_date": to_date}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/groups/{group_id}.json"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_metrics_groups(self, group_id, **kwargs):
+ """List available metrics for a group.
+
+ Args:
+ group_id (str): ID of the group
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+ Returns:
+ dict: Response from the API. List of available metrics on success,
+ error message else.
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/groups/{group_id}/metrics"
+ return self.api.get(url_suffix, json=params)
+
+
+
+
+[docs]
+class Feedrations:
+ """
+ This Class represents the /feedrations endpoint of the PublicAPIV2.
+ https://api.smaxtec.com/api/v2/
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/feedrations"
+
+
+[docs]
+ def post(self, name, organisation_id, **kwargs):
+ """Creates a new feedration.
+
+ Args:
+ name (str): Name of the feedration to be created
+ organisation_id (str): ID of the organisation the feedration
+ 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 feedration on success,
+ error message else.
+
+ """
+ params = {
+ "name": name,
+ "organisation_id": organisation_id,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ self.api.post(self.path_suffix, json=params)
+
+
+
+[docs]
+ def put(self, feedration_id, name, organisation_id, **kwargs):
+ """Updates an existing feedration.
+
+ Args:
+ feedration_id (str): ID of the feedration which should be updated.
+ name (str): Name of the feedration to be updated
+ organisation_id (str): ID of the organisation the feedration
+ should be updated for
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Updated feedration on success,
+ error message else.
+
+ """
+ params = {
+ "name": name,
+ "organisation_id": organisation_id,
+ }
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{feedration_id}"
+ return self.api.put(url_suffix, json=params)
+
+
+
+[docs]
+ def get(self, feedration_id, **kwargs):
+ """Get one feedration.
+
+ Args:
+ feedration_id (str): ID of the desired feedration
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Feedration on success,
+ error message else.
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{feedration_id}"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def delete(self, feedration_id, **kwargs):
+ """Deletes a feedration.
+
+ Args:
+ feedration_id (str): ID of the feedration which should be deleted.
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Result on success, error message else.
+
+ """
+ params = {}
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{feedration_id}"
+ return self.api.delete(url_suffix, json=params)
+
+
+
+
+[docs]
+class Groups:
+ """
+ This Class represents the /groups endpoint of the PublicAPIV2.
+ https://api.smaxtec.com/api/v2/
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/groups"
+
+
+[docs]
+ def put_actions(self, group_id, **kwargs):
+ """
+ Add an action to a group.
+
+ Args:
+ group_id (str): ID of the group 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 group on success, error message else.
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{group_id}/actions"
+ self.api.put(url_suffix, json=params)
+
+
+
+[docs]
+ def get_actions(self, group_id, **kwargs):
+ """
+ Get all actions of a group.
+
+ Args:
+ group_id (str): ID of the group 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 group on success, error message else.
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{group_id}/actions"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def delete_actions(self, group_id, action_id, **kwargs):
+ """
+ Delete an action from a group.
+
+ Args:
+ group_id (str): ID of the group which should be updated.
+ action_id (str): ID of the action which should be deleted.
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Result on success, error message else.
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{group_id}/actions/{action_id}"
+ return self.api.delete(url_suffix, json=params)
+
+
+
+from datetime import (
+ datetime,
+ timedelta,
+)
+
+from sxapi.publicV2 import PublicAPIV2
+
+
+
+[docs]
+def get_sensor_data_from_animal(api, animal_id, *args, **kwargs):
+ """
+ Performs a get call to PUBLIC_API_V2, to get the sensordata from the given animal_id
+ """
+ if not isinstance(api, PublicAPIV2):
+ print("This function is only available to PublicAPIV2!")
+ return
+
+ metrics = kwargs.get("metrics", None)
+ if not metrics:
+ metrics = ["temp", "act"]
+ from_date_string = kwargs.get("from_date")
+ to_date_string = kwargs.get("to_date")
+
+ to_date = datetime.utcnow()
+ from_date = to_date - timedelta(days=2)
+
+ if to_date_string:
+ try:
+ to_date = datetime.strptime(*to_date_string, "%Y-%m-%d")
+ except ValueError:
+ print("to_date has not the right format YYYY-MM-DD!")
+ return None
+
+ if from_date_string:
+ try:
+ from_date = datetime.strptime(*from_date_string, "%Y-%m-%d")
+ except ValueError:
+ print("from_date has not the right format YYYY-MM-DD!")
+ return None
+
+ return api.data.get_data_animals(
+ animal_id, metrics, from_date.isoformat(), to_date.isoformat()
+ )
+
+
+
+[docs]
+class Todos:
+ """
+ This Class represents the /todos endpoint of the PublicAPIV2.
+
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/todos"
+
+
+[docs]
+ 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)
+
+
+
+[docs]
+ 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)
+
+
+
+[docs]
+ 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}")
+
+
+
+[docs]
+ 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)
+
+
+
+[docs]
+ 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)
+
+
+
+[docs]
+ 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)
+
+
+
+
+[docs]
+class Users:
+ """
+ This Class represents the /users endpoint fo the PublicAPIV2
+ https://api.smaxtec.com/api/v2/
+ """
+
+ def __init__(self, api=None):
+ self.api = api
+ self.path_suffix = "/users"
+
+
+[docs]
+ def post_activate(self, user_secret, **kwargs):
+ """Active a user with secret.
+
+ Args:
+ user_secret (str): secrete received from registration email.
+
+ Returns:
+ dict: Response of API call. Activated User on success, error message else.
+ """
+
+ params = {"secret": user_secret}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/activate"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def post_credentials(self, user, password, **kwargs):
+ """Create smaxtec api-access-token and an optional firestore-token.
+
+ Args:
+ user (str): Username/email
+ password (str): User password
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Requested tokens and additional user
+ information on success, error message else.
+ """
+
+ params = {
+ "user": user,
+ "password": password,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/credentials"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def get_credentials(self, **kwargs):
+ """Retrieve smaxtec api-access-tokens with a JWT Token.
+
+ Args:
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Current tokens and additional user
+ information on success, error message else.
+ """
+
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/credentials"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def post_reset_password(self, secret, new_password, **kwargs):
+ """Reset password with secret.
+
+ Args:
+ secret (str): secret received from email request.
+ new_password (str): new password for the user.
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Updated User on success, error message else.
+ """
+
+ params = {"secret": secret, "new_password": new_password}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/reset_password"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def get_reset_password_request(self, email, **kwargs):
+ """Request a password reset email.
+
+ Args:
+ email (str): email of the user.
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result on success, error message else.
+ """
+
+ params = {"email": email}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + "/reset_password_request"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get(self, user_id, **kwargs):
+ """Get one user by id.
+
+ Args:
+ user_id (str): ID of the desired user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. User object on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_account(self, user_id, **kwargs):
+ """Get a list of all Accounts of the given user
+
+ Args:
+ user_id (str): ID of the desired user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. List of Account objects on success,
+ error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/account"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def get_alarms(self, user_id, **kwargs):
+ """Get a list of all Alarms of the given user
+
+ Args:
+ user_id (str): ID of the desired user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. List of Alarm objects on success,
+ error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/alarms"
+ return self.api.get(url_suffix, json=params)
+
+
+
+[docs]
+ def put_change_password(self, user_id, old_password, new_password, **kwargs):
+ """Change password of a user with old password.
+
+ Args:
+ user_id (str): ID of the desired user
+ old_password (str): old password of the user
+ new_password (str): new password of the user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result on success, error message else.
+
+ """
+ params = {
+ "old_password": old_password,
+ "new_password": new_password,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/change_password"
+ return self.api.put(url_suffix, json=params)
+
+
+
+[docs]
+ def post_password_strength(self, user_id, email, password, **kwargs):
+ """Check password strength.
+
+ Args:
+ user_id (str): ID of the desired user
+ email (str): email of the user
+ password (str): password to check
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result and password strength on success,
+ error message else.
+
+ """
+ params = {
+ "password": password,
+ "email": email,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/password_strength"
+ return self.api.post(url_suffix, json=params)
+
+
+
+
+
+
+[docs]
+ def post_test_email(self, user_id, **kwargs):
+ """Send a test email to the user.
+
+ Args:
+ user_id (str): ID of the desired user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Empty dict on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/test_email"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def post_test_push(self, user_id, **kwargs):
+ """Send a test push notification to the user.
+
+ Args:
+ user_id (str): ID of the desired user
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Empty dict on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/test_push"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def put_tokens(self, user_id, token, platform, token_type, **kwargs):
+ """Adds the token if it does not exist, else updates the token.
+
+ Args:
+ user_id (str): ID of the desired user
+ token (str): some kind of token
+ platform (str): platform of the token device
+ token_type (str): type of the token (add push_ if push token)
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result on success, error message else.
+
+ """
+ params = {
+ "token": token,
+ "platform": platform,
+ "token_type": token_type,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/tokens"
+ return self.api.put(url_suffix, json=params)
+
+
+
+[docs]
+ def post_tokens(self, user_id, token, platform, token_type, **kwargs):
+ """Adds the token to the user.
+
+ Args:
+ user_id (str): ID of the desired user
+ token (str): some kind of token
+ platform (str): platform of the token device
+ token_type (str): type of the token (add push_ if push token)
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result on success, error message else.
+
+ """
+ params = {
+ "token": token,
+ "platform": platform,
+ "token_type": token_type,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/tokens"
+ return self.api.post(url_suffix, json=params)
+
+
+
+[docs]
+ def delete_tokens(self, user_id, token, **kwargs):
+ """Deletes the token from the user.
+
+ Args:
+ user_id (str): ID of the desired user
+ token (str): token to be deleted
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Request result on success, error message else.
+
+ """
+ params = {}
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/tokens/{token}"
+ return self.api.delete(url_suffix, json=params)
+
+
+
+[docs]
+ def post_update_metadata(self, user_id, metadata, **kwargs):
+ """Update metadata of a user.
+
+ Args:
+ user_id (str): ID of the desired user
+ metadata (dict): updated metadata
+ **kwargs: Optional parameters of the API call.
+ Find supported parameters under
+ https://api.smaxtec.com/api/v2/
+
+ Returns:
+ dict: Response of API call. Updated user on success, error message else.
+
+ """
+ params = {
+ "metadata": metadata,
+ }
+
+ for k, v in kwargs.items():
+ params[k] = v
+
+ url_suffix = self.path_suffix + f"/{user_id}/update_metadata"
+ return self.api.post(url_suffix, json=params)
+
+
+
' + + '' + + _("Hide Search Matches") + + "
" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api/modules.html b/api/modules.html new file mode 100644 index 0000000..fd16cac --- /dev/null +++ b/api/modules.html @@ -0,0 +1,165 @@ + + + + + + + +Bases: object
CliUser class used for initializing, storing, retrieving and deleting +credentials and creating/holding Instances of supported API +Client.
+This class should only be used in the cli package.
+ + + + +Gets token named ‘SMAXTEC_API_ACCESS_TOKEN’ from the systems’ environment.
+This function retrieves the token from the specified resource +(keyring, environment or args) and initializes clients +of the supported APIs (PublicV2, IntegrationV2).
+If no token can be found the token is retrieved via +the username and password.
+If username and password are also missing, no credentials get +stored and not API clients are created.
+get_sensor_data subparser for cli_tests. +Responsible for performing api-call to get the sensor data for a given animal.
+The ‘animals_id’ is mandatory argument ‘animal_id’. +It represents the animal you want to get data from.
+The following flag are only optional. +The –metrics/-m Flag defines the metrics you want to get from the animal sensor. +It expects at most two arguments ‘temp’, ‘act’ or both together. Where ‘temp’ means +getting the temperature metric and ‘act’ means the activity metric.
+The –from_date Flag defines the start-date of window you want to get data from. +It expects exactly one argument, a datetime in the format ‘YYYY-MM-DD’ +(e.g. 2022.01.12).
+The –to_date Flag defines the end-date of window you want to get data from. +It expects exactly one argument, a datetime in the format ‘YYYY-MM-DD’ +(e.g. 2022.01.12).
+Token subparser for cli_tests. +Responsible for managing tokens/credentials.
+The –print_token/-p Flag prints the token, stored in keyring or in +environment, to stdout. It expects exactly only one argument -> ‘e’ +for printing the token stored in the environment, ‘k’ for printing +the token stored in keyring and ‘ek’ for printing both at the same time.
+The –set_keyring/-s flag stores the token (given as argument) in the keyring. +It expects exactly one argument -> the token you want to store.
+The –clear_keyring/-c Flag deletes the token from the keyring. +This flag doesn’t expect any argument.
+The –new_token/-n Flag calls api to get new token and prints it to stdout. +It expects exactly two arguments -> smaxtec-username and smaxtec-password.
+It is not possible to use more than one of those flags at the same time
+Logic behind the token subparser –clear_keyring flag.
+Deletes the token from the keyring.
+Logic behind the token subparser –new_token flag.
+Parses the args, creates an PublicAPIV2 instance to get new token and +print the new token to stdout.
+Logic behind the token subparser –print_token flag.
+Prints the token from the desired source (environment or keyring) to stdout.
+Data
Data.get_data_animals()
Data.get_data_devices()
Data.get_data_feedrations()
Data.get_data_groups()
Data.get_download_animal_data()
Data.get_download_device_data()
Data.get_download_group_data()
Data.get_downloads()
Data.get_metrics_animals()
Data.get_metrics_devices()
Data.get_metrics_groups()
Data.post_downloads_excel_report()
Data.post_downloads_messages_excel_report()
Data.post_downloads_organisation_messages_excel_report()
Users
Users.delete_tokens()
Users.get()
Users.get_account()
Users.get_alarms()
Users.get_credentials()
Users.get_reset_password_request()
Users.get_shares()
Users.post_activate()
Users.post_credentials()
Users.post_password_strength()
Users.post_reset_password()
Users.post_test_email()
Users.post_test_push()
Users.post_tokens()
Users.post_update_metadata()
Users.put_change_password()
Users.put_tokens()
PublicAPIV2
Bases: Enum
An enumeration.
+Bases: object
This class represents the /alarms API endpoint of the PublicAPIV2. +https://api.smaxtec.com/api/v2/
+Delete one alarm.
+alarm_id (str) – ID of the alarm to delete
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Deleted alarm on success, error message else.
+Get one alarm.
+alarm_id (str) – ID of the desired alarm
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Queried alarm on success, error message else.
+Get all alarms categories for a user or organisation. +If no user or organisation is given, this +function return a BadRequestError
+**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
+Response of API call. List of alarms on success, error message else.
+Creates a new alarm.
+organisation_id (str) – ID of organisation the alarm should be created for
title (str) – Title of the alarm
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Created alarm on success, error message else.
+Updates an existing alarm.
+alarm_id (str) – ID of the alarm which should be updated.
organisation_id (str) – ID of organisation the alarm should be updated for
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Updated alarm on success, error message else.
+Bases: object
This Class represents the /data endpoint fo the PublicAPIV2
+Query sensordata for an animal.
+error message else.
+Query sensordata for a device.
+error message else.
+Query feedration data.
+error message else.
+Query group data.
+error message else.
+Download sensordata for animals.
+error message else.
+Download sensordata for devices.
+error message else.
+Download sensordata for groups.
+error message else.
+Download a generated Excel report.
+download_id (str) – ID of the download
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Returns:
+List available metrics for an animal.
+animal_id (str) – ID of the animal
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+List available metrics for a device.
+device_id (str) – ID of the device
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+List available metrics for a group.
+group_id (str) – ID of the group
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Generates an Excel report and sends an email +containing a download link for the Excel report to the user.
+from_date (str) – Query from date
to_date (str) – Query end date
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Empty dict on success, error message else.
+Generates an Excel report and sends an email +containing a download link for the Excel report to the user.
+from_date (str) – Query from date
to_date (str) – Query end date
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Empty dict on success, error message else.
+Generates an Excel report and sends an email +containing a download link for the Excel report to the user.
+organisation_id (str) – ID of organisation the report should be created for
from_date (str) – Query from date
to_date (str) – Query end date
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Empty dict on success, error message else.
+Bases: object
This Class represents the /feedrations endpoint of the PublicAPIV2. +https://api.smaxtec.com/api/v2/
+Deletes a feedration.
+feedration_id (str) – ID of the feedration which should be deleted.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Result on success, error message else.
+Get one feedration.
+feedration_id (str) – ID of the desired feedration
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Creates a new feedration.
+name (str) – Name of the feedration to be created
organisation_id (str) – ID of the organisation the feedration +should be created for
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Updates an existing feedration.
+feedration_id (str) – ID of the feedration which should be updated.
name (str) – Name of the feedration to be updated
organisation_id (str) – ID of the organisation the feedration +should be updated for
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Bases: object
This Class represents the /groups endpoint of the PublicAPIV2. +https://api.smaxtec.com/api/v2/
+Delete an action from a group.
+group_id (str) – ID of the group which should be updated.
action_id (str) – ID of the action which should be deleted.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Result on success, error message else.
+Get all actions of a group.
+group_id (str) – ID of the group which should be updated.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Updated group on success, error message else.
+Add an action to a group.
+group_id (str) – ID of the group which should be updated.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Updated group on success, error message else.
+Bases: object
This Class represents the /todos endpoint of the PublicAPIV2.
+ + + + +Creates a new todo.
+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/
Response of API call. Created todo on success, error message else.
+Updates an existing todo.
+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/
Response of API call. Updated todo on success, error message else.
+Bases: object
This Class represents the /users endpoint fo the PublicAPIV2 +https://api.smaxtec.com/api/v2/
+Deletes the token from the user.
+user_id (str) – ID of the desired user
token (str) – token to be deleted
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Request result on success, error message else.
+Get one user by id.
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. User object on success, error message else.
+Get a list of all Accounts of the given user
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Get a list of all Alarms of the given user
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Retrieve smaxtec api-access-tokens with a JWT Token.
+**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
+Response of API call. Current tokens and additional user +information on success, error message else.
+Request a password reset email.
+email (str) – email of the user.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Request result on success, error message else.
+Get a list of all Shares of the given user
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Create smaxtec api-access-token and an optional firestore-token.
+user (str) – Username/email
password (str) – User password
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Requested tokens and additional user +information on success, error message else.
+Check password strength.
+user_id (str) – ID of the desired user
email (str) – email of the user
password (str) – password to check
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
error message else.
+Reset password with secret.
+secret (str) – secret received from email request.
new_password (str) – new password for the user.
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Updated User on success, error message else.
+Send a test email to the user.
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Empty dict on success, error message else.
+Send a test push notification to the user.
+user_id (str) – ID of the desired user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Empty dict on success, error message else.
+Adds the token to the user.
+user_id (str) – ID of the desired user
token (str) – some kind of token
platform (str) – platform of the token device
token_type (str) – type of the token (add push_ if push token)
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Request result on success, error message else.
+Update metadata of a user.
+user_id (str) – ID of the desired user
metadata (dict) – updated metadata
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Updated user on success, error message else.
+Change password of a user with old password.
+user_id (str) – ID of the desired user
old_password (str) – old password of the user
new_password (str) – new password of the user
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Request result on success, error message else.
+Adds the token if it does not exist, else updates the token.
+user_id (str) – ID of the desired user
token (str) – some kind of token
platform (str) – platform of the token device
token_type (str) – type of the token (add push_ if push token)
**kwargs – Optional parameters of the API call. +Find supported parameters under +https://api.smaxtec.com/api/v2/
Response of API call. Request result on success, error message else.
+Florian Klien <florian.klien@smaxtec.com>
Philipp Kulich <philipp.kulich@smaxtec.com>
Marco Julian Moser <hyper_chrome@gmx.at>
Welcome to sxapi
contributor’s guide.
This document focuses on getting any potential contributor familiarized +with the development processes, but other kinds of contributions are also +appreciated.
+If you are new to using git or have never collaborated in a project previously, +please have a look at contribution-guide.org. Other resources are also +listed in the excellent guide created by FreeCodeCamp [1].
+Please notice, all users and contributors are expected to be open, +considerate, reasonable, and respectful. When in doubt, Python Software +Foundation’s Code of Conduct is a good reference in terms of behavior +guidelines.
+If you experience bugs or general issues with sxapi
, please have a look
+on the issue tracker. If you don’t see anything useful there, please feel
+free to fire an issue report.
Tip
+Please don’t forget to include the closed issues in your search. +Sometimes a solution was already reported, and the problem is considered +solved.
+New issue reports should include information about your programming environment +(e.g., operating system, Python version) and steps to reproduce the problem. +Please try also to simplify the reproduction steps to a very minimal example +that still illustrates the problem you are facing. By removing other factors, +you help us to identify the root cause of the issue.
+You can help improve sxapi
docs by making them more readable and coherent, or
+by adding missing information and correcting mistakes.
sxapi
documentation uses Sphinx as its main documentation compiler, with reStructuredText as markup language.
+This means that the docs are kept in the same repository as the project code, and
+that any documentation update is done in the same way was a code contribution.
Tip
+Please notice that the GitHub web interface provides a quick way of
+propose changes in sxapi
’s files. While this mechanism can
+be tricky for normal code contributions, it works perfectly fine for
+contributing to the docs, and can be quite handy.
If you are interested in trying this method out, please navigate to
+the docs
folder in the source repository, find which file you
+would like to propose changes and click in the little pencil icon at the
+top, to open GitHub’s code editor. Once you finish editing the file,
+please write a message in the form at the bottom of the page describing
+which changes have you made and what are the motivations behind them and
+submit your proposal.
When working on documentation changes in your local machine, you can
+compile them using tox
:
tox -e docs
+
and use Python’s built-in web server for a preview in your web browser
+(http://localhost:8000
):
python3 -m http.server --directory 'docs/_build/html'
+
You can find the API documentation for the smaxtec system on the API documentation page and the integration API documentation page.
+This API is only available with a smaxtec user account after logging in. All calls must use an access token. +.. todo:: fix contact info. +If you need an account for the API you can contact smaXtec.
+Before you work on any non-trivial code contribution it’s best to first create +a report in the issue tracker to start a discussion on the subject. +This often provides additional considerations and avoids unnecessary work.
+Before you start coding, we recommend creating an isolated virtual
+environment to avoid any problems with your installed Python packages.
+This can easily be done via either virtualenv
:
virtualenv <PATH TO VENV>
+source <PATH TO VENV>/bin/activate
+
Create an user account on GitHub if you do not already have one.
Fork the project repository: click on the Fork button near the top of the +page. This creates a copy of the code under your account on GitHub.
Clone this copy to your local disk:
+git clone git@github.com:YourLogin/sxapi.git
+cd sxapi
+
You should run:
+pip install -U pip setuptools -e .
+
to be able run putup --help
.
Install pre-commit
:
pip install pre-commit
+pre-commit install
+
sxapi
comes with a lot of hooks configured to automatically help the
+developer to check the code being written.
Create a branch to hold your changes:
+git checkout -b my-feature
+
and start making changes. Never work on the master branch!
+Start your work on this branch. Don’t forget to add docstrings to new +functions, modules and classes, especially if they are part of public APIs.
Add yourself to the list of contributors in AUTHORS.rst
.
When you’re done editing, do:
+git add <MODIFIED FILES>
+git commit
+
to record your changes in git.
+Please make sure to see the validation messages from pre-commit
and fix
+any eventual issues.
+This should automatically use flake8/black to check/fix the code style
+in a way that is compatible with the project.
Important
+Don’t forget to add unit tests and documentation in case your +contribution adds an additional feature and is not just a bugfix.
+Moreover, writing a descriptive commit message is highly recommended. +In case of doubt, you can check the commit history with:
+git log --graph --decorate --pretty=oneline --abbrev-commit --all
+
to look for recurring communication patterns.
+Please check that your changes don’t break any unit tests with:
+tox
+
(after having installed tox
with pip install tox
or pipx
).
You can also use tox
to run several other pre-configured tasks in the
+repository. Try tox -av
to see a list of the available checks.
If everything works fine, push your local branch to GitHub with:
+git push -u origin my-feature
+
Go to the web page of your fork and click “Create pull request” +to send your changes for review.
+Find more detailed information creating a PR. You might also want to open +the PR as a draft first and mark it as ready for review after the feedbacks +from the continuous integration (CI) system or any required fixes.
+The following tips can be used when facing problems to build or test the +package:
+Make sure to fetch all the tags from the upstream repository.
+The command git describe --abbrev=0 --tags
should return the version you
+are expecting. If you are trying to run CI scripts in a fork repository,
+make sure to push all the tags.
+You can also try to remove all the egg files or the complete egg folder, i.e.,
+.eggs
, as well as the *.egg-info
folders in the src
folder or
+potentially in the root of your project.
Sometimes tox
misses out when new dependencies are added, especially to
+setup.cfg
and docs/requirements.txt
. If you find any problems with
+missing dependencies when running a command with tox
, try to recreate the
+tox
environment using the -r
flag. For example, instead of:
tox -e docs
+
Try running:
+tox -r -e docs
+
Make sure to have a reliable tox
installation that uses the correct
+Python version (e.g., 3.7+). When in doubt you can run:
tox --version
+# OR
+which tox
+
If you have trouble and are seeing weird errors upon running tox
, you can
+also try to create a dedicated virtual environment with a tox
binary
+freshly installed. For example:
virtualenv .venv
+source .venv/bin/activate
+.venv/bin/pip install tox
+.venv/bin/tox -e all
+
Pytest can drop you in an interactive session in the case an error occurs.
+In order to do that you need to pass a --pdb
option (for example by
+running tox -- -k <NAME OF THE FALLING TEST> --pdb
).
+You can also setup breakpoints manually instead of using the --pdb
option.
If you are part of the group of maintainers and have correct user permissions
+on PyPI, the following steps can be used to release a new version for
+sxapi
:
Make sure all unit tests are successful.
Tag the current commit on the main branch with a release tag, e.g., v1.2.3
.
Push the new tag to the upstream repository, e.g., git push upstream v1.2.3
Clean up the dist
and build
folders with tox -e clean
+(or rm -rf dist build
)
+to avoid confusion with old builds and Sphinx docs.
Run tox -e build
and check that the files in dist
have
+the correct version (no .dirty
or git hash) according to the git tag.
+Also check the sizes of the distributions, if they are too big (e.g., >
+500KB), unwanted clutter may have been accidentally included.
Run tox -e publish -- --repository pypi
and check that everything was
+uploaded to PyPI correctly.
+ | + |
+ |
+ | + |
+ | + |
+ |
+ | + |
+ | + |
|
+
+ | + |
|
+
|
+
+ | + |
+ | + |
+ |
This is the documentation of sxapi.
+Note
+This is the main page of your project’s Sphinx documentation.
+It is formatted in reStructuredText. Add additional pages
+by creating rst-files in docs
and adding them to the toctree below.
+Use then references in order to link them from this page, e.g.
+Contributors and Changelog.
It is also possible to refer to the documentation of other Python packages
+with the Python domain syntax. By default you can reference the
+documentation of Sphinx, Python, NumPy, SciPy, matplotlib,
+Pandas, Scikit-Learn. You can add more by extending the
+intersphinx_mapping
in your Sphinx’s conf.py
.
The pretty useful extension autodoc is activated by default and lets +you include documentation from docstrings. Docstrings can be written in +Google style (recommended!), NumPy style and classical style.
+++++++ +++Apache License
+Version 2.0, January 2004
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
++
+- +
Definitions.
+“License” shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document.
+“Licensor” shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License.
+“Legal Entity” shall mean the union of the acting entity and all +other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +“control” means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity.
+“You” (or “Your”) shall mean an individual or Legal Entity +exercising permissions granted by this License.
+“Source” form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files.
+“Object” form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types.
+“Work” shall mean the work of authorship, whether in Source or +Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work +(an example is provided in the Appendix below).
+“Derivative Works” shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the purposes +of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, +the Work and Derivative Works thereof.
+“Contribution” shall mean any work of authorship, including +the original version of the Work and any modifications or additions +to that Work or Derivative Works thereof, that is intentionally +submitted to Licensor for inclusion in the Work by the copyright owner +or by an individual or Legal Entity authorized to submit on behalf of +the copyright owner. For the purposes of this definition, “submitted” +means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as “Not a Contribution.”
+“Contributor” shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work.
+- +
Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form.
- +
Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work, +where such license applies only to those patent claims licensable +by such Contributor that are necessarily infringed by their +Contribution(s) alone or by combination of their Contribution(s) +with the Work to which such Contribution(s) was submitted. If You +institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work +or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate +as of the date such litigation is filed.
- +
Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You +meet the following conditions:
++
+- +
You must give any other recipients of the Work or +Derivative Works a copy of this License; and
- +
You must cause any modified files to carry prominent notices +stating that You changed the files; and
- +
You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and +attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of +the Derivative Works; and
- +
If the Work includes a “NOTICE” text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained +within such NOTICE file, excluding those notices that do not +pertain to any part of the Derivative Works, in at least one +of the following places: within a NOTICE text file distributed +as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, +within a display generated by the Derivative Works, if and +wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and +do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside +or as an addendum to the NOTICE text from the Work, provided +that such additional attribution notices cannot be construed +as modifying the License.
You may add Your own copyright statement to Your modifications and +may provide additional or different license terms and conditions +for use, reproduction, or distribution of Your modifications, or +for any such Derivative Works as a whole, provided Your use, +reproduction, and distribution of the Work otherwise complies with +the conditions stated in this License.
+- +
Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions.
- +
Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file.
- +
Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License.
- +
Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages.
- +
Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+APPENDIX: How to apply the Apache License to your work.
+++To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets “[]” +replaced with your own identifying information. (Don’t include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same “printed page” as the copyright notice for easier +identification within third-party archives.
+Copyright [yyyy] [name of copyright owner]
+Licensed under the Apache License, Version 2.0 (the “License”); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at
+++Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.
+
+ s | ||
+ |
+ sxapi | + |
+ |
+ sxapi.base | + |
+ |
+ sxapi.cli | + |
+ |
+ sxapi.cli.cli | + |
+ |
+ sxapi.cli.cli_user | + |
+ |
+ sxapi.cli.subparser | + |
+ |
+ sxapi.cli.subparser.get_sensor_data | + |
+ |
+ sxapi.cli.subparser.token | + |
+ |
+ sxapi.publicV2 | + |
+ |
+ sxapi.publicV2.alarms | + |
+ |
+ sxapi.publicV2.data | + |
+ |
+ sxapi.publicV2.feedrations | + |
+ |
+ sxapi.publicV2.groups | + |
+ |
+ sxapi.publicV2.sensordata | + |
+ |
+ sxapi.publicV2.todos | + |
+ |
+ sxapi.publicV2.users | + |
++a new API to interact with the smaXtec system.
+
sxapi lets you import and export data through an easy to understand python API and a command line interface.
+This project has been set up using PyScaffold 4.1. For details and usage +information on PyScaffold see https://pyscaffold.org/.
++ Searching for multiple words only shows matches that contain + all words. +
+ + + + + + +