Skip to content

Commit 0c56030

Browse files
committed
add typing; cleanup code; add note on openhab 2; fix badges
1 parent 86b6db6 commit 0c56030

11 files changed

+121
-119
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ target/
6363
.pydevproject
6464
.project
6565
.settings
66+
.idea
67+
.mypy_cache

.landscape.yml

-8
This file was deleted.

README.rst

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
:target: https://landscape.io/github/sim0nx/python-openhab/master
33
:alt: Code Health
44

5+
.. image:: https://api.codacy.com/project/badge/Grade/c9f4e32e536f4150a8e7e18039f8f102
6+
:target: https://www.codacy.com/app/sim0nx/python-openhab?utm_source=github.com&utm_medium=referral&utm_content=sim0nx/python-openhab&utm_campaign=Badge_Grade
7+
:alt: Codacy badge
8+
59
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest
610
:target: http://python-openhab.readthedocs.io/en/latest/
711
:alt: Documentation
812

9-
.. image:: https://www.quantifiedcode.com/api/v1/project/0cd779d9548547c09f69009316e548e1/badge.svg
10-
:target: https://www.quantifiedcode.com/app/project/0cd779d9548547c09f69009316e548e1
11-
:alt: Code issues
13+
.. image:: https://badge.fury.io/py/python-openhab.svg
14+
:target: https://badge.fury.io/py/python-openhab
15+
:alt: pypi version
1216

1317

1418
python library for accessing the openHAB REST API
@@ -23,11 +27,13 @@ Requirements
2327
- python 2.7.x / 3.5
2428
- python :: dateutil
2529
- python :: requests
30+
- python :: typing
2631

2732
Note on openHAB1:
2833
-----------------
2934

30-
Make sure to use the 1.x branch for openHAB1.x!
35+
The current version is focused on OpenHAB 2.x; OpenHAB 1.x might still work, though this is not tested. If you require
36+
older OpenHAB support, please use an older version of this library.
3137

3238
Installation
3339
------------

openhab/__init__.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
from __future__ import absolute_import, division, print_function, unicode_literals
2-
3-
from openhab.openhab import openHAB
4-
1+
from openhab.openhab import OpenHAB, openHAB

openhab/items.py

+27-24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from __future__ import absolute_import, division, print_function, unicode_literals
21
# -*- coding: utf-8 -*-
32
"""python library for accessing the openHAB REST API"""
43

54
#
6-
# Georges Toth (c) 2016 <[email protected]>
5+
# Georges Toth (c) 2016-present <[email protected]>
76
#
87
# python-openhab is free software: you can redistribute it and/or modify
98
# it under the terms of the GNU General Public License as published by
@@ -21,30 +20,34 @@
2120

2221
# pylint: disable=bad-indentation
2322

24-
import six
2523
import dateutil.parser
26-
from openhab.types import DateTimeType, OnOffType, DecimalType, OpenCloseType
24+
import typing
25+
26+
import openhab
27+
import openhab.types
2728

2829
__author__ = 'Georges Toth <[email protected]>'
2930
__license__ = 'AGPLv3+'
3031

3132

32-
class Item(object):
33+
class Item:
3334
"""Base item class"""
34-
def __init__(self, openhab, json_data):
35+
types = [] # type: typing.List[typing.Type[openhab.types.CommandType]]
36+
37+
def __init__(self, openhab: openhab.OpenHAB, json_data: dict) -> None:
3538
"""
3639
Args:
37-
openhab (openHAB): openHAB object.
40+
openhab (openhab.OpenHAB): openHAB object.
3841
json_data (dic): A dict converted from the JSON data returned by the openHAB
3942
server.
4043
"""
4144
self.openhab = openhab
4245
self.type_ = None
4346
self.name = ''
44-
self._state = None
47+
self._state = None # type: typing.Optional[typing.Any]
4548
self.init_from_json(json_data)
4649

47-
def init_from_json(self, json_data):
50+
def init_from_json(self, json_data: dict):
4851
"""Initialize this object from a json configuration as fetched from
4952
openHAB
5053
@@ -57,7 +60,7 @@ def init_from_json(self, json_data):
5760
self.__set_state(json_data['state'])
5861

5962
@property
60-
def state(self):
63+
def state(self) -> typing.Any:
6164
"""The state property represents the current state of the item. The state is
6265
automatically refreshed from openHAB on reading it.
6366
Updating the value via this property send an update to the event bus.
@@ -68,41 +71,41 @@ def state(self):
6871
return self._state
6972

7073
@state.setter
71-
def state(self, value):
74+
def state(self, value: typing.Any):
7275
self.update(value)
7376

74-
def _validate_value(self, value):
77+
def _validate_value(self, value: typing.Union[str, typing.Type[openhab.types.CommandType]]):
7578
"""Private method for verifying the new value before modifying the state of the
7679
item.
7780
"""
7881
if self.type_ == 'String':
79-
if not isinstance(value, six.string_types):
82+
if not isinstance(value, str):
8083
raise ValueError()
81-
elif 'types' in dir(self):
84+
elif len(self.types):
8285
for type_ in self.types:
8386
type_.validate(value)
8487
else:
8588
raise ValueError()
8689

87-
def _parse_rest(self, value):
90+
def _parse_rest(self, value: str) -> str:
8891
"""Parse a REST result into a native object."""
8992
return value
9093

91-
def _rest_format(self, value):
94+
def _rest_format(self, value: str) -> str:
9295
"""Format a value before submitting to openHAB."""
9396
return value
9497

95-
def __set_state(self, value):
98+
def __set_state(self, value: str):
9699
"""Private method for setting the internal state."""
97100
if value in ('UNDEF', 'NULL'):
98101
self._state = None
99102
else:
100103
self._state = self._parse_rest(value)
101104

102-
def __str__(self):
105+
def __str__(self) -> str:
103106
return '<{0} - {1} : {2}>'.format(self.type_, self.name, self._state)
104107

105-
def update(self, value):
108+
def update(self, value: typing.Any):
106109
"""Updates the state of an item.
107110
108111
Args:
@@ -115,7 +118,7 @@ def update(self, value):
115118

116119
self.openhab.req_put('/items/' + self.name + '/state', data=v)
117120

118-
def command(self, value):
121+
def command(self, value: typing.Any):
119122
"""Sends the given value as command to the event bus.
120123
121124
Args:
@@ -131,7 +134,7 @@ def command(self, value):
131134

132135
class DateTimeItem(Item):
133136
"""DateTime item type"""
134-
types = [DateTimeType]
137+
types = [openhab.types.DateTimeType]
135138

136139
def __gt__(self, other):
137140
return self._state > other
@@ -171,7 +174,7 @@ def _rest_format(self, value):
171174

172175
class SwitchItem(Item):
173176
"""SwitchItem item type"""
174-
types = [OnOffType]
177+
types = [openhab.types.OnOffType]
175178

176179
def on(self):
177180
"""Set the state of the switch to ON"""
@@ -184,7 +187,7 @@ def off(self):
184187

185188
class NumberItem(Item):
186189
"""NumberItem item type"""
187-
types = [DecimalType]
190+
types = [openhab.types.DecimalType]
188191

189192
def _parse_rest(self, value):
190193
"""Parse a REST result into a native object
@@ -211,7 +214,7 @@ def _rest_format(self, value):
211214

212215
class ContactItem(Item):
213216
"""Contact item type"""
214-
types = [OpenCloseType]
217+
types = [openhab.types.OpenCloseType]
215218

216219
def open(self):
217220
"""Set the state of the contact item to OPEN"""

openhab/openhab.py

+28-17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from __future__ import absolute_import, division, print_function, unicode_literals
21
# -*- coding: utf-8 -*-
32
"""python library for accessing the openHAB REST API"""
43

54
#
6-
# Georges Toth (c) 2016 <[email protected]>
5+
# Georges Toth (c) 2016-present <[email protected]>
76
#
87
# python-openhab is free software: you can redistribute it and/or modify
98
# it under the terms of the GNU General Public License as published by
@@ -24,17 +23,21 @@
2423
import requests
2524
from requests.auth import HTTPBasicAuth
2625
from openhab.items import Item, DateTimeItem, SwitchItem, NumberItem, ContactItem
26+
import warnings
27+
import typing
2728

2829
__author__ = 'Georges Toth <[email protected]>'
2930
__license__ = 'AGPLv3+'
3031

3132

32-
33-
class openHAB(object):
33+
class OpenHAB:
3434
"""openHAB REST API client
3535
"""
3636

37-
def __init__(self, base_url, username=None, password=None, http_auth=None):
37+
def __init__(self, base_url: str,
38+
username: typing.Optional[str] = None,
39+
password: typing.Optional[str] = None,
40+
http_auth: typing.Optional[requests.auth.AuthBase] = None) -> None:
3841
"""
3942
Args:
4043
base_url (str): The openHAB REST URL, e.g. http://example.com/rest
@@ -46,7 +49,7 @@ def __init__(self, base_url, username=None, password=None, http_auth=None):
4649
specify a custom http authentication object of type :class:`requests.auth.AuthBase`.
4750
4851
Returns:
49-
openHAB: openHAB class instance.
52+
OpenHAB: openHAB class instance.
5053
"""
5154
self.base_url = base_url
5255

@@ -55,10 +58,11 @@ def __init__(self, base_url, username=None, password=None, http_auth=None):
5558

5659
if http_auth is not None:
5760
self.session.auth = http_auth
58-
elif username is not None and password is not None:
61+
elif not(username is None or password is None):
5962
self.session.auth = HTTPBasicAuth(username, password)
6063

61-
def _check_req_return(self, req):
64+
@staticmethod
65+
def _check_req_return(req: requests.Response) -> None:
6266
"""Internal method for checking the return value of a REST HTTP request.
6367
6468
Args:
@@ -71,12 +75,12 @@ def _check_req_return(self, req):
7175
ValueError: Raises a ValueError exception in case of a non-successful
7276
REST request.
7377
"""
74-
if not (req.status_code >= 200 and req.status_code < 300):
78+
if not (200 <= req.status_code < 300):
7579
req.raise_for_status()
7680

7781
return None
7882

79-
def req_get(self, uri_path):
83+
def req_get(self, uri_path: str) -> typing.Any:
8084
"""Helper method for initiating a HTTP GET request. Besides doing the actual
8185
request, it also checks the return value and returns the resulting decoded
8286
JSON data.
@@ -91,7 +95,7 @@ def req_get(self, uri_path):
9195
self._check_req_return(r)
9296
return r.json()
9397

94-
def req_post(self, uri_path, data=None):
98+
def req_post(self, uri_path: str, data: typing.Optional[dict]=None) -> None:
9599
"""Helper method for initiating a HTTP POST request. Besides doing the actual
96100
request, it also checks the return value and returns the resulting decoded
97101
JSON data.
@@ -108,7 +112,7 @@ def req_post(self, uri_path, data=None):
108112

109113
return None
110114

111-
def req_put(self, uri_path, data=None):
115+
def req_put(self, uri_path: str, data: typing.Optional[dict]=None) -> None:
112116
"""Helper method for initiating a HTTP PUT request. Besides doing the actual
113117
request, it also checks the return value and returns the resulting decoded
114118
JSON data.
@@ -126,13 +130,13 @@ def req_put(self, uri_path, data=None):
126130
return None
127131

128132
# fetch all items
129-
def fetch_all_items(self):
133+
def fetch_all_items(self) -> dict:
130134
"""Returns all items defined in openHAB except for group-items
131135
132136
Returns:
133137
dict: Returns a dict with item names as key and item class instances as value.
134138
"""
135-
items = {}
139+
items = {} # type: dict
136140
res = self.req_get('/items/')
137141

138142
for i in res:
@@ -145,7 +149,7 @@ def fetch_all_items(self):
145149

146150
return items
147151

148-
def get_item(self, name):
152+
def get_item(self, name: str) -> object:
149153
"""Returns an item with its state and type as fetched from openHAB
150154
151155
Args:
@@ -158,7 +162,7 @@ def get_item(self, name):
158162

159163
return self.json_to_item(json_data)
160164

161-
def json_to_item(self, json_data):
165+
def json_to_item(self, json_data: dict) -> object:
162166
"""This method takes as argument the RAW (JSON decoded) response for an openHAB
163167
item. It checks of what type the item is and returns a class instance of the
164168
specific item filled with the item's state.
@@ -180,7 +184,7 @@ def json_to_item(self, json_data):
180184
else:
181185
return Item(self, json_data)
182186

183-
def get_item_raw(self, name):
187+
def get_item_raw(self, name: str) -> typing.Any:
184188
"""Private method for fetching a json configuration of an item.
185189
186190
Args:
@@ -190,3 +194,10 @@ def get_item_raw(self, name):
190194
dict: A JSON decoded dict.
191195
"""
192196
return self.req_get('/items/{}'.format(name))
197+
198+
199+
class openHAB(OpenHAB):
200+
def __init__(self, *args, **kwargs):
201+
super().__init__(*args, **kwargs)
202+
203+
warnings.warn('The use of the "openHAB" class is deprecated, please use "OpenHAB" instead.', DeprecationWarning)

0 commit comments

Comments
 (0)