Skip to content

Commit

Permalink
chore: ci fixups and poetry update
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewthetechie committed May 5, 2024
1 parent cb862fa commit d0b9860
Show file tree
Hide file tree
Showing 24 changed files with 831 additions and 1,028 deletions.
3 changes: 1 addition & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ updates:
directory: "/docs"
schedule:
interval: daily
commit-message:
commit-message:
prefix: docs
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
commit-message:
prefix: deps

10 changes: 5 additions & 5 deletions .github/workflows/constraints.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pip==23.1.2
nox==2023.4.22
nox-poetry==1.0.2
poetry==1.5.1
virtualenv==20.23.1
pip==24.0.0
nox==2024.4.15
nox-poetry==1.0.3
poetry==1.8.2
virtualenv==20.26.1
toml==0.10.2
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
payload = sys.version.encode() + sys.executable.encode()
digest = hashlib.sha256(payload).hexdigest()
result = "${{ runner.os }}-{}-{}-pre-commit".format(python, digest[:8])
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
fh.write(f"result={result}\n")
Expand Down
53 changes: 27 additions & 26 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
exclude: ".*tests\/fixtures.*"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.3
hooks:
# Run the linter.
- id: ruff
args: [ --fix ]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/rhysd/actionlint
rev: v1.6.27
hooks:
- id: actionlint-docker
name: Actionlint
- repo: local
hooks:
- id: black
name: black
entry: black
- id: bandit
name: bandit
entry: bandit
language: system
types: [python]
require_serial: true
args: ["-c", "pyproject.toml"]
- id: check-added-large-files
name: Check for added large files
entry: check-added-large-files
Expand All @@ -27,38 +50,16 @@ repos:
language: system
types: [text]
stages: [commit, push, manual]
- id: flake8
name: flake8
entry: flake8
language: system
types: [python]
exclude: "^(test/*|examples/*|noxfile.py)"
require_serial: true
args: ["--config=.flake8"]
- id: pyupgrade
name: pyupgrade
description: Automatically upgrade syntax for newer versions.
entry: pyupgrade
language: system
types: [python]
args: [--py37-plus]
- id: reorder-python-imports
name: Reorder python imports
entry: reorder-python-imports
language: system
types: [python]
args: [--application-directories=src]
args: [--py311-plus]
- id: trailing-whitespace
name: Trim Trailing Whitespace
entry: trailing-whitespace-fixer
language: system
types: [text]
stages: [commit, push, manual]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
- id: prettier
- repo: https://github.com/rhysd/actionlint
rev: v1.6.15
hooks:
- id: actionlint-docker
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Sphinx configuration."""

from datetime import datetime


Expand Down
6 changes: 3 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Nox sessions."""

import os
import shlex
import shutil
Expand All @@ -23,15 +24,14 @@


package = "healthchecks_io"
python_versions = ["3.10", "3.11", "3.9", "3.8", "3.7"]
python_versions = ["3.10", "3.11", "3.9", "3.8"]
nox.needs_version = ">= 2021.6.6"
nox.options.sessions = (
"pre-commit",
"bandit",
"safety",
"mypy",
"tests",
# "typeguard",
"xdoctest",
"docs-build",
)
Expand Down Expand Up @@ -59,7 +59,7 @@ def activate_virtualenv_in_precommit_hooks(session: Session) -> None:
Args:
session: The Session object.
"""
assert session.bin is not None # noqa: S101
assert session.bin is not None # nosec: B101

# Only patch hooks containing a reference to this session's bindir. Support
# quoting rules for Python and bash, but strip the outermost quotes so we
Expand Down
1,344 changes: 640 additions & 704 deletions poetry.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ classifiers = [
Changelog = "https://github.com/andrewthetechie/py-healthchecks.io/releases"

[tool.poetry.dependencies]
python = "^3.7"
python = "^3.8"
pydantic = "^1.9.1"
httpx = ">=0.23.0,<0.25.0"
croniter = "^1.1.0"
Expand Down Expand Up @@ -67,6 +67,9 @@ source = ["healthchecks_io"]
show_missing = true
fail_under = 100

[tool.bandit]
exclude_dirs = ["tests", "noxfile.py", ".github/scripts", "test_errbot", "dist"]

[tool.mypy]
strict = true
warn_unreachable = true
Expand All @@ -84,4 +87,4 @@ addopts = "-n 4 --ignore examples --cov=healthchecks_io --cov-report xml:.covera

[tool.ruff]
line-length = 120
target-version = "py37"
target-version = "py38"
1 change: 1 addition & 0 deletions src/healthchecks_io/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Py Healthchecks.Io."""

# set by poetry-dynamic-versioning
__version__ = "0.4.0" # noqa: E402

Expand Down
1 change: 1 addition & 0 deletions src/healthchecks_io/client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""healthchecks_io clients."""

from .async_client import AsyncClient # noqa: F401
from .check_trap import CheckTrap # noqa: F401
from .sync_client import Client # noqa: F401
Expand Down
30 changes: 6 additions & 24 deletions src/healthchecks_io/client/_abstract.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from abc import ABC
from abc import abstractmethod
from typing import Any
from typing import Dict
from typing import Optional
from typing import Union
from urllib.parse import parse_qsl
from urllib.parse import ParseResult
from urllib.parse import unquote
Expand Down Expand Up @@ -57,9 +54,7 @@ def _finalizer_method(self) -> None: # pragma: no cover
"""Finalizer method is called by weakref.finalize when the object is dereferenced to do cleanup of clients."""
pass

def _get_api_request_url(
self, path: str, params: Optional[Dict[str, Any]] = None
) -> str:
def _get_api_request_url(self, path: str, params: dict[str, Any] | None = None) -> str:
"""Get a full request url for the healthchecks api.
Args:
Expand Down Expand Up @@ -165,9 +160,7 @@ def check_response(response: Response) -> Response:
raise CheckNotFoundError(f"CHeck not found at {response.request.url}")

if response.status_code == 400:
raise BadAPIRequestError(
f"Bad request when requesting {response.request.url}. {response.text}"
)
raise BadAPIRequestError(f"Bad request when requesting {response.request.url}. {response.text}")

return response

Expand Down Expand Up @@ -208,21 +201,15 @@ def check_ping_response(response: Response) -> Response:
raise HCAPIRateLimitError(f"Rate limited on {response.request.url}")

if response.status_code == 400:
raise BadAPIRequestError(
f"Bad request when requesting {response.request.url}. {response.text}"
)
raise BadAPIRequestError(f"Bad request when requesting {response.request.url}. {response.text}")

if response.status_code == 409:
raise NonUniqueSlugError(
f"Bad request, slug conflict {response.request.url}. {response.text}"
)
raise NonUniqueSlugError(f"Bad request, slug conflict {response.request.url}. {response.text}")

return response

@staticmethod
def _add_url_params(
url: str, params: Dict[str, Union[str, int, bool]], replace: bool = True
) -> str:
def _add_url_params(url: str, params: dict[str, str | int | bool], replace: bool = True) -> str:
"""Add GET params to provided URL being aware of existing.
:param url: string of target URL
Expand Down Expand Up @@ -255,12 +242,7 @@ def _add_url_params(
# get all the duplicated keys from params and urlencode them, we'll concat this to the params string later
duplicated_params = [x for x in params if x in parsed_get_args]
# get all the args that aren't duplicated and add them to parsed_get_args
parsed_get_args.update(
{
key: parsed_params[key]
for key in [x for x in params if x not in parsed_get_args]
}
)
parsed_get_args.update({key: parsed_params[key] for key in [x for x in params if x not in parsed_get_args]})
# if we have any duplicated parameters, urlencode them, we append them later
extra_parameters = (
f"&{urlencode({key: params[key] for key in duplicated_params}, doseq=True)}"
Expand Down
38 changes: 17 additions & 21 deletions src/healthchecks_io/client/async_client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"""An async healthchecks.io client."""

import asyncio
from types import TracebackType
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import Type

from httpx import AsyncClient as HTTPXAsyncClient

Expand All @@ -29,7 +25,7 @@ def __init__(
api_url: str = "https://healthchecks.io/api/",
ping_url: str = "https://hc-ping.com/",
api_version: int = 1,
client: Optional[HTTPXAsyncClient] = None,
client: HTTPXAsyncClient | None = None,
) -> None:
"""An AsyncClient can be used in code using asyncio to work with the Healthchecks.io api.
Expand Down Expand Up @@ -64,9 +60,9 @@ async def __aenter__(self) -> "AsyncClient":

async def __aexit__(
self,
exc_type: Optional[Type[BaseException]],
exc: Optional[BaseException],
traceback: Optional[TracebackType],
exc_type: type[BaseException] | None,
exc: BaseException | None,
traceback: TracebackType | None,
) -> None:
"""Context manager exit."""
await self._afinalizer_method()
Expand Down Expand Up @@ -118,7 +114,7 @@ async def update_check(self, uuid: str, update_check: CheckCreate) -> Check:
)
return Check.from_api_result(response.json())

async def get_checks(self, tags: Optional[List[str]] = None) -> List[Check]:
async def get_checks(self, tags: list[str] | None = None) -> list[Check]:
"""Get a list of checks from the healthchecks api.
Args:
Expand Down Expand Up @@ -213,7 +209,7 @@ async def delete_check(self, check_id: str) -> Check:
response = self.check_response(await self._client.delete(request_url))
return Check.from_api_result(response.json())

async def get_check_pings(self, check_id: str) -> List[CheckPings]:
async def get_check_pings(self, check_id: str) -> list[CheckPings]:
"""Returns a list of pings this check has received.
This endpoint returns pings in reverse order (most recent first),
Expand Down Expand Up @@ -241,10 +237,10 @@ async def get_check_pings(self, check_id: str) -> List[CheckPings]:
async def get_check_flips(
self,
check_id: str,
seconds: Optional[int] = None,
start: Optional[int] = None,
end: Optional[int] = None,
) -> List[CheckStatuses]:
seconds: int | None = None,
start: int | None = None,
end: int | None = None,
) -> list[CheckStatuses]:
"""Returns a list of "flips" this check has experienced.
A flip is a change of status (from "down" to "up," or from "up" to "down").
Expand Down Expand Up @@ -281,7 +277,7 @@ async def get_check_flips(
response = self.check_response(await self._client.get(request_url))
return [CheckStatuses(**status_data) for status_data in response.json()]

async def get_integrations(self) -> List[Optional[Integration]]:
async def get_integrations(self) -> list[Integration | None]:
"""Returns a list of integrations belonging to the project.
Raises:
Expand All @@ -297,7 +293,7 @@ async def get_integrations(self) -> List[Optional[Integration]]:
response = self.check_response(await self._client.get(request_url))
return [Integration.from_api_result(integration_dict) for integration_dict in response.json()["channels"]]

async def get_badges(self) -> Dict[str, Badges]:
async def get_badges(self) -> dict[str, Badges]:
"""Returns a dict of all tags in the project, with badge URLs for each tag.
Healthchecks.io provides badges in a few different formats:
Expand Down Expand Up @@ -325,7 +321,7 @@ async def get_badges(self) -> Dict[str, Badges]:
response = self.check_response(await self._client.get(request_url))
return {key: Badges.from_api_result(item) for key, item in response.json()["badges"].items()}

async def success_ping(self, uuid: str = "", slug: str = "", data: str = "") -> Tuple[bool, str]:
async def success_ping(self, uuid: str = "", slug: str = "", data: str = "") -> tuple[bool, str]:
"""Signals to Healthchecks.io that a job has completed successfully.
Can also be used to indicate a continuously running process is still running and healthy.
Expand Down Expand Up @@ -359,7 +355,7 @@ async def success_ping(self, uuid: str = "", slug: str = "", data: str = "") ->
response = self.check_ping_response(await self._client.post(ping_url, content=data))
return (True if response.status_code == 200 else False, response.text)

async def start_ping(self, uuid: str = "", slug: str = "", data: str = "") -> Tuple[bool, str]:
async def start_ping(self, uuid: str = "", slug: str = "", data: str = "") -> tuple[bool, str]:
"""Sends a "job has started!" message to Healthchecks.io.
Sending a "start" signal is optional, but it enables a few extra features:
Expand Down Expand Up @@ -395,7 +391,7 @@ async def start_ping(self, uuid: str = "", slug: str = "", data: str = "") -> Tu
response = self.check_ping_response(await self._client.post(ping_url, content=data))
return (True if response.status_code == 200 else False, response.text)

async def fail_ping(self, uuid: str = "", slug: str = "", data: str = "") -> Tuple[bool, str]:
async def fail_ping(self, uuid: str = "", slug: str = "", data: str = "") -> tuple[bool, str]:
"""Signals to Healthchecks.io that the job has failed.
Actively signaling a failure minimizes the delay from your monitored service failing to you receiving an alert.
Expand Down Expand Up @@ -429,7 +425,7 @@ async def fail_ping(self, uuid: str = "", slug: str = "", data: str = "") -> Tup
response = self.check_ping_response(await self._client.post(ping_url, content=data))
return (True if response.status_code == 200 else False, response.text)

async def exit_code_ping(self, exit_code: int, uuid: str = "", slug: str = "", data: str = "") -> Tuple[bool, str]:
async def exit_code_ping(self, exit_code: int, uuid: str = "", slug: str = "", data: str = "") -> tuple[bool, str]:
"""Signals to Healthchecks.io that the job has failed.
Actively signaling a failure minimizes the delay from your monitored service failing to you receiving an alert.
Expand Down
Loading

0 comments on commit d0b9860

Please sign in to comment.