Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d6bbb916 | ||
|
|
b02f6318a7 | ||
|
|
c1435e74e8 | ||
|
|
b30da661e5 | ||
|
|
3a22dddc82 | ||
|
|
a19a17d4dc | ||
|
|
bff6ef92ce | ||
|
|
263572eb66 | ||
|
|
3a97a928de | ||
|
|
0322414de1 | ||
|
|
1c75e86863 | ||
|
|
0ae71f6367 | ||
|
|
af7c38695a | ||
|
|
c741c22876 | ||
|
|
06b9b12eeb | ||
|
|
daf7078f98 | ||
|
|
c2db57ecb3 | ||
|
|
0336c6a8f8 | ||
|
|
22d3fa9565 | ||
|
|
9d81973b3a | ||
|
|
fe8eac3dc6 | ||
|
|
5fc315201a | ||
|
|
a9d3d5568b | ||
|
|
f88dbdaeba | ||
|
|
48028914de | ||
|
|
fcdb70d246 | ||
|
|
e8589bfa05 | ||
|
|
854ffbf26a | ||
|
|
ca109f703c | ||
|
|
82d5a7ea51 | ||
|
|
79ead7b826 | ||
|
|
6e360b2bb1 | ||
|
|
435f3b9831 | ||
|
|
bcf0bb5525 | ||
|
|
151d9b7375 | ||
|
|
d393c861d7 | ||
|
|
02c4b2e7e1 |
+37
@@ -4,6 +4,43 @@ Changelog
|
||||
|
||||
A list of changes between each release
|
||||
|
||||
0.16.1 (2020-07-29)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Unpin requeirements, set minimum version instead
|
||||
- Bump coverage to 5.2.1
|
||||
- Bump pytest to 6.0.0
|
||||
|
||||
|
||||
0.16.0 (2020-07-20)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
- Add arm property to camera, deprecate motion enable method (`#273 <https://github.com/fronzbot/blinkpy/pull/273>`__)
|
||||
- Complete refactoring of auth logic (breaks all pre-0.16.0 setups!) (`#261 <https://github.com/fronzbot/blinkpy/pull/261>`__)
|
||||
|
||||
**New Features:**
|
||||
|
||||
- Add is_errored property to Auth class (`#275 <https://github.com/fronzbot/blinkpy/pull/275>`__)
|
||||
- Add new endpoint to get user infor (`#280 <https://github.com/fronzbot/blinkpy/pull/280>`__)
|
||||
- Add get_liveview command to camera module (`#289 <https://github.com/fronzbot/blinkpy/pull/289>`__)
|
||||
- Add blink Mini Camera support (`#290 <https://github.com/fronzbot/blinkpy/pull/290>`__)
|
||||
- Add option to skip homescreen check (`#305 <https://github.com/fronzbot/blinkpy/pull/305>`__)
|
||||
- Add different timeout for video and image retrieval (`#323 <https://github.com/fronzbot/blinkpy/pull/323>`__)
|
||||
- Modifiy session to use HTTPAdapter and handle retries (`#324 <https://github.com/fronzbot/blinkpy/pull/324>`__)
|
||||
- Add retry option overrides (`#339 <https://github.com/fronzbot/blinkpy/pull/339>`__)
|
||||
|
||||
**All changes:**
|
||||
|
||||
Please see the change list in the (`Release Notes <https://github.com/fronzbot/releases/tag/v0.16.0>`__)
|
||||
|
||||
|
||||
0.15.1 (2020-07-11)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- Bugfix: remove "Host" from auth header (`#330 <https://github.com/fronzbot/blinkpy/pull/330>`__)
|
||||
|
||||
|
||||
0.15.0 (2020-05-08)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
**Breaking Changes:**
|
||||
|
||||
+2
-2
@@ -27,12 +27,12 @@ def request_login(
|
||||
"password": login_data["password"],
|
||||
"notification_key": login_data["notification_key"],
|
||||
"unique_id": login_data["uid"],
|
||||
"app_version": "6.0.7 (520300) #afb0be72a",
|
||||
"app_version": "6.0.12",
|
||||
"device_identifier": login_data["device_id"],
|
||||
"client_name": "Computer",
|
||||
"client_type": "android",
|
||||
"os_version": "5.1.1",
|
||||
"reauth": "false",
|
||||
"reauth": "true",
|
||||
}
|
||||
)
|
||||
return auth.query(
|
||||
|
||||
+16
-4
@@ -55,15 +55,20 @@ class Auth:
|
||||
return None
|
||||
return {"TOKEN_AUTH": self.token}
|
||||
|
||||
def create_session(self):
|
||||
def create_session(self, opts=None):
|
||||
"""Create a session for blink communication."""
|
||||
if opts is None:
|
||||
opts = {}
|
||||
backoff = opts.get("backoff", 1)
|
||||
retries = opts.get("retries", 3)
|
||||
retry_list = opts.get("retry_list", [429, 500, 502, 503, 504])
|
||||
sess = Session()
|
||||
assert_status_hook = [
|
||||
lambda response, *args, **kwargs: response.raise_for_status()
|
||||
]
|
||||
sess.hooks["response"] = assert_status_hook
|
||||
retry = Retry(
|
||||
total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504]
|
||||
total=retries, backoff_factor=backoff, status_forcelist=retry_list
|
||||
)
|
||||
adapter = HTTPAdapter(max_retries=retry)
|
||||
sess.mount("https://", adapter)
|
||||
@@ -174,11 +179,18 @@ class Auth:
|
||||
"Connection error. Endpoint %s possibly down or throttled.", url,
|
||||
)
|
||||
except BlinkBadResponse:
|
||||
code = None
|
||||
reason = None
|
||||
try:
|
||||
code = response.status_code
|
||||
reason = response.reason
|
||||
except AttributeError:
|
||||
pass
|
||||
_LOGGER.error(
|
||||
"Expected json response from %s, but received: %s: %s",
|
||||
url,
|
||||
response.status_code,
|
||||
response.reason,
|
||||
code,
|
||||
reason,
|
||||
)
|
||||
except UnauthorizedError:
|
||||
try:
|
||||
|
||||
+1
-3
@@ -151,9 +151,7 @@ class BlinkCamera:
|
||||
if config.get("thumbnail", False):
|
||||
thumb_addr = config["thumbnail"]
|
||||
else:
|
||||
_LOGGER.warning(
|
||||
"Could not find thumbnail for camera %s", self.name, exc_info=True
|
||||
)
|
||||
_LOGGER.warning("Could not find thumbnail for camera %s", self.name)
|
||||
|
||||
if thumb_addr is not None:
|
||||
new_thumbnail = f"{self.sync.urls.base_url}{thumb_addr}.jpg"
|
||||
|
||||
@@ -4,7 +4,7 @@ import os
|
||||
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 16
|
||||
PATCH_VERSION = "0-rc12"
|
||||
PATCH_VERSION = "2-rc0"
|
||||
|
||||
__version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}.{PATCH_VERSION}"
|
||||
|
||||
|
||||
@@ -93,9 +93,7 @@ class BlinkSyncModule:
|
||||
self.serial = self.summary["serial"]
|
||||
self.status = self.summary["status"]
|
||||
except KeyError:
|
||||
_LOGGER.error(
|
||||
"Could not extract some sync module info: %s", response, exc_info=True
|
||||
)
|
||||
_LOGGER.error("Could not extract some sync module info: %s", response)
|
||||
|
||||
is_ok = self.get_network_info()
|
||||
self.check_new_videos()
|
||||
@@ -158,7 +156,7 @@ class BlinkSyncModule:
|
||||
try:
|
||||
return response["event"]
|
||||
except (TypeError, KeyError):
|
||||
_LOGGER.error("Could not extract events: %s", response, exc_info=True)
|
||||
_LOGGER.error("Could not extract events: %s", response)
|
||||
return False
|
||||
|
||||
def get_camera_info(self, camera_id, **kwargs):
|
||||
@@ -170,7 +168,7 @@ class BlinkSyncModule:
|
||||
try:
|
||||
return response["camera"][0]
|
||||
except (TypeError, KeyError):
|
||||
_LOGGER.error("Could not extract camera info: %s", response, exc_info=True)
|
||||
_LOGGER.error("Could not extract camera info: %s", response)
|
||||
return {}
|
||||
|
||||
def get_network_info(self):
|
||||
|
||||
@@ -30,6 +30,29 @@ By default, the ``blink.auth.Auth`` class creates its own websession via its ``c
|
||||
blink.auth = Auth()
|
||||
blink.auth.session = YourCustomSession
|
||||
|
||||
|
||||
Custom Retry Logic
|
||||
--------------------
|
||||
The built-in auth session via the ``create_session`` method allows for customizable retry intervals and conditions. These parameters are:
|
||||
|
||||
- retries
|
||||
- backoff
|
||||
- retry_list
|
||||
|
||||
``retries`` is the total number of retry attempts that each http request can do before timing out. ``backoff`` is a parameter that allows for non-linear retry times such that the time between retries is backoff*(2^(retries) - 1). ``retry_list`` is simply a list of status codes to force a retry. By default ``retries=3``, ``backoff=1``, and ``retry_list=[429, 500, 502, 503, 504]``. To override them, you need to add you overrides to a dictionary and use that to create a new session with the ``opts`` variable in the ``create_session`` method. The following example can serve as a guide where only the number of retries and backoff factor are overridden:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from blinkpy.blinkpy import Blink
|
||||
from blinkpy.auth import Auth
|
||||
|
||||
blink = Blink()
|
||||
blink.auth = Auth()
|
||||
|
||||
opts = {"retries": 10, "backoff": 2}
|
||||
blink.auth.session = blink.auth.create_session(opts=opts)
|
||||
|
||||
|
||||
Custom HTTP requests
|
||||
---------------------
|
||||
In addition to custom sessions, custom blink server requests can be performed. This give you the ability to bypass the built-in ``Auth.query`` method. It also allows flexibility by giving you the option to pass your own url, rather than be limited to what is currently implemented in the ``blinkpy.api`` module.
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
python-dateutil~=2.8.1
|
||||
requests~=2.24.0
|
||||
python-slugify~=4.0.1
|
||||
testtools==2.4.0
|
||||
python-dateutil>=2.8.1
|
||||
requests>=2.24.0
|
||||
python-slugify>=4.0.1
|
||||
testtools>=2.4.0
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
black==19.10b0
|
||||
coverage==5.2
|
||||
coverage==5.2.1
|
||||
flake8==3.8.3
|
||||
flake8-docstrings==1.5.0
|
||||
pre-commit==2.6.0
|
||||
pylint==2.5.3
|
||||
pydocstyle==5.0.2
|
||||
pytest==5.4.3
|
||||
pytest==6.0.1
|
||||
pytest-cov==2.10.0
|
||||
pytest-sugar==0.9.4
|
||||
pytest-timeout==1.4.1
|
||||
pytest-timeout==1.4.2
|
||||
restructuredtext-lint==1.3.1
|
||||
pygments==2.6.1
|
||||
|
||||
+44
-1
@@ -230,7 +230,7 @@ class TestAuth(unittest.TestCase):
|
||||
@mock.patch("blinkpy.auth.Auth.refresh_token")
|
||||
def test_query_retry_failed(self, mock_refresh, mock_validate):
|
||||
"""Check handling of failed retry request."""
|
||||
self.auth.seession = MockSession()
|
||||
self.auth.session = MockSession()
|
||||
mock_validate.side_effect = [UnauthorizedError, BlinkBadResponse]
|
||||
mock_refresh.return_value = True
|
||||
self.assertEqual(self.auth.query(url="http://example.com"), None)
|
||||
@@ -238,6 +238,49 @@ class TestAuth(unittest.TestCase):
|
||||
mock_validate.side_effect = [UnauthorizedError, TokenRefreshFailed]
|
||||
self.assertEqual(self.auth.query(url="http://example.com"), None)
|
||||
|
||||
def test_default_session(self):
|
||||
"""Test default session creation."""
|
||||
sess = self.auth.create_session()
|
||||
adapter = sess.adapters["https://"]
|
||||
self.assertEqual(adapter.max_retries.total, 3)
|
||||
self.assertEqual(adapter.max_retries.backoff_factor, 1)
|
||||
self.assertEqual(
|
||||
adapter.max_retries.status_forcelist, [429, 500, 502, 503, 504]
|
||||
)
|
||||
|
||||
def test_custom_session_full(self):
|
||||
"""Test full custom session creation."""
|
||||
opts = {"backoff": 2, "retries": 10, "retry_list": [404]}
|
||||
sess = self.auth.create_session(opts=opts)
|
||||
adapter = sess.adapters["https://"]
|
||||
self.assertEqual(adapter.max_retries.total, 10)
|
||||
self.assertEqual(adapter.max_retries.backoff_factor, 2)
|
||||
self.assertEqual(adapter.max_retries.status_forcelist, [404])
|
||||
|
||||
def test_custom_session_partial(self):
|
||||
"""Test partial custom session creation."""
|
||||
opts1 = {"backoff": 2}
|
||||
opts2 = {"retries": 5}
|
||||
opts3 = {"retry_list": [101, 202]}
|
||||
sess1 = self.auth.create_session(opts=opts1)
|
||||
sess2 = self.auth.create_session(opts=opts2)
|
||||
sess3 = self.auth.create_session(opts=opts3)
|
||||
adapt1 = sess1.adapters["https://"]
|
||||
adapt2 = sess2.adapters["https://"]
|
||||
adapt3 = sess3.adapters["https://"]
|
||||
|
||||
self.assertEqual(adapt1.max_retries.total, 3)
|
||||
self.assertEqual(adapt1.max_retries.backoff_factor, 2)
|
||||
self.assertEqual(adapt1.max_retries.status_forcelist, [429, 500, 502, 503, 504])
|
||||
|
||||
self.assertEqual(adapt2.max_retries.total, 5)
|
||||
self.assertEqual(adapt2.max_retries.backoff_factor, 1)
|
||||
self.assertEqual(adapt2.max_retries.status_forcelist, [429, 500, 502, 503, 504])
|
||||
|
||||
self.assertEqual(adapt3.max_retries.total, 3)
|
||||
self.assertEqual(adapt3.max_retries.backoff_factor, 1)
|
||||
self.assertEqual(adapt3.max_retries.status_forcelist, [101, 202])
|
||||
|
||||
|
||||
class MockSession:
|
||||
"""Object to mock a session."""
|
||||
|
||||
@@ -117,10 +117,7 @@ class TestBlinkCameraSetup(unittest.TestCase):
|
||||
"WARNING:blinkpy.camera:Could not retrieve calibrated "
|
||||
"temperature."
|
||||
),
|
||||
(
|
||||
"WARNING:blinkpy.camera:Could not find thumbnail for camera new"
|
||||
"\nNoneType: None"
|
||||
),
|
||||
("WARNING:blinkpy.camera:Could not find thumbnail for camera new"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user