Skip to main content
Python Software Foundation 20th Year Anniversary Fundraiser  Donate today!

Mist API Python module

Project description

Mistifi

Mistifi is a highly scalable Python module enabling full interfacing with the Mist RestAPI.

Motivation

To provide a scalable, easy to use and easy to contribute to module that will be able to interface to the fullest with the Mist Systems cloud for wired and wireless.

Installation

The module can be pip installed

pip install mistifi

or using pip3 if using python3.

The module is imported with

import mistifi
from mistifi import MistiFi

Usage

The usage workflow intended is:

  1. Create an instance with passing in the cloud and authentication options.
  2. Initiate communication with the comms() method.
  3. Interface with the API with the use of either a specific endpoint method (like wlans() for example) or the resource() method.

Create an instance

Selecting a cloud

When creating an instance pass in the cloud option to specify a direct instance of a cloud.

There are currently two cloud options to select from. Either EU or US, with US being the default if not provided with the cloud attribute. They default to

  • US = api.mist.com
  • EU = api.eu.mist.com

If not passed in, the default US will be used.

Ex. 1: Using the default US cloud

mist = MistiFi()

In this case not only will the US cloud be used but also a username/password option for user login (Look at next section for explanation on this).

Ex. 2: Specifying the EU cloud

mist = MistiFi(cloud="EU")

Note that the cloud parameter is case-insensitive. In the below example the US cloud will be used.

mist = MistiFi(cloud="us")

Using a token or username/password

Ex. 1: Using a token

In below example a token thetoken is used with the US cloud. You can create a user token by following these instructions

mist = MistiFi(token="thetoken")

An alternative with specifying the EU cloud would be.

mist = MistiFi(cloud="EU", token="thetoken")

The token always has preference before username/password or other option, so in the below example a token would be used.

mist = MistiFi(token="thetoken", username="theuser@mistifi.com", password="thepass")

Ex. 2: Using username and password.

Currently 2FA and OAUTH aren't supported.

The minimum required for this option is to create an instance without any attributes like below.

mist = MistiFi()

In this case you are asked for username and password.

You can provide one or both when creating a new instance and be asked about the other once the comms() method is run.

mist = MistiFi(cloud='us', username="theuser@mistifi.com")

Communicating with the cloud

Once the cloud and authentication options are selected you must run the comms() method which correctly sets up the headers depending on the authentication method used. For example X-CSRFTOKEN is setup for the username/password option.

mist = comms()

Interfacing with the cloud URIs

If a specific resource method for a specific URI is not defined the main method that can be used is the resource() one. The resource methods defined start with Resource method in the docstring.

For example, GET-ing /self can be achieved by either the resource() method or the whoami() one.

>>> whoami = mist.whoami()
>>> rwhoami = mist.resource("GET", uri="/self")
>>> print(whoami == rwhoami)
True

Understanding the resource() method

The main method all others use on is resource(). You can pass keyword arguments into it. Pretty much anything will work, but there are some rules.

First thing is that those kwargs are used to build the URL to the Mist cloud endpoint, therefore passing in proper parameters is necessary. Some parameters are special and handled differently.

Example of special kwargs is params. If passing in that kwarg, it will be handled differently so that it is passed into the requests.Session() as params.

If passing in org_id=':org_id', site_id='site_id', uri='some_uri' will create URL properly with the org_id first site_id second and then the uri.

All other kwargs will be added at the end to the URL, so make sure that URL exists. Error 400 is thrown otherwise.

Example:

mist.resource(
	"GET", 
	site_id=":site_id123", 
	wlan_id=":wlan_id123", 
	org_id=":org_id123", 
	blah="/blah", 
	params={"paramA": "valueA", 'paramB': 'valueB'})

builds the URL to https://api.mist.com/api/v1/orgs/:org_id123/sites/:site_id123/wlans/:wlan_id123/blah and params are added at the end when passed in the requests as params.

Additional

Debugging

The default debug level is ERROR, which can be changed per method call by preempting it with logzero.loglevel(logging.LEVEL) where LEVEL is the debug level. Each method then resets logging to ERROR, so you need to set logging level before each one.

You can import the below for this

import logging
import logzero
from logzero import logger

Ex. 1: DEBUG level

>>> logzero.loglevel(logging.DEBUG)
>>> mist.whoami()
[I 200326 14:48:17 mistifi:547] Calling whoami()
[I 200326 14:48:17 mistifi:548] kwargs in: {}
[I 200326 14:48:17 mistifi:511] Calling resource()
[D 200326 14:48:17 mistifi:512] kwargs in: {'uri': '/self'}
[I 200326 14:48:17 mistifi:471] Calling _params()
[I 200326 14:48:17 mistifi:472] kwargs in: {'uri': '/self'}
[D 200326 14:48:17 mistifi:479] Returned params: {}
[I 200326 14:48:17 mistifi:395] Calling _resource_url()
[I 200326 14:48:17 mistifi:396] kwargs in: {'uri': '/self'}
[D 200326 14:48:17 mistifi:450] URL to endpoint: https://api.mist.com/api/v1/self
[I 200326 14:48:17 mistifi:333] Calling _api_call()
[I 200326 14:48:17 mistifi:334] Method is: GET
[I 200326 14:48:17 mistifi:335] Calling URL: https://api.mist.com/api/v1/self
[D 200326 14:48:17 mistifi:336] With headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}
[I 200326 14:48:18 mistifi:346] Response status code: 200
[D 200326 14:48:18 mistifi:356] Response HEAD: {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': 'https://manage.mist.com', 'Access-Control-Expose-Headers': 'X-CSRFTOKEN,X-Requested-With,X-Page-Page,X-Page-Total', 'Allow': 'GET, OPTIONS, DELETE, PUT', 'Cache-Control': 'no-cache, no-store', 'Content-Type': 'application/json', 'Date': 'Thu, 26 Mar 2020 14:48:18 GMT', 'Pragma': 'no-cache', 'Server': 'gunicorn/19.10.0', 'Set-Cookie': 'sessionid=8trv1zr79sknwk0n7sz2pim8x26g84mh; Domain=.mist.com; expires=Fri, 27-Mar-2020 14:48:18 GMT; HttpOnly; Max-Age=86400; Path=/; Secure', 'Vary': 'Origin', 'Via': 'kong/0.9.3', 'X-Frame-Options': 'SAMEORIGIN', 'X-Kong-Proxy-Latency': '0', 'X-Kong-Upstream-Latency': '39', 'Content-Length': '608', 'Connection': 'keep-alive'}
[D 200326 14:48:18 mistifi:357] The response: {'email': 'blah@mist.com'...}

Ex. 2: INFO level

>>> logzero.loglevel(logging.INFO)
>>> mist.whoami()
[I 200326 14:58:23 mistifi:547] Calling whoami()
[I 200326 14:58:23 mistifi:548] kwargs in: {}
[I 200326 14:58:23 mistifi:511] Calling resource()
[I 200326 14:58:23 mistifi:471] Calling _params()
[I 200326 14:58:23 mistifi:472] kwargs in: {'uri': '/self'}
[I 200326 14:58:23 mistifi:395] Calling _resource_url()
[I 200326 14:58:23 mistifi:396] kwargs in: {'uri': '/self'}
[I 200326 14:58:23 mistifi:333] Calling _api_call()
[I 200326 14:58:23 mistifi:334] Method is: GET
[I 200326 14:58:23 mistifi:335] Calling URL: https://api.mist.com/api/v1/self
[I 200326 14:58:23 mistifi:346] Response status code: 200

Ex. 3: Examples of error output Here no log level was set.

>>> mist.whoami()
[E 200326 14:58:24 mistifi:351] Response Error:
    {"detail":"Method \"GET\" not allowed."}
[E 200326 14:58:24 mistifi:351] Response Error:
    {"detail":"CSRF Failed: CSRF token missing or incorrect."}

TODO

The general TODO list is:

  • add more/all URIs

Contributing

Thank you for helping us develop Mistifi. We're happy to accept contribution of any kind. Feel free to submit feature requests and bug reports under Issues.

Submitting a pull request guidelines

  • All pull requests require a code review.
  • Any merge conflicts needs to be resolved.
  • Include unit tests when you contribute new features and bugs, as they help to a) prove that your code works correctly, and b) guard against future breaking changes to lower the maintenance cost.
  • All tests needs to pass before we will review your PR.
  • When you respond to changes based on comments from a code review, please reply with "Done." so that we get a notification.

Contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for mistifi, version 0.0.9
Filename, size File type Python version Upload date Hashes
Filename, size mistifi-0.0.9-py3-none-any.whl (17.0 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size mistifi-0.0.9.tar.gz (31.0 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page