From 5c1d9a2d8006fe8797ce6c3c106941b1a2c8814b Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Thu, 20 May 2021 23:21:17 +0200 Subject: [PATCH] Add additional dependencies to make Flake8 verify docstrings (#88) * Add additional dependencies to make Flake8 verify docstrings * Fix pydocstyle for init, main, api and errors * Fix pydocstyle for applications * Fix pydocstyle in api discovery, basic device info and event instances * Fix pydoctstyle in event stream, light control, MQTT and param cgi * Fix pydocstyle in port cgi, port management, PTZ and pwdgrp cgi * Fix pydocstyle in stream profiles, stream manager, user groups, vapix and view areas --- axis/__init__.py | 2 + axis/__main__.py | 3 +- axis/api.py | 10 ++++ axis/api_discovery.py | 2 + axis/applications/__init__.py | 2 + axis/applications/api.py | 11 ++-- axis/applications/applications.py | 5 +- axis/applications/fence_guard.py | 3 +- axis/applications/loitering_guard.py | 3 +- axis/applications/motion_guard.py | 3 +- axis/applications/object_analytics.py | 7 +-- axis/applications/vmd4.py | 1 + axis/basic_device_info.py | 72 +++++++++++++++++++++------ axis/errors.py | 1 + axis/event_instances.py | 6 +-- axis/event_stream.py | 12 ++--- axis/light_control.py | 6 ++- axis/mqtt.py | 5 +- axis/param_cgi.py | 35 +++++++++++-- axis/port_cgi.py | 11 ++-- axis/port_management.py | 12 +++-- axis/ptz.py | 4 +- axis/pwdgrp_cgi.py | 6 +++ axis/stream_profiles.py | 10 ++-- axis/streammanager.py | 2 +- axis/user_groups.py | 1 + axis/vapix.py | 4 +- axis/view_areas.py | 8 +-- requirements-test.txt | 2 + 29 files changed, 182 insertions(+), 67 deletions(-) diff --git a/axis/__init__.py b/axis/__init__.py index ccf548db..a1532ba2 100644 --- a/axis/__init__.py +++ b/axis/__init__.py @@ -1,2 +1,4 @@ +"""Library to communicate with a Axis device.""" + from .device import AxisDevice # noqa: F401 from .errors import * # noqa: F401, F403 diff --git a/axis/__main__.py b/axis/__main__.py index 8ac8c1cb..11fe743b 100644 --- a/axis/__main__.py +++ b/axis/__main__.py @@ -13,6 +13,7 @@ def event_handler(action, event): + """Receive and print events from RTSP stream.""" LOGGER.info(f"{action} {event}") @@ -48,7 +49,7 @@ async def axis_device(host, port, username, password): async def main(host, port, username, password, params, events): - """Main function.""" + """CLI method for library.""" LOGGER.info("Connecting to Axis device") device = await axis_device(host, port, username, password) diff --git a/axis/api.py b/axis/api.py index 8bb49b83..12ebec19 100644 --- a/axis/api.py +++ b/axis/api.py @@ -25,6 +25,7 @@ class APIItems: """Base class for a map of API Items.""" def __init__(self, raw, request, path, item_cls) -> None: + """Initialize API items.""" self._request = request self._path = path self._item_cls = item_cls @@ -33,6 +34,7 @@ def __init__(self, raw, request, path, item_cls) -> None: LOGGER.debug(pformat(raw)) async def update(self) -> None: + """Refresh data.""" raw = await self._request("get", self._path) self.process_raw(raw) @@ -57,26 +59,33 @@ def process_raw(self, raw: Any) -> set: return new_items def items(self) -> dict: + """Return items.""" return self._items.items() def keys(self) -> str: + """Return item keys.""" return self._items.keys() def values(self): + """Return item values.""" return self._items.values() def get(self, obj_id: str, default: Optional[Any] = None): + """Get item value based on key, return default if no match.""" if obj_id in self: return self[obj_id] return default def __getitem__(self, obj_id: str): + """Get item value based on key.""" return self._items[obj_id] def __iter__(self): + """Allow iterate over items.""" return iter(self._items) def __contains__(self, obj_id: str): + """Validate membership of item ID.""" return obj_id in self._items def __len__(self) -> int: @@ -95,6 +104,7 @@ class APIItem: """Base class for all end points using APIItems class.""" def __init__(self, id: str, raw: dict, request: object) -> None: + """Initialize API item.""" self._id = id self._raw = raw self._request = request diff --git a/axis/api_discovery.py b/axis/api_discovery.py index 52847cb0..a29c926d 100644 --- a/axis/api_discovery.py +++ b/axis/api_discovery.py @@ -17,9 +17,11 @@ class ApiDiscovery(APIItems): """API Discovery for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize API discovery manager.""" super().__init__({}, request, URL, Api) async def update(self) -> None: + """Refresh data.""" raw = await self.get_api_list() self.process_raw(raw) diff --git a/axis/applications/__init__.py b/axis/applications/__init__.py index ed00b72f..a8550597 100644 --- a/axis/applications/__init__.py +++ b/axis/applications/__init__.py @@ -1 +1,3 @@ +"""Control stand alone applications of an Axis device.""" + from .applications import * # noqa: F401, F403 diff --git a/axis/applications/api.py b/axis/applications/api.py index 5314e637..cde39614 100644 --- a/axis/applications/api.py +++ b/axis/applications/api.py @@ -11,11 +11,12 @@ class ApplicationAPIItems(APIItems): def __init__( self, request: object, path: str, item_cls: object, api_version: str ) -> None: + """Initialize API items.""" self._api_version = api_version super().__init__({}, request, path, item_cls) async def update(self) -> None: - """No update method.""" + """Refresh data.""" raw = await self.get_configuration() self.process_raw(raw) @@ -32,7 +33,7 @@ def pre_process_raw(raw: dict) -> dict: return profiles async def get_configuration(self) -> dict: - """Current configuration of application.""" + """Retrieve configuration of application.""" return await self._request( "post", self._path, @@ -53,7 +54,7 @@ def camera(self) -> int: @property def filters(self) -> list: - """An array of exclude filters.""" + """Array of exclude filters.""" return self.raw["filters"] @property @@ -68,10 +69,10 @@ def perspective(self) -> list: @property def triggers(self) -> list: - """An array of triggers.""" + """Array of triggers.""" return self.raw["triggers"] @property def uid(self) -> int: - """Unique ID of profile.""" + """Profile ID.""" return self.raw["uid"] diff --git a/axis/applications/applications.py b/axis/applications/applications.py index 81a206c7..f0933eeb 100644 --- a/axis/applications/applications.py +++ b/axis/applications/applications.py @@ -22,10 +22,11 @@ class Applications(APIItems): """Applications on Axis devices.""" def __init__(self, request: object) -> None: + """Initialize applications manager.""" super().__init__({}, request, URL, Application) async def update(self) -> None: - """No update method""" + """Refresh data.""" raw = await self.list() self.process_raw(raw) @@ -52,7 +53,7 @@ def pre_process_raw(raw: dict) -> dict: return applications async def list(self) -> dict: - """The applications/list.cgi is used to list information about installed applications.""" + """Retrieve information about installed applications.""" return await self._request("post", URL_LIST) diff --git a/axis/applications/fence_guard.py b/axis/applications/fence_guard.py index 6557f1d7..3bf9205e 100644 --- a/axis/applications/fence_guard.py +++ b/axis/applications/fence_guard.py @@ -19,9 +19,10 @@ class FenceGuard(ApplicationAPIItems): - """Fence Guard application on Axis devices""" + """Fence Guard application on Axis devices.""" APPLICATION_NAME = APPLICATION_NAME def __init__(self, request: object) -> None: + """Initialize fence guard manager.""" super().__init__(request, URL, ApplicationAPIItem, API_VERSION) diff --git a/axis/applications/loitering_guard.py b/axis/applications/loitering_guard.py index 04416d95..8c92a862 100644 --- a/axis/applications/loitering_guard.py +++ b/axis/applications/loitering_guard.py @@ -17,9 +17,10 @@ class LoiteringGuard(ApplicationAPIItems): - """Loitering Guard application on Axis devices""" + """Loitering Guard application on Axis devices.""" APPLICATION_NAME = APPLICATION_NAME def __init__(self, request: object) -> None: + """Initialize loitering guard manager.""" super().__init__(request, URL, ApplicationAPIItem, API_VERSION) diff --git a/axis/applications/motion_guard.py b/axis/applications/motion_guard.py index 33456508..66c3118d 100644 --- a/axis/applications/motion_guard.py +++ b/axis/applications/motion_guard.py @@ -18,9 +18,10 @@ class MotionGuard(ApplicationAPIItems): - """Motion Guard application on Axis devices""" + """Motion Guard application on Axis devices.""" APPLICATION_NAME = APPLICATION_NAME def __init__(self, request: object) -> None: + """Initialize motion guard manager.""" super().__init__(request, URL, ApplicationAPIItem, API_VERSION) diff --git a/axis/applications/object_analytics.py b/axis/applications/object_analytics.py index 6e9c3f60..220a00a0 100644 --- a/axis/applications/object_analytics.py +++ b/axis/applications/object_analytics.py @@ -18,11 +18,12 @@ class ObjectAnalytics(ApplicationAPIItems): - """Object Analytics application on Axis devices""" + """Object Analytics application on Axis devices.""" APPLICATION_NAME = APPLICATION_NAME def __init__(self, request: object) -> None: + """Initialize object analyticz manager.""" super().__init__(request, URL, ObjectAnalyticsScenario, API_VERSION) @staticmethod @@ -38,7 +39,7 @@ def pre_process_raw(raw: dict) -> dict: return scenarios async def get_configuration(self) -> dict: - """Current configuration of application.""" + """Retrieve configuration of application.""" return await self._request( "post", self._path, @@ -78,5 +79,5 @@ def trigger_type(self) -> str: @property def uid(self) -> int: - """Unique ID of scenario.""" + """Scenario ID.""" return self.raw["id"] diff --git a/axis/applications/vmd4.py b/axis/applications/vmd4.py index a708ae75..3809d004 100644 --- a/axis/applications/vmd4.py +++ b/axis/applications/vmd4.py @@ -18,4 +18,5 @@ class Vmd4(ApplicationAPIItems): APPLICATION_NAME = APPLICATION_NAME def __init__(self, request: object) -> None: + """Initialize VMD4 manager.""" super().__init__(request, URL, ApplicationAPIItem, API_VERSION) diff --git a/axis/basic_device_info.py b/axis/basic_device_info.py index 96b63263..b035a449 100644 --- a/axis/basic_device_info.py +++ b/axis/basic_device_info.py @@ -20,6 +20,7 @@ class BasicDeviceInfo(APIItems): """Basic device information for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize basic device information manager.""" super().__init__({}, request, URL, APIItem) def __getitem__(self, obj_id: str) -> Optional[Any]: @@ -27,6 +28,7 @@ def __getitem__(self, obj_id: str) -> Optional[Any]: return self._items[obj_id].raw async def update(self) -> None: + """Refresh data.""" raw = await self.get_all_properties() self.process_raw(raw) @@ -59,70 +61,112 @@ async def get_supported_versions(self) -> dict: @property def architecture(self) -> str: - """ApiVersion 1.1""" + """SOC architecture. + + ApiVersion 1.1. + """ return self["Architecture"] @property def brand(self) -> str: - """ApiVersion 1.1""" + """Device branding. + + ApiVersion 1.1. + """ return self["Brand"] @property def builddate(self) -> str: - """ApiVersion 1.1""" + """Firmware build date. + + ApiVersion 1.1. + """ return self["BuildDate"] @property def hardwareid(self) -> str: - """ApiVersion 1.1""" + """Device hardware ID. + + ApiVersion 1.1. + """ return self["HardwareID"] @property def prodfullname(self) -> str: - """ApiVersion 1.1""" + """Device product full name. + + ApiVersion 1.1. + """ return self["ProdFullName"] @property def prodnbr(self) -> str: - """ApiVersion 1.1""" + """Device product number. + + ApiVersion 1.1. + """ return self["ProdNbr"] @property def prodshortname(self) -> str: - """ApiVersion 1.1""" + """Device product short name. + + ApiVersion 1.1. + """ return self["ProdShortName"] @property def prodtype(self) -> str: - """ApiVersion 1.1""" + """Device product type. + + ApiVersion 1.1. + """ return self["ProdType"] @property def prodvariant(self) -> str: - """ApiVersion 1.1""" + """Device product variant. + + ApiVersion 1.1. + """ return self["ProdVariant"] @property def serialnumber(self) -> str: - """ApiVersion 1.1""" + """Device serial number. + + ApiVersion 1.1. + """ return self["SerialNumber"] @property def soc(self) -> str: - """ApiVersion 1.1""" + """System on chip variant. + + ApiVersion 1.1. + """ return self["Soc"] @property def socserialnumber(self) -> str: - """ApiVersion 1.1""" + """SOC serial number. + + ApiVersion 1.1. + """ return self["SocSerialNumber"] @property def version(self) -> str: - """ApiVersion 1.1""" + """Firmware version. + + ApiVersion 1.1. + """ return self["Version"] @property def weburl(self) -> str: - """ApiVersion 1.1""" + """Device home page URL. + + ApiVersion 1.1. + """ return self["WebURL"] diff --git a/axis/errors.py b/axis/errors.py index 7371f2a7..37faed59 100644 --- a/axis/errors.py +++ b/axis/errors.py @@ -40,6 +40,7 @@ class NoPermission(AxisException): def raise_error(error): + """Raise error.""" type = error cls = ERRORS.get(type, AxisException) raise cls("{}".format(type)) diff --git a/axis/event_instances.py b/axis/event_instances.py index 513e5238..0299d6d6 100644 --- a/axis/event_instances.py +++ b/axis/event_instances.py @@ -1,4 +1,4 @@ -"""Event service and action service APIs available in Axis network products.""" +"""Event service and action service APIs available in Axis network device.""" from typing import Callable, List, Optional, Union @@ -163,12 +163,12 @@ def stateless(self) -> bool: @property def source(self) -> Union[dict, list]: - """Source instance providing information about source of the event.""" + """Event source information.""" message = self.raw["data"]["MessageInstance"] return message.get("SourceInstance", {}).get("SimpleItemInstance", {}) @property def data(self) -> Union[dict, list]: - """Data instance providing information about data of the event.""" + """Event data description.""" message = self.raw["data"]["MessageInstance"] return message.get("DataInstance", {}).get("SimpleItemInstance", {}) diff --git a/axis/event_stream.py b/axis/event_stream.py index cf59949a..2e4e13ed 100644 --- a/axis/event_stream.py +++ b/axis/event_stream.py @@ -147,7 +147,7 @@ def source(self) -> str: @property def id(self) -> str: - """Id of the event. + """ID of the event. -1 means ANY source. """ @@ -196,7 +196,7 @@ class FenceGuard(AxisBinaryEvent): @property def id(self) -> str: - """Id of the event.""" + """ID of the event.""" return self.topic.split("/")[-1] @@ -230,7 +230,7 @@ class LoiteringGuard(AxisBinaryEvent): @property def id(self) -> str: - """Id of the event.""" + """ID of the event.""" return self.topic.split("/")[-1] @@ -251,7 +251,7 @@ class MotionGuard(AxisBinaryEvent): @property def id(self) -> str: - """Id of the event.""" + """ID of the event.""" return self.topic.split("/")[-1] @@ -264,7 +264,7 @@ class ObjectAnalytics(AxisBinaryEvent): @property def id(self) -> str: - """Id of the event.""" + """ID of the event.""" return self.topic.split("/")[-1] @@ -330,7 +330,7 @@ class Vmd4(AxisBinaryEvent): @property def id(self) -> str: - """Id of the event.""" + """ID of the event.""" return self.topic.split("/")[-1] diff --git a/axis/light_control.py b/axis/light_control.py index a4d7e681..c84c5d11 100644 --- a/axis/light_control.py +++ b/axis/light_control.py @@ -18,9 +18,11 @@ class LightControl(APIItems): """Light control for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize light control manager.""" super().__init__({}, request, URL, Light) async def update(self) -> None: + """Refresh data.""" raw = await self.get_light_information() self.process_raw(raw) @@ -339,7 +341,7 @@ def enabled(self) -> bool: @property def synchronize_day_night_mode(self) -> bool: - """Synchronized with day night mode.""" + """Will synchronize with day night mode.""" return self.raw["synchronizeDayNightMode"] @property @@ -359,7 +361,7 @@ def automatic_angle_of_illumination_mode(self) -> bool: @property def number_of_leds(self) -> int: - """Number of LEDs.""" + """Amount of LEDs.""" return self.raw["nrOfLEDs"] @property diff --git a/axis/mqtt.py b/axis/mqtt.py index b3194d7a..c5ccf9c3 100644 --- a/axis/mqtt.py +++ b/axis/mqtt.py @@ -90,10 +90,11 @@ class MqttClient(APIItems): """MQTT Client for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize MQTT client manager.""" super().__init__({}, request, URL_CLIENT, Client) async def update(self) -> None: - """No update method""" + """No update method.""" async def configure_client(self, client_config: ClientConfig) -> None: """Configure MQTT Client.""" @@ -154,4 +155,4 @@ async def configure_event_publication(self, topics: list = DEFAULT_TOPICS) -> No class Client(APIItem): - """ """ + """MQTT client.""" diff --git a/axis/param_cgi.py b/axis/param_cgi.py index 51e0e9d6..b86fe41e 100644 --- a/axis/param_cgi.py +++ b/axis/param_cgi.py @@ -41,9 +41,11 @@ class Params(APIItems): """Represents all parameters of param.cgi.""" def __init__(self, request: object) -> None: + """Initialize parameter manager.""" super().__init__("", request, URL_GET, Param) async def update(self, group: str = "") -> None: + """Refresh data.""" path = URL_GET + (f"&group={group}" if group else "") raw = await self._request("get", path) self.process_raw(raw) @@ -114,30 +116,37 @@ async def update_brand(self) -> None: @property def brand(self) -> str: + """Device branding.""" return self[BRAND]["Brand"] @property def prodfullname(self) -> str: + """Device product full name.""" return self[BRAND]["ProdFullName"] @property def prodnbr(self) -> str: + """Device product number.""" return self[BRAND]["ProdNbr"] @property def prodshortname(self) -> str: + """Device product short name.""" return self[BRAND]["ProdShortName"] @property def prodtype(self) -> str: + """Device product type.""" return self[BRAND]["ProdType"] @property def prodvariant(self) -> str: + """Device product variant.""" return self[BRAND]["ProdVariant"] @property def weburl(self) -> str: + """Device home page URL.""" return self[BRAND]["WebURL"] # Image @@ -264,19 +273,22 @@ async def update_properties(self) -> None: @property def api_http_version(self) -> str: + """HTTP API version.""" return self[PROPERTIES]["API.HTTP.Version"] @property def api_metadata(self) -> str: + """Support metadata API.""" return self[PROPERTIES]["API.Metadata.Metadata"] @property def api_metadata_version(self) -> str: + """Metadata API version.""" return self[PROPERTIES]["API.Metadata.Version"] @property def api_ptz_presets_version(self) -> Union[str, bool]: - """The index for the preset that is the device's home position at start-up. + """Preset index for device home position at start-up. As of version 2.00 of the PTZ preset API Properties.API.PTZ.Presets.Version=2.00 adding, updating and removing presets using param.cgi is no longer supported. @@ -293,47 +305,57 @@ def embedded_development(self) -> str: @property def firmware_builddate(self) -> str: + """Firmware build date.""" return self[PROPERTIES]["Firmware.BuildDate"] @property def firmware_buildnumber(self) -> str: + """Firmware build number.""" return self[PROPERTIES]["Firmware.BuildNumber"] @property def firmware_version(self) -> str: + """Firmware version.""" return self[PROPERTIES]["Firmware.Version"] @property def image_format(self) -> str: + """Supported image formats.""" return self[PROPERTIES].get("Image.Format") @property def image_nbrofviews(self) -> int: - """Number of supported view areas.""" + """Amount of supported view areas.""" return int(self[PROPERTIES]["Image.NbrOfViews"]) @property def image_resolution(self) -> str: + """Supported image resolutions.""" return self[PROPERTIES]["Image.Resolution"] @property def image_rotation(self) -> str: + """Supported image rotations.""" return self[PROPERTIES]["Image.Rotation"] @property def light_control(self) -> bool: + """Support light control.""" return self.get(PROPERTIES, {}).get("LightControl.LightControl2") == "yes" @property def ptz(self) -> bool: + """Support PTZ control.""" return self.get(PROPERTIES, {}).get("PTZ.PTZ") == "yes" @property def digital_ptz(self) -> bool: + """Support digital PTZ control.""" return self[PROPERTIES].get("PTZ.DigitalPTZ") == "yes" @property def system_serialnumber(self) -> str: + """Device serial number.""" return self[PROPERTIES]["System.SerialNumber"] # PTZ @@ -344,17 +366,20 @@ async def update_ptz(self) -> None: @property def ptz_camera_default(self) -> int: - """The video channel used if the camera parameter is omitted in HTTP requests.""" + """PTZ default video channel. + + When camera parameter is omitted in HTTP requests. + """ return int(self[PTZ]["CameraDefault"]) @property def ptz_number_of_cameras(self) -> int: - """Number of video channels.""" + """Amount of video channels.""" return int(self[PTZ]["NbrOfCameras"]) @property def ptz_number_of_serial_ports(self) -> int: - """Number of serial ports.""" + """Amount of serial ports.""" return int(self[PTZ]["NbrOfSerPorts"]) @property diff --git a/axis/port_cgi.py b/axis/port_cgi.py index 288c4b87..2a5d836b 100644 --- a/axis/port_cgi.py +++ b/axis/port_cgi.py @@ -27,10 +27,12 @@ class Ports(APIItems): """Represents all ports of io/port.cgi.""" def __init__(self, param_cgi: object, request: str) -> None: + """Initialize port cgi manager.""" self.param_cgi = param_cgi super().__init__(self.param_cgi.ports, request, None, Port) async def update(self) -> None: + """Refresh data.""" await self.param_cgi.update_ports() self.process_raw(self.param_cgi.ports) @@ -47,18 +49,19 @@ class Port: """Represents a port.""" def __init__(self, id: str, raw: dict, request: object) -> None: + """Initialize port.""" self.id = id self.raw = raw self._request = request @property def configurable(self) -> bool: - """The port is configurable or not.""" + """Is port configurable.""" return self.raw.get("Configurable", False) @property def direction(self) -> str: - """The port is configured to act as input or output. + """Port is configured to act as input or output. Read-only for non-configurable ports. """ @@ -66,7 +69,7 @@ def direction(self) -> str: @property def input_trig(self) -> str: - """Determines when to trig. + """When port should trigger. closed=The input port triggers when the circuit is closed. open=The input port triggers when the circuit is open. @@ -82,7 +85,7 @@ def name(self) -> str: @property def output_active(self) -> str: - """The active state of the output. + """When is output port state active. closed=The output port is active when the circuit is closed. open=The output port is active when the circuit is open. diff --git a/axis/port_management.py b/axis/port_management.py index 449539f5..78bf6ef2 100644 --- a/axis/port_management.py +++ b/axis/port_management.py @@ -45,9 +45,11 @@ class IoPortManagement(APIItems): """I/O port management for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize I/O port manager.""" super().__init__({}, request, URL, Port) async def update(self) -> None: + """Refresh data.""" raw = await self.get_ports() self.process_raw(raw) @@ -64,7 +66,7 @@ def pre_process_raw(raw: dict) -> dict: return {port["port"]: port for port in ports} async def get_ports(self) -> dict: - """This CGI method can be used to retrieve information about all ports on the device and their capabilities.""" + """Retrieve information about all ports on the device and their capabilities.""" return await self._request( "post", URL, @@ -75,7 +77,7 @@ async def get_ports(self) -> dict: ) async def set_ports(self, ports: list) -> None: - """Configures anything from one to several ports. + """Configure one or more ports. Some of the available options are: * Setting a nice name that can be used in the user interface. @@ -94,7 +96,7 @@ async def set_ports(self, ports: list) -> None: ) async def set_state_sequence(self, sequence: PortSequence) -> None: - """Applies a sequence of state changes with a delay in milliseconds between states.""" + """Apply a sequence of state changes with a delay in milliseconds between states.""" await self._request( "post", URL, @@ -102,7 +104,7 @@ async def set_state_sequence(self, sequence: PortSequence) -> None: ) async def get_supported_versions(self) -> dict: - """This CGI method can be used to retrieve a list of supported API versions.""" + """Retrieve a list of supported API versions.""" return await self._request( "post", URL, @@ -136,7 +138,7 @@ def name(self) -> str: @property def normalState(self) -> str: - """Normal state of port. + """Port normal state. . """ diff --git a/axis/ptz.py b/axis/ptz.py index c9f92f6a..079c9fdf 100644 --- a/axis/ptz.py +++ b/axis/ptz.py @@ -236,7 +236,7 @@ async def control( return await self._request("post", URL, data=data) async def query(self, query: str) -> str: - """Returns the current status. + """Retrieve current status. limits = PTZ limits for the Axis product. mode = Products with Panopsis technology: The current mode (overview or normal). @@ -255,5 +255,5 @@ async def configured_device_driver(self) -> str: return await self._request("post", URL, data={"whoami": 1}) async def available_ptz_commands(self) -> str: - """Description of available PTZ commands.""" + """Available PTZ commands.""" return await self._request("post", URL, data={"info": 1}) diff --git a/axis/pwdgrp_cgi.py b/axis/pwdgrp_cgi.py index df8f65bc..f151f289 100644 --- a/axis/pwdgrp_cgi.py +++ b/axis/pwdgrp_cgi.py @@ -40,6 +40,7 @@ class Users(APIItems): """Represents all users of a device.""" def __init__(self, raw: str, request: object) -> None: + """Initialize user manager.""" super().__init__(raw, request, URL_GET, User) async def update(self) -> None: @@ -121,20 +122,25 @@ class User(APIItem): @property def name(self) -> str: + """User name.""" return self.id @property def admin(self) -> bool: + """Is user part of admin group.""" return self.raw[ADMIN] @property def operator(self) -> bool: + """Is user part of operator group.""" return self.raw[OPERATOR] @property def viewer(self) -> bool: + """Is user part of viewer group.""" return self.raw[VIEWER] @property def ptz(self) -> bool: + """Is user part of PTZ group.""" return self.raw[PTZ] diff --git a/axis/stream_profiles.py b/axis/stream_profiles.py index 9f55201c..4582862e 100644 --- a/axis/stream_profiles.py +++ b/axis/stream_profiles.py @@ -22,9 +22,11 @@ class StreamProfiles(APIItems): """Stream profiles for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize stream profiles manager.""" super().__init__({}, request, URL, StreamProfile) async def update(self) -> None: + """Refresh data.""" raw = await self.list() self.process_raw(raw) @@ -41,7 +43,7 @@ def pre_process_raw(raw: dict) -> dict: return {profile["name"]: profile for profile in profiles} async def list(self, params: list = []) -> dict: - """This API method can be used to list the content of a stream profile. + """List the content of a stream profile. It is possible to list either one or multiple profiles and if the parameter streamProfileName is the empty list [] all available stream profiles will be listed. @@ -55,7 +57,7 @@ async def list(self, params: list = []) -> dict: ) async def get_supported_versions(self) -> dict: - """This CGI method can be used to retrieve a list of supported API versions.""" + """Retrieve a list of supported API versions.""" return await self._request( "post", URL, @@ -76,10 +78,10 @@ def name(self) -> str: @property def description(self) -> str: - """Description of API.""" + """Stream profile description.""" return self.raw["description"] @property def parameters(self) -> str: - """Parameters of API.""" + """Parameters of stream profile.""" return self.raw["parameters"] diff --git a/axis/streammanager.py b/axis/streammanager.py index 4539b5e1..48c98b6d 100644 --- a/axis/streammanager.py +++ b/axis/streammanager.py @@ -19,7 +19,7 @@ class StreamManager: """Setup, start, stop and retry stream.""" def __init__(self, config: Configuration) -> None: - """Setup stream manager.""" + """Initialize stream manager.""" self.config = config self.video = None # Unsupported self.audio = None # Unsupported diff --git a/axis/user_groups.py b/axis/user_groups.py index 7d649015..8373fc6f 100644 --- a/axis/user_groups.py +++ b/axis/user_groups.py @@ -15,6 +15,7 @@ class UserGroups(APIItems): """User group access rights for Axis devices.""" def __init__(self, raw: str, request: object) -> None: + """Initialize user groups manager.""" super().__init__(raw, request, URL, APIItem) @staticmethod diff --git a/axis/vapix.py b/axis/vapix.py index 998f8c7b..6e13a7d1 100644 --- a/axis/vapix.py +++ b/axis/vapix.py @@ -89,7 +89,7 @@ def product_type(self) -> str: @property def serial_number(self) -> str: - """Serial number of device.""" + """Device serial number.""" if self.basic_device_info: return self.basic_device_info.serialnumber return self.params.system_serialnumber @@ -216,7 +216,7 @@ async def initialize_applications(self) -> None: await asyncio.gather(*tasks) async def initialize_event_instances(self) -> None: - """Setup event instances of what events are supported by the device.""" + """Initialize event instances of what events are supported by the device.""" await self._initialize_api_attribute(EventInstances, "event_instances") async def initialize_users(self) -> None: diff --git a/axis/view_areas.py b/axis/view_areas.py index 1fab139e..3a5f85d5 100644 --- a/axis/view_areas.py +++ b/axis/view_areas.py @@ -98,9 +98,11 @@ class ViewAreas(APIItems): """View areas for Axis devices.""" def __init__(self, request: object) -> None: + """Initialize view area manager.""" super().__init__({}, request, URL, ViewArea) async def update(self) -> None: + """Refresh data.""" raw = await self.list() self.process_raw(raw) @@ -111,7 +113,7 @@ def pre_process_raw(raw: dict) -> dict: return {api["id"]: api for api in view_area_data} async def list(self) -> dict: - """This API method can be used to list the content of a view area. + """List the content of a view area. It is possible to list either one or multiple profiles and if the parameter streamProfileName is the empty list [] all available stream profiles will be listed. @@ -127,7 +129,7 @@ async def list(self) -> dict: ) async def get_supported_versions(self) -> dict: - """This CGI method can be used to retrieve a list of supported API versions. + """Retrieve a list of supported API versions. Request info.cgi Security level: Viewer @@ -202,7 +204,7 @@ async def reset_geometry( self.process_raw(raw) async def get_supported_config_versions(self) -> dict: - """This CGI method can be used to retrieve a list of supported API versions. + """Retrieve a list of supported API versions. Request info.cgi Security level: Viewer diff --git a/requirements-test.txt b/requirements-test.txt index b29c8760..3ff3ba57 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -4,6 +4,8 @@ pytest-asyncio httpx==0.18.1 respx==0.17.0 flake8==3.9.2 +flake8-docstrings==1.6.0 flake8-noqa==1.1.0 black==21.5b1 isort==5.8.0 +pydocstyle==6.0.0