Load credentials from json file
This commit is contained in:
+17
@@ -55,6 +55,23 @@ The simplest way to use this package from a terminal is to call ``Blink.start()`
|
||||
|
||||
If you would like to log in without setting up the cameras or system, you can simply call the ``Blink.login()`` function which will prompt for a username and password and then authenticate with the server. This is useful if you want to avoid use of the ``start()`` function which simply acts as a wrapper for more targeted API methods.
|
||||
|
||||
In addition, you can also save your credentials in a json file and initialize Blink with the credential file as follows:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from blinkpy import blinkpy
|
||||
blink = blinkpy.Blink(cred_file="path/to/credentials.json")
|
||||
blink.start()
|
||||
|
||||
The credential file must be json formatted with a ``username`` and ``password`` key like follows:
|
||||
|
||||
.. code:: json
|
||||
|
||||
{
|
||||
'username': 'YOUR USER NAME',
|
||||
'password': 'YOUR PASSWORD'
|
||||
}
|
||||
|
||||
Cameras are instantiated as individual ``BlinkCamera`` classes within a ``BlinkSyncModule`` instance. All of your sync modules are stored within the ``Blink.sync`` dictionary and can be accessed using the name of the sync module as the key (this is the name of your sync module in the Blink App).
|
||||
|
||||
The below code will display cameras and their available attributes:
|
||||
|
||||
+26
-2
@@ -17,6 +17,7 @@ import os.path
|
||||
import time
|
||||
import getpass
|
||||
import logging
|
||||
import json
|
||||
from shutil import copyfileobj
|
||||
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
@@ -42,6 +43,7 @@ class Blink():
|
||||
"""Class to initialize communication."""
|
||||
|
||||
def __init__(self, username=None, password=None,
|
||||
cred_file=None,
|
||||
refresh_rate=DEFAULT_REFRESH,
|
||||
motion_interval=DEFAULT_MOTION_INTERVAL,
|
||||
legacy_subdomain=False):
|
||||
@@ -50,6 +52,10 @@ class Blink():
|
||||
|
||||
:param username: Blink username (usually email address)
|
||||
:param password: Blink password
|
||||
:param cred_file: JSON formatted file to store credentials.
|
||||
If username and password are given, file
|
||||
is ignored. Otherwise, username and password
|
||||
are loaded from file.
|
||||
:param refresh_rate: Refresh rate of blink information.
|
||||
Defaults to 15 (seconds)
|
||||
:param motion_interval: How far back to register motion in minutes.
|
||||
@@ -62,6 +68,7 @@ class Blink():
|
||||
"""
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._cred_file = cred_file
|
||||
self._token = None
|
||||
self._auth_header = None
|
||||
self._host = None
|
||||
@@ -117,8 +124,25 @@ class Blink():
|
||||
|
||||
def login(self):
|
||||
"""Prompt user for username and password."""
|
||||
self._username = input("Username:")
|
||||
self._password = getpass.getpass("Password:")
|
||||
if self._cred_file is not None and os.path.isfile(self._cred_file):
|
||||
try:
|
||||
with open(self._cred_file, 'r') as json_file:
|
||||
creds = json.load(json_file)
|
||||
self._username = creds['username']
|
||||
self._password = creds['password']
|
||||
except ValueError:
|
||||
_LOGGER.error("Improperly formated json file %s.",
|
||||
self._cred_file,
|
||||
exc_info=True)
|
||||
return False
|
||||
except KeyError:
|
||||
_LOGGER.error("JSON file information incomplete %s.",
|
||||
exc_info=True)
|
||||
return False
|
||||
else:
|
||||
self._username = input("Username:")
|
||||
self._password = getpass.getpass("Password:")
|
||||
|
||||
if self.get_auth_token():
|
||||
_LOGGER.debug("Login successful!")
|
||||
return True
|
||||
|
||||
@@ -79,6 +79,47 @@ class TestBlinkSetup(unittest.TestCase):
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(self.blink_no_cred._password, PASSWORD)
|
||||
|
||||
@mock.patch('blinkpy.blinkpy.getpass.getpass')
|
||||
@mock.patch('blinkpy.blinkpy.Blink.get_auth_token')
|
||||
def test_no_cred_file(self, getpwd, getauth, mock_sess):
|
||||
"""Check that normal login occurs when cred file doesn't exist."""
|
||||
# pylint: disable=protected-access
|
||||
self.blink._cred_file = '/tmp/fake.file'
|
||||
getpwd.return_value = PASSWORD
|
||||
getauth.return_value = True
|
||||
with mock.patch('builtins.input', return_value=USERNAME):
|
||||
self.assertTrue(self.blink.login())
|
||||
|
||||
def test_exit_on_missing_json(self, mock_sess):
|
||||
"""Test that we fail on missing json data."""
|
||||
# pylint: disable=protected-access
|
||||
self.blink._cred_file = '/tmp/fake.file'
|
||||
with mock.patch('os.path.isfile', return_value=True):
|
||||
with mock.patch('builtins.open', mock.mock_open(read_data="{}")):
|
||||
self.assertFalse(self.blink.login())
|
||||
|
||||
def test_exit_on_bad_json(self, mock_sess):
|
||||
"""Test that we fail on bad json format."""
|
||||
# pylint: disable=protected-access
|
||||
self.blink._cred_file = '/tmp/fake.file'
|
||||
with mock.patch('os.path.isfile', return_value=True):
|
||||
with mock.patch('builtins.open', mock.mock_open(read_data='{]')):
|
||||
self.assertFalse(self.blink.login())
|
||||
|
||||
@mock.patch('blinkpy.blinkpy.json.load')
|
||||
def test_cred_file(self, mockjson, mock_sess):
|
||||
"""Test that loading credential file works."""
|
||||
# pylint: disable=protected-access
|
||||
self.blink_no_cred._cred_file = '/tmp/fake.file'
|
||||
mockjson.return_value = {'username': 'foo', 'password': 'bar'}
|
||||
with mock.patch('os.path.isfile', return_value=True):
|
||||
with mock.patch('builtins.open', mock.mock_open(read_data='')):
|
||||
self.assertTrue(self.blink_no_cred.login())
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(self.blink_no_cred._username, 'foo')
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(self.blink_no_cred._password, 'bar')
|
||||
|
||||
def test_bad_request(self, mock_sess):
|
||||
"""Check that we raise an Exception with a bad request."""
|
||||
self.blink.session = create_session()
|
||||
|
||||
@@ -18,7 +18,7 @@ setenv =
|
||||
LANG=en_US.UTF-8
|
||||
PYTHONPATH = {toxinidir}
|
||||
commands =
|
||||
pytest --timeout=9 --durations=10 --cov=blinkpy --cov-report=xml {posargs}
|
||||
pytest --timeout=9 --durations=10 --cov=blinkpy --cov-report=xml --cov-report=term-missing {posargs}
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/requirements_test.txt
|
||||
|
||||
Reference in New Issue
Block a user