Skip to content

Commit

Permalink
Merge pull request #2009 from jsl12/dev
Browse files Browse the repository at this point in the history
docstrings, type hints, and import sorting
  • Loading branch information
acockburn authored Jun 18, 2024
2 parents d288fc0 + ad96e58 commit 9be468a
Show file tree
Hide file tree
Showing 24 changed files with 592 additions and 260 deletions.
18 changes: 10 additions & 8 deletions appdaemon/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
import signal
import sys

import appdaemon.appdaemon as ad
import appdaemon.http as adhttp
import appdaemon.logging as logging
import appdaemon.utils as utils
import pytz

import appdaemon.appdaemon as ad
import appdaemon.utils as utils
from appdaemon.app_management import UpdateMode
from appdaemon.http import HTTP
from appdaemon.logging import Logging

try:
import pid
Expand All @@ -39,6 +39,8 @@ class ADMain:
Class to encapsulate all main() functionality.
"""

logging: Logging

def __init__(self):
"""Constructor."""

Expand Down Expand Up @@ -104,7 +106,7 @@ def stop(self):
self.http_object.stop()

# noinspection PyBroadException,PyBroadException
def run(self, appdaemon, hadashboard, admin, aui, api, http):
def run(self, appdaemon: ad.AppDaemon, hadashboard, admin, aui, api, http):
"""Start AppDaemon up after initial argument parsing.
Args:
Expand All @@ -126,7 +128,7 @@ def run(self, appdaemon, hadashboard, admin, aui, api, http):
self.logger.info("Running AD using uvloop")
uvloop.install()

loop = asyncio.get_event_loop()
loop: asyncio.BaseEventLoop = asyncio.get_event_loop()

# Initialize AppDaemon

Expand All @@ -138,7 +140,7 @@ def run(self, appdaemon, hadashboard, admin, aui, api, http):
hadashboard is not None or admin is not None or aui is not None or api is not False
):
self.logger.info("Initializing HTTP")
self.http_object = adhttp.HTTP(
self.http_object = HTTP(
self.AD,
loop,
self.logging,
Expand Down Expand Up @@ -357,7 +359,7 @@ def main(self): # noqa: C901
else:
logs = {}

self.logging = logging.Logging(logs, args.debug)
self.logging = Logging(logs, args.debug)
self.logger = self.logging.get_logger()

if "time_zone" in config["appdaemon"]:
Expand Down
50 changes: 37 additions & 13 deletions appdaemon/adapi.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from datetime import timedelta
from copy import deepcopy
from typing import Any, Optional, Callable, Union
from asyncio import Future

import asyncio
import datetime as dt
import inspect
import re
import uuid
from asyncio import Future
from copy import deepcopy
from datetime import timedelta
from typing import Any, Callable, Dict, Optional, Union

import iso8601

from appdaemon import utils
from appdaemon.appdaemon import AppDaemon
from appdaemon.entity import Entity
from appdaemon.logging import Logging


class ADAPI:
Expand All @@ -22,17 +23,40 @@ class ADAPI:
"""

AD: AppDaemon
"""Reference to the top-level AppDaemon container object
"""
name: str
"""The app name, which is set by the top-level key in the YAML file
"""
_logging: Logging
"""Reference to the Logging subsystem object
"""
args: Dict[str, Any]
"""The arguments provided in this app's YAML config file
"""

#
# Internal parameters
#
def __init__(self, ad: AppDaemon, name, logging_obj, args, config, app_config, global_vars):
def __init__(
self,
ad: AppDaemon,
name: str,
logging_obj: Logging,
args: Dict[str, Any],
config: Dict[str, Any],
app_config,
global_vars,
):
# Store args

self.AD = ad
self.name = name
self._logging = logging_obj
self.config = config
self.app_config = app_config
# same as self.AD.app_management.app_config
self.args = deepcopy(args)
self.app_dir = self.AD.app_dir
self.config_dir = self.AD.config_dir
Expand All @@ -58,7 +82,7 @@ def __init__(self, ad: AppDaemon, name, logging_obj, args, config, app_config, g
@staticmethod
def _sub_stack(msg):
# If msg is a data structure of some type, don't sub
if type(msg) is str:
if isinstance(msg, str):
stack = inspect.stack()
if msg.find("__module__") != -1:
msg = msg.replace("__module__", stack[2][1])
Expand Down Expand Up @@ -2494,9 +2518,9 @@ async def run_once(self, callback: Callable, start: Union[dt.time, str], **kwarg
>>> handle = self.run_once(self.run_once_c, "sunrise + 01:00:00")
"""
if type(start) == dt.time:
if isinstance(start, dt.time):
when = start
elif type(start) == str:
elif isinstance(start, str):
start_time_obj = await self.AD.sched._parse_time(start, self.name)
when = start_time_obj["datetime"].time()
else:
Expand Down Expand Up @@ -2571,9 +2595,9 @@ async def run_at(self, callback: Callable, start: Union[dt.datetime, str], **kwa
>>> handle = self.run_at(self.run_at_c, "sunrise + 01:00:00")
"""
if type(start) == dt.datetime:
if isinstance(start, dt.datetime):
when = start
elif type(start) == str:
elif isinstance(start, str):
start_time_obj = await self.AD.sched._parse_time(start, self.name)
when = start_time_obj["datetime"]
else:
Expand Down Expand Up @@ -2644,9 +2668,9 @@ async def run_daily(self, callback: Callable, start: Union[dt.time, str], **kwar
"""
info = None
when = None
if type(start) == dt.time:
if isinstance(start, dt.time):
when = start
elif type(start) == str:
elif isinstance(start, str):
info = await self.AD.sched._parse_time(start, self.name)
else:
raise ValueError("Invalid type for start")
Expand Down
7 changes: 5 additions & 2 deletions appdaemon/admin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import os
import traceback
from typing import TYPE_CHECKING

from jinja2 import Environment, FileSystemLoader, select_autoescape

import appdaemon.utils as utils
from appdaemon.appdaemon import AppDaemon

if TYPE_CHECKING:
from appdaemon.appdaemon import AppDaemon


class Admin:
def __init__(self, config_dir, logger, ad: AppDaemon, **kwargs):
def __init__(self, config_dir, logger, ad: "AppDaemon", **kwargs):
#
# Set Defaults
#
Expand Down
19 changes: 17 additions & 2 deletions appdaemon/admin_loop.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import asyncio
from appdaemon.appdaemon import AppDaemon
from logging import Logger
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from appdaemon.appdaemon import AppDaemon


class AdminLoop:
def __init__(self, ad: AppDaemon):
"""Called by :meth:`~appdaemon.appdaemon.AppDaemon.register_http`. Loop timed with :attr:`~appdaemon.AppDaemon.admin_delay`"""

AD: "AppDaemon"
"""Reference to the AppDaemon container object
"""
stopping: bool
logger: Logger
"""Standard python logger named ``AppDaemon._admin_loop``
"""

def __init__(self, ad: "AppDaemon"):
self.AD = ad
self.stopping = False
self.logger = ad.logging.get_child("_admin_loop")
Expand All @@ -13,6 +27,7 @@ def stop(self):
self.stopping = True

async def loop(self):
"""Handles calling :meth:`~.threading.Threading.get_callback_update` and :meth:`~.threading.Threading.get_q_update`"""
while not self.stopping:
if self.AD.http.stats_update != "none" and self.AD.sched is not None:
await self.AD.threading.get_callback_update()
Expand Down
Loading

0 comments on commit 9be468a

Please sign in to comment.