Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"rebaseWhen": "behind-base-branch",
"extends": [
"config:recommended"
],
"pre-commit": {
"enabled": true
}
}
29 changes: 15 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,29 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.9', '3.8', '3.7']
python-version: ['3.13', '3.12', '3.11', '3.10']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: |
pip install -r requirements-test.txt
run: uv sync --locked --all-extras --dev
- name: Test
run: python -m pytest test.py
run: uv run pytest test.py
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.10
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: |
pip install -r requirements-test.txt
- name: Lint
run: flake8 haaska.py
run: uv sync --locked --all-extras --dev
- uses: pre-commit/[email protected]
111 changes: 9 additions & 102 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,105 +1,12 @@
# Byte-compiled / optimized / DLL files
# Python specific
__pycache__/
*.py[cod]
*$py.class
/.mypy_cache/
/.ruff_cache/

# C extensions
*.so
.noseids
# Distribution / packaging
.vscode/
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtualenvs
.venv/

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# dotenv
.env

# virtualenv
.venv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

config/*
build
.DS_Store
haaska.zip
/.vs
/.idea/
# Project ignored
/config/
!/config/config.json.sample
/haaska.zip
8 changes: 8 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[env]
PROJECT_NAME = "{{ config_root | basename }}"
_.python.venv = { path = ".venv", create = true }

[tasks.install]
description = "Install dependencies"
alias = "i"
run = "uv sync --locked --all-extras --dev"
26 changes: 26 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-added-large-files
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
hooks:
- id: isort
additional_dependencies: [toml]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.16.1
hooks:
- id: mypy
additional_dependencies: [types-requests]
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.12.9'
hooks:
- id: ruff
args:
- '--fix'
- id: ruff-format
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13.7
17 changes: 0 additions & 17 deletions Dockerfile

This file was deleted.

38 changes: 20 additions & 18 deletions haaska.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
import json
import logging
import os

import requests

logger = logging.getLogger()
Expand All @@ -35,15 +36,15 @@ def __init__(self, config):

self.session = requests.Session()
self.session.headers = {
'Authorization': f'Bearer {config.bearer_token}',
'content-type': 'application/json',
'User-Agent': self.get_user_agent()
"Authorization": f"Bearer {config.bearer_token}",
"content-type": "application/json",
"User-Agent": self.get_user_agent(),
}
self.session.verify = config.ssl_verify
self.session.cert = config.ssl_client

def build_url(self, endpoint):
return f'{self.config.url}/api/{endpoint}'
return f"{self.config.url}/api/{endpoint}"

def get_user_agent(self):
library = "Home Assistant Alexa Smart Home Skill"
Expand All @@ -59,16 +60,17 @@ def get(self, endpoint):
def post(self, endpoint, data, wait=False):
read_timeout = None if wait else 0.01
try:
logger.debug(f'calling {endpoint} with {data}')
r = self.session.post(self.build_url(endpoint),
data=json.dumps(data),
timeout=(None, read_timeout))
logger.debug(f"calling {endpoint} with {data}")
r = self.session.post(
self.build_url(endpoint),
data=json.dumps(data),
timeout=(None, read_timeout),
)
r.raise_for_status()
return r.json()
except requests.exceptions.ReadTimeout:
# Allow response timeouts after request was sent
logger.debug(
f'request for {endpoint} sent without waiting for response')
logger.debug(f"request for {endpoint} sent without waiting for response")
return None


Expand All @@ -82,11 +84,11 @@ def __init__(self, filename=None, opts_dict=None):
if opts_dict is not None:
self._json = opts_dict

self.url = self.get_url(self.get(['url', 'ha_url']))
self.ssl_verify = self.get(['ssl_verify', 'ha_cert'], default=True)
self.bearer_token = self.get(['bearer_token'], default='')
self.ssl_client = self.get(['ssl_client'], default='')
self.debug = self.get(['debug'], default=False)
self.url = self.get_url(self.get(["url", "ha_url"]))
self.ssl_verify = self.get(["ssl_verify", "ha_cert"], default=True)
self.bearer_token = self.get(["bearer_token"], default="")
self.ssl_client = self.get(["ssl_client"], default="")
self.debug = self.get(["debug"], default=False)

def get(self, keys, default=None):
for key in keys:
Expand All @@ -103,9 +105,9 @@ def get_url(self, url):


def event_handler(event, context):
config = Configuration('config.json')
config = Configuration("config.json")
if config.debug:
logger.setLevel(logging.DEBUG)
ha = HomeAssistant(config)

return ha.post('alexa/smart_home', event, wait=True)
return ha.post("alexa/smart_home", event, wait=True)
14 changes: 14 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[project]
name = "haaska"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"requests>=2.32.5",
]

[dependency-groups]
dev = [
"pytest>=8.4.1",
]
3 changes: 0 additions & 3 deletions requirements-test.txt

This file was deleted.

1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

28 changes: 15 additions & 13 deletions test.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import os

import pytest

from haaska import HomeAssistant, Configuration
from haaska import Configuration, HomeAssistant


@pytest.fixture
def configuration():
return Configuration(opts_dict={
"url": "http://localhost:8123",
"bearer_token": "",
"debug": False,
"ssl_verify": True,
"ssl_client": []
})
return Configuration(
opts_dict={
"url": "http://localhost:8123",
"bearer_token": "",
"debug": False,
"ssl_verify": True,
"ssl_client": [],
}
)


@pytest.fixture
Expand All @@ -28,7 +31,9 @@ def test_ha_build_url(home_assistant):
def test_get_user_agent(home_assistant):
os.environ["AWS_DEFAULT_REGION"] = "test"
user_agent = home_assistant.get_user_agent()
assert user_agent.startswith("Home Assistant Alexa Smart Home Skill - test - python-requests/")
assert user_agent.startswith(
"Home Assistant Alexa Smart Home Skill - test - python-requests/"
)


def test_config_get(configuration):
Expand All @@ -38,10 +43,7 @@ def test_config_get(configuration):


def test_config_get_url(configuration):
test_urls = [
"http://hass.example.com:8123",
"http://hass.example.app"
]
test_urls = ["http://hass.example.com:8123", "http://hass.example.app"]
for expected_url in test_urls:
assert configuration.get_url(expected_url + "/") == expected_url
assert configuration.get_url(expected_url + "/api") == expected_url
Expand Down
Loading
Loading