Skip to content

Commit

Permalink
Merge pull request #849 from fronzbot/dev
Browse files Browse the repository at this point in the history
0.22.5
  • Loading branch information
fronzbot authored Jan 7, 2024
2 parents 0944fed + eebcd0c commit 5f929f0
Show file tree
Hide file tree
Showing 22 changed files with 183 additions and 164 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
matrix:
platform:
- ubuntu-latest
python-version: ['3.9']
python-version: ['3.11']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
Expand All @@ -33,7 +33,7 @@ jobs:
run: |
tox -r -e cov
- name: Codecov
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9]
python-version: [3.11]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
platform:
- ubuntu-latest
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v3
Expand Down
33 changes: 31 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,42 @@ Changelog

A list of changes between each release

0.22.5 (2024-01-07)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Warning: This release removes support for Python 3.8 and adds Python 3.12 support.

**Bugfixes**

- Add new keys for wifi, lfr, and battery (`mkmer #835 <https://github.com/fronzbot/blinkpy/pull/835>`__)
- Battery level (`mkmer #837 <https://github.com/fronzbot/blinkpy/pull/837>`__)
- Address not awaited warning (`mkmer #838 <https://github.com/fronzbot/blinkpy/pull/838>`__)
- Catch ContentTypeError in 2FA (`mkmer #843 <https://github.com/fronzbot/blinkpy/pull/843>`__)
- Handle empty put response in wait_command (`mkmer #847 <https://github.com/fronzbot/blinkpy/pull/847>`__)
- Change default user agent to fix API calls (`gingerm0nkey #848 <https://github.com/fronzbot/blinkpy/pull/848>`__)
- Android for new user agent (`mkmer #850 <https://github.com/fronzbot/blinkpy/pull/850>`__)

**Other changes**

- Remove Py3.8, add 3.12 (`fronzbot #839 <https://github.com/fronzbot/blinkpy/pull/839>`__)
- Deprecate py38 (`fronzbot #840 <https://github.com/fronzbot/blinkpy/pull/840>`__)
- Add/extract firmware version (`mkmer #842 <https://github.com/fronzbot/blinkpy/pull/842>`__)
- Additional logging, fix blinksync json (`mkmer #844 <https://github.com/fronzbot/blinkpy/pull/844>`__)
- Log text response (`mkmer #845 <https://github.com/fronzbot/blinkpy/pull/845>`__)
- Add tests for logging (`mkmer #846 <https://github.com/fronzbot/blinkpy/pull/846>`__)
- Bump ruff to 0.1.11
- Bump black to 23.12.1
- Bump coverage to 7.4.0
- Bump pytest to 7.4.4


0.22.4 (2023-12-18)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Bugfixes**

- Allow kwargs to throttled functions, await sleep in throttle (`mkmer #823 <https://github.com/fronzbot/blinkpy/pull/800>`__)
- add missing entry in type_key_map (`@Rosi2143 <https://github.com/fronzbot/blinkpy/pull/813>`__)
- Allow kwargs to throttled functions, await sleep in throttle (`mkmer #823 <https://github.com/fronzbot/blinkpy/pull/823>`__)
- add missing entry in type_key_map (`@Rosi2143 #813 <https://github.com/fronzbot/blinkpy/pull/813>`__)

** Other Changes **

Expand Down
6 changes: 2 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
blinkpy |Build Status| |Coverage Status| |PyPi Version| |Codestyle|
=============================================================================================
A Python library for the Blink Camera system (Python 3.8+)
A Python library for the Blink Camera system (Python 3.9+)

Like the library? Consider buying me a cup of coffee!

Expand Down Expand Up @@ -32,9 +32,7 @@ To install the current development version, perform the following steps. Note t
$ cd ~
$ git clone https://github.com/fronzbot/blinkpy.git
$ cd blinkpy
$ rm -rf build dist
$ python3 setup.py bdist_wheel
$ pip3 install --upgrade dist/*.whl
$ pip install .
If you'd like to contribute to this library, please read the `contributing instructions <https://github.com/fronzbot/blinkpy/blob/dev/CONTRIBUTING.rst>`__.
Expand Down
7 changes: 5 additions & 2 deletions blinkpy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,11 @@ async def http_post(blink, url, is_retry=False, data=None, json=True, timeout=TI
async def wait_for_command(blink, json_data: dict) -> bool:
"""Wait for command to complete."""
_LOGGER.debug("Command Wait %s", json_data)
network_id = json_data.get("network_id")
command_id = json_data.get("id")
try:
network_id = json_data.get("network_id")
command_id = json_data.get("id")
except AttributeError:
return False
if command_id and network_id:
for _ in range(0, MAX_RETRY):
_LOGGER.debug("Making GET request waiting for command")
Expand Down
24 changes: 18 additions & 6 deletions blinkpy/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Login handler for blink."""
import logging
from aiohttp import ClientSession, ClientConnectionError
from aiohttp import (
ClientSession,
ClientConnectionError,
ContentTypeError,
ClientResponse,
)
from blinkpy import api
from blinkpy.helpers import util
from blinkpy.helpers.constants import (
Expand Down Expand Up @@ -123,7 +128,7 @@ async def startup(self):
if None in self.login_attributes.values():
await self.refresh_token()

async def validate_response(self, response, json_resp):
async def validate_response(self, response: ClientResponse, json_resp):
"""Check for valid response."""
if not json_resp:
self.is_errored = False
Expand All @@ -137,6 +142,9 @@ async def validate_response(self, response, json_resp):
json_data = await response.json()
except (AttributeError, ValueError) as error:
raise BlinkBadResponse from error
except ContentTypeError as error:
_LOGGER.warning("Got text for JSON response: %s", await response.text())
raise BlinkBadResponse from error

self.is_errored = False
return json_data
Expand Down Expand Up @@ -172,10 +180,11 @@ async def query(
url=url, data=data, headers=headers, timeout=timeout
)
return await self.validate_response(response, json_resp)
except (ClientConnectionError, TimeoutError):
except (ClientConnectionError, TimeoutError) as er:
_LOGGER.error(
"Connection error. Endpoint %s possibly down or throttled.",
"Connection error. Endpoint %s possibly down or throttled. Error: %s",
url,
er,
)
except BlinkBadResponse:
code = None
Expand Down Expand Up @@ -220,8 +229,11 @@ async def send_auth_key(self, blink, key):
if not blink.available:
_LOGGER.error("%s", json_resp["message"])
return False
except (KeyError, TypeError):
_LOGGER.error("Did not receive valid response from server.")
except (KeyError, TypeError, ContentTypeError) as er:
_LOGGER.error(
"Did not receive valid response from server. Error: %s",
er,
)
return False
return True

Expand Down
27 changes: 17 additions & 10 deletions blinkpy/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ def __init__(self, sync):
self.network_id = None
self.thumbnail = None
self.serial = None
self.version = None
self.motion_enabled = None
self.battery_voltage = None
self.battery_level = None
self.clip = None
# A clip remains in the recent clips list until is has
# been downloaded or has been expired.
Expand All @@ -43,6 +44,7 @@ def __init__(self, sync):
self._cached_video = None
self.camera_type = ""
self.product_type = None
self.sync_signal_strength = None

@property
def attributes(self):
Expand All @@ -51,11 +53,12 @@ def attributes(self):
"name": self.name,
"camera_id": self.camera_id,
"serial": self.serial,
"version": self.version,
"temperature": self.temperature,
"temperature_c": self.temperature_c,
"temperature_calibrated": self.temperature_calibrated,
"battery": self.battery,
"battery_voltage": self.battery_voltage,
"battery_level": self.battery_level,
"thumbnail": self.thumbnail,
"video": self.clip,
"recent_clips": self.recent_clips,
Expand All @@ -64,6 +67,7 @@ def attributes(self):
"wifi_strength": self.wifi_strength,
"network_id": self.sync.network_id,
"sync_module": self.sync.name,
"sync_signal_strength": self.sync_signal_strength,
"last_record": self.last_record,
"type": self.product_type,
}
Expand Down Expand Up @@ -229,15 +233,18 @@ def extract_config_info(self, config):
self.name = config.get("name", "unknown")
self.camera_id = str(config.get("id", "unknown"))
self.network_id = str(config.get("network_id", "unknown"))
self.serial = config.get("serial", None)
self.serial = config.get("serial")
self.version = config.get("fw_version")
self.motion_enabled = config.get("enabled", "unknown")
self.battery_voltage = config.get("battery_voltage", None)
self.battery_state = config.get("battery_state", None) or config.get(
"battery", None
)
self.temperature = config.get("temperature", None)
self.wifi_strength = config.get("wifi_strength", None)
self.product_type = config.get("type", None)
self.battery_state = config.get("battery_state") or config.get("battery")
self.temperature = config.get("temperature")
if signals := config.get("signals"):
self.wifi_strength = signals.get("wifi")
self.battery_level = signals.get("battery")
self.sync_signal_strength = signals.get("lfr")
else:
self.wifi_strength = config.get("wifi_strength")
self.product_type = config.get("type")

async def get_sensor_info(self):
"""Retrieve calibrated temperature from special endpoint."""
Expand Down
7 changes: 2 additions & 5 deletions blinkpy/helpers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@
"""
OTHER
"""
DEFAULT_USER_AGENT = (
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/71.0.3578.98 Safari/537.36"
)

DEFAULT_USER_AGENT = "27.0ANDROID_28373244"
DEVICE_ID = "Blinkpy"
TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
DEFAULT_MOTION_INTERVAL = 1
Expand Down
3 changes: 3 additions & 0 deletions blinkpy/sync_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self, blink, network_name, network_id, camera_list):
self.region_id = blink.auth.region_id
self.name = network_name
self.serial = None
self.version = None
self.status = "offline"
self.sync_id = None
self.host = None
Expand Down Expand Up @@ -72,6 +73,7 @@ def attributes(self):
"id": self.sync_id,
"network_id": self.network_id,
"serial": self.serial,
"version": self.version,
"status": self.status,
"region_id": self.region_id,
"local_storage": self.local_storage,
Expand Down Expand Up @@ -153,6 +155,7 @@ async def sync_initialize(self):
"Could not retrieve sync module information with response: %s", response
)
return False
self.version = self.summary.get("fw_version")
return response

async def _init_local_storage(self, sync_id):
Expand Down
1 change: 1 addition & 0 deletions blinksync/blinksync.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ async def main():
working = None
frame = None
await session.close()
await blink.save(f"{path}/blink.json")


# Run the program
Expand Down
9 changes: 5 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "blinkpy"
version = "0.22.4"
version = "0.22.5"
license = {text = "MIT"}
description = "A Blink camera Python Library."
readme = "README.rst"
Expand All @@ -15,13 +15,13 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Home Automation",
]
requires-python = ">=3.8.0"
requires-python = ">=3.9.0"
dynamic = ["dependencies"]

[tool.setuptools.dynamic]
Expand Down Expand Up @@ -79,13 +79,14 @@ ignore = [
"UP006", # keep type annotation style as is
"UP007", # keep type annotation style as is
"UP015", # Unnecessary open mode parameters
"UP017", # UTC stuff
# Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923
"UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)`
]

line-length = 88

target-version = "py39"
target-version = "py311"

[tool.ruff.per-file-ignores]

Expand Down
8 changes: 4 additions & 4 deletions requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ruff==0.1.8
black==23.12.0
ruff==0.1.11
black==23.12.1
build==1.0.3
coverage==7.3.2
pytest==7.4.3
coverage==7.4.0
pytest==7.4.4
pytest-cov==4.1.0
pytest-sugar==0.9.7
pytest-timeout==2.2.0
Expand Down
13 changes: 12 additions & 1 deletion tests/mock_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,28 @@
class MockResponse:
"""Class for mock request response."""

def __init__(self, json_data, status_code, headers={}, raw_data=None):
def __init__(
self,
json_data,
status_code,
headers={},
raw_data=None,
raise_error=None,
):
"""Initialize mock get response."""
self.json_data = json_data
self.status = status_code
self.raw_data = raw_data
self.reason = "foobar"
self.headers = headers
self.read = mock.AsyncMock(return_value=self.raw_data)
self.raise_error = raise_error
self.text = mock.AsyncMock(return_vlaue="some text")

async def json(self):
"""Return json data from get_request."""
if self.raise_error:
raise self.raise_error("I'm broken", "")
return self.json_data

def get(self, name):
Expand Down
3 changes: 3 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,6 @@ async def test_wait_for_command(self, mock_resp):
mock_resp.side_effect = (COMMAND_COMPLETE_BAD, {})
response = await api.wait_for_command(self.blink, COMMAND_RESPONSE)
self.assertFalse(response)

response = await api.wait_for_command(self.blink, None)
self.assertFalse(response)
Loading

0 comments on commit 5f929f0

Please sign in to comment.