Skip to content

Commit

Permalink
fix 58: use orjson for json parsing to improve performance (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrester authored Jan 10, 2024
1 parent fba979e commit abd7cbb
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ dmypy.json
.direnv

# MacOS finder stuff
.DS_Store
.DS_Store
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.5.1]

- Use orjson for parsing json

## [0.5.0]

- BREAKING: The API is now async by default (by @bubonicbob)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 Jrester
Copyright (c) 2024 Jrester

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Powerwall Software versions from 1.47.0 to 1.50.1 as well as 20.40 to 22.9.2 are
- [Gateway DIN](#gateway-din)
- [VIN](#vin)
- [Off-grid status](#off-grid-status-set-island-mode)
- [Development](#development)

## Installation

Expand Down Expand Up @@ -389,6 +390,18 @@ await powerwall.set_island_mode(IslandMode.ONGRID)

# Development

## pre-commit

This project uses pre-commit to run linters, formatters and type checking. You can easily run those checks locally:

```sh
# Install the pre-commit hooks
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
```

Now those checks will be execute on every `git commit`. You can also execute all checks manually with `pre-commit run --all-files`.

## Building

```sh
Expand All @@ -397,6 +410,9 @@ $ python -m build

## Testing

The tests are split in unit and integration tests.
The unit tests are self-contained and can simply be run locally by executing `tox -e unit`, whereas the integration test, run against a real powerwall.

### Unit-Tests

To run unit tests use tox:
Expand All @@ -407,6 +423,12 @@ $ tox -e unit

### Integration-Tests

To execute the integration tests you need to first provide some information about your powerwall:

```sh
$ export POWERWALL_IP=<ip of your powerwall>
$ export POWERWALL_PASSWORD=<password for your powerwall>
$ tox -e integration
```

> The integration tests might take your powerwall off grid and bring it back online. Before running the tests, make sure that you know what you are doing!
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ keywords = ["api", "tesla", "powerwall", "tesla_powerwall"]
dependencies = [
"aiohttp>=3.7.4",
"urllib3>=1.26.18",
"orjson>=3.9.0"
]

[project.urls]
Expand Down
7 changes: 4 additions & 3 deletions tesla_powerwall/api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import aiohttp
from http.client import responses
from json.decoder import JSONDecodeError
from types import TracebackType
from typing import Any, List, Optional, Type
from urllib.parse import urljoin

import aiohttp
import orjson
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning

Expand Down Expand Up @@ -68,7 +69,7 @@ async def _handle_error(response: aiohttp.ClientResponse) -> None:
if response.status == 401 or response.status == 403:
response_json = None
try:
response_json = await response.json()
response_json = await response.json(loads=orjson.loads)
except Exception:
raise AccessDeniedError(str(response.real_url))
else:
Expand Down Expand Up @@ -104,7 +105,7 @@ async def _process_response(self, response: aiohttp.ClientResponse) -> dict:
return {}

try:
response_json = await response.json(content_type=None)
response_json = await response.json(content_type=None, loads=orjson.loads)
except JSONDecodeError:
raise ApiError(
"Error while decoding json of response: {}".format(response.text)
Expand Down
2 changes: 1 addition & 1 deletion tesla_powerwall/powerwall.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from types import TracebackType
from typing import List, Union, Optional, Type
from typing import List, Optional, Type, Union

import aiohttp

Expand Down
1 change: 0 additions & 1 deletion tests/integration/test_powerwall.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import aiohttp
import asyncio
import unittest

Expand Down
10 changes: 3 additions & 7 deletions tests/unit/test_api.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import json
import unittest

import aiohttp
import aresponses
import json

from tesla_powerwall import API, AccessDeniedError, ApiError, PowerwallUnreachableError
from tesla_powerwall import API, AccessDeniedError, ApiError
from tesla_powerwall.const import User
from tests.unit import (
ENDPOINT_HOST,
ENDPOINT_PATH,
ENDPOINT,
)
from tests.unit import ENDPOINT, ENDPOINT_HOST, ENDPOINT_PATH


class TestAPI(unittest.IsolatedAsyncioTestCase):
Expand Down
9 changes: 5 additions & 4 deletions tests/unit/test_powerwall.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import aiohttp
import aresponses
import datetime
import json
from typing import Optional, Union
import unittest
from typing import Optional, Union

import aiohttp
import aresponses

from tesla_powerwall import (
API,
Expand All @@ -24,9 +25,9 @@
)
from tesla_powerwall.const import OperationMode
from tests.unit import (
ENDPOINT,
ENDPOINT_HOST,
ENDPOINT_PATH,
ENDPOINT,
GRID_STATUS_RESPONSE,
ISLANDING_MODE_OFFGRID_RESPONSE,
ISLANDING_MODE_ONGRID_RESPONSE,
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ commands = python -m unittest discover tests/unit

[testenv:integration]
passenv = POWERWALL_IP,POWERWALL_PASSWORD
commands = python -m unittest discover tests/integration
commands = python -m unittest discover tests/integration

0 comments on commit abd7cbb

Please sign in to comment.