Giter Site home page Giter Site logo

pyunifi's People

Contributors

aenea avatar agauvrit-tis avatar bachp avatar calmh avatar candlerb avatar chrismandich avatar cyr3xx avatar digitlength avatar elfixit avatar finish06 avatar gottsman avatar hamiltont avatar jamenlang avatar jchasey avatar jgarland79 avatar jsayles avatar kleo avatar luken avatar makuser avatar martey avatar matsimon avatar mtnocean avatar ryanaguilar avatar saroberts avatar sdague avatar the-loeki avatar timball avatar voltagex avatar xaviertorras avatar zakx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyunifi's Issues

Issues with login into a Cloud Key Gen2 plus

I tried to use pyunifi against a Cloud Key Gen2 plus, and I found a login issue to it.
I tried to use version="unifiOS" and then I got this error back:
raise APIError("Login failed - status code: %i" % r.status_code)
APIError: Login failed - status code: 401

I used F12 to login to the cloud key, and checked which URI it posted the login call to.
It is supposted to be towards: https://IP/api/auth/login.

In the script, the self.url is:
self.url = 'https://' + host + '/proxy/network/'

and the login function is using self.url like this:
login_url = self.url + 'api/login'

Which means it gets /proxy/network/ before api/login.

So I changed the init from:
if version == "unifiOS":
self.host = host
self.username = username
self.password = password
self.site_id = site_id
self.ssl_verify = ssl_verify
self.url = 'https://' + host + '/proxy/network/'

to:
if version == "unifiOS":
self.host = host
self.username = username
self.password = password
self.site_id = site_id
self.ssl_verify = ssl_verify
self.url = 'https://' + host + '/proxy/network/'
self.urllogin= 'https://' + host + '/'
self.version=version

And the login function I changed from this:
def _login(self):
log.debug('login() as %s', self.username)

    # XXX Why doesn't passing in the dict work?
    params = {'username': self.username, 'password': self.password}
    login_url = self.url + 'api/login'

To:
def _login(self):
log.debug('login() as %s', self.username)

    # XXX Why doesn't passing in the dict work?
    params = {'username': self.username, 'password': self.password}
    if self.version=="v5":
        login_url = self.url + 'api/login'
    elif self.version=="unifiOS":
        login_url = self.urllogin + 'api/auth/login'

And then I could login to the Cloud key and pull everything I needed.

Just wanted to inform you about this issue, awesome job with the library!

Scripts use dos line endings

Brand new install on linux will break as the scripts are using dos line endings. I worked around by manually editing the (pip installed) scripts. I'm not sure what the proper "fix" is - perhaps to have setuptools generate the scripts for the project, which would then generate OS-correct scripts?

Steps to reproduce:

m ~$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.2 LTS
Release:	18.04
Codename:	bionic
m ~$ uname -an
Linux media 4.15.0-51-generic #55-Ubuntu SMP Wed May 15 14:27:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
~$ sudo pip install -U pyunifi
/usr/local/lib/python2.7/dist-packages/pip/_vendor/requests/__init__.py:83: RequestsDependencyWarning: Old version of cryptography ([1, 2, 1]) may cause slowdown.
  warnings.warn(warning, RequestsDependencyWarning)
The directory '/home/hamiltont/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/hamiltont/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting pyunifi
  Downloading https://files.pythonhosted.org/packages/aa/6e/e4e524081f8e795b8e60e1e46fb30f30fe88f651da65fd77b24ce3032176/pyunifi-2.16.tar.gz
Requirement already satisfied, skipping upgrade: requests in /usr/lib/python2.7/dist-packages (from pyunifi) (2.18.4)
Installing collected packages: pyunifi
  Running setup.py install for pyunifi ... done
Successfully installed pyunifi-2.16
m ~$ unifi-ls-clients
/usr/bin/env: ‘python\r’: No such file or directory

Note: See https://stackoverflow.com/questions/19425857/env-python-r-no-such-file-or-directory for multiple methods to manually fix the issue

InsecureRequestWarning appearing while liburl3 is configured to mute them

Hey Pyunifi developers,

I have set the flag ssl_verify to False as x.509 certificate verification is not a concern in my environment. While this flag is disabled, I noticed that the script's output is spammed warnings of type InsecureRequestWarning. In the context of urllib3, this is a normal behavior, as stated in the official documentation. This may be disabled using the following code:

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

Nonetheless, after implementing this code in my project, the warnings are still triggered. After diving into Pyunifi, I discovered that this issue was bound to the following instructions:

if ssl_verify is False:
warnings.simplefilter("default", category=InsecureRequestWarning)

Indeed, Pyunifi reactivates the warnings in case the flag ssl_verify is set to False.

From a developer perspective that consumes your library, I have the feeling the library forces me to trigger that warning in the underlying library urllib3 and mask the possibility to use the built-in feature of that underlying library to mute the warnings. In my opinion, this choice must be made by the consumer of the end application, rather than the library, to allow better extensibility.

I propose two solutions for improving that case:
c

  • removing these two lines and leaving the developers to apply the warning filter(s) as they pleased, or
  • adding another flag to control the execution of the call of warnings.simplefilter (a dedicated flag, instead of ssl_verify).

The latter solution keeps the library backward compatible in terms of behavior, but on the other hand, I think these two instructions don't add any values to Pyunifi.

If you are satisfied with one of these solutions, I can submit a pull request to perform those changes. If not so, I'm looking forward to discussing to find a better alternative to those unmaskable warnings.

Many thanks!
Cheers

pyunifi.controller.APIError: Login failed - status code: 404 after FW upgrade

Hi @finish06 ,

Today i updated FW on my Cloud Key Gen2 and now I’m receiving and error pyunifi.controller.APIError: Login failed - status code: 404

Here is my Client initialisation

c = Controller('host', 'login', 'pass, ssl_verify=False, site_id="default")

Python version - 3.7.3
pyunifi version - 2.21
Cloud Key version - 2.1.11
Cloud Network version - 6.4.54

Can you please help me to solve this issue ?

Support Unifi's insistence on ancient TLSv1

Connecting (at least with Python 3.7) gives the error:

requests.exceptions.SSLError: HTTPSConnectionPool(host='xxx', port=8443): Max retries exceeded with url: /api/login (Caused by SSLError(SSLError(1, '[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:1056)')))

Caused by the Unifi controller supporting only TLS v1.

This can be resolved by manually adjusting your controller to support TLSv1.2, however given that Ubiquiti have deemed the default to be only TLSv1 support, this API probably should support it.

Controller Login Fails with "Remote end closed connection without response"

I have verified that I can login and have full use of the Unifi manager.

Whenever I try to initialize a Controller I would say I have a 1/6 chance of actually logging in. The other 5/6 times I simply have a trace-back that looks like the following:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 649, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py", line 357, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.6/site-packages/urllib3/packages/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 382, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1331, in getresponse
    response.begin()
  File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 266, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))

I've been attempting to remedy this issue in some form which included me adding a couple of lines for a Requests adapter for max_retries, but this doesn't seem to actually help.

It could be related to psf/requests#2422 and psf/requests#2448

SSL: CERTIFICATE_VERIFY_FAILED

Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\connectionpool.py", line 839, in _validate_conn
    conn.connect()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\connection.py", line 344, in connect
    ssl_context=context)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\util\ssl_.py", line 357, in ssl_wrap_socket
    return context.wrap_socket(sock)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 817, in __init__
    self.do_handshake()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 1077, in do_handshake
    self._sslobj.do_handshake()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\adapters.py", line 449, in send
    timeout=timeout
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\urllib3\util\retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.66.6', port=8443): Max retries exceeded with url: /api/login (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)'),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\Checkunifi.py", line 2, in <module>
    c = Controller('192.168.66.6', 'nulee', 'shuidoubushi')
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\pyunifi\controller.py", line 89, in __init__
    self._login()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\pyunifi\controller.py", line 137, in _login
    r = self.session.post(login_url, json=params)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\requests\adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.66.6', port=8443): Max retries exceeded with url: /api/login (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)'),))

ImportError: No module named parse

I'm not that familiar with python, so there might be an obvious answer to this; my apologies if that is the case.

I receive the following error while running unifi-ls-clients:

Traceback (most recent call last):
File "/usr/local/bin/unifi-ls-clients", line 5, in
from pyunifi.controller import Controller
File "/usr/local/lib/python2.7/dist-packages/pyunifi/controller.py", line 6, in
import urllib.parse
ImportError: No module named parse

I have urllib3 installed and parse

$ pip list --format=columns | grep -e 'urllib' -e 'parse'
parse 1.6.6
parsedatetime 1.4
urllib3 1.22

I worked around the issue by making the import statement in controller.py, line 6:
import urllib.parse -> import parse

It works like this, but I'm not sure why and I'm not sure if this work around is appropriate.

Change Password Function

Maybe something like this, probably add private 'put' function. Possibly call another function, as you can change anything with the put. Was in a rush, did this - much thanks much for your project.

    def set_wlan_pass(self, ssid, key):
        """Changes the password for a given
        ssid.  Daniel ToDo: Put method. """
        for wlan in self._api_read('list/wlanconf'):
            if wlan['name'] == ssid:
                wlan_id = wlan['_id']
                wlan_settings = {}
                wlan_settings["x_passphrase"] = key 
                params = json.dumps(wlan_settings)
                url = 'rest/wlanconf/' + wlan_id
                r = self.session.put(self._api_url() + url,
                        params)
                if r.status_code is not 200:
                    raise APIError("Login failed - status code: %i" %  
                            r.status_code)
        return 

List or query multiple sites

Hello,

As per the documentation, we need to give the site ID when connecting to the controller.
Is it possible to list the controller for sites and query multiple sites? E.g. search for a client across all sites or create a given setting for all existing sites on the controller?
Likewise, can one create a new site with this API client?

Thanks a lot.

Issues with create_backup()

I am using a Raspberry pi as my Unifi controller(version atag_6.0.45_14358), and I am trying to take backup of it.
I get the error message:
Exception has occurred: IndexError
list index out of range
File "C:\Users\mabor\OneDrive - IT Relation\Skrivebord\Python\Private\Unifi\UnifiAP.py", line 31, in
CreateBackup=c.create_backup()

This is basically my code(edited to remove unneeded things and passwords and so on):

from future import print_function

import argparse
import time
from collections import defaultdict

from pyunifi.controller import Controller

ControllerIP="192.168.254.111"
Username=""
Password=""
Port="8443" #Management port, default is 8443
Version="v5" #Default version is v5
Siteid="default" #Default siteID in Unifi

c = Controller(ControllerIP, Username, Password, Port, Version, Siteid ,ssl_verify = False)

CreateBackup=c.create_backup()
time.sleep(15)
print(CreateBackup)

Backup=c.get_backup(CreateBackup)

print(Backup)

I got it to work by editing the function create_backup().
Before I started:
def create_backup(self, days='0'):
"""Ask controller to create a backup archive file

    ..warning:
        This process puts significant load on the controller
        and may render it partially unresponsive for other requests.

    :param days: metrics of the last x days will be added to the backup.
        '-1' backup all metrics. '0' backup only the configuration.
    :return: URL path to backup file
    """
    res = self._run_command('backup', mgr='system', params={'days': days})
    return res[0]['url']

I changed mgr='system" to mgr='backup' and then it worked. This seems to be due to the fact that run_command uses the mgr in its API call.
I installed pyunifi using pip install pyunifi on my windows machine. I use pyunifi version
pyunifi==2.20.1

Official Version

I know that the original project is on pypi as well, but perhaps this one could become the official one since it is now maintained. Maybe tell the original author to link to this project in his documentation ?

use-case: dynamic IPv6 port forwarding

Here's what I'm trying to do: I'd like to be able to, on demand, expose port 443 on various network devices over IPv6. Each one has a globally routable address, after all, and so I should be able to do this. I already have automation on the DNS side of things; I just need to expose the network port.

  • I can't do it with static firewall configuration. Unifi doesn't support suffix masking so I can't mask out the prefix delegation and forward just the unchanging part of a machine's IP.
  • I can't do it with UPnP. I can't find any documentation on this, and whether it's a UPnP restriction or a Unifi configuration issue, but upnpc gets a "failed with code 606 (Action not authorized)" for port numbers less than 1024.
  • I can't do it with ULA addresses and NAT66, since that seems to just be totally unsupported.
  • I can't (currently) do it with pyunifi because it doesn't expose these objects via the API.

https://github.com/nickovs/unificontrol seems like it might expose some of the relevant APIs via list_networkconf and set_networksettings, but I can't experiment with those since I have a UDM pro and that library can't authenticate against a UDM Pro whereas this one can.

These APIs appear to be specified declaratively which might help copy them (and all the others, for that matter) into this library without too much additional work.

NameError: global name 'urllib' is not defined

I'm receiving the following errors when I run a simple get_alerts_unarchived() call. All other API calls and sample scripts work perfectly. This seems to be the only call that references urllib. Tested in 2.X and 3.X. It seems the format for urllib changed in 3 so that may be related.

File "/usr/lib/python2.7/site-packages/pyunifi/controller.py", line 166, in get_alerts_unarchived
params = urllib.urlencode({'json': js})
NameError: global name 'urllib' is not defined

File "/usr/lib/python3.6/site-packages/pyunifi/controller.py", line 166, in get_alerts_unarchived
params = urllib.urlencode({'json': js})
NameError: name 'urllib' is not defined

RADIUS functions and utilities

Hi,
I've written some code for setting RADIUS usernames and passwords along with some demo Python code. Please tell me if you would like me to submit a pull request.
Paul

https://github.com/mtnocean/pyunifi/tree/radius

functions:

  • get_radius_users(self)
  • add_radius_user(self, name, password)
  • update_radius_user(self, name, password, id)
  • delete_radius_user(self, id)

support functions for delete_radius_user():

  • _delete(self, url, params=None)
  • _api_delete(self, url, params=None)

utilities:

  • unifi-ls-radius - lists all usernames/passwords
  • unifi-save-radius - saves all usernames/passwords to a .csv file
  • unifi-copy-radius - copies all usernames/passwords from one site to another

in progress:

  • unifi-upload-radius - uploads a .csv file of usernames/passwords to a site

Unable to login to Controller v5.9

Logging in always returns "Login failed - status code: 400".

Trace:

>>> from pyunifi.controller import Controller, APIError
>>> c = Controller('myhostname.tld', 'username', 'password', 8443, version='v5', site_id='site')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/pyunifi/controller.py", line 89, in __init__
    self._login(version)
  File "/usr/local/lib/python3.6/site-packages/pyunifi/controller.py", line 151, in _login
    raise APIError("Login failed - status code: %i" % r.status_code)
pyunifi.controller.APIError: Login failed - status code: 400
>>> try:
...     c = Controller('myhostname.tld', 'username', 'password', 8443, version='v5', site_id='site')
... except APIError as e:
...     print(e)
... 
Login failed - status code: 400
>>> 

Using pyunifi on an IP without SSL cert

Hi there,

our UniFi controller is running on a server (software-install, v5.12.35) which is only accessable via an IP (which is not public). Therefore this IP is not SSL certified, but I see that the controller.py always creates an URL with https://

So I set the ssl_verify to false.

Is this an issue?

Question

Excuse me Sir, currently i am having thesis about python scripting with UBNT and i'm quite new to UBNT because i just learn with Mikrotik. I want to asking some questions, can you help me?

  1. Can this script works on ubnt devices like rocket m2?
  2. Can rocket m2 use controller like any other device?

Thanks. Any answer will help me a lot

Grab USG Network

Hi!

Im trying to grab information from an USG-3P
image

like sent and recieved information.
any chance to help me out?

in network_table inside device_stat i get:
{ "_id":"xxxxxxxxxxxxxxx", "attr_hidden_id":"LAN", "attr_no_delete":true, "auto_scale_enabled":false, "dhcpd_enabled":true, "dhcpd_start":"192.168.1.6", "dhcpd_stop":"192.168.1.254", "dhcpdv6_enabled":false, "domain_name":"localdomain", "ip_subnet":"192.168.1.1/24", "ipv6_interface_type":"none", "ipv6_ra_enabled":false, "is_nat":true, "lte_lan_enabled":true, "mdns_enabled":true, "name":"Default", "networkgroup":"LAN", "purpose":"corporate", "setting_preference":"manual", "site_id":"xxxxxxxxx", "vlan_enabled":false, "is_guest":false, "ip":"192.168.1.1", "mac":"fc:ec:da:48:9e:07", "up":"true", "gateway_interface_name":"eth1", "num_sta":41, "rx_bytes":138500632107, "rx_packets":113999749, "tx_bytes":22781296050, "tx_packets":49695580 } ]

ssl_verify issues

Hi,

Trying to modify an old script.

I have an argument set as:

parser.add_argument('-s', '--sslCert', help = "SSL CertPath True or False", default = "False")

and parse the argument as below:

if args.sslcert is not None:
    sslCert = args.sslcert
else:
    sslCert = os.getenv("SSL_CERT_VAR")
    if sslCert is None:
        sslCert = raw_input('SSL_Var: ')

And use the argument here:

c = Controller(controllerIP, userName, password, "8443", "v4", "default", sslCert)
clients = c.get_clients()
list = {}

I'm getting the error:

Traceback (most recent call last):
  File "/home/pi/client-mapping.py", line 58, in <module>
    c = Controller(controllerIP, userName, password, "8443", "v4", "default", sslCert)
  File "/usr/local/lib/python2.7/dist-packages/pyunifi/controller.py", line 113, in __init__
    self._login()
  File "/usr/local/lib/python2.7/dist-packages/pyunifi/controller.py", line 161, in _login
    r = self.session.post(login_url, json=params)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 578, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 416, in send
    self.cert_verify(conn, request.url, verify, cert)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 228, in cert_verify
    "invalid path: {}".format(cert_loc))
IOError: Could not find a suitable TLS CA certificate bundle, invalid path: False

So it seems it sees "False", but it's not seeing it as an input for "ssl_verify"

Any ideas? As you can tell, I'm still learning.

Thanks,
Shane.

ssl_verify attempt to suppress warnings is broken

This code does not work and also if the caller has already called urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) it prevents that from working either:

if ssl_verify is False:
    warnings.simplefilter("default", category=InsecureRequestWarning)

Removing that code from the Controller constructor allows disable_warnings() to do its job again and actually disable the warning.

requests.version
'2.21.0'
urllib3.version
'1.24.1'

pyunifi current git version as of today.

SSL Error

Any idea why I'm getting an error related to SSL?

from pyunifi.controller import Controller

c = Controller('192.168.2.126', 'JeffHerr', 'XXXXXX')
for ap in c.get_aps():
print('AP named %s with MAC %s', ap.get('name'), ap['mac'])

requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.2.126', port=8443): Max retries exceeded with url: /api/login (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

I'm using a self-signed cert, I suppose, as I don't have a formal cert assigned.

Authentication issue with unifi controller 5.5.9

I'm using the unify home assistant component which depends on this library at version 2.0.0.

After updating my unifi controller to the latest beta (5.5.9), I noticed that my home-assistant unify integration stopped working.

Here's the debug output:

17-04-19 22:04:23 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "uvloop/future.pyx", line 374, in uvloop.loop.BaseTask._fast_step (uvloop/loop.c:112704)
  File "/usr/src/app/homeassistant/components/device_tracker/__init__.py", line 698, in async_device_tracker_scan
    found_devices = yield from scanner.async_scan_devices()
  File "uvloop/future.pyx", line 230, in __iter__ (uvloop/loop.c:110600)
  File "uvloop/future.pyx", line 432, in uvloop.loop.BaseTask._fast_wakeup (uvloop/loop.c:113980)
  File "uvloop/future.pyx", line 101, in uvloop.loop.BaseFuture._result_impl (uvloop/loop.c:108900)
  File "/usr/local/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/app/homeassistant/components/device_tracker/unifi.py", line 88, in scan_devices
    self._update()
  File "/usr/src/app/homeassistant/components/device_tracker/unifi.py", line 79, in _update
    clients = self._controller.get_clients()
  File "/usr/local/lib/python3.5/site-packages/pyunifi/controller.py", line 183, in get_clients
    return self._read(self.api_url + 'stat/sta')
  File "/usr/local/lib/python3.5/site-packages/pyunifi/controller.py", line 82, in _read
    return self._jsondec(r.text)
  File "/usr/local/lib/python3.5/site-packages/pyunifi/controller.py", line 75, in _jsondec
    raise APIError(obj['meta']['msg'])
pyunifi.controller.APIError: api.err.LoginRequired

Any idea on what the issue may be?

update docs and possibly improve login

I had a very hard time getting this working.

At first I got an SSL _CERTIFICATE verification error, so apparently you need to add ssl_verify = False to the controller command line. This generates a warning when you run the script, but that apparently is a KNOWN 'feature'.

Next it would not connect and login. I got 404 no matter what I tried. Turns out that the port and version parameters ARE NOT OPTIONAL, and the library does not try to figure them out. so for the UDM Pro you also need to add port=443, version='UDMP-unifiOS'

Finally, the username and password worked with the values used for primary login to the device/cloud at ubiquity, in my case my username was my email address. using the "SSH" password DOES NOT work. that returns 403.

I RECOMMEND that the parameters be considered NOT OPTIONAL and that a note be added to that effect in the documentation. when parameters are "optional" the user expects that the library will figure out a reasonable value to use, unless you REALLY want something different.

Allow to define request timeout

Currently this library doesn't seem to support setting a request timeout. In case the Unifi Controller is not responding, a script using this library is waiting infinitely.

In my case I'm using this library in a small local check for Check_MK to monitor my access points. If the Unifi Controller is not responding, every check will start an additional Python process waiting for the Unifi Controller to respond which will soon end in having hundreds of processes waiting for the Unifi Controller.

Could you please add the possibility to specify the timeout for the API requests?

Unable to login on Controller v5.10

In [11]: ctrl = Controller(host, username, password, port, version='v4', site_id=site_id, ssl_verify=False)                    
/home/homeassistant/.virtualenvs/hass/lib64/python3.6/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
---------------------------------------------------------------------------
APIError                                  Traceback (most recent call last)
<ipython-input-11-f04d4ea99bd7> in <module>
----> 1 ctrl = Controller(host, username, password, port, version='v4', site_id=site_id, ssl_verify=False)

~/.virtualenvs/hass/lib64/python3.6/site-packages/pyunifi/controller.py in __init__(self, host, username, password, port, version, site_id, ssl_verify)
     87 
     88         log.debug('Controller for %s', self.url)
---> 89         self._login(version)
     90 
     91     def _jsondec(self, data):

~/.virtualenvs/hass/lib64/python3.6/site-packages/pyunifi/controller.py in _login(self, version)
    149 
    150         if r.status_code is not 200:
--> 151             raise APIError("Login failed - status code: %i" % r.status_code)
    152 
    153     def _logout(self):

APIError: Login failed - status code: 400

Same for v5:

In [13]: ctrl = Controller(host, username, password, port, version='v5', site_id=site_id, ssl_verify=False)                    
/home/homeassistant/.virtualenvs/hass/lib64/python3.6/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
---------------------------------------------------------------------------
APIError                                  Traceback (most recent call last)
<ipython-input-13-b48ed86d0681> in <module>
----> 1 ctrl = Controller(host, username, password, port, version='v5', site_id=site_id, ssl_verify=False)

~/.virtualenvs/hass/lib64/python3.6/site-packages/pyunifi/controller.py in __init__(self, host, username, password, port, version, site_id, ssl_verify)
     87 
     88         log.debug('Controller for %s', self.url)
---> 89         self._login(version)
     90 
     91     def _jsondec(self, data):

~/.virtualenvs/hass/lib64/python3.6/site-packages/pyunifi/controller.py in _login(self, version)
    149 
    150         if r.status_code is not 200:
--> 151             raise APIError("Login failed - status code: %i" % r.status_code)
    152 
    153     def _logout(self):

APIError: Login failed - status code: 400

CC: @finish06

InsecureRequestWarning spams log

Hello!
Maybe dumb question but is following necessary?:

if ssl_verify is False:
warnings.simplefilter("default", category=requests.packages.
urllib3.exceptions.
InsecureRequestWarning)

My Home Assistant core log is getting spammed by these warnings.

switch_port_power_off error

switch_port_power_off or switch_port_power_on will fail: TypeError: list indices must be integers or slices, not dict.

I fixed it with replacing for i in overrides: with for i in range(len(overrides)): in _switch_port_power().

switch_port_power_on/off issues

executing switch_port_power_on or switch_port_power_off will modify the port overrides such that the assigned network is set to "default". the port configuration gets into a jacked up state where the only way to fix it is to reset the port overrides and then reassign the network. not sure why this is happening because the json payload only contains the poe setting. i'm using a udmpro with the current firmware. i suspect that the pyunifi usage of these apis is not what is expected by the udmpro.

i really didn't need power off & power on but really wanted the power cycle api. so i implemented the devmgr/power-cycle for my purposes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.