Skip to content

Commit

Permalink
enable 3.13
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemanspiff2007 committed Nov 13, 2024
1 parent 2321f38 commit 31d4709
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 160 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
with:
ref: master

- name: Set up Python 3.10
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.12'

- name: Install setuptools
run: |
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Packages required to build the documentation
sphinx == 8.1.3
sphinx-autodoc-typehints == 2.5.0
sphinx_rtd_theme == 3.0.1
sphinx_rtd_theme == 3.0.2
sphinx-exec-code == 0.13
autodoc_pydantic == 2.2.0
sphinx-copybutton == 0.5.2
1 change: 0 additions & 1 deletion requirements_setup.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
aiohttp == 3.10.10
pydantic == 2.9.2
msgspec == 0.18.6
bidict == 0.23.1
watchdog == 6.0.0
ujson == 5.10.0
Expand Down
1 change: 0 additions & 1 deletion src/HABApp/__check_dependency_packages__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def get_dependencies() -> list[str]:
'ujson',
'immutables',
'javaproperties',
'msgspec',

'typing-extensions',
]
Expand Down
2 changes: 1 addition & 1 deletion src/HABApp/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
# Development versions contain the DEV-COUNTER postfix:
# - 24.01.0.DEV-1

__version__ = '24.09.0.DEV-12'
__version__ = '24.09.0.DEV-13'
6 changes: 0 additions & 6 deletions src/HABApp/core/const/json.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from collections.abc import Callable
from typing import Any

import msgspec


try:
import ujson
Expand All @@ -12,7 +10,3 @@
import json
load_json: Callable[[str], Any] = json.loads
dump_json: Callable[[str], Any] = json.dumps


decode_struct = msgspec.json.decode
encode_struct = msgspec.json.encode
57 changes: 32 additions & 25 deletions src/HABApp/openhab/connection/handler/func_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@
from typing import Any
from urllib.parse import quote as quote_url

from HABApp.core.const.json import decode_struct
from HABApp.core.internals import ItemRegistryItem
from HABApp.openhab.definitions.rest import (
ItemChannelLinkResp,
ItemChannelLinkRespList,
ItemHistoryResp,
ItemResp,
ItemRespList,
PersistenceServiceResp,
PersistenceServiceRespList,
RootResp,
ShortItemResp,
ShortItemRespList,
SystemInfoRootResp,
ThingResp,
ThingRespList,
TransformationResp,
TransformationRespList,
)
from HABApp.openhab.definitions.rest.habapp_data import get_api_vals, load_habapp_meta
from HABApp.openhab.errors import (
ItemNotEditableError,
ItemNotFoundError,
Expand All @@ -31,7 +37,6 @@
TransformationsRequestError,
)

from ...definitions.rest.habapp_data import get_api_vals, load_habapp_meta
from . import convert_to_oh_type
from .handler import delete, get, post, put

Expand All @@ -48,7 +53,7 @@ async def async_get_root() -> RootResp | None:
if not (b := await resp.read()):
return None

return decode_struct(b, type=RootResp)
return RootResp.model_validate_json(b)


# ----------------------------------------------------------------------------------------------------------------------
Expand All @@ -71,18 +76,18 @@ async def async_get_system_info():
if not (b := await resp.read()):
return None

return decode_struct(b, type=SystemInfoRootResp).system_info
return SystemInfoRootResp.model_validate_json(b).system_info


# ----------------------------------------------------------------------------------------------------------------------
# /items
# ----------------------------------------------------------------------------------------------------------------------
async def async_get_items() -> list[ItemResp]:
async def async_get_items() -> tuple[ItemResp, ...]:

resp = await get('/rest/items', params={'metadata': '.+'})
body = await resp.read()

return decode_struct(body, type=list[ItemResp])
return ItemRespList.validate_json(body)


async def async_get_item(item: str | ItemRegistryItem) -> ItemResp | None:
Expand All @@ -95,14 +100,14 @@ async def async_get_item(item: str | ItemRegistryItem) -> ItemResp | None:

body = await resp.read()

return decode_struct(body, type=ItemResp)
return ItemResp.model_validate_json(body)


async def async_get_all_items_state() -> list[ShortItemResp]:
async def async_get_all_items_state() -> tuple[ShortItemResp, ...]:
resp = await get('/rest/items', params={'fields': 'name,state,type'})
body = await resp.read()

return decode_struct(body, type=list[ShortItemResp])
return ShortItemRespList.validate_json(body)


async def async_item_exists(item: str | ItemRegistryItem) -> bool:
Expand Down Expand Up @@ -163,7 +168,7 @@ async def async_create_item(item_type: str, name: str,
return ret.status < 300


async def async_remove_metadata(item: str | ItemRegistryItem, namespace: str):
async def async_remove_metadata(item: str | ItemRegistryItem, namespace: str) -> bool:
# noinspection PyProtectedMember
item = item if isinstance(item, str) else item._name

Expand All @@ -177,7 +182,7 @@ async def async_remove_metadata(item: str | ItemRegistryItem, namespace: str):
return ret.status < 300


async def async_set_metadata(item: str | ItemRegistryItem, namespace: str, value: str, config: dict):
async def async_set_metadata(item: str | ItemRegistryItem, namespace: str, value: str, config: dict) -> bool:
# noinspection PyProtectedMember
item = item if isinstance(item, str) else item._name

Expand All @@ -191,19 +196,19 @@ async def async_set_metadata(item: str | ItemRegistryItem, namespace: str, value

if ret.status == 404:
raise ItemNotFoundError.from_name(item)
elif ret.status == 405:
if ret.status == 405:
raise MetadataNotEditableError.create_text(item, namespace)
return ret.status < 300


# ----------------------------------------------------------------------------------------------------------------------
# /things
# ----------------------------------------------------------------------------------------------------------------------
async def async_get_things() -> list[ThingResp]:
async def async_get_things() -> tuple[ThingResp, ...]:
resp = await get('/rest/things')
body = await resp.read()

return decode_struct(body, type=list[ThingResp])
return ThingRespList.validate_json(body)


async def async_get_thing(thing: str | ItemRegistryItem) -> ThingResp:
Expand All @@ -215,7 +220,7 @@ async def async_get_thing(thing: str | ItemRegistryItem) -> ThingResp:
raise ThingNotFoundError.from_uid(thing)

body = await resp.read()
return decode_struct(body, type=ThingResp)
return ThingResp.model_validate_json(body)


async def async_set_thing_cfg(thing: str | ItemRegistryItem, cfg: dict[str, Any]):
Expand Down Expand Up @@ -259,7 +264,8 @@ async def async_set_thing_enabled(thing: str | ItemRegistryItem, enabled: bool):
async def async_purge_links():
resp = await post('/rest/purge')
if resp.status != 200:
raise LinkRequestError('Unexpected error')
msg = 'Unexpected error'
raise LinkRequestError(msg)


async def async_remove_obj_links(name: str | ItemRegistryItem) -> bool:
Expand All @@ -277,14 +283,15 @@ async def async_remove_obj_links(name: str | ItemRegistryItem) -> bool:
return True


async def async_get_links() -> list[ItemChannelLinkResp]:
async def async_get_links() -> tuple[ItemChannelLinkResp, ...]:

resp = await get('/rest/links')
if resp.status != 200:
raise LinkRequestError('Unexpected error')
msg = 'Unexpected error'
raise LinkRequestError(msg)

body = await resp.read()
return decode_struct(body, type=list[ItemChannelLinkResp])
return ItemChannelLinkRespList.validate_json(body)


def __get_item_link_url(item: str | ItemRegistryItem, channel: str) -> str:
Expand All @@ -302,7 +309,7 @@ async def async_get_link(item: str | ItemRegistryItem, channel: str) -> ItemChan
resp = await get(__get_item_link_url(item, channel), log_404=False)
if resp.status == 200:
body = await resp.read()
return decode_struct(body, type=ItemChannelLinkResp)
return ItemChannelLinkResp.model_validate_json(body)

if resp.status == 404:
raise LinkNotFoundError.from_names(item, channel)
Expand Down Expand Up @@ -357,25 +364,25 @@ async def async_remove_link(item: str | ItemRegistryItem, channel: str):
# ----------------------------------------------------------------------------------------------------------------------
# /transformations
# ----------------------------------------------------------------------------------------------------------------------
async def async_get_transformations() -> list[TransformationResp]:
async def async_get_transformations() -> tuple[TransformationResp, ...]:
resp = await get('/rest/transformations')
if resp.status >= 300:
raise TransformationsRequestError()

body = await resp.read()
return decode_struct(body, type=list[TransformationResp])
return TransformationRespList.validate_json(body)


# ----------------------------------------------------------------------------------------------------------------------
# /persistence
# ----------------------------------------------------------------------------------------------------------------------
async def async_get_persistence_services() -> list[PersistenceServiceResp]:
async def async_get_persistence_services() -> tuple[PersistenceServiceResp, ...]:
resp = await get('/rest/persistence')
if resp.status >= 300:
raise PersistenceRequestError()

body = await resp.read()
return decode_struct(body, type=list[PersistenceServiceResp])
return PersistenceServiceRespList.validate_json(body)


async def async_get_persistence_data(item: str | ItemRegistryItem, persistence: str | None,
Expand All @@ -399,7 +406,7 @@ async def async_get_persistence_data(item: str | ItemRegistryItem, persistence:
raise PersistenceRequestError()

body = await resp.read()
return decode_struct(body, type=ItemHistoryResp)
return ItemHistoryResp.model_validate_json(body)


async def async_set_persistence_data(item: str | ItemRegistryItem, persistence: str | None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
from pathlib import Path
from typing import Any

import msgspec

import HABApp
import HABApp.openhab.events
from HABApp.core.connections import BaseConnectionPlugin
Expand Down Expand Up @@ -81,7 +79,7 @@ async def clean_items(self) -> None:

async def load_thing_data(self, always: bool) -> list[dict[str, Any]]:
if always or not self.cache_cfg or time.time() - self.cache_ts > 20:
self.cache_cfg = [msgspec.to_builtins(k) for k in await HABApp.openhab.interface_async.async_get_things()]
self.cache_cfg = [k.model_dump(mode='json') for k in await HABApp.openhab.interface_async.async_get_things()]
self.cache_ts = time.time()
return self.cache_cfg

Expand Down
11 changes: 5 additions & 6 deletions src/HABApp/openhab/definitions/rest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from .items import ShortItemResp, ItemResp
from .things import ThingResp, ChannelResp
from .links import ItemChannelLinkResp

from .items import ItemResp, ItemRespList, ShortItemResp, ShortItemRespList
from .links import ItemChannelLinkResp, ItemChannelLinkRespList
from .persistence import ItemHistoryResp, PersistenceServiceResp, PersistenceServiceRespList
from .root import RootResp
from .systeminfo import SystemInfoRootResp
from .transformations import TransformationResp
from .persistence import ItemHistoryResp, PersistenceServiceResp
from .things import ChannelResp, ThingResp, ThingRespList
from .transformations import TransformationResp, TransformationRespList
Loading

0 comments on commit 31d4709

Please sign in to comment.