Skip to content
Open
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/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand Down
7 changes: 7 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
graft obniz/obniz
graft obniz/parts

# documentation assets under obniz/parts have no runtime purpose --
# excluding them keeps the wheel small (photos/GIFs alone are ~13MB)
global-exclude *.jpg *.jpeg *.png *.gif *.fzz
recursive-exclude obniz/parts index.json
recursive-exclude obniz/parts README.md README-ja.md
global-exclude __pycache__ *.py[cod]
10 changes: 5 additions & 5 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ name = "pypi"
test = "pytest -vv"
lint = "sh -c 'flake8 && pipenv run format --check'"
format = "black obniz/ tests/ "
build = "sh -c 'rm -rf build/ dist/ obniz.egg-info/ && python setup.py sdist bdist_wheel'"
build = "sh -c 'rm -rf build/ dist/ obniz.egg-info/ && python -m build'"
testsubmit = "twine upload --repository testpypi dist/*"
# no shortcut for production submit for safe

[packages]
pyee = "==6.0.0"
websockets = ">=12,<14"
attrdict3 = "==2.0.2"
semver = "==2.8.1"
pyee = "==13.0.1"
websockets = ">=14.2,<16"
semver = "==3.0.4"

[dev-packages]
# "black" requires python 3.6+
Expand All @@ -30,6 +29,7 @@ pep8-naming = "*"
pytest = "*"
pytest-mock = "*"
pyyaml = "*"
build = "*"
setuptools = "*"
wheel = "*"
twine = "*"
Expand Down
216 changes: 105 additions & 111 deletions Pipfile.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README-ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[obniz](https://obniz.io/)をpythonから操作するためのsdkです。
[obnizBoard](https://obniz.io/ja/doc/obniz_board_hobby_90/hw_overview)と[obnizOS](https://obniz.io/ja/doc/obnizos/os_overview)に対応しています

**Python 3.8以上**で動作します。
**Python 3.9以上**で動作します。

<img src="https://object-storage.tyo1.conoha.io/v1/nc_35a49f4e51c74e35ad3493c52d37f63e/images/obniz-python-readme.gif" width="100%" />

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Control obniz from python.

This sdk works with [obniz api](https://obniz.io/doc/about_obniz_api).

Compatible with **Python 3.8+**.
Compatible with **Python 3.9+**.

<img src="https://object-storage.tyo1.conoha.io/v1/nc_35a49f4e51c74e35ad3493c52d37f63e/images/obniz-python-readme.gif" width="100%" />

Expand Down
2 changes: 1 addition & 1 deletion obniz/obniz/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.7.0"
__version__ = "0.8.0"
2 changes: 1 addition & 1 deletion obniz/obniz/libs/embeds/ble/ble_attribute_abstract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyee import AsyncIOEventEmitter
from pyee.asyncio import AsyncIOEventEmitter

from .ble_helper import BleHelper
from ...utils.eventloop import get_event_loop
Expand Down
2 changes: 1 addition & 1 deletion obniz/obniz/libs/embeds/ble/ble_remote_peripheral.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from pyee import AsyncIOEventEmitter
from pyee.asyncio import AsyncIOEventEmitter

from .ble_helper import BleHelper
from .ble_remote_service import BleRemoteService
Expand Down
2 changes: 1 addition & 1 deletion obniz/obniz/libs/embeds/ble/ble_scan.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyee import AsyncIOEventEmitter
from pyee.asyncio import AsyncIOEventEmitter

from .ble_helper import BleHelper

Expand Down
4 changes: 2 additions & 2 deletions obniz/obniz/libs/embeds/ble/ble_security.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyee import AsyncIOEventEmitter
from pyee.asyncio import AsyncIOEventEmitter
import semver

class BleSecurity:
Expand Down Expand Up @@ -51,7 +51,7 @@ def set_mode_level(self, mode, level):
raise Exception(msg)

def check_introduced_firmware(self, introduced_version, function_name):
res = semver.match(self.obniz.firmware_ver, "<=" + introduced_version)
res = semver.Version.parse(self.obniz.firmware_ver).match("<=" + introduced_version)
if res:
msg = (
"{} is available ".format(function_name) +
Expand Down
2 changes: 1 addition & 1 deletion obniz/obniz/libs/embeds/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def _require_firmware_major(self, major):
if not fw:
raise Exception("unknown obniz firmware version. connect first")

if semver.parse_version_info(fw).major < major:
if semver.Version.parse(fw).major < major:
raise Exception(
"Please update obniz firmware >= {}.0.0".format(major)
)
4 changes: 2 additions & 2 deletions obniz/obniz/libs/io_peripherals/spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def write_wait(self, data):
if not self.used:
raise Exception("spi{} is not started".format(self.id))

if semver.match(self.obniz.firmware_ver, "<=1.0.2") and len(data) > 32:
if semver.Version.parse(self.obniz.firmware_ver).match("<=1.0.2") and len(data) > 32:
raise Exception(
"with your obniz "
+ self.obniz.firmware_ver
Expand All @@ -110,7 +110,7 @@ def write_wait(self, data):
def write(self, data):
if not self.used:
raise Exception("spi{0} is not started".format(self.id))
if semver.match(self.obniz.firmware_ver, "<=1.0.2") and len(data) > 32:
if semver.Version.parse(self.obniz.firmware_ver).match("<=1.0.2") and len(data) > 32:
raise Exception(
"with your obniz {0}. spi max length=32byte but yours {1}. Please update obniz firmware".format(
self.obniz.firmware_ver, len(data)
Expand Down
4 changes: 2 additions & 2 deletions obniz/obniz/libs/plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ def _require_firmware(self, version):
if not fw:
raise Exception("unknown obniz firmware version. connect first")

info = semver.parse_version_info(fw)
info = semver.Version.parse(fw)
if version == "7.1.0":
# accept prereleases like 7.1.0-beta.0, as obniz.js does
ok = info.major > 7 or (info.major == 7 and info.minor >= 1)
elif version == "7.0.0":
ok = info.major >= 7
else:
ok = not semver.match(fw, "<" + version)
ok = not info.match("<" + version)

if not ok:
raise Exception("Please update obniz firmware >= " + version)
Expand Down
39 changes: 39 additions & 0 deletions obniz/obniz/libs/utils/attr_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class AttrDefault(dict):
"""In-repo replacement for the abandoned attrdict package's AttrDefault.

A dict whose keys are also readable/writable as attributes, and whose
missing keys yield default_factory() (stored, like collections.defaultdict)
instead of raising. Parts rely on all three behaviors, e.g.
``self.params.mode = self.params.mode or 'master'``.
"""

def __init__(self, default_factory=bool, items=None):
super().__init__(items if items is not None else {})
object.__setattr__(self, "_default_factory", default_factory)

def __getitem__(self, key):
if key not in self:
default = self._default_factory()
super().__setitem__(key, default)
return default
return super().__getitem__(key)

def __getattr__(self, key):
if key.startswith("__"):
raise AttributeError(key)
return self[key]

def __setattr__(self, key, value):
self[key] = value

def __delattr__(self, key):
try:
del self[key]
except KeyError:
raise AttributeError(key)

def get(self, key, default=None):
# do not auto-create on .get(), matching plain dict semantics
if key in self:
return dict.__getitem__(self, key)
return default
5 changes: 2 additions & 3 deletions obniz/obniz/libs/utils/util.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import json
import attrdict

class ObnizUtil:
@classmethod
def _key_filter(cls, params, keys):
filterd_params = {}
if type(params) not in [dict, attrdict.default.AttrDefault]:
if not isinstance(params, dict):
return filterd_params

for key in [key for key in params.keys() if key in keys]:
Expand All @@ -15,7 +14,7 @@ def _key_filter(cls, params, keys):

@classmethod
def _required_keys(cls, params, keys):
if type(params) not in [dict, attrdict.default.AttrDefault]:
if not isinstance(params, dict):
return keys[0]

for key in keys:
Expand Down
9 changes: 4 additions & 5 deletions obniz/obniz/obniz_components.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import asyncio

from .libs.embeds.ble.ble import ObnizBLE
from .libs.embeds.display import Display
from .libs.embeds.storage import Storage
Expand All @@ -16,9 +18,6 @@
from .obniz_connection import ObnizConnection
from .obniz_parts import ObnizParts

import attrdict
import asyncio


class ObnizComponents(ObnizParts):
def __init__(self, id, options):
Expand Down Expand Up @@ -178,7 +177,7 @@ def get_free_i2c(self):
return self._get_free_peripheral_unit('i2c')

def get_i2c_with_config(self, config):
if type(config) not in [dict, attrdict.default.AttrDefault]:
if not isinstance(config, dict):
raise Exception("get_i2c_with_config need config arg")
if config.get("i2c"):
return config.get("i2c")
Expand All @@ -190,7 +189,7 @@ def get_free_spi(self):
return self._get_free_peripheral_unit('spi')

def get_spi_with_config(self, config):
if type(config) not in [dict, attrdict.default.AttrDefault]:
if not isinstance(config, dict):
raise Exception("get_spi_with_config need config arg")
if config.get("spi"):
return config.get("spi")
Expand Down
19 changes: 12 additions & 7 deletions obniz/obniz/obniz_connection.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import inspect
import json

from pyee import AsyncIOEventEmitter
from pyee.asyncio import AsyncIOEventEmitter
import websockets
from websockets.protocol import State

from .__version__ import __version__
from .libs.utils.eventloop import ensure_future, get_event_loop
Expand Down Expand Up @@ -146,7 +147,7 @@ def wsconnect(self, desired_server):
if desired_server:
server = desired_server

if self.socket and self.socket.open:
if self._socket_open(self.socket):
self.close()

url = server + "/obniz/{}/ws/1".format(self.id)
Expand Down Expand Up @@ -232,7 +233,7 @@ async def connecting():

def _disconnect_local(self):
if self.socket_local:
if self.socket.open:
if self._socket_open(self.socket):
self.socket_local.close()

self.clear_socket(self.socket_local)
Expand Down Expand Up @@ -273,8 +274,12 @@ def clear_socket(self, socket):
# socket.onerror = null
# }

@staticmethod
def _socket_open(socket):
return socket is not None and socket.state is State.OPEN

def connect(self):
if self.socket and self.socket.open:
if self._socket_open(self.socket):
return

self.wsconnect()
Expand All @@ -283,7 +288,7 @@ def close(self):
# self._drainQueued()
self._disconnect_local()
if self.socket:
if self.socket.open:
if self._socket_open(self.socket):
# Connecting & Connected
self.connection_state = 'closing'
ensure_future(self.socket.close(1000, "close"))
Expand All @@ -300,7 +305,7 @@ def _call_on_connect(self):
self._wait_for_local_connect_ready_timer = None
else:
# obniz.js hasn't wait local_connect
if self.socket_local and self.socket.open:
if self.socket_local and self._socket_open(self.socket):
# delayed connect
should_call = False
else:
Expand Down Expand Up @@ -358,7 +363,7 @@ def _send_routed(self, data):
)
return

if self.socket and self.socket.open:
if self._socket_open(self.socket):
ensure_future(self.socket.send(data))
# if self.socket.buffered_amount > self.bufferd_amound_warn_bytes:
# self.warning(
Expand Down
5 changes: 2 additions & 3 deletions obniz/obniz/obniz_parts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from attrdict import AttrDefault

from .obniz_connection import ObnizConnection
from .libs.utils.attr_default import AttrDefault
from .libs.utils.util import ObnizUtil
from .obniz_connection import ObnizConnection

_parts = {}

Expand Down
4 changes: 2 additions & 2 deletions obniz/parts/Camera/ArduCAMMini/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from attrdict import AttrDefault

import asyncio
import base64

from obniz.obniz.libs.utils.attr_default import AttrDefault

class ArduCAMMini:
def __init__(self):
self.keys = ['cs', 'mosi', 'miso', 'sclk', 'gnd', 'vcc', 'sda', 'scl', 'spi', 'i2c', 'spi_frequency', 'spi_drive']
Expand Down
4 changes: 2 additions & 2 deletions obniz/parts/DistanceSensor/GP2Y0A21YK0F/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from attrdict import AttrDefault

import asyncio
import math

from obniz.obniz.libs.utils.attr_default import AttrDefault

class GP2Y0A21YK0F:
def __init__(self):
self.keys = ['vcc', 'gnd', 'signal']
Expand Down
3 changes: 1 addition & 2 deletions obniz/parts/DistanceSensor/HC-SR04/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import math

from attrdict import AttrDefault

from obniz.obniz.libs.utils.attr_default import AttrDefault
from obniz.obniz.libs.utils.eventloop import get_event_loop


Expand Down
2 changes: 1 addition & 1 deletion obniz/parts/Light/LED/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from attrdict import AttrDefault
from obniz.obniz.libs.utils.attr_default import AttrDefault

class LED:
def __init__(self):
Expand Down
3 changes: 1 addition & 2 deletions obniz/parts/MovementSensor/Button/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from attrdict import AttrDefault

from obniz.obniz.libs.utils.attr_default import AttrDefault
from obniz.obniz.libs.utils.eventloop import get_event_loop


Expand Down
3 changes: 2 additions & 1 deletion obniz/parts/MovementSensor/HC-SR505/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from attrdict import AttrDefault
import asyncio

from obniz.obniz.libs.utils.attr_default import AttrDefault

class HCSR505:
def __init__(self):
self.keys = ['vcc', 'gnd', 'signal']
Expand Down
4 changes: 2 additions & 2 deletions obniz/parts/MovementSensor/JoyStick/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from attrdict import AttrDefault

import asyncio

from obniz.obniz.libs.utils.attr_default import AttrDefault

class JoyStick:
def __init__(self):
self.keys = ['sw', 'y', 'x', 'vcc', 'gnd', 'i2c']
Expand Down
4 changes: 2 additions & 2 deletions obniz/parts/MovementSensor/KXR94-2050/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from attrdict import AttrDefault

import asyncio

from obniz.obniz.libs.utils.attr_default import AttrDefault

class KXR942050:
def __init__(self):
self.keys = ['x', 'y', 'z', 'vcc', 'gnd', 'enable', 'self_test']
Expand Down
Loading
Loading