Kyanit API
Kyanit API is a Python API for interfacing and interacting with Kyanit.
For a command-line utility, see Kyanit CTL at https://kyanit-project.github.io/kyanit-ctl/kyanitctl/.
Install the latest released version of Kyanit API from PyPI with:
pip install kyanitapi
Then import the module with:
import kyanitapi
The module publishes the Kyanit
class to connect to Kyanit boards. Import the class
directly with:
from kyanitapi import Kyanit
Kyanit provides an addressing mechanism called the "Color ID," which mapps to the IP address of the Kyanit board. The Color ID consists of 3 colors from the Red, Green, Blue, Cyan, Magenta, Yellow and White pallette. If you don't know how to find out the Color ID of a Kyanit board, head to Kyanit's documentation at: https://kyanit-project.github.io/kyanit/kyanit/
Addressing using the Color ID works on home networks with a subnet mask of
255.255.255.0, which is what most home and small business routers create. Assuming you
know the Color ID of the board, and the network address to which it's connected, you can
instantiate the Kyanit
class with:
my_kyanit = Kyanit('BCG', '192.168.1.0')
Where 'BCG' is the Color ID of the board and '192.168.1.0' is the network address.
On non-255.255.255.0 networks, it is possible to connect to the Kyanit board providing only it's IP address:
my_kyanit = Kyanit(ip_addr='192.168.1.6')
Once instantiated, you can perform all sorts of actions on your Kyanit board. You can
ping the board with Kyanit.ping()
, get its status with Kyanit.get_status()
, and perform
file operations like listing the files on the board with Kyanit.get_file_list()
or
downloading and uploading files with Kyanit.get_file()
and Kyanit.put_file()
respectively. Other file actions, like delete and rename are also possible.
System-level operations are provided as well, these being the Kyanit.reboot()
, which
re-initializes the board, Kyanit.stop()
and Kyanit.start()
which stop and start the user
code.
Kyanit also provides a notion of a "network variable" called the Netvar, which can be
accessed with the Kyanit.netvar()
method.
Here's an example in the REPL to demonstrate some of these actions:
>>> from kyanitapi import Kyanit
>>> my_kyanit = Kyanit('BCG', '192.168.1.0')
>>> my_kyanit.ping()
True
>>> my_kyanit.get_status()
{'free_flash': 3514368, 'free_memory': 18768, 'run_state': 'CODE.PY MAIN', ...}
>>> my_kyanit.get_file_list()
['wlan.json', 'code.py']
>>> my_kyanit.put_file('some_file.txt', 'some text')
'OK'
>>> my_kyanit.get_file_list()
['wlan.json', 'code.py', 'some_file.txt']
>>> my_kyanit.get_file('some_file.txt')
b'some text'
>>> my_kyanit.delete_file('some_file.txt')
'OK'
>>> my_kyanit.get_file_list()
['wlan.json', 'code.py']
>>> my_kyanit.stop()
'OK'
>>> my_kyanit.get_status()
{'free_flash': 3514368, 'free_memory': 20288, 'run_state': 'STOPPED', ...}
>>> my_kyanit.start()
'OK'
>>> my_kyanit.get_status()
{'free_flash': 3514368, 'free_memory': 17744, 'run_state': 'CODE.PY MAIN', ...}
See the Kyanit
class and module function documentations to see what the class and this
module can do.
License Notice
Copyright (C) 2020 Zsolt Nagy
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
Functions
def cid_is_valid(color_id)
-
Return
True
ifcolor_id
is a valid Color ID string, andFalse
otherwise.'BBB' (an address of 0) is not considered to be valid, and neither is any ID representing an address above 254.
def cid_to_ip(color_id, network_addr)
-
Convert a Color ID to an IP address within the network given in
network_addr
.If
color_id
is not a valid Color ID,ValueError: Color ID invalid
will be raised. Consequently ifnetwork_addr
is not a valid address,ValueError: Network invalid<code> will be raised. The last octet of </code>network_addr
must be zero, and a subnet mask of 255.255.255.0 is assumed.Returned value is an IP address string.
def get_networks()
-
Return a list with networks that have a netmask of 255.255.255.0 in the current system. Only such networks are supported for connecting to a Kyanit using the Color ID.
Return an empty list, if no such networks are found.
List items will be tuples in the form of
('Interface Name', '<ip_address>')
, such as('eth0', '192.168.1.0')
or('Local Area Connection', '192.168.3.0')
depending on the operating system. def ip_is_valid(ip_addr)
-
Return
True
ifip_addr
is a valid IP address string, andFalse
otherwise. def ip_to_cid(ip_addr)
-
Convert an IP address string to a Color ID. It is assumed that the IP address is from a network with a netmask of 255.255.255.0.
If the passed IP address is not valid,
ValueError: IP invalid
will be raised.Returned value is the Color ID string.
def netmask_is_valid(netmask)
-
Return
True
ifnetmask
is a valid netmask string, andFalse
otherwise.
Classes
class Kyanit (color_id=None, network_addr=None, ip_addr=None, timeout=3)
-
Class for a Kyanit connection instance. No connection attempt is made on instantiation.
Provide either a Color ID with a Network address OR an IP address. These can not be changed after instantiation. Timeout is in seconds.
If both Color ID and IP address are provided,
ValueError: bad connection method
will be raised. If neither is provided,ValueError: no connection method
will be raised.All methods that perform a request towards Kyanit will be blocking until a response is received or the request is timed out.
Methods
def delete_file(self, filename)
-
Delete a file with the name passed to
filename
on the Kyanit.KyanitRequestError
with status code 404 will be raised if file is not found.Directories are not supported, if the filename contains a '/'
KyanitRequestError
will be raised with a status code 500. The same error will be raised if trying to deletemain.py
,boot.py
or_boot.py
as these files are protected and internal to Kyanit.Return value is the string
OK
if successful. def get_file(self, filename)
-
Get the contents of the file with the name passed to
filename
from Kyanit.KyanitRequestError
with status code 404 will be raised if file is not found.Directories are not supported, if the filename contains a '/'
KyanitRequestError
will be raised with a status code 500. The same error will be raised if trying to getmain.py
,boot.py
or_boot.py
as these files are protected and internal to Kyanit.Return type is bytes (the contents of the file).
def get_file_list(self)
-
Return a list with all of the file names present on Kyanit.
def get_status(self, tries=1)
-
Get status of Kyanit. Getting status will be attempted a number of times defined in
tries
. Each try may time out, therefore getting status may taketries * self.timeout
amount of time. (Useful after some longer operation, ex. directly after reboot.)Returned value will be a dict with the following schema:
{ 'firmware_version': str, # version number in the format major.minor.patch 'color_id': str, # current Color ID of the Kyanit 'free_memory': int, # free heap RAM in bytes 'free_flash': int, # amount of bytes free in the filesystem 'run_state': str, # see note below 'error_traceback': [ str ] # key is present if run_state is ERROR, and contains the traceback lines }
Note: for possible run states see https://kyanit-project.github.io/kyanit/kyanit/#run-states
def info(self)
-
Return connection info.
Return value is a dict with the following schema:
{ 'color_id': str, 'network_addr': str, 'ip_addr': str }
def netvar(self, obj=None, clear=False)
-
Read or write the Netvar on Kyanit.
If
obj
isNone
, return the value of Netvar.outbound() from Kyanit.If
obj
is other thanNone
, set the value of Netvar.inbound() on the Kyanit. In that case return value is the string 'OK' if successful. OtherwiseTypeError
will be raised ifobj
is not JSON serializable.If
clear
isTrue
,obj
is disregarded and Netvar.inbound() will be set toNone
on the Kyanit.Examples:
Get Netvar.inbound() with:
Kyanit.netvar()
Set Netvar.outbound() with:
Kyanit.netvar('new_value')
'new_value'
could be can be any Python object that's JSON serializable.Clear Netvar.outbound() with:
Kyanit.netvar(clear=True)
See https://kyanit-project.github.io/kyanit/kyanit/#kyanit-netvar for more on Netvar.
def ping(self, count=3, timeout=1, verbose=False)
-
Ping Kyanit.
You may provide ping count and timeout in seconds. If verbose is
True
, results will be printed.Return value is
True
is ping was successful,False
otherwise def put_file(self, filename, content)
-
Create or replace a file with the name passed to
filename
on the Kyanit, and upload contents passed tocontent
, which may be bytes or string.Directories are not supported, if the filename contains a '/'
KyanitRequestError
will be raised with a status code 500. The same error will be raised if trying to putmain.py
,boot.py
or_boot.py
as these files are protected and internal to Kyanit.Return value is the string
OK
if successful. def reboot(self)
-
Perform a hard reset on the Kyanit. The system will fully restart, wlan connection will be performed again.
kyanit.RebootError will be passed to code.cleanup on Kyanit before the reboot procedure.
Might take some time before Kyanit will respond to further requests. It's a good practice to
get_status
with a number of tries larger than 1 (ex. 5) after reboot or reset.Return value is the string
OK
if successful. def rename_file(self, filename, newname)
-
Rename a file with the name passed to
filename
tonewname
on the Kyanit.KyanitRequestError
with status code 404 will be raised if file is not found.Directories are not supported, if the filename contains a '/'
KyanitRequestError
will be raised with a status code 500. The same error will be raised if trying to renamemain.py
,boot.py
or_boot.py
as these files are protected and internal to Kyanit. def set_timeout(self, seconds)
-
Set connection timeout in seconds.
def start(self)
-
Start runner. Kyanit will attempt to import 'code.py' and call main.
Return value is the string
OK
if successful. def stop(self, force=False)
-
Stop runner, stopping all tasks. New run state will be 'STOPPED'.
A kyanit.StoppedError will be passed to code.cleanup on Kyanit.
Return value is the string
OK
if successful.
class KyanitConnectionError (...)
-
Raised when connecting to Kyanit fails or results in a timeout. No arguments are passed to this exception.
Handle it as follows:
try: # some Kyanit operation ... except KyanitConnectionError: # do something on connection error
Ancestors
- builtins.Exception
- builtins.BaseException
class KyanitRequestError (...)
-
Raised when Kyanit responds with a status code other than 200 OK. The first argument passed to this exception will be the response status code, the second will be the response body.
Handle it as follows:
try: # some Kyanit operation ... except KyanitRequestError as error: status_code = error.args[0] response_body = error.args[1] if status_code == 404: # do something on 404 Not Found ... # handle the rest, if desired ...
Ancestors
- builtins.Exception
- builtins.BaseException