Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
key: pip_cache
- name: Install depencency
run: |
pip install gql gql[aiohttp] gql[websockets] graphql-core asyncio-atexit pytest pytest-cov
pip install gql==3.5.2 gql[aiohttp] gql[websockets] graphql-core asyncio-atexit pytest pytest-cov
- name: Pytest
run: |
python -m pytest --cov=tibber tests/ --cov-report xml:coverage.xml
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/code-formatting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ jobs:
path: ~/.cache/pip
key: pip_cache
- name: Install formatting tools
run: pip install black isort flake8
run: pip install black flake8

- name: Running black
run: black --check tibber

- name: Running isort
run: isort --check tibber

- name: Running flake8
run: flake8 --per-file-ignores="./tibber/__init__.py:E402"
2 changes: 1 addition & 1 deletion .github/workflows/pytests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
key: pip_cache
- name: Install depencency
run: |
pip install gql gql[aiohttp] gql[websockets] graphql-core asyncio-atexit pytest pytest-timeout
pip install gql==3.5.2 gql[aiohttp] gql[websockets] graphql-core asyncio-atexit pytest pytest-timeout
- name: Pytest
run: |
python -m pytest tests
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
long_description_content_type='text/markdown',
packages=["tibber", "tibber.networking", "tibber.exceptions", "tibber.types"],
install_requires=[
"gql>=3.4.0",
"gql==3.5.3",
"gql[aiohttp]>=3.4.0",
"gql[websockets]>=3.4.0",
"graphql-core>=3.2.3",
Expand Down
2 changes: 1 addition & 1 deletion tests/cached/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_getting_user_id(account):
assert account.user_id == "dcc2355e-6f55-45c2-beb9-274241fe450c"

def test_getting_account_type(account):
assert account.account_type == ["tibber", "customer"]
assert account.account_type == ["customer"]

def test_getting_homes(account):
assert len(account.homes) == 1
Expand Down
2 changes: 1 addition & 1 deletion tibber/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__version__ = "0.6.0"
DEMO_TOKEN = "5K4MVS-OjfWhK_4yrjOlFe1F6kJXPVf7eQYggo8ebAE"
DEMO_TOKEN = "3A77EECF61BD445F47241A5A36202185C35AF3AF58609E19B53F3A8872AD7BE1-1"
API_ENDPOINT = "https://api.tibber.com/v1-beta/gql"

import asyncio
Expand Down
24 changes: 24 additions & 0 deletions tibber/networking/query_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,30 @@ def price_rating_entry(cls) -> dict:
def single_home(home_id: str) -> dict:
return {f"home({home_id})": QueryBuilder.home()}

@classmethod
def price_info_range_query(
cls, resolution: str, first: int, last: int, before: str, after: str
):
first_arg = f"first: {first}" if first else None
last_arg = f"last: {last}" if last else None
before_arg = f'before: "{before}"' if before else None
after_arg = f'after: "{after}"' if after else None

args = ", ".join(
[
arg
for arg in [first_arg, last_arg, before_arg, after_arg]
if arg is not None
]
)
return {
f"priceInfoRange(resolution: {resolution}, {args})": {
"pageInfo": QueryBuilder.subscription_price_connection_page_info(),
"edges": QueryBuilder.subscription_price_edge(),
"nodes": QueryBuilder.price(),
}
}

@classmethod
def range_query(
cls, resolution: str, first: int, last: int, before: str, after: str
Expand Down
40 changes: 39 additions & 1 deletion tibber/types/subscription.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

"""A class representing the Subscription type from the GraphQL Tibber API."""
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

from tibber.networking.query_builder import QueryBuilder
from tibber.types.legal_entity import LegalEntity
from tibber.types.price_info import PriceInfo
from tibber.types.price_rating import PriceRating
from tibber.types.subscription_price_connection import SubscriptionPriceConnection

# Import type checking modules
if TYPE_CHECKING:
Expand Down Expand Up @@ -48,6 +50,42 @@ def price_info(self) -> PriceInfo:
"""Price information related to the subscription"""
return PriceInfo(self.cache.get("priceInfo"), self.tibber_client)

def fetch_price_info_range(
self,
resolution: str,
first: Optional[str] = None,
last: Optional[str] = None,
before: Optional[str] = None,
after: Optional[str] = None,
home_id: Optional[str] = None,
) -> PriceInfo:
"""Fetch PriceInfo for a given range.

The before and after arguments are Base64 encoded ISO 8601 datetimes."""
price_info_range_query_dict = QueryBuilder.price_info_range_query(
resolution, first, last, before, after
)

price_info_range_query = QueryBuilder.create_query(
"viewer", "homes", "currentSubscription", price_info_range_query_dict
)
full_data = self.tibber_client.execute_query(
self.tibber_client.token, price_info_range_query
)

home = full_data["viewer"]["homes"][0]
if home_id:
home_of_id = [
home for home in full_data["viewer"]["homes"] if home["id"] == home_id
][0]

if home_of_id:
home = home_of_id

return SubscriptionPriceConnection(
home["currentSubscription"]["priceInfoRange"], self.tibber_client
)

@property
def price_rating(self) -> PriceRating:
"""Price information related to the subscription"""
Expand Down
Loading