Skip to content

Commit

Permalink
Merge pull request #85 from pupil-labs/pre-commit-ci-update-config
Browse files Browse the repository at this point in the history
[pre-commit.ci] pre-commit autoupdate
  • Loading branch information
papr authored Feb 7, 2023
2 parents fcc04a0 + 0efa782 commit 5fb48ff
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 77 deletions.
16 changes: 16 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[flake8]
max-line-length = 88

max-complexity = 18

extend-ignore =
# Black creates whitespace before colon
E203
W503
F541

extend-select = B,C,E,F,W,T4,B9
exclude =
.venv
.pyenv
__pycache__
13 changes: 7 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.4.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
Expand All @@ -12,30 +12,31 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/asottile/pyupgrade
rev: v2.37.3
rev: v3.3.1
hooks:
- id: pyupgrade
name: PyUpgrade 3.6+
args: ["--py36-plus"]
exclude: ^bin/

- repo: https://github.com/pycqa/flake8
rev: 5.0.4
rev: 6.0.0
hooks:
- id: flake8

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
rev: 5.12.0
hooks:
- id: isort
args: [--profile, black]

- repo: https://github.com/psf/black
rev: 22.6.0
rev: 23.1.0
hooks:
- id: black

- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.0.0
rev: v2.2.0
hooks:
- id: setup-cfg-fmt
args: ["--min-py3-version", "3.6"]
5 changes: 2 additions & 3 deletions examples/ndsi-client-example.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
import signal
import sys
import time

import ndsi

logging.basicConfig(
format="%(asctime)s [%(levelname)8s | %(name)-14s] %(message)s",
datefmt="%H:%M:%S",
Expand All @@ -11,8 +12,6 @@
logger = logging.getLogger(__name__)
logging.getLogger("pyre").setLevel(logging.WARNING)

import ndsi

sensors = {}


Expand Down
2 changes: 1 addition & 1 deletion examples/uvc-ndsi-bridge-host.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def poll_cmd_socket(self):
sensor, cmd_str = self.cmd.recv_multipart()
try:
cmd = json.loads(cmd_str.decode())
except Exception as e:
except Exception:
logger.debug(f"Could not parse received cmd: {cmd_str}")
else:
logger.debug(f"Received cmd: {cmd}")
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ install_requires =
pyzmq
zeromq-pyre
importlib-metadata;python_version<"3.8"
python_requires = >=3.6
python_requires = >=3.7
include_package_data = True
package_dir =
=src
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"""
import glob
import os
import pathlib
import platform

import numpy
Expand Down
24 changes: 10 additions & 14 deletions src/ndsi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,7 @@
----------------------------------------------------------------------------------~(*)
"""


class CaptureError(Exception):
def __init__(self, message):
super().__init__()
self.message = message


class StreamError(CaptureError):
def __init__(self, message):
super().__init__(message)
self.message = message


from ndsi.errors import CaptureError, StreamError
from ndsi.formatter import DataFormat

try:
Expand All @@ -42,4 +30,12 @@ def __init__(self, message):
from ndsi.sensor import Sensor
from ndsi.writer import H264Writer

__all__ = ["Network", "Sensor", "H264Writer", "__version__", "frame"]
__all__ = [
"__version__",
"CaptureError",
"frame",
"H264Writer",
"Network",
"Sensor",
"StreamError",
]
10 changes: 10 additions & 0 deletions src/ndsi/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CaptureError(Exception):
def __init__(self, message):
super().__init__()
self.message = message


class StreamError(CaptureError):
def __init__(self, message):
super().__init__(message)
self.message = message
15 changes: 8 additions & 7 deletions src/ndsi/formatter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import abc
import collections
import enum
import functools
import struct
Expand Down Expand Up @@ -37,7 +36,8 @@
"""
To add a new data format version, in `formatter.py`:
1. Add a new case to the `DataFormat` enum.
2. For each concrete sublcass of `DataFormatter` (except `UnsupportedFormatter`), extend the implementation of `get_formatter` to correctly handle the new format version.
2. For each concrete sublcass of `DataFormatter` (except `UnsupportedFormatter`), extend
the implementation of `get_formatter` to correctly handle the new format version.
3. Run the test suit to make sure that all the tests pass again.
4. Write additional tests to cover the custom behaviour of the new data format.
"""
Expand All @@ -46,7 +46,8 @@
@enum.unique
class DataFormat(enum.Enum):
"""
`DataFormat` enum represents the format for serializing and deserializing data between NDSI hosts and clients.
`DataFormat` enum represents the format for serializing and deserializing data
between NDSI hosts and clients.
"""

V3 = "v3"
Expand Down Expand Up @@ -97,7 +98,8 @@ def decode_msg(self, data_msg: DataMessage) -> typing.Iterator[DataValue]:

class UnsupportedFormatter(DataFormatter[typing.Any]):
"""
Represents a formatter that is not supported for a specific data format and sensor type combination.
Represents a formatter that is not supported for a specific data format and sensor
type combination.
"""

@staticmethod
Expand Down Expand Up @@ -145,7 +147,7 @@ class _VideoDataFormatter_V3(VideoDataFormatter):
def decode_msg(self, data_msg: DataMessage) -> VideoValue:
meta_data = struct.unpack("<LLLLdLL", data_msg.header)
meta_data_mutable = list(meta_data)
meta_data_mutable[4] *= 1e6 # Convert timestamp s -> us
meta_data_mutable[4] *= 1e6 # Convert timestamp s -> us
meta_data = tuple(meta_data_mutable)
if meta_data[0] == VIDEO_FRAME_FORMAT_MJPEG:
yield self._frame_factory.create_jpeg_frame(data_msg.body, meta_data)
Expand All @@ -161,7 +163,7 @@ class _VideoDataFormatter_V4(VideoDataFormatter):
def decode_msg(self, data_msg: DataMessage) -> VideoValue:
meta_data = struct.unpack("<LLLLQLL", data_msg.header)
meta_data_mutable = list(meta_data)
meta_data_mutable[4] /= 1e3 # Convert timestamp ns -> us
meta_data_mutable[4] /= 1e3 # Convert timestamp ns -> us
meta_data = tuple(meta_data_mutable)
if meta_data[0] == VIDEO_FRAME_FORMAT_MJPEG:
yield self._frame_factory.create_jpeg_frame(data_msg.body, meta_data)
Expand Down Expand Up @@ -344,7 +346,6 @@ def encode_msg(self, value: EventValue) -> DataMessage:


class _EventDataFormatter_V4(EventDataFormatter):

_encoding_lookup = {0: "utf-8"}

def decode_msg(self, data_msg: DataMessage) -> typing.Iterator[EventValue]:
Expand Down
16 changes: 0 additions & 16 deletions src/ndsi/frame.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,6 @@ VIDEO_FRAME_FORMAT_MJPEG = 0x10
VIDEO_FRAME_FORMAT_H264 = 0x12
VIDEO_FRAME_FORMAT_VP8 = 0x13

class CaptureError(Exception):
def __init__(self, message):
super(CaptureError, self).__init__()
self.message = message

class StreamError(CaptureError):
def __init__(self, message):
super(StreamError, self).__init__(message)
self.message = message

class InitError(CaptureError):
def __init__(self, message):
super(InitError, self).__init__(message)
self.message = message


cdef class FrameFactory:

def __cinit__(self, *args, **kwargs):
Expand Down
18 changes: 9 additions & 9 deletions src/ndsi/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@

import abc
import collections
import functools
import itertools
import json as serial
import logging
import sys
import time
import traceback as tb
import typing

import zmq
from pyre import Pyre, PyreEvent, zhelper
from pyre import Pyre, PyreEvent

from ndsi import __protocol_version__
from ndsi.formatter import DataFormat
Expand Down Expand Up @@ -181,7 +177,7 @@ def handle_event(self):
if not self.has_events:
return
event = PyreEvent(self._pyre_node)
uuid = event.peer_uuid
# uuid = event.peer_uuid
if event.type == "SHOUT" or event.type == "WHISPER":
try:
payload = event.msg.pop(0).decode()
Expand Down Expand Up @@ -225,9 +221,10 @@ def handle_event(self):
# - [<unrelated group>, <unrelated version>]
# - ['pupil-mobile']
# - ['pupil-mobile', <version>]
group_version = event.group.split("-v")
group = group_version[0]
version = group_version[1] if len(group_version) > 1 else "0"
# group_version = event.group.split("-v")
# group = group_version[0]
# version = group_version[1] if len(group_version) > 1 else "0"
pass

elif event.type == "EXIT":
gone_peer = event.peer_uuid.hex
Expand Down Expand Up @@ -391,3 +388,6 @@ def sensor(

def group_name_from_format(format: DataFormat) -> str:
return f"pupil-mobile-{format}"


__all__ = ["__protocol_version__"]
26 changes: 13 additions & 13 deletions src/ndsi/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,10 @@
import json as serial
import logging
import traceback as tb
import typing

import numpy as np
import zmq

logger = logging.getLogger(__name__)

import typing

from ndsi import StreamError
from ndsi.formatter import (
AnnotateDataFormatter,
Expand All @@ -38,6 +34,7 @@
VideoValue,
)

logger = logging.getLogger(__name__)
NANO = 1e-9


Expand All @@ -53,8 +50,11 @@ def __str__(self):
To add a new sensor, in `sensor.py`:
1. Add a new case to the `SensorType` enum.
2. Add a new subclass of `Sensor` and implement the custom sensor behaviour.
3. Add a new entry into the `_SENSOR_TYPE_CLASS_MAP`, mapping the new `SensorType` case to the new `Sensor` subclass.
4. (Optional) If the new `Sensor` subclass will include `SensorFetchDataMixin`, the subclass must define a property `formatter` that returns an instance of `DataFormatter` which serializes/deserializes the data handled by the sensor.
3. Add a new entry into the `_SENSOR_TYPE_CLASS_MAP`, mapping the new `SensorType` case
to the new `Sensor` subclass.
4. (Optional) If the new `Sensor` subclass will include `SensorFetchDataMixin`, the
subclass must define a property `formatter` that returns an instance of
`DataFormatter` which serializes/deserializes the data handled by the sensor.
5. Run the test suit to make sure that all the tests pass again.
6. Write additional tests to cover the custom behaviour of the new sensor type.
"""
Expand Down Expand Up @@ -101,8 +101,9 @@ def class_for_type(sensor_type: SensorType):
@staticmethod
def create_sensor(sensor_type: SensorType, **kwargs) -> "Sensor":
sensor_class = Sensor.class_for_type(sensor_type=sensor_type)
# TODO: Passing sensor_type to the class init as str, to preserve API compatibility.
# Ideally, the sensor_type passed and stored by Sensor is of type SensorType.
# TODO: Passing sensor_type to the class init as str, to preserve API
# compatibility. Ideally, the sensor_type passed and stored by Sensor is
# of type SensorType.
kwargs["sensor_type"] = str(sensor_type)
return sensor_class(**kwargs)

Expand Down Expand Up @@ -207,7 +208,7 @@ def handle_notification(self):
else:
try:
self.execute_callbacks(notification)
except:
except Exception:
logger.debug(tb.format_exc())

def execute_callbacks(self, event):
Expand Down Expand Up @@ -261,9 +262,8 @@ def reset_control_value(self, control_id):
self.set_control_value(control_id, value)
else:
logger.error(
(
"Could not reset control `{}` because it does not have a default value."
).format(control_id)
f"Could not reset control `{control_id}` because it does not have a"
" default value."
)
else:
logger.error(f"Could not reset unknown control `{control_id}`")
Expand Down
31 changes: 29 additions & 2 deletions tests/test_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,35 @@ def test_imu_formatter_v4_decoding():

data_msg = DataMessage(
sensor_id=b"fa25fb2f-ab58-4058-990c-bcd49a67c3ce",
header=b"\x00\x00\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00@\x02\x00\x00\x00\x00\x00\x00",
body=b"\x81\x01\x9d}\xcaS\x86\x16\x00PB>\x00\xcc{?\x00\xa0\xec=\x90\xc1y=\x90\xc1y>\xfa\x18\x1c\xbfab\xe8}\xcaS\x86\x16\x00\xc0@>\x00\x18|?\x00\xa0\xe8=\x90\xc1y=,Q;>\xe1|\x0c\xbfA\xc33~\xcaS\x86\x16\x00 @>\x00<{?\x00@\xe0=\x00\x00\x00\x80,Q;>\xe1|\x0c\xbf!$\x7f~\xcaS\x86\x16\x00\xf0@>\x00\xc4{?\x00\x80\xeb=\x00\x00\x00\x80\x90\xc1y>\xe1|\x0c\xbf\x01\x85\xca~\xcaS\x86\x16\x00pA>\x00\xcc{?\x00\x00\xec=\x90\xc1\xf9\xbd\x90\xc1\xf9=\x90\xc1\xf9\xbe\xe1\xe5\x15\x7f\xcaS\x86\x16\x00PA>\x00L{?\x00\x00\xea=\x90\xc1y\xbd\x90\xc1\xf9=^\x89\xda\xbe\xc1Fa\x7f\xcaS\x86\x16\x00\xa0?>\x00\xf4z?\x00 \xe6=\x00\x00\x00\x80\x90\xc1\xf9=\xe1|\x0c\xbf\xa1\xa7\xac\x7f\xcaS\x86\x16\x00\xa0C>\x00|{?\x00\x80\xe1=\x90\xc1y=\x90\xc1y>\x13\xb5+\xbf\x81\x08\xf8\x7f\xcaS\x86\x16\x00@@>\x00${?\x00@\xe6=\x90\xc1\xf9=,Q;>\xe1|\x0c\xbfaiC\x80\xcaS\x86\x16\x00p?>\x00\xcc{?\x00\x00\xe4=\x90\xc1\xf9=\x90\xc1y=\x13\xb5+\xbfA\xca\x8e\x80\xcaS\x86\x16\x00\xf0B>\x00\x80{?\x00 \xee=\x90\xc1y=\x90\xc1\xf9=,Q;\xbf!+\xda\x80\xcaS\x86\x16\x00@C>\x00\xdcz?\x00\xc0\xe8=\x90\xc1\xf9=,Q;>\x13\xb5+\xbf\x01\x8c%\x81\xcaS\x86\x16\x00\xe0C>\x00\xa4{?\x00@\xe6=,Q;>\x90\xc1\xf9=\x13\xb5+\xbf\xe1\xecp\x81\xcaS\x86\x16\x00\xd0@>\x00\xcc{?\x00\x80\xea=\x90\xc1y=,Q;>\x13\xb5+\xbf\xc1M\xbc\x81\xcaS\x86\x16\x00\x80D>\x00\xc8{?\x00 \xe7=\x90\xc1y\xbd\xfa\x18\x9c>\xe1|\x0c\xbf\xa1\xae\x07\x82\xcaS\x86\x16\x00pA>\x00\xac{?\x00\xc0\xe5=\x90\xc1y=\x90\xc1\xf9=\xe1|\x0c\xbf\x81\x0fS\x82\xcaS\x86\x16\x00\xb0?>\x00\xb0{?\x00\xa0\xe5=\x00\x00\x00\x80\x90\xc1y>\x13\xb5+\xbfap\x9e\x82\xcaS\x86\x16\x00\xf0A>\x00\x88{?\x00@\xe7=\x00\x00\x00\x80\x90\xc1\xf9=\xfa\x18\x1c\xbf",
header=(
b"\x00\x00\x00\x00\x07\x00\x00\x00\x12\x00"
b"\x00\x00@\x02\x00\x00\x00\x00\x00\x00"
),
body=(
b"\x81\x01\x9d}\xcaS\x86\x16\x00PB>\x00\xcc{?\x00\xa0\xec=\x90\xc1y=\x90"
b"\xc1y>\xfa\x18\x1c\xbfab\xe8}\xcaS\x86\x16\x00\xc0@>\x00\x18|?\x00\xa0"
b"\xe8=\x90\xc1y=,Q;>\xe1|\x0c\xbfA\xc33~\xcaS\x86\x16\x00 @>\x00<{?\x00@"
b"\xe0=\x00\x00\x00\x80,Q;>\xe1|\x0c\xbf!$\x7f~\xcaS\x86\x16\x00\xf0@>\x00"
b"\xc4{?\x00\x80\xeb=\x00\x00\x00\x80\x90\xc1y>\xe1|\x0c\xbf\x01\x85\xca~"
b"\xcaS\x86\x16\x00pA>\x00\xcc{?\x00\x00\xec=\x90\xc1\xf9\xbd\x90\xc1\xf9="
b"\x90\xc1\xf9\xbe\xe1\xe5\x15\x7f\xcaS\x86\x16\x00PA>\x00L{?\x00\x00\xea="
b"\x90\xc1y\xbd\x90\xc1\xf9=^\x89\xda\xbe\xc1Fa\x7f\xcaS\x86\x16\x00\xa0?>"
b"\x00\xf4z?\x00 \xe6=\x00\x00\x00\x80\x90\xc1\xf9=\xe1|\x0c\xbf\xa1\xa7"
b"\xac\x7f\xcaS\x86\x16\x00\xa0C>\x00|{?\x00\x80\xe1=\x90\xc1y=\x90\xc1y>"
b"\x13\xb5+\xbf\x81\x08\xf8\x7f\xcaS\x86\x16\x00@@>\x00${?\x00@\xe6=\x90"
b"\xc1\xf9=,Q;>\xe1|\x0c\xbfaiC\x80\xcaS\x86\x16\x00p?>\x00\xcc{?\x00\x00"
b"\xe4=\x90\xc1\xf9=\x90\xc1y=\x13\xb5+\xbfA\xca\x8e\x80\xcaS\x86\x16\x00"
b"\xf0B>\x00\x80{?\x00 \xee=\x90\xc1y=\x90\xc1\xf9=,Q;\xbf!+\xda\x80\xcaS"
b"\x86\x16\x00@C>\x00\xdcz?\x00\xc0\xe8=\x90\xc1\xf9=,Q;>\x13\xb5+\xbf\x01"
b"\x8c%\x81\xcaS\x86\x16\x00\xe0C>\x00\xa4{?\x00@\xe6=,Q;>\x90\xc1\xf9=\x13"
b"\xb5+\xbf\xe1\xecp\x81\xcaS\x86\x16\x00\xd0@>\x00\xcc{?\x00\x80\xea=\x90"
b"\xc1y=,Q;>\x13\xb5+\xbf\xc1M\xbc\x81\xcaS\x86\x16\x00\x80D>\x00\xc8{?\x00"
b" \xe7=\x90\xc1y\xbd\xfa\x18\x9c>\xe1|\x0c\xbf\xa1\xae\x07\x82\xcaS\x86"
b"\x16\x00pA>\x00\xac{?\x00\xc0\xe5=\x90\xc1y=\x90\xc1\xf9=\xe1|\x0c\xbf"
b"\x81\x0fS\x82\xcaS\x86\x16\x00\xb0?>\x00\xb0{?\x00\xa0\xe5=\x00\x00\x00"
b"\x80\x90\xc1y>\x13\xb5+\xbfap\x9e\x82\xcaS\x86\x16\x00\xf0A>\x00\x88{?"
b"\x00@\xe7=\x00\x00\x00\x80\x90\xc1\xf9=\xfa\x18\x1c\xbf"
),
)

imu_vals = list(imu_v4_fmt.decode_msg(data_msg=data_msg))
Expand Down
Loading

0 comments on commit 5fb48ff

Please sign in to comment.