Convert to use poetry & pyproject.toml for dep & build management (#54)

* Convert to use poetry and pyproject.toml, update README

* add some resources for contributors

* minor adjustments

* ci: separate tests from linting, run using poetry

* add pytest-mock to dev requirements

* combine running tests and reporting to codecov

* generate both xml and html coverage reports

* add codecov to dev dependencies
This commit is contained in:
Teemu R 2020-05-12 12:11:47 +02:00 committed by GitHub
parent c6d76836d7
commit ed57563e8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 296 additions and 312 deletions

8
.flake8 Normal file
View File

@ -0,0 +1,8 @@
[flake8]
exclude = .git,.tox,__pycache__,kasa/tests/newfakes.py,kasa/tests/test_fixtures.py
max-line-length = 88
per-file-ignores =
kasa/tests/*.py:D100,D101,D102,D103,D104
setup.py:D100
ignore = D105, D107, E203, E501, W503
max-complexity = 18

View File

@ -26,11 +26,11 @@ repos:
- id: flake8 - id: flake8
additional_dependencies: [flake8-docstrings] additional_dependencies: [flake8-docstrings]
- repo: https://github.com/pre-commit/mirrors-isort - repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21 rev: v4.3.21
hooks: hooks:
- id: isort - id: isort
additional_dependencies: [toml]
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.740 rev: v0.740

View File

@ -1,50 +0,0 @@
####################################################
# Use python 3.x and the latest version of alpine #
####################################################
FROM python:3-alpine
LABEL maintainer=peter@grainger.xyz
###################################################
# Add all system packages relied upon by python #
###################################################
RUN apk update && \
apk add --no-cache gcc \
libffi-dev \
openssl-dev \
libxslt-dev \
libxml2-dev \
musl-dev \
linux-headers
###################################################
# Create somewhere to put the files #
###################################################
RUN mkdir -p /opt/python-kasa
WORKDIR /opt/python-kasa
###################################################
# Requirements file first to help cache #
###################################################
COPY requirements.txt .
RUN pip install -r requirements.txt
###################################################
# Install dev dependancies #
###################################################
RUN pip install pytest pytest-cov voluptuous typing
###################################################
# Copy over the rest. #
###################################################
COPY ./ ./
###################################################
# Install everything to the path #
###################################################
RUN python setup.py install
###################################################
# Run tests #
###################################################
CMD pytest

146
README.md
View File

@ -3,9 +3,10 @@
[![PyPI version](https://badge.fury.io/py/python-kasa.svg)](https://badge.fury.io/py/python-kasa) [![PyPI version](https://badge.fury.io/py/python-kasa.svg)](https://badge.fury.io/py/python-kasa)
[![Build Status](https://dev.azure.com/python-kasa/python-kasa/_apis/build/status/python-kasa.python-kasa?branchName=master)](https://dev.azure.com/python-kasa/python-kasa/_build/latest?definitionId=2&branchName=master) [![Build Status](https://dev.azure.com/python-kasa/python-kasa/_apis/build/status/python-kasa.python-kasa?branchName=master)](https://dev.azure.com/python-kasa/python-kasa/_build/latest?definitionId=2&branchName=master)
[![Coverage Status](https://coveralls.io/repos/github/python-kasa/python-kasa/badge.svg?branch=master)](https://coveralls.io/github/python-kasa/python-kasa?branch=master) [![Coverage Status](https://coveralls.io/repos/github/python-kasa/python-kasa/badge.svg?branch=master)](https://coveralls.io/github/python-kasa/python-kasa?branch=master)
[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
Python Library to control TPLink smart plugs/switches and smart bulbs. python-kasa is a Python library to control TPLink smart home devices (plugs, wall switches, power strips, and bulbs) using asyncio.
This project is a maintainer-made fork of [pyHS100](https://github.com/GadgetReactor/pyHS100) project.
**Supported devices** **Supported devices**
@ -13,6 +14,7 @@ Python Library to control TPLink smart plugs/switches and smart bulbs.
* HS100 * HS100
* HS103 * HS103
* HS105 * HS105
* HS107
* HS110 * HS110
* Power Strips * Power Strips
* HS300 * HS300
@ -32,6 +34,9 @@ Python Library to control TPLink smart plugs/switches and smart bulbs.
* KL120 * KL120
* KL130 * KL130
**Contributions (be it adding missing features, fixing bugs or improving documentation) are more than welcome, feel free to submit pull requests! See below for instructions for setting up a development environment.**
# Usage # Usage
The package is shipped with a console tool named kasa, please refer to ```kasa --help``` for detailed usage. The package is shipped with a console tool named kasa, please refer to ```kasa --help``` for detailed usage.
@ -82,7 +87,7 @@ All devices support a variety of common commands, including:
* `state` which returns state information * `state` which returns state information
* `on` and `off` for turning the device on or off * `on` and `off` for turning the device on or off
* `emeter` (where applicable) to return energy consumption information * `emeter` (where applicable) to return energy consumption information
* `sysinfo` to return raw system information which is used by e.g. `state`, useful for debugging and when adding support for new device types * `sysinfo` to return raw system information
## Energy meter ## Energy meter
@ -96,128 +101,95 @@ $ kasa emeter
Current state: {'total': 133.105, 'power': 108.223577, 'current': 0.54463, 'voltage': 225.296283} Current state: {'total': 133.105, 'power': 108.223577, 'current': 0.54463, 'voltage': 225.296283}
``` ```
## Plug-specific commands
At the moment only switching the state of the LED is implemented.
**Feel free to submit patches as pull requests for further features!**
### Controlling the LED
`led` command can be used to control whether the LED light on front of the plug is on or off.
```
$ kasa --plug led
LED state: False
$ kasa --plug led 1
Turning led to True
```
## Bulb-specific commands ## Bulb-specific commands
At the moment setting brightness, color temperature and color (in HSV) is supported. At the moment setting brightness, color temperature and color (in HSV) are supported depending on the device.
The commands are straightforward, so feel free to check `--help` for instructions how to use them. The commands are straightforward, so feel free to check `--help` for instructions how to use them.
**Feel free to submit patches as pull requests to add more functionality (e.g. scenes)!**
# Library usage # Library usage
The public API is well documented, but here are some examples to get you started. The property accesses use the data obtained before by awaiting `update()`.
For all available API functions run ```help(SmartPlug)``` or ```help(SmartBulb)```. The values are cached until the next update call.
Each method changing the state of the device will automatically update the cached state.
Errors are raised as `SmartDeviceException` instances for the user to handle.
## Discovering devices ## Discovering devices
`Discover` class' `discover()` can be used to discover supported devices, `Discover.discover()` can be used to discover supported devices in the local network.
which returns a dictionary keyed with the IP address whose value hold a ready-to-use instance of the detected device type. The return value is a dictionary keyed with the IP address and the value holds a ready-to-use instance of the detected device type.
Example: Example:
```python ```python
import asyncio
from kasa import Discover from kasa import Discover
for dev in Discover.discover().values(): devices = asyncio.run(Discover.discover())
print(dev) for addr, dev in devices.items():
asyncio.run(dev.update())
print(f"{addr} >> {dev}")
``` ```
``` ```
$ python3 example.py $ python example.py
<SmartPlug at 192.168.XXX.XXX (My Smart Plug), is_on: True - dev specific: {'LED state': True, 'On since': datetime.datetime(2017, 3, 26, 18, 29, 17, 52073)}> <SmartPlug at 192.168.XXX.XXX (My Smart Plug), is_on: True - dev specific: {'LED state': True, 'On since': datetime.datetime(2017, 3, 26, 18, 29, 17, 52073)}>
``` ```
## Querying basic information ## Querying basic information
*Please note that most property getters do I/O (e.g. fetching the system information) on each call.
If you want to avoid unnecessary communication with the device please use `get_sysinfo` and handle parsing of information by yourself.*
```python ```python
from kasa import SmartPlug, SmartBulb import asyncio
from kasa import SmartPlug
from pprint import pformat as pf from pprint import pformat as pf
plug = SmartPlug("192.168.XXX.XXX") plug = SmartPlug("192.168.XXX.XXX")
asyncio.run(plug.update())
print("Hardware: %s" % pf(plug.hw_info)) print("Hardware: %s" % pf(plug.hw_info))
print("Full sysinfo: %s" % pf(plug.get_sysinfo())) # this prints lots of information about the device print("Full sysinfo: %s" % pf(plug.sys_info))
``` ```
The rest of the examples assume that you have initialized an instance.
## State & switching ## State & switching
Devices can be turned on and off by either calling appropriate methods on the device object, Devices can be turned on and off by either calling appropriate methods on the device object.
or by assigning a new state to `state` property.
```python ```python
print("Current state: %s" % plug.state) print("Current state: %s" % plug.is_on)
plug.turn_off() await plug.turn_off()
plug.turn_on() await plug.turn_on()
```
```python
plug.state = "ON"
plug.state = "OFF"
```
## Time information
```python
print("Current time: %s" % plug.time)
print("Timezone: %s" % plug.timezone)
```
## Getting and setting the name
```python
print("Alias: %s" % plug.alias)
plug.alias = "My New Smartplug"
``` ```
## Getting emeter status (if applicable) ## Getting emeter status (if applicable)
```python ```python
print("Current consumption: %s" % plug.get_emeter_realtime()) print("Current consumption: %s" % await plug.get_emeter_realtime())
print("Per day: %s" % plug.get_emeter_daily(year=2016, month=12)) print("Per day: %s" % await plug.get_emeter_daily(year=2016, month=12))
print("Per month: %s" % plug.get_emeter_monthly(year=2016)) print("Per month: %s" % await plug.get_emeter_monthly(year=2016))
``` ```
## Plug-specific ## Bulb and dimmer-specific APIs
### Switching the led (plugs only)
```python
print("Current LED state: %s" % plug.led)
plug.led = False # turn off led
print("New LED state: %s" % plug.led)
```
## Bulb-specific API
The bulb API is likewise straightforward, so please refer to its API documentation. The bulb API is likewise straightforward, so please refer to its API documentation.
Information about supported features can be queried by using properties prefixed with `is_`, e.g. `is_dimmable`. Information about supported features can be queried by using properties prefixed with `is_`, e.g. `is_dimmable`.
### Setting the brightness ### Setting the brightness
The `brightness` property works in percentages.
```python ```python
print(bulb.brightness) import asyncio
from kasa import SmartBulb
bulb = SmartBulb("192.168.1.123")
asyncio.run(bulb.update())
if bulb.is_dimmable: if bulb.is_dimmable:
bulb.brightness = 100 asyncio.run(bulb.set_brightness(100))
print(bulb.brightness)
``` ```
### Setting the color temperature ### Setting the color temperature
```python ```python
print(bulb.color_temp)
if bulb.is_variable_color_temp: if bulb.is_variable_color_temp:
bulb.color_temp = 3000 await bulb.set_color_temp(3000)
print(bulb.color_temp)
``` ```
### Setting the color ### Setting the color
@ -225,19 +197,29 @@ if bulb.is_variable_color_temp:
Hue is given in degrees (0-360) and saturation and value in percentage. Hue is given in degrees (0-360) and saturation and value in percentage.
```python ```python
print(bulb.hsv)
if bulb.is_color: if bulb.is_color:
bulb.hsv = (180, 100, 100) # set to cyan await bulb.set_hsv(180, 100, 100) # set to cyan
print(bulb.hsv)
``` ```
## Development Setup ## Contributing
### Docker Contributions are very welcome! To simplify the process, we are leveraging automated checks and tests for contributions.
The following assumes you have a working installation of Docker. ### Resources
Set up the environment and run the tests on demand. * [softScheck's github contains lot of information and wireshark dissector](https://github.com/softScheck/tplink-smartplug#wireshark-dissector)
* [https://github.com/plasticrake/tplink-smarthome-simulator](tplink-smarthome-simulator)
```shell ### Setting up development environment
docker build . -t kasa && docker run -v $(PWD)/kasa/tests:/opt/python-kasa/kasa/tests kasa pytest
```bash
poetry install
pre-commit install
``` ```
### Code-style checks
We use several tools to automatically check all contributions, which are run automatically when you commit your code.
If you want to manually execute the checks, you can run `tox -e lint` to do the linting checks or `tox` to also execute the tests.

View File

@ -3,93 +3,116 @@ trigger:
pr: pr:
- master - master
strategy:
matrix:
Python 3.7 Ubuntu:
python.version: '3.7'
vmImage: 'ubuntu-latest'
Python 3.8 Ubuntu:
python.version: '3.8'
vmImage: 'ubuntu-latest'
# PyPy Ubuntu:
# python.version: pypy3
# vmImage: 'ubuntu-latest'
Python 3.7 Windows:
python.version: '3.7'
vmImage: 'windows-latest'
Python 3.8 Windows:
python.version: '3.8'
vmImage: 'windows-latest'
Python 3.7 OSX:
python.version: '3.7'
vmImage: 'macOS-latest'
Python 3.8 OSX:
python.version: '3.8'
vmImage: 'macOS-latest'
pool: stages:
- stage: "Linting"
jobs:
- job: "LintChecks"
pool:
vmImage: "ubuntu-latest"
strategy:
matrix:
Python 3.8:
python.version: '3.8'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(python.version)'
displayName: 'Use Python $(python.version)'
- script: |
python -m pip install --upgrade pip poetry
poetry install
displayName: 'Install dependencies'
- script: |
poetry run pre-commit run black --all-files
displayName: 'Code formating (black)'
- script: |
poetry run pre-commit run flake8 --all-files
displayName: 'Code formating (flake8)'
- script: |
poetry run pre-commit run mypy --all-files
displayName: 'Typing checks (mypy)'
- script: |
poetry run pre-commit run isort --all-files
displayName: 'Order of imports (isort)'
- script: |
poetry run pre-commit run trailing-whitespace --all-files
displayName: 'Run trailing-whitespace'
- script: |
poetry run pre-commit run end-of-file-fixer --all-files
displayName: 'Run end-of-file-fixer'
- script: |
poetry run pre-commit run check-docstring-first --all-files
displayName: 'Run check-docstring-first'
- script: |
poetry run pre-commit run check-yaml --all-files
displayName: 'Run check-yaml'
- script: |
poetry run pre-commit run debug-statements --all-files
displayName: 'Run debug-statements'
- script: |
poetry run pre-commit run check-ast --all-files
displayName: 'Run check-ast'
- stage: "Tests"
jobs:
- job: "Tests"
strategy:
matrix:
Python 3.7 Ubuntu:
python.version: '3.7'
vmImage: 'ubuntu-latest'
Python 3.8 Ubuntu:
python.version: '3.8'
vmImage: 'ubuntu-latest'
Python 3.7 Windows:
python.version: '3.7'
vmImage: 'windows-latest'
Python 3.8 Windows:
python.version: '3.8'
vmImage: 'windows-latest'
Python 3.7 OSX:
python.version: '3.7'
vmImage: 'macOS-latest'
Python 3.8 OSX:
python.version: '3.8'
vmImage: 'macOS-latest'
pool:
vmImage: $(vmImage) vmImage: $(vmImage)
steps: steps:
- task: UsePythonVersion@0 - task: UsePythonVersion@0
inputs: inputs:
versionSpec: '$(python.version)' versionSpec: '$(python.version)'
displayName: 'Use Python $(python.version)' displayName: 'Use Python $(python.version)'
- script: | - script: |
python -m pip install --upgrade pip python -m pip install --upgrade pip poetry
pip install -r requirements.txt poetry install
pip install -r requirements_test.txt displayName: 'Install dependencies'
displayName: 'Install dependencies'
- script: | - script: |
pre-commit run black --all-files poetry run pytest --cov kasa --cov-report=xml --cov-report=html
displayName: 'Code formating (black)' displayName: 'Run tests'
- script: | - script: |
pre-commit run flake8 --all-files poetry run codecov -t $(codecov.token)
displayName: 'Code formating (flake8)' displayName: 'Report code coverage'
- script: |
pre-commit run mypy --all-files
displayName: 'Typing checks (mypy)'
- script: |
pre-commit run isort --all-files
displayName: 'Order of imports (isort)'
- script: |
pre-commit run trailing-whitespace --all-files
displayName: 'Run trailing-whitespace'
- script: |
pre-commit run end-of-file-fixer --all-files
displayName: 'Run end-of-file-fixer'
- script: |
pre-commit run check-docstring-first --all-files
displayName: 'Run check-docstring-first'
- script: |
pre-commit run check-yaml --all-files
displayName: 'Run check-yaml'
- script: |
pre-commit run debug-statements --all-files
displayName: 'Run debug-statements'
- script: |
pre-commit run check-ast --all-files
displayName: 'Run check-ast'
- script: |
pre-commit run isort --all-files
displayName: 'Order of imports (isort)'
- script: |
pytest --cov kasa --cov-report xml
displayName: 'Tests'
- script: |
codecov -t $(codecov.token)
displayName: Report Coverage to codecov

View File

@ -11,6 +11,7 @@ For device type specific actions `SmartBulb`, `SmartPlug`, or `SmartStrip`
Module-specific errors are raised as `SmartDeviceException` and are expected Module-specific errors are raised as `SmartDeviceException` and are expected
to be handled by the user of the library. to be handled by the user of the library.
""" """
from importlib_metadata import version # type: ignore
from kasa.discover import Discover from kasa.discover import Discover
from kasa.protocol import TPLinkSmartHomeProtocol from kasa.protocol import TPLinkSmartHomeProtocol
from kasa.smartbulb import SmartBulb from kasa.smartbulb import SmartBulb
@ -19,6 +20,9 @@ from kasa.smartdimmer import SmartDimmer
from kasa.smartplug import SmartPlug from kasa.smartplug import SmartPlug
from kasa.smartstrip import SmartStrip from kasa.smartstrip import SmartStrip
__version__ = version("python-kasa")
__all__ = [ __all__ = [
"Discover", "Discover",
"TPLinkSmartHomeProtocol", "TPLinkSmartHomeProtocol",

View File

@ -7,6 +7,7 @@ from pprint import pformat as pf
from typing import cast from typing import cast
import asyncclick as click import asyncclick as click
from kasa import Discover, SmartBulb, SmartDevice, SmartPlug, SmartStrip from kasa import Discover, SmartBulb, SmartDevice, SmartPlug, SmartStrip
click.anyio_backend = "asyncio" click.anyio_backend = "asyncio"

View File

@ -23,7 +23,7 @@ TPLINK_KELVIN = {
class SmartBulb(SmartDevice): class SmartBulb(SmartDevice):
"""Representation of a TP-Link Smart Bulb. """Representation of a TP-Link Smart Bulb.
Usage example when used as library: Usage example:
```python ```python
p = SmartBulb("192.168.1.105") p = SmartBulb("192.168.1.105")
await p.update() await p.update()
@ -33,6 +33,7 @@ class SmartBulb(SmartDevice):
# change state of bulb # change state of bulb
await p.turn_on() await p.turn_on()
assert p.is_on
await p.turn_off() await p.turn_off()
# query and print current state of plug # query and print current state of plug
@ -40,12 +41,11 @@ class SmartBulb(SmartDevice):
# check whether the bulb supports color changes # check whether the bulb supports color changes
if p.is_color: if p.is_color:
print("we got color!")
# set the color to an HSV tuple # set the color to an HSV tuple
await p.set_hsv(180, 100, 100) await p.set_hsv(180, 100, 100)
# get the current HSV value
# get the current HSV value print(p.hsv)
print(p.hsv)
# check whether the bulb supports setting color temperature # check whether the bulb supports setting color temperature
if p.is_variable_color_temp: if p.is_variable_color_temp:
@ -57,12 +57,11 @@ class SmartBulb(SmartDevice):
# check whether the bulb is dimmable # check whether the bulb is dimmable
if p.is_dimmable: if p.is_dimmable:
# set the bulb to 50% brightness
await p.set_brightness(50)
# set the bulb to 50% brightness # check the current brightness
await p.set_brightness(50) print(p.brightness)
# check the current brightness
print(p.brightness)
``` ```
Errors reported by the device are raised as SmartDeviceExceptions, Errors reported by the device are raised as SmartDeviceExceptions,

View File

@ -10,7 +10,7 @@ _LOGGER = logging.getLogger(__name__)
class SmartPlug(SmartDevice): class SmartPlug(SmartDevice):
"""Representation of a TP-Link Smart Switch. """Representation of a TP-Link Smart Switch.
Usage example when used a a synchronous library: Usage example:
```python ```python
p = SmartPlug("192.168.1.105") p = SmartPlug("192.168.1.105")
@ -19,9 +19,10 @@ class SmartPlug(SmartDevice):
# change state of plug # change state of plug
await p.turn_on() await p.turn_on()
assert p.is_on is True
await p.turn_off() await p.turn_off()
# query and print current state of plug # print current state of plug
print(p.state_information) print(p.state_information)
``` ```

View File

@ -4,7 +4,7 @@ import json
import os import os
from os.path import basename from os.path import basename
import pytest import pytest # type: ignore # see https://github.com/pytest-dev/pytest/issues/3342
from kasa import Discover, SmartBulb, SmartDimmer, SmartPlug, SmartStrip from kasa import Discover, SmartBulb, SmartDimmer, SmartPlug, SmartStrip

View File

@ -1,7 +1,16 @@
import logging import logging
import re import re
from voluptuous import REMOVE_EXTRA, All, Any, Coerce, Invalid, Optional, Range, Schema from voluptuous import ( # type: ignore
REMOVE_EXTRA,
All,
Any,
Coerce,
Invalid,
Optional,
Range,
Schema,
)
from ..protocol import TPLinkSmartHomeProtocol from ..protocol import TPLinkSmartHomeProtocol

View File

@ -1,6 +1,6 @@
import pytest import pytest
from asyncclick.testing import CliRunner from asyncclick.testing import CliRunner
from kasa import SmartDevice from kasa import SmartDevice
from kasa.cli import alias, brightness, emeter, raw_command, state, sysinfo from kasa.cli import alias, brightness, emeter, raw_command, state, sysinfo

View File

@ -2,7 +2,7 @@ import asyncio
from datetime import datetime from datetime import datetime
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342
from kasa import DeviceType, SmartDeviceException, SmartStrip from kasa import DeviceType, SmartDeviceException, SmartStrip

View File

@ -1,2 +0,0 @@
# flake8: noqa
__version__ = "0.4.0.dev0"

57
pyproject.toml Normal file
View File

@ -0,0 +1,57 @@
[tool.poetry]
name = "python-kasa"
version = "0.4.0.dev0"
description = "Python API for TP-Link Kasa Smarthome devices"
license = "GPL-3.0-or-later"
authors = ["Your Name <you@example.com>"]
repository = "https://github.com/python-kasa/python-kasa"
readme = "README.md"
packages = [
{ include = "kasa" }
]
[tool.poetry.scripts]
kasa = "kasa.cli:cli"
[tool.poetry.dependencies]
python = "^3.7"
importlib-metadata = "*"
asyncclick = "^7"
[tool.poetry.dev-dependencies]
pytest = "^5"
pytest-azurepipelines = "^0.8"
pytest-cov = "^2.8"
pytest-asyncio = "^0.11"
pytest-sugar = "*"
pre-commit = "*"
voluptuous = "*"
toml = "*"
tox = "*"
pytest-mock = "^3.1.0"
codecov = "^2.0"
[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
line_length = 88
known_first_party = "kasa"
known_third_party = ["asyncclick", "pytest", "setuptools", "voluptuous"]
[tool.coverage.run]
source = ["kasa"]
branch = true
omit = ["kasa/cli.py", "kasa/tests/*"]
[tool.coverage.report]
exclude_lines = [
# ignore abstract methods
"raise NotImplementedError",
"def __repr__"
]
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

View File

@ -1,3 +0,0 @@
asyncclick
pre-commit
voluptuous

View File

@ -1,8 +0,0 @@
pytest
pytest-azurepipelines
pytest-cov
pytest-asyncio
pytest-mock
asyncclick
voluptuous
codecov

View File

@ -1,19 +0,0 @@
from setuptools import setup
with open("kasa/version.py") as f:
exec(f.read())
setup(
name="python-kasa",
version=__version__, # type: ignore # noqa: F821
description="Python API for TP-Link Kasa Smarthome products",
url="https://github.com/python-kasa/python-kasa",
author="",
author_email="",
license="GPLv3",
packages=["kasa"],
install_requires=["asyncclick"],
python_requires=">=3.7",
entry_points={"console_scripts": ["kasa=kasa.cli:cli"]},
zip_safe=False,
)

72
tox.ini
View File

@ -1,16 +1,35 @@
[tox] [tox]
envlist=py37,py38,flake8,linting,typing envlist=py37,py38,flake8,lint,coverage
skip_missing_interpreters = True skip_missing_interpreters = True
isolated_build = True
[tox:travis]
3.7 = py37
3.8 = py38
[testenv] [testenv]
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH whitelist_externals =
deps = -r{toxinidir}/requirements_test.txt poetry
commands= coverage
pytest --cov --cov-config=tox.ini kasa commands =
poetry install -v
poetry run pytest --cov kasa/tests/
[testenv:clean]
deps = coverage
skip_install = true
commands = coverage erase
[testenv:py37]
commands = coverage run -m pytest {posargs}
[testenv:py38]
commands = coverage run -m pytest {posargs}
[testenv:coverage]
basepython = python3.8
skip_install = true
deps = coverage[toml]
commands =
coverage report
coverage html
[testenv:flake8] [testenv:flake8]
deps= deps=
@ -18,44 +37,7 @@ deps=
flake8-docstrings flake8-docstrings
commands=flake8 kasa commands=flake8 kasa
[testenv:typing]
skip_install=true
deps=mypy
commands=mypy --ignore-missing-imports kasa
[flake8]
exclude = .git,.tox,__pycache__,kasa/tests/newfakes.py,kasa/tests/test_fixtures.py
max-line-length = 88
per-file-ignores =
kasa/tests/*.py:D100,D101,D102,D103,D104
setup.py:D100
ignore = D105, D107, E203, E501, W503
#ignore = E203, E266, E501, W503, F403, F401
#max-complexity = 18
#select = B,C,E,F,W,T4,B9
[testenv:lint] [testenv:lint]
deps = pre-commit deps = pre-commit
skip_install = true skip_install = true
commands = pre-commit run --all-files commands = pre-commit run --all-files
[coverage:run]
source = kasa
branch = True
omit =
kasa/tests/*
[coverage:report]
exclude_lines =
# ignore abstract methods
raise NotImplementedError
def __repr__
[isort]
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88
known_first_party=kasa
known_third_party=click,pytest,setuptools,voluptuous