Moved imports for extra dependencies inside the methods where they are actually used

This commit is contained in:
Fabio Manganiello 2019-12-01 23:35:05 +01:00
parent f8d3ea5197
commit d38746d278
33 changed files with 112 additions and 89 deletions

View File

@ -7,11 +7,6 @@ import json
import os
import time
import google.oauth2.credentials
from google.assistant.library import Assistant
from google.assistant.library.event import EventType, AlertType
from platypush.backend import Backend
from platypush.message.event.assistant import \
ConversationStartEvent, ConversationEndEvent, ConversationTimeoutEvent, \
@ -83,17 +78,15 @@ class AssistantGoogleBackend(Backend):
super().__init__(**kwargs)
self.credentials_file = credentials_file
self.device_model_id = device_model_id
self.credentials = None
self.assistant = None
self._has_error = False
with open(self.credentials_file, 'r') as f:
self.credentials = google.oauth2.credentials.Credentials(
token=None,
**json.load(f))
self.logger.info('Initialized Google Assistant backend')
def _process_event(self, event):
from google.assistant.library.event import EventType, AlertType
self.logger.info('Received assistant event: {}'.format(event))
self._has_error = False
@ -149,8 +142,16 @@ class AssistantGoogleBackend(Backend):
self.assistant.stop_conversation()
def run(self):
import google.oauth2.credentials
from google.assistant.library import Assistant
super().run()
with open(self.credentials_file, 'r') as f:
self.credentials = google.oauth2.credentials.Credentials(
token=None,
**json.load(f))
while not self.should_stop():
self._has_error = False

View File

@ -1,4 +1,3 @@
import gps
import threading
import time
@ -49,6 +48,8 @@ class GpsBackend(Backend):
self._devices = {}
def _get_session(self):
import gps
with self._session_lock:
if not self._session:
self._session = gps.gps(host=self.gpsd_server, port=self.gpsd_port, reconnect=True)

View File

@ -1,6 +1,5 @@
import datetime
import enum
import feedparser
import os
from sqlalchemy import create_engine, Column, Integer, String, DateTime, \
@ -20,7 +19,13 @@ Session = scoped_session(sessionmaker())
class RssUpdates(HttpRequest):
""" Gets new items in an RSS feed """
"""
Gets new items in an RSS feed
Requires:
* **feedparser** (``pip install feedparser``)
"""
user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ' + \
'Chrome/62.0.3202.94 Safari/537.36'
@ -80,6 +85,7 @@ class RssUpdates(HttpRequest):
return response.get('content')
def get_new_items(self, response):
import feedparser
engine = create_engine('sqlite:///{}'.format(self.dbfile),
connect_args={'check_same_thread': False})

View File

@ -1,5 +1,4 @@
import os
import inotify.adapters
from platypush.backend import Backend
from platypush.message.event.path import PathCreateEvent, PathDeleteEvent, \
@ -49,6 +48,7 @@ class InotifyBackend(Backend):
self.inotify_watch = None
def run(self):
import inotify.adapters
super().run()
self.inotify_watch = inotify.adapters.Inotify()

View File

@ -1,4 +1,3 @@
import inputs
import time
from platypush.backend import Backend
@ -30,6 +29,8 @@ class JoystickBackend(Backend):
self.device = device
def run(self):
import inputs
super().run()
self.logger.info('Initialized joystick backend on device {}'.format(self.device))

View File

@ -2,8 +2,6 @@ import json
import logging
import time
from kafka import KafkaConsumer, KafkaProducer
from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.message import Message
@ -82,6 +80,7 @@ class KafkaBackend(Backend):
self.logger.exception(e)
def run(self):
from kafka import KafkaConsumer
super().run()
self.consumer = KafkaConsumer(self.topic, bootstrap_servers=self.server)

View File

@ -1,7 +1,5 @@
import base64
import json
import nfc
import ndef
from platypush.backend import Backend
from platypush.message.event.nfc import NFCTagDetectedEvent, NFCTagRemovedEvent, NFCDeviceConnectedEvent, \
@ -21,7 +19,8 @@ class NfcBackend(Backend):
Requires:
* **nfcpy** >= 1.0 (``pip install nfcpy``)
* **nfcpy** >= 1.0 (``pip install 'nfcpy>=1.0'``)
* **ndef** (``pip install ndef``)
Run the following to check if your device is compatible with nfcpy and the right permissions are set::
@ -44,6 +43,8 @@ class NfcBackend(Backend):
self._clf = None
def _get_clf(self):
import nfc
if not self._clf:
self._clf = nfc.ContactlessFrontend()
self._clf.open(self.device_id)
@ -63,6 +64,7 @@ class NfcBackend(Backend):
@staticmethod
def _parse_records(tag):
import ndef
records = []
for record in tag.ndef.records:

View File

@ -1,8 +1,6 @@
import json
import time
from pushbullet import Pushbullet, Listener
from platypush.backend import Backend
from platypush.message.event.pushbullet import PushbulletEvent
@ -43,6 +41,7 @@ class PushbulletBackend(Backend):
:type proxy_port: int
"""
from pushbullet import Pushbullet
super().__init__(**kwargs)
self.token = token
@ -133,6 +132,7 @@ class PushbulletBackend(Backend):
return self.close()
def run(self):
from pushbullet import Listener
super().run()
self.logger.info('Initialized Pushbullet backend - device_id: {}'

View File

@ -1,10 +1,5 @@
import json
from smartcard.CardType import AnyCardType, ATRCardType
from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import NoCardException, CardConnectionException
from smartcard.util import toHexString
from platypush.backend import Backend
from platypush.message.event.scard import SmartCardDetectedEvent, SmartCardRemovedEvent
@ -32,6 +27,7 @@ class ScardBackend(Backend):
:param atr: If set, the backend will trigger events only for card(s) with the specified ATR(s). It can be either an ATR string (space-separated hex octects) or a list of ATR strings. Default: none (any card will be detected)
"""
from smartcard.CardType import AnyCardType, ATRCardType
super().__init__(*args, **kwargs)
self.ATRs = []
@ -51,6 +47,10 @@ class ScardBackend(Backend):
def run(self):
from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import NoCardException, CardConnectionException
from smartcard.util import toHexString
super().run()
self.logger.info('Initialized smart card reader backend - ATR filter: {}'.

View File

@ -2,7 +2,6 @@
.. moduleauthor:: Fabio Manganiello <blacklight86@gmail.com>
"""
import cwiid
import re
import time
@ -51,6 +50,8 @@ class WiimoteBackend(Backend):
def get_wiimote(self):
import cwiid
if not self._wiimote:
if self._bdaddr:
self._wiimote = cwiid.Wiimote(bdaddr=self._bdaddr)
@ -67,6 +68,7 @@ class WiimoteBackend(Backend):
return self._wiimote
def get_state(self):
import cwiid
wm = self.get_wiimote()
state = wm.state
parsed_state = {}

View File

@ -4,8 +4,6 @@ import json
import time
from threading import Thread, Lock
from Adafruit_IO import Client
from Adafruit_IO.errors import ThrottlingError
from platypush.context import get_backend
from platypush.plugins import Plugin, action
@ -64,6 +62,7 @@ class AdafruitIoPlugin(Plugin):
:type throttle_seconds: float
"""
from Adafruit_IO import Client
global data_throttler_lock
super().__init__(**kwargs)

View File

@ -4,11 +4,6 @@
import os
from avs.auth import auth
from avs.alexa import Alexa
from avs.config import DEFAULT_CONFIG_FILE
from avs.mic import Audio
from platypush.context import get_bus
from platypush.plugins import action
from platypush.plugins.assistant import AssistantPlugin
@ -43,7 +38,7 @@ class AssistantEchoPlugin(AssistantPlugin):
* **avs** (``pip install avs``)
"""
def __init__(self, avs_config_file: str = DEFAULT_CONFIG_FILE, audio_device: str = 'default',
def __init__(self, avs_config_file: str = None, audio_device: str = 'default',
audio_player: str = 'default', **kwargs):
"""
:param avs_config_file: AVS credentials file - default: ~/.avs.json. If the file doesn't exist then
@ -55,9 +50,17 @@ class AssistantEchoPlugin(AssistantPlugin):
:param audio_player: Player to be used for audio playback (default: 'default').
Supported values: 'mpv', 'mpg123', 'gstreamer'
"""
from avs.alexa import Alexa
from avs.config import DEFAULT_CONFIG_FILE
from avs.mic import Audio
super().__init__(**kwargs)
if not avs_config_file:
avs_config_file = DEFAULT_CONFIG_FILE
if not avs_config_file or not os.path.isfile(avs_config_file):
from avs.auth import auth
auth(None, avs_config_file)
self.logger.warning('Amazon Echo assistant credentials not configured. Open http://localhost:3000 ' +
'to authenticate this client')

View File

@ -5,9 +5,6 @@
import json
import os
import googlesamples.assistant.grpc.audio_helpers as audio_helpers
import googlesamples.assistant.grpc.device_helpers as device_helpers
from platypush.context import get_bus
from platypush.message.event.assistant import ConversationStartEvent, \
ConversationEndEvent, SpeechRecognizedEvent, VolumeChangedEvent, \
@ -17,7 +14,6 @@ from platypush.message.event.google import GoogleDeviceOnOffEvent
from platypush.plugins import action
from platypush.plugins.assistant import AssistantPlugin
from platypush.plugins.assistant.google.lib import SampleAssistant
class AssistantGooglePushtotalkPlugin(AssistantPlugin):
@ -40,11 +36,6 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
"""
api_endpoint = 'embeddedassistant.googleapis.com'
audio_sample_rate = audio_helpers.DEFAULT_AUDIO_SAMPLE_RATE
audio_sample_width = audio_helpers.DEFAULT_AUDIO_SAMPLE_WIDTH
audio_iter_size = audio_helpers.DEFAULT_AUDIO_ITER_SIZE
audio_block_size = audio_helpers.DEFAULT_AUDIO_DEVICE_BLOCK_SIZE
audio_flush_size = audio_helpers.DEFAULT_AUDIO_DEVICE_FLUSH_SIZE
grpc_deadline = 60 * 3 + 5
device_handler = None
@ -79,8 +70,15 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
:type play_response: bool
"""
import googlesamples.assistant.grpc.audio_helpers as audio_helpers
super().__init__(**kwargs)
self.audio_sample_rate = audio_helpers.DEFAULT_AUDIO_SAMPLE_RATE
self.audio_sample_width = audio_helpers.DEFAULT_AUDIO_SAMPLE_WIDTH
self.audio_iter_size = audio_helpers.DEFAULT_AUDIO_ITER_SIZE
self.audio_block_size = audio_helpers.DEFAULT_AUDIO_DEVICE_BLOCK_SIZE
self.audio_flush_size = audio_helpers.DEFAULT_AUDIO_DEVICE_FLUSH_SIZE
self.language = language
self.credentials_file = credentials_file
self.device_config = device_config
@ -112,7 +110,9 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
self.conversation_stream = None
def _init_assistant(self):
import googlesamples.assistant.grpc.audio_helpers as audio_helpers
from google.auth.transport.grpc import secure_authorized_channel
self.interactions = []
# Create an authorized gRPC channel.
@ -217,6 +217,8 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
"""
from platypush.plugins.assistant.google.lib import SampleAssistant
if not language:
language = self.language
@ -262,6 +264,7 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
get_bus().post(ConversationEndEvent(assistant=self))
def _install_device_handlers(self):
import googlesamples.assistant.grpc.device_helpers as device_helpers
self.device_handler = device_helpers.DeviceRequestHandler(self.device_id)
@self.device_handler.command('action.devices.commands.OnOff')

View File

@ -6,8 +6,6 @@ import datetime
import dateutil.parser
import requests
from icalendar import Calendar
from platypush.plugins import Plugin, action
from platypush.plugins.calendar import CalendarInterface
@ -68,6 +66,7 @@ class CalendarIcalPlugin(Plugin, CalendarInterface):
"""
import pytz
from icalendar import Calendar
events = []
try:

View File

@ -4,9 +4,6 @@ import os
import subprocess
import time
# noinspection PyPackageRequirements
from PIL import Image
from platypush.plugins import Plugin, action
@ -36,11 +33,7 @@ class CameraIrMlx90640Plugin(Plugin):
"""
_img_size = (32, 24)
_rotate_values = {
90: Image.ROTATE_90,
180: Image.ROTATE_180,
270: Image.ROTATE_270,
}
_rotate_values = {}
def __init__(self, fps=16, skip_frames=2, scale_factor=1, rotate=0, rawrgb_path=None, **kwargs):
"""
@ -53,8 +46,15 @@ class CameraIrMlx90640Plugin(Plugin):
https://github.com/pimoroni/mlx90640-library is in another folder than
`<directory of this file>/lib/examples`.
"""
from PIL import Image
super().__init__(**kwargs)
self._rotate_values = {
90: Image.ROTATE_90,
180: Image.ROTATE_180,
270: Image.ROTATE_270,
}
if not rawrgb_path:
rawrgb_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'lib', 'examples', 'rawrgb')
rawrgb_path = os.path.abspath(os.path.expanduser(rawrgb_path))
@ -121,6 +121,7 @@ class CameraIrMlx90640Plugin(Plugin):
output_file is not set, otherwise a list with the captured image files will be returned.
"""
from PIL import Image
fps = self.fps if fps is None else fps
skip_frames = self.skip_frames if skip_frames is None else skip_frames
scale_factor = self.scale_factor if scale_factor is None else scale_factor
@ -170,6 +171,7 @@ class CameraIrMlx90640Plugin(Plugin):
@staticmethod
def _convert_to_grayscale(image):
from PIL import Image
new_image = Image.new('L', image.size)
for i in range(0, image.size[0]):

View File

@ -1,5 +1,3 @@
import pyperclip
from platypush.plugins import Plugin, action
@ -20,6 +18,7 @@ class ClipboardPlugin(Plugin):
:param text: Text to copy
:type text: str
"""
import pyperclip
pyperclip.copy(text)
@ -28,6 +27,7 @@ class ClipboardPlugin(Plugin):
"""
Get the current content of the clipboard
"""
import pyperclip
return pyperclip.paste()

View File

@ -5,7 +5,6 @@
import os
from platypush.plugins import Plugin
from platypush.plugins.google.credentials import get_credentials
class GooglePlugin(Plugin):
@ -41,6 +40,7 @@ class GooglePlugin(Plugin):
:type scopes: list
"""
from platypush.plugins.google.credentials import get_credentials
super().__init__(*args, **kwargs)
self._scopes = scopes or []

View File

@ -7,8 +7,6 @@ import httplib2
import mimetypes
import os
from apiclient import discovery
from email.encoders import encode_base64
from email.mime.application import MIMEApplication
from email.mime.audio import MIMEAudio

View File

@ -1,5 +1,3 @@
import envirophat
from platypush.plugins import action
from platypush.plugins.gpio.sensor import GpioSensorPlugin
@ -46,6 +44,8 @@ class GpioSensorEnvirophatPlugin(GpioSensorPlugin):
"""
import envirophat
ret = {}
weather = envirophat.weather
light = envirophat.light

View File

@ -2,9 +2,6 @@ import enum
import math
import time
# noinspection PyUnresolvedReferences,PyPackageRequirements
from pmw3901 import PMW3901, BG_CS_FRONT_BCM, BG_CS_BACK_BCM
from platypush.plugins import action
from platypush.plugins.gpio.sensor import GpioSensorPlugin
@ -43,7 +40,9 @@ class GpioSensorMotionPwm3901Plugin(GpioSensorPlugin):
:param spi_port: SPI port (default: 0)
:type spi_slot: int
"""
from pmw3901 import BG_CS_FRONT_BCM, BG_CS_BACK_BCM
super().__init__(**kwargs)
self.spi_port = spi_port
self._sensor = None
self._events_per_sec = {}
@ -70,6 +69,8 @@ class GpioSensorMotionPwm3901Plugin(GpioSensorPlugin):
spi_slot, [s.value for s in SPISlot]))
def _get_sensor(self):
from pmw3901 import PMW3901
if not self._sensor:
self._sensor = PMW3901(spi_port=self.spi_port,
spi_cs=1,

View File

@ -1,5 +1,3 @@
import feedparser
from platypush.plugins import action
from platypush.plugins.http.request import HttpRequestPlugin
@ -14,6 +12,7 @@ class HttpRequestRssPlugin(HttpRequestPlugin):
@action
def get(self, url):
import feedparser
response = super().get(url, output='text').output
feed = feedparser.parse(response)
return feed.entries

View File

@ -2,8 +2,6 @@ import json
import logging
import time
from kafka import KafkaProducer
from platypush.context import get_backend
from platypush.plugins import Plugin, action
@ -47,6 +45,8 @@ class KafkaPlugin(Plugin):
:type server: str
"""
from kafka import KafkaProducer
if not server:
if not self.server:
try:

View File

@ -1,4 +1,3 @@
import pylast
import time
from platypush.plugins import Plugin, action
@ -28,7 +27,9 @@ class LastfmPlugin(Plugin):
:type api_key: str
"""
import pylast
super().__init__()
self.api_key = api_key
self.api_secret = api_secret
self.username = username

View File

@ -1,10 +1,7 @@
import datetime
import re
import pychromecast
import time
from pychromecast.controllers.youtube import YouTubeController
from platypush.context import get_plugin, get_bus
from platypush.plugins import action
from platypush.plugins.media import MediaPlugin
@ -151,6 +148,7 @@ class MediaChromecastPlugin(MediaPlugin):
:type callback: func
"""
import pychromecast
self.chromecasts.update({
cast.device.friendly_name: cast
for cast in pychromecast.get_chromecasts(tries=tries, retry_wait=retry_wait,
@ -193,6 +191,7 @@ class MediaChromecastPlugin(MediaPlugin):
cast.media_controller.register_status_listener(self._media_listeners[name])
def get_chromecast(self, chromecast=None, n_tries=2):
import pychromecast
if isinstance(chromecast, pychromecast.Chromecast):
return chromecast
@ -268,6 +267,7 @@ class MediaChromecastPlugin(MediaPlugin):
:type subtitle_id: int
"""
from pychromecast.controllers.youtube import YouTubeController
if not chromecast:
chromecast = self.chromecast

View File

@ -1,6 +1,3 @@
from plexapi.myplex import MyPlexAccount
from plexapi.video import Movie, Show
from platypush.context import get_plugin
from platypush.plugins import Plugin, action
@ -26,6 +23,7 @@ class MediaPlexPlugin(Plugin):
:type username: str
"""
from plexapi.myplex import MyPlexAccount
super().__init__(*args, **kwargs)
self.resource = MyPlexAccount(username, password).resource(server)
@ -378,6 +376,8 @@ class MediaPlexPlugin(Plugin):
def _flatten_item(self, item):
from plexapi.video import Movie, Show
_item = {
'summary': item.summary,
'title': item.title,

View File

@ -1,4 +1,3 @@
import rtmidi
import time
from platypush.plugins import Plugin, action
@ -23,6 +22,7 @@ class MidiPlugin(Plugin):
:type device_name: str
"""
import rtmidi
super().__init__(*args, **kwargs)
self.device_name = device_name
@ -126,6 +126,7 @@ class MidiPlugin(Plugin):
:returns: dict: A list of the available MIDI ports with index and name
"""
import rtmidi
in_ports = rtmidi.MidiIn().get_ports()
out_ports = rtmidi.MidiOut().get_ports()

View File

@ -1,6 +1,5 @@
import json
import os
import paho.mqtt.publish as publisher
from platypush.message import Message
from platypush.plugins import Plugin, action
@ -105,6 +104,8 @@ class MqttPlugin(Plugin):
:type password: str
"""
import paho.mqtt.publish as publisher
if not host and not self.host:
raise RuntimeError('No host specified and no default host configured')

View File

@ -1,4 +1,3 @@
import mpd
import re
import threading
import time
@ -39,6 +38,8 @@ class MusicMpdPlugin(MusicPlugin):
self.client = None
def _connect(self, n_tries=2):
import mpd
with self._client_lock:
if self.client:
return

View File

@ -2,8 +2,6 @@ import struct
import subprocess
import time
from bluetooth.ble import DiscoveryService, GATTRequester
from platypush.plugins import action
from platypush.plugins.switch import SwitchPlugin
@ -39,6 +37,7 @@ class Scanner(object):
return uuids
def scan(self):
from bluetooth.ble import DiscoveryService
service = DiscoveryService(self.bt_interface) \
if self.bt_interface else DiscoveryService()
@ -62,6 +61,7 @@ class Driver(object):
self.req = None
def connect(self):
from bluetooth.ble import GATTRequester
if self.bt_interface:
self.req = GATTRequester(self.device, False, self.bt_interface)
else:

View File

@ -1,5 +1,3 @@
from pyHS100 import Discover
from platypush.plugins import action
from platypush.plugins.switch import SwitchPlugin
@ -21,6 +19,8 @@ class SwitchTplinkPlugin(SwitchPlugin):
super().__init__(**kwargs)
def _scan(self):
from pyHS100 import Discover
devices = Discover.discover()
self._ip_to_dev = {}
self._alias_to_dev = {}

View File

@ -2,8 +2,6 @@ import os
import subprocess
import tempfile
from google.cloud import texttospeech
from platypush.plugins import Plugin, action
@ -35,7 +33,9 @@ class TtsGooglePlugin(Plugin):
:type credentials_file: str
"""
from google.cloud import texttospeech
super().__init__()
self.language = language
self.voice = voice
@ -84,6 +84,7 @@ class TtsGooglePlugin(Plugin):
:type gender: str
"""
from google.cloud import texttospeech
client = texttospeech.TextToSpeechClient()
synthesis_input = texttospeech.types.SynthesisInput(text=text)
@ -120,4 +121,3 @@ class TtsGooglePlugin(Plugin):
# vim:sw=4:ts=4:et:

View File

@ -15,7 +15,7 @@ pyyaml
# kafka-python
# Pushbullet backend support
git+https://github.com/rbrcsk/pushbullet.py
# git+https://github.com/rbrcsk/pushbullet.py
# HTTP backend support
flask
@ -181,3 +181,6 @@ croniter
# Support for Alexa/Echo voice integrations
# git+https://github.com:BlackLight/avs.git
# Support for clipboard manipulation
# pyperclip

View File

@ -145,9 +145,9 @@ setup(
# Support for Pushbullet backend and plugin
'pushbullet': ['pushbullet.py'],
# Support for HTTP backend
'http': ['flask','websockets', 'python-dateutil', 'tz', 'frozendict', 'bcrypt', 'sqlalchemy'],
'http': ['flask', 'websockets', 'python-dateutil', 'tz', 'frozendict', 'bcrypt', 'sqlalchemy'],
# Support for uWSGI HTTP backend
'uwsgi': ['flask','websockets', 'python-dateutil', 'tz', 'frozendict', 'uwsgi', 'bcrypt', 'sqlalchemy'],
'uwsgi': ['flask', 'websockets', 'python-dateutil', 'tz', 'frozendict', 'uwsgi', 'bcrypt', 'sqlalchemy'],
# Support for database
'db': ['sqlalchemy'],
# Support for MQTT backends