Skip to content

Commit

Permalink
Merge pull request #7 from ustudio/add-type-annotations
Browse files Browse the repository at this point in the history
Add Type Annotations and Switch to Poetry
  • Loading branch information
spiralman authored Jun 13, 2023
2 parents f0b4e2b + 67a72ad commit 791fdc4
Show file tree
Hide file tree
Showing 14 changed files with 760 additions and 107 deletions.
57 changes: 30 additions & 27 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,35 @@ jobs:
- restore_cache:
keys:
- v1-python-{{ checksum "pythonversion" }}-dependencies-{{ checksum "requirements.txt" }}
- v1-python-{{ checksum "pythonversion" }}-dependencies-{{ checksum "poetry.lock" }}

- run:
name: install dependencies
command: |
python -m virtualenv ~/venv
. ~/venv/bin/activate
pip install -e .
pip install -r requirements.txt
poetry self update --no-ansi -- 1.5.1
poetry install --no-ansi
mkdir -p test-reports
- save_cache:
paths:
- ~/venv
key: v1-python-{{ checksum "pythonversion" }}-dependencies-{{ checksum "requirements.txt" }}
- ~/.cache/pypoetry/virtualenvs
key: v1-python-{{ checksum "pythonversion" }}-dependencies-{{ checksum "poetry.lock" }}

- run:
name: run tests
command: |
. ~/venv/bin/activate
pytest --verbose --junit-xml=test-reports/pytest.xml
poetry run pytest --verbose --junit-xml=test-reports/pytest.xml
- run:
name: run lint
command: |
poetry run flake8 | tee test-reports/flake8-errors
- run:
name: run typechecks
command: |
poetry run mypy --junit-xml=test-reports/mypy.xml
- store_artifacts:
path: test-reports
Expand All @@ -49,51 +57,46 @@ jobs:

publish:
docker:
- image: cimg/python:3.7
- image: cimg/python:3.11
working_directory: ~/repo
steps:
- checkout

- run:
name: install dependencies
command: |
python -m virtualenv ~/venv
. ~/venv/bin/activate
pip install twine
- run:
name: Publish to PyPI
command: |
. ~/venv/bin/activate
./publish_to_pypi.sh
export POETRY_HTTP_BASIC_PYPI_USERNAME=$PYPI_USERNAME
export POETRY_HTTP_BASIC_PYPI_PASSWORD=$PYPI_PASSWORD
poetry publish --build
workflows:
version: 2
test-and-build:
jobs:
- test:
name: test-3.7
python_version: "3.7"
name: test-3.9
python_version: "3.9"
filters:
tags:
only: /.*/
- test:
name: test-3.8
python_version: "3.8"
name: test-3.10
python_version: "3.10"
filters:
tags:
only: /.*/
- test:
name: test-3.9
python_version: "3.9"
name: test-3.11
python_version: "3.11"
filters:
tags:
only: /.*/
- publish:
requires:
- test-3.7
- test-3.8
- test-3.9
- test-3.10
- test-3.11
filters:
tags:
only: /^v[0-9]+(\.[0-9]+)*.*/
Expand Down
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 100
ignore=
21 changes: 21 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[mypy]
files = .
show_error_codes = True
mypy_path = stubs

# The rest of these settings are currently equivalent to "strict" mode
warn_unused_configs = True
disallow_subclassing_any = True
disallow_any_generics = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_return_any = True
implicit_reexport = False
strict_equality = True
strict_concatenate = True
630 changes: 630 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

27 changes: 0 additions & 27 deletions publish_to_pypi.sh

This file was deleted.

23 changes: 23 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool.poetry]
name = "ustack-logging"
version = "1.0.0"
description = "Default logging configuration for uStack style Python applications."
authors = ["uStudio Developers <dev@ustudio.com>"]
license = "MIT"
readme = "README.md"
packages = [{include = "ustack_logging"}]

[tool.poetry.dependencies]
python = "^3.9"
datadog-logger = "^1.0.0"
datadog = "^0.45.0"
kubernetes = "^26.1.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.3.1"
flake8 = "^6.0.0"
mypy = "^1.3.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
26 changes: 0 additions & 26 deletions requirements.txt

This file was deleted.

18 changes: 0 additions & 18 deletions setup.py

This file was deleted.

Empty file added stubs/kubernetes/__init__.pyi
Empty file.
34 changes: 34 additions & 0 deletions stubs/kubernetes/client/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from collections.abc import Mapping
from typing import AnyStr


class V1Secret:
data: Mapping[str, str]

def __init__(self, data: Mapping[str, AnyStr]) -> None:
...


class V1ObjectMeta:
labels: Mapping[str, str]

def __init__(self, labels: Mapping[str, str]) -> None:
...


class V1Pod:
metadata: V1ObjectMeta

def __init__(self, metadata: V1ObjectMeta) -> None:
...


class CoreV1Api:
def __init__(self) -> None:
...

def read_namespaced_secret(self, secretName: str, namespaceName: str) -> V1Secret:
...

def read_namespaced_pod(self, podName: str, namespaceName: str) -> V1Pod:
...
2 changes: 2 additions & 0 deletions stubs/kubernetes/config/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def load_incluster_config() -> None:
...
21 changes: 14 additions & 7 deletions tests/test_ustack_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@

from kubernetes.client import V1Secret, V1Pod, V1ObjectMeta

try:
from unittest import mock
except ImportError:
import mock
from unittest import mock

from ustack_logging.logging_configuration import configure_logging

Expand All @@ -20,8 +17,14 @@ class TestLogging(unittest.TestCase):
@mock.patch("datadog.initialize", autospec=True)
@mock.patch("logging.basicConfig", autospec=True)
def test_configures_logging_format_and_logs_errors_to_datadog(
self, mock_log_config, mock_dd_init, mock_log_errors, mock_k8s_api_class,
mock_k8s_config, mock_gethostname):
self,
mock_log_config: mock.Mock,
mock_dd_init: mock.Mock,
mock_log_errors: mock.Mock,
mock_k8s_api_class: mock.Mock,
mock_k8s_config: mock.Mock,
mock_gethostname: mock.Mock
) -> None:

mock_k8s_api = mock_k8s_api_class.return_value

Expand Down Expand Up @@ -65,7 +68,11 @@ def test_configures_logging_format_and_logs_errors_to_datadog(

@mock.patch("kubernetes.config.load_incluster_config")
@mock.patch("logging.basicConfig", autospec=True)
def test_ignores_errors_from_datadog_initialization(self, mock_log_config, mock_k8s_config):
def test_ignores_errors_from_datadog_initialization(
self,
mock_log_config: mock.Mock,
mock_k8s_config: mock.Mock
) -> None:

mock_k8s_config.side_effect = RuntimeError

Expand Down
5 changes: 3 additions & 2 deletions ustack_logging/logging_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import datadog
from datadog_logger import log_error_events
import kubernetes.client
import kubernetes.config
import logging
import socket


def configure_logging():
def configure_logging() -> None:
logging.basicConfig(
format="%(asctime)s %(levelname)s:%(module)s:%(message)s",
datefmt="%Y-%m-%d %H:%M:%S%z", level=logging.INFO)
Expand All @@ -33,5 +34,5 @@ def configure_logging():
"service:{0}".format(namespace),
"role:{0}".format(pod_info.metadata.labels["role"])
])
except:
except Exception:
logging.warning("Could not initialize DataDog error logging, with error:", exc_info=True)
Empty file added ustack_logging/py.typed
Empty file.

0 comments on commit 791fdc4

Please sign in to comment.