From 51924686c994f1e66508b2b4a3efdb04a139bc1f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 18:56:26 +0000 Subject: [PATCH] Deploy to GitHub pages --- .buildinfo | 4 + .nojekyll | 0 _modules/index.html | 107 ++ _modules/sxapi/base.html | 254 +++++ _modules/sxapi/cli/cli.html | 255 +++++ _modules/sxapi/cli/credentials.html | 198 ++++ .../sxapi/cli/subparser/get_sensor_data.html | 193 ++++ _modules/sxapi/cli/subparser/token.html | 299 ++++++ _modules/sxapi/publicV2/sensordata.html | 155 +++ _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 | 15 + _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 | 159 +++ api/sxapi.cli.html | 231 +++++ api/sxapi.cli.subparser.html | 213 ++++ api/sxapi.html | 247 +++++ api/sxapi.publicV2.html | 128 +++ authors.html | 116 +++ changelog.html | 120 +++ contributing.html | 367 +++++++ genindex.html | 383 ++++++++ index.html | 162 +++ license.html | 298 ++++++ objects.inv | Bin 0 -> 859 bytes py-modindex.html | 166 ++++ readme.html | 129 +++ search.html | 125 +++ searchindex.js | 1 + 48 files changed, 7297 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/credentials.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/sensordata.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..9b1cc65 --- /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: 7b6d15ea29cbfe9c00587b91cc29979b +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..cc2f2e0 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,107 @@ + + + +
+ + +
+#!/usr/bin/python
+# coding: utf8
+
+from enum import Enum
+
+import requests
+
+PUBLIC_API_V2_BASE_URL = "https://api.smaxtec.com/api/v2"
+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 PublicAPIV2(BaseAPI):
+ def __init__(self, base_url=None, email=None, password=None, api_token=None):
+ """Initialize a new public api client instance."""
+ base_url = base_url or PUBLIC_API_V2_BASE_URL
+ api_type = ApiTypes.PUBLIC
+ super().__init__(
+ base_url,
+ email=email,
+ password=password,
+ api_token=api_token,
+ api_type=api_type,
+ )
+
+
+
+
+[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 os
+import sys
+
+from setuptools import setup
+
+from sxapi.base import (
+ IntegrationAPIV2,
+ PublicAPIV2,
+)
+from sxapi.cli import user_credentials
+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.public_api = None
+ self.integration_api = None
+
+
+[docs]
+ @staticmethod
+ def api_status():
+ """
+ Print online status of api/v2 and integration/v2
+ """
+
+ # TODO: this part is just a hacky trick, this should be moved
+ # when its finalized where to locate them!!!
+ email = os.environ.get("SMAXTEC_USER")
+ password = os.environ.get("SMAXTEC_PASSWORD")
+ api_token = os.environ.get("SMAXTEC_TOKEN")
+
+ public_api = PublicAPIV2(email=email, password=password, api_token=api_token)
+ integration_api = IntegrationAPIV2(
+ email=email, password=password, api_token=api_token
+ )
+ # hacky part end
+
+ pub_resp = public_api.get("/service/status")
+ int_resp = integration_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!",
+ )
+
+ # 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.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
+
+ if args.use_keyring:
+ user_credentials.token = user_credentials.get_token_keyring()
+ elif args.arg_token:
+ user_credentials.token = args.arg_token
+
+ # run set_defaults for subparser
+ if hasattr(args, "func"):
+ args.func(args)
+
+
+
+
+
+
+
+import os
+
+import keyring
+
+
+
+[docs]
+class UserCredentials:
+ """
+ Credentials class used for initializing, storing, retrieving and deleting
+ credentials.
+
+ This class should only be used in the cli_tests package.
+ """
+
+ def __init__(self):
+ """
+ Basic User Credentials Constructor
+
+ calls self._init_creds() to set available credentials on startup.
+ """
+
+ self.token_env_names = "SMAXTEC_TOKEN"
+ self.token = None
+
+ self._init_creds()
+
+
+[docs]
+ def get_token_environment(self):
+ """
+ Gets token named 'SMAXTEC_TOKEN' from the systems environment.
+ """
+
+ return os.environ.get("SMAXTEC_TOKEN", None)
+
+
+
+[docs]
+ def set_token_keyring(self, token):
+ """
+ Store the given token in keyring.
+ """
+ keyring.set_password("sxapi", "SMAXTEC_TOKEN", token)
+ self.token = token
+
+
+
+[docs]
+ def get_token_keyring(self):
+ """
+ Gets the token stored in the keyring.
+ """
+ return keyring.get_password("sxapi", "SMAXTEC_TOKEN")
+
+
+
+[docs]
+ def clear_token_keyring(self):
+ """
+ Deletes the token from the keyring.
+ """
+ keyring.delete_password("sxapi", "SMAXTEC_TOKEN")
+
+
+ # general functions
+
+[docs]
+ def check_credentials_set(self):
+ """
+ Checks if token is already set.
+ """
+ if self.token is not None:
+ return True
+ return False
+
+
+ def _init_creds(self):
+ """
+ This function tries to get the token from the system environment and
+ stores it in self.token, on failure (no token found) it does the same
+ with the keyring.
+
+ If both sources fail self.token remains None.
+ """
+ env_token = self.get_token_environment()
+ if env_token is not None:
+ self.token = env_token
+ return
+
+ keyring_token = self.get_token_keyring()
+ if keyring_token is not None:
+ self.token = keyring_token
+ return
+
+
+import json
+
+from sxapi.base import PublicAPIV2
+from sxapi.cli import user_credentials
+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 user_credentials.check_credentials_set():
+ print("No credentials set. Use --help for more information.")
+ return
+
+ api = PublicAPIV2(api_token=user_credentials.token)
+
+ 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.base import PublicAPIV2
+from sxapi.cli import user_credentials
+
+
+
+[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_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(user_credentials.get_token_keyring())
+ env = str(user_credentials.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]
+ user_credentials.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.
+ """
+ user_credentials.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_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 datetime import (
+ datetime,
+ timedelta,
+)
+from urllib.parse import urlencode
+
+from ..base 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
+
+ param = {
+ "metrics": metrics,
+ "to_date": to_date,
+ "from_date": from_date,
+ }
+ url_path = f"/data/animals/{animal_id}.json?{urlencode(param, True)}"
+ resp = api.get(url_path)
+
+ return resp
+
+
' + + '' + + _("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..7e8c745 --- /dev/null +++ b/api/modules.html @@ -0,0 +1,159 @@ + + + + + + + +Bases: object
Credentials class used for initializing, storing, retrieving and deleting +credentials.
+This class should only be used in the cli_tests package.
+ + + + + + + + + + +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.
+Bases: Enum
An enumeration.
+Bases: object
Geneates a new HTTP session on the fly and logs in if no session exists.
+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.credentials | + |
+ |
+ sxapi.cli.subparser | + |
+ |
+ sxapi.cli.subparser.get_sensor_data | + |
+ |
+ sxapi.cli.subparser.token | + |
+ |
+ sxapi.publicV2 | + |
+ |
+ sxapi.publicV2.sensordata | + |
++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. +
+ + + + + + +