diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1e7eeee..def24d06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,76 +1,116 @@ -name: Continous Integration (CI) +name: Continuous Integration on: pull_request: jobs: - lint: + unit: + runs-on: ubuntu-latest strategy: - fail-fast: false matrix: - os: [ubuntu-latest] - architecture: ['x64'] - python-version: ['3.8', '3.9', '3.10', '3.11'] - runs-on: ${{ matrix.os }} + # TODO: Test Hatch matrices again. + # They could be as fast as concurrent GitHub jobs thanks to caching of dependencies and type check results. + # Then it is always possible to target a specific version of Python, for example with +py3.9 in the Dockerfile. + # Hatch matrices also vastly reduce the size of this workflow, with a single step for lint, test and audit. + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - architecture: ${{ matrix.architecture }} - - - name: Install dependencies - run: make install - - - name: Lint - run: make lint + - name: Set up pip cache + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Install Hatch + run: pipx install hatch + - name: List Hatch environments + run: hatch env show --ascii + - name: Run unit tests with coverage + run: hatch run test:unit-cov + env: + MIN_VALID_EVENTS: 10 + GOOGLE_APPLICATION_CREDENTIALS: tests/unit/fixtures/fake_credentials.json - unit: + lint: + runs-on: ubuntu-latest strategy: - fail-fast: false matrix: - os: [ubuntu-latest] - architecture: ['x64'] - python-version: ['3.8', '3.9', '3.10', '3.11'] - runs-on: ${{ matrix.os }} + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - architecture: ${{ matrix.architecture }} - - - name: Install dependencies - run: make install - - - name: Run unit tests - run: make unit - env: - MIN_VALID_EVENTS: "10" - GOOGLE_APPLICATION_CREDENTIALS: tests/unit/fixtures/fake_credentials.json - - - name: Run coverage report - run: make coverage + - name: Set up pip cache + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Install Hatch + run: pipx install hatch + - name: List Hatch environments + run: hatch env show --ascii + - name: Lint + run: hatch run lint:all audit: runs-on: ubuntu-latest + # TODO: Not sure `audit` is required to run on multiple versions of Python. + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.9" # same as Dockerfile - - - name: Install dependencies - run: make install - - - name: Audit for CVEs - run: make audit + python-version: ${{ matrix.python-version }} + - name: Set up pip cache + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Install Hatch + run: pipx install hatch + - name: List Hatch environments + run: hatch env show --ascii + - name: Audit + run: hatch run audit:all - docker: + build: runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 - - uses: docker-practice/actions-setup-docker@master + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Set up pip cache + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} + restore-keys: ${{ runner.os }}-pip- + - name: Install Hatch + run: pipx install hatch + - name: List Hatch environments + run: hatch env show --ascii + - name: Build + run: hatch build + docker: + runs-on: ubuntu-latest + steps: + - uses: docker/build-push-action@v5 - name: Build Docker image run: make docker_build diff --git a/.gitignore b/.gitignore index cdbd6ec9..9625388d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# FIXME: Clean up unused entries and sort by categories __pycache__/ *.py[cod] *$py.class @@ -50,4 +51,4 @@ reports/ .pytest_cache/ .pytype/ .pip-wheel-metadata/ -.ruff_cache +.ruff_cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eedaf763..3be609d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,3 +22,7 @@ repos: - id: ruff # Run the formatter. - id: ruff-format +- repo: https://github.com/PyCQA/bandit + rev: 1.7.8 + hooks: + - id: bandit diff --git a/Makefile b/Makefile index 28b9cc9f..a49a4ef8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#!/usr/bin/make +#!/usr/bin/env make # WARN: gmake syntax ######################################################## # Makefile for $(NAME) @@ -12,25 +12,29 @@ # make audit -- run CVE scan separately # make integration -- run integration tests ######################################################## -# variable section + +# Variables NAME = slo_generator +HATCH = hatch PIP = pip3 PYTHON = python3 -TWINE = twine COVERAGE = coverage -SITELIB = $(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") -VERSION ?= $(shell grep "version = " setup.cfg | cut -d ' ' -f 3) +VERSION ?= $(shell grep "version = " pyproject.toml | cut -d ' ' -f 3) ######################################################## all: clean install test +############## + info: @echo "slo-generator version: ${VERSION}" +############## + clean: @echo "Cleaning up distutils stuff" rm -rf build @@ -46,46 +50,64 @@ clean: @echo "Cleaning up test reports" rm -rf report/* +############## + build: clean - $(PYTHON) setup.py sdist bdist_wheel + $(HATCH) build -deploy: clean install_twine build - $(TWINE) upload dist/* +deploy: build + $(HATCH) publish -install_twine: - $(PIP) install twine - -develop: install - pre-commit install +############## +#TODO: Replace with Hatch. install: clean +#FIXME: Are all dependencies and features requested for all these targets? $(PIP) install -e ."[api, datadog, prometheus, elasticsearch, opensearch, splunk, pubsub, cloud_monitoring, bigquery, dev]" uninstall: clean - $(PIP) freeze --exclude-editable | xargs $(PIP) uninstall -y + $(HATCH) env prune + +############## + +#TODO: How to handle pre-commit with Hatch environments? +develop: install + pre-commit install +############## + +format: + $(HATCH) fmt + +############## + +#FIXME: Are all dependencies and features requested for all these targets? test: install unit lint audit +############## + unit: clean - pytest --cov=$(NAME) tests -p no:warnings + $(HATCH) run test:unit coverage: - $(COVERAGE) report --rcfile=".coveragerc" + $(HATCH) run test:cov -format: - ruff format +############## lint: ruff pytype mypy ruff: - ruff format --check - ruff check + $(HATCH) fmt pytype: - pytype + $(HATCH) run lint:pytype mypy: - mypy --show-error-codes $(NAME) + $(HATCH) run lint:mypy + +############## + +audit: bandit safety audit: bandit safety @@ -97,6 +119,8 @@ safety: # We do not use the `--extra-index-url` option, and the behavior is intended anyway. safety check --ignore 67599 +############## + integration: int_cm int_csm int_custom int_dd int_dt int_es int_prom int_sp int_os int_cm: @@ -126,6 +150,8 @@ int_sp: int_os: slo-generator compute -f samples/opensearch -c samples/config.yaml +############## + # Run API locally run_api: slo-generator api --target=run_compute --signature-type=http -c samples/config.yaml diff --git a/hatch.toml b/hatch.toml new file mode 100644 index 00000000..a80ad3a9 --- /dev/null +++ b/hatch.toml @@ -0,0 +1,100 @@ +[envs.default] +python = "3.10" +# Install all optional dependencies. +features = [ + "api", + "bigquery", + "cloud_monitoring", + "cloud_service_monitoring", + "cloud_storage", + "cloudevent", + "datadog", + "dynatrace", + "elasticsearch", + "opensearch", + "prometheus", + "pubsub", + "splunk", +] + +[envs.test] +python = "3.10" +dependencies = [ + "coverage[toml]>=6.5", + "mock", + "pytest", + "pytest-cov", +] +# Install all optional dependencies. +features = [ + "api", + "bigquery", + "cloud_monitoring", + "cloud_service_monitoring", + "cloud_storage", + "cloudevent", + "datadog", + "dynatrace", + "elasticsearch", + "opensearch", + "prometheus", + "pubsub", + "splunk", +] +[envs.test.scripts] +#TODO: Check what coverage does exactly, and if there is a more modern approach, for example with `py-cov`. +unit = "pytest --cov=coverage {args:tests} -p no:warnings" +cov = "coverage report --rcfile='.coveragerc'" + +[envs.lint] +python="3.10" +detached = true +dependencies = [ + "mypy", + "pytype", + "ruff", +] +# Install all optional dependencies. +features = [ + "api", + "bigquery", + "cloud_monitoring", + "cloud_service_monitoring", + "cloud_storage", + "cloudevent", + "datadog", + "dynatrace", + "elasticsearch", + "opensearch", + "prometheus", + "pubsub", + "splunk", +] +[envs.lint.scripts] +style = [ + "ruff {args:.}", +] +typing = [ + "pytype", + #FIXME Configure `mypy` from `pyproject.toml`, like `pytype`. + "mypy --install-types --show-error-codes --disable-error-code=import-untyped --non-interactive {args:src/slo_generator}", +] +all = [ + "style", + "typing", +] + +[envs.audit] +python = "3.10" +detached = true +dependencies = [ + "bandit", + "safety", +] +[envs.audit.scripts] +all = [ + "bandit -c pyproject.toml -r .", + # Ignore CVE-2018-20225 with Vulnerability ID 67599. + # We do not use the `--extra-index-url` option, and the behavior is intended anyway. + "safety check --ignore 67599", +] diff --git a/pyproject.toml b/pyproject.toml index 9b234df1..e2d177af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,149 @@ [build-system] -requires = ["setuptools>=42", "wheel"] # PEP 508 specifications. -build-backend = "setuptools.build_meta" +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "slo-generator" +#TODO: Use dynamic version, stored in `src/slo_generator/__init__.py` as `__version__ = "2.6.0"`? +# Then use with `from . import __version__`. +# Is it compatible with release-please? +version = "2.6.0" +description = "SLO Generator" +readme = "README.md" +license = "Apache License 2.0" +requires-python = ">=3.7, <4" +authors = [ + { name = "Google Inc.", email = "olivier.cervello@gmail.com" }, +] +keywords = [ + "gcp", + "generator", + "sli", + "slo", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Topic :: Software Development :: Build Tools", + "Topic :: System :: Monitoring", +] +dependencies = [ + "certifi >=2023.07.22", + "click", + "python-dateutil", + "pyyaml", + "ruamel.yaml", + "setuptools >=65.5.1", +] + +[project.optional-dependencies] +api = [ + "cloudevents", + "Flask", + "functions-framework", + "gunicorn", + "requests", +] +bigquery = [ + "google-api-python-client", + "google-cloud-bigquery", +] +cloud_monitoring = [ + "google-api-python-client", + "google-cloud-monitoring", +] +cloud_service_monitoring = [ + "google-api-python-client", + "google-cloud-monitoring", +] +cloud_storage = [ + "google-api-python-client", + "google-cloud-storage", +] +cloudevent = [ + "cloudevents", +] +datadog = [ + "datadog", + "retrying==1.3.4", +] +dev = [ + "bandit", + "black >=24.3.0", + "flake8", + "GitPython >=3.1.35", + "isort", + "mock", + "mypy", + "pip >=23.3", + "pre-commit", + "pylint", + "pytest", + "pytest-cov", + "pytype", + "safety >=3", + "types-mock", + "types-protobuf", + "types-python-dateutil", + "types-PyYAML", + "types-requests", + "types-setuptools", + "wheel", +] +dynatrace = [ + "requests", +] +elasticsearch = [ + "elasticsearch", +] +opensearch = [ + "opensearch-py", +] +prometheus = [ + "prometheus-client", + "prometheus-http-client", +] +pubsub = [ + "google-api-python-client", + "google-cloud-pubsub", +] +splunk = [ + "splunk-sdk", +] + +[project.scripts] +slo-generator = "slo_generator.cli:main" + +[project.urls] +Homepage = "https://github.com/google/slo-generator" + +[tool.hatch.version] +path = "slo_generator/__init__.py" + +[tool.hatch.build.targets.sdist] +exclude = [ + "/.github", + "/docs", + "/tests", +] [tool.mypy] # https://mypy.readthedocs.io/en/stable/config_file.html#using-a-pyproject-toml-file -ignore_missing_imports = true +# https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-library-stubs-or-py-typed-marker +disable_error_code = "import-untyped" [tool.pytype] -inputs = ['slo_generator'] +inputs = [ + "src/slo_generator", +] [tool.ruff.lint] # https://docs.astral.sh/ruff/linter/#rule-selection diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index eb640317..00000000 --- a/setup.cfg +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[metadata] -name = slo-generator -version = 2.6.0 -author = Google Inc. -author_email = olivier.cervello@gmail.com -maintainer = Laurent VAYLET -maintainer_email = laurent.vaylet@gmail.com -url = https://github.com/google/slo-generator -description = SLO Generator -long_description = file: README.md -long_description_content_type = text/markdown -keywords = - slo - sli - generator - gcp -license = Apache License 2.0 -license_files = LICENSE -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Console - Intended Audience :: Developers - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Programming Language :: Python - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Topic :: Software Development :: Build Tools - Topic :: System :: Monitoring - -[options] -packages = find: -python_requires = >=3.7, <4 -install_requires = - pyyaml - ruamel.yaml - python-dateutil - click - setuptools >=65.5.1 # https://pyup.io/v/52495/f17 (reported by `safety check`) - certifi >=2023.07.22 # avoid CVE-2023-37920 (reported by `safety check`) - -[options.packages.find] -exclude = - contrib - docs - tests - -[options.extras_require] -api = - Flask - gunicorn - cloudevents - functions-framework - requests -prometheus = - prometheus-client - prometheus-http-client -datadog = - datadog - retrying==1.3.4 -dynatrace = - requests -bigquery = - google-api-python-client - google-cloud-bigquery -cloud_monitoring = - google-api-python-client - google-cloud-monitoring -cloud_service_monitoring = - google-api-python-client - google-cloud-monitoring -cloud_storage = - google-api-python-client - google-cloud-storage -elasticsearch = - elasticsearch -opensearch = - opensearch-py -splunk = - splunk-sdk -pubsub = - google-api-python-client - google-cloud-pubsub -cloudevent = - cloudevents -dev = - bandit - GitPython >=3.1.35 # avoid CVE-2023-41040, CVE-2023-40267 and CVE-2023-40590 (reported by `safety check`) - mock - mypy - pip >=23.3 # avoid known vulnerabilities in pip <23.3 (reported by `safety check`) - pre-commit - pytest - pytest-cov - pytype - ruff - safety - types-mock - types-protobuf - types-python-dateutil - types-PyYAML - types-requests - types-setuptools - wheel - -[options.entry_points] -console_scripts = - slo-generator = slo_generator.cli:main - -# Generated by synthtool. DO NOT EDIT! -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100644 index e042dc15..00000000 --- a/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2018 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""A setuptools based setup module. - -See: -https://packaging.python.org/en/latest/distributing.html -https://github.com/pypa/sampleproject -""" - -import sys - -from setuptools import setup - -sys.dont_write_bytecode = True # avoid generating .pyc files - -if __name__ == "__main__": - setup() diff --git a/slo_generator/__init__.py b/src/slo_generator/__init__.py similarity index 100% rename from slo_generator/__init__.py rename to src/slo_generator/__init__.py diff --git a/slo_generator/api/__init__.py b/src/slo_generator/api/__init__.py similarity index 100% rename from slo_generator/api/__init__.py rename to src/slo_generator/api/__init__.py diff --git a/slo_generator/api/main.py b/src/slo_generator/api/main.py similarity index 100% rename from slo_generator/api/main.py rename to src/slo_generator/api/main.py diff --git a/slo_generator/backends/__init__.py b/src/slo_generator/backends/__init__.py similarity index 100% rename from slo_generator/backends/__init__.py rename to src/slo_generator/backends/__init__.py diff --git a/slo_generator/backends/cloud_monitoring.py b/src/slo_generator/backends/cloud_monitoring.py similarity index 100% rename from slo_generator/backends/cloud_monitoring.py rename to src/slo_generator/backends/cloud_monitoring.py diff --git a/slo_generator/backends/cloud_monitoring_mql.py b/src/slo_generator/backends/cloud_monitoring_mql.py similarity index 100% rename from slo_generator/backends/cloud_monitoring_mql.py rename to src/slo_generator/backends/cloud_monitoring_mql.py diff --git a/slo_generator/backends/cloud_service_monitoring.py b/src/slo_generator/backends/cloud_service_monitoring.py similarity index 100% rename from slo_generator/backends/cloud_service_monitoring.py rename to src/slo_generator/backends/cloud_service_monitoring.py diff --git a/slo_generator/backends/datadog.py b/src/slo_generator/backends/datadog.py similarity index 100% rename from slo_generator/backends/datadog.py rename to src/slo_generator/backends/datadog.py diff --git a/slo_generator/backends/dynatrace.py b/src/slo_generator/backends/dynatrace.py similarity index 100% rename from slo_generator/backends/dynatrace.py rename to src/slo_generator/backends/dynatrace.py diff --git a/slo_generator/backends/elasticsearch.py b/src/slo_generator/backends/elasticsearch.py similarity index 100% rename from slo_generator/backends/elasticsearch.py rename to src/slo_generator/backends/elasticsearch.py diff --git a/slo_generator/backends/open_search.py b/src/slo_generator/backends/open_search.py similarity index 100% rename from slo_generator/backends/open_search.py rename to src/slo_generator/backends/open_search.py diff --git a/slo_generator/backends/prometheus.py b/src/slo_generator/backends/prometheus.py similarity index 100% rename from slo_generator/backends/prometheus.py rename to src/slo_generator/backends/prometheus.py diff --git a/slo_generator/backends/splunk.py b/src/slo_generator/backends/splunk.py similarity index 100% rename from slo_generator/backends/splunk.py rename to src/slo_generator/backends/splunk.py diff --git a/slo_generator/cli.py b/src/slo_generator/cli.py similarity index 98% rename from slo_generator/cli.py rename to src/slo_generator/cli.py index aa678bad..9f891dc6 100644 --- a/slo_generator/cli.py +++ b/src/slo_generator/cli.py @@ -20,10 +20,10 @@ import os import sys import time +from importlib import metadata from pathlib import Path import click -from pkg_resources import get_distribution from slo_generator import utils from slo_generator.compute import compute as _compute @@ -47,7 +47,7 @@ def main(ctx, version): """CLI entrypoint.""" utils.setup_logging() if ctx.invoked_subcommand is None or version: - ver = get_distribution("slo-generator").version + ver = metadata.version("slo-generator") print(f"slo-generator v{ver}") sys.exit(0) diff --git a/slo_generator/compute.py b/src/slo_generator/compute.py similarity index 100% rename from slo_generator/compute.py rename to src/slo_generator/compute.py diff --git a/slo_generator/constants.py b/src/slo_generator/constants.py similarity index 100% rename from slo_generator/constants.py rename to src/slo_generator/constants.py diff --git a/slo_generator/exporters/__init__.py b/src/slo_generator/exporters/__init__.py similarity index 100% rename from slo_generator/exporters/__init__.py rename to src/slo_generator/exporters/__init__.py diff --git a/slo_generator/exporters/base.py b/src/slo_generator/exporters/base.py similarity index 100% rename from slo_generator/exporters/base.py rename to src/slo_generator/exporters/base.py diff --git a/slo_generator/exporters/bigquery.py b/src/slo_generator/exporters/bigquery.py similarity index 100% rename from slo_generator/exporters/bigquery.py rename to src/slo_generator/exporters/bigquery.py diff --git a/slo_generator/exporters/cloud_monitoring.py b/src/slo_generator/exporters/cloud_monitoring.py similarity index 100% rename from slo_generator/exporters/cloud_monitoring.py rename to src/slo_generator/exporters/cloud_monitoring.py diff --git a/slo_generator/exporters/cloudevent.py b/src/slo_generator/exporters/cloudevent.py similarity index 100% rename from slo_generator/exporters/cloudevent.py rename to src/slo_generator/exporters/cloudevent.py diff --git a/slo_generator/exporters/datadog.py b/src/slo_generator/exporters/datadog.py similarity index 100% rename from slo_generator/exporters/datadog.py rename to src/slo_generator/exporters/datadog.py diff --git a/slo_generator/exporters/dynatrace.py b/src/slo_generator/exporters/dynatrace.py similarity index 100% rename from slo_generator/exporters/dynatrace.py rename to src/slo_generator/exporters/dynatrace.py diff --git a/slo_generator/exporters/prometheus.py b/src/slo_generator/exporters/prometheus.py similarity index 100% rename from slo_generator/exporters/prometheus.py rename to src/slo_generator/exporters/prometheus.py diff --git a/slo_generator/exporters/prometheus_self.py b/src/slo_generator/exporters/prometheus_self.py similarity index 100% rename from slo_generator/exporters/prometheus_self.py rename to src/slo_generator/exporters/prometheus_self.py diff --git a/slo_generator/exporters/pubsub.py b/src/slo_generator/exporters/pubsub.py similarity index 100% rename from slo_generator/exporters/pubsub.py rename to src/slo_generator/exporters/pubsub.py diff --git a/slo_generator/migrations/__init__.py b/src/slo_generator/migrations/__init__.py similarity index 100% rename from slo_generator/migrations/__init__.py rename to src/slo_generator/migrations/__init__.py diff --git a/slo_generator/migrations/migrator.py b/src/slo_generator/migrations/migrator.py similarity index 99% rename from slo_generator/migrations/migrator.py rename to src/slo_generator/migrations/migrator.py index 2ddae44f..9a17a376 100644 --- a/slo_generator/migrations/migrator.py +++ b/src/slo_generator/migrations/migrator.py @@ -30,7 +30,7 @@ from typing import Optional import click -from ruamel import yaml +from ruamel import yaml # type: ignore from slo_generator import utils from slo_generator.constants import ( diff --git a/slo_generator/report.py b/src/slo_generator/report.py similarity index 100% rename from slo_generator/report.py rename to src/slo_generator/report.py diff --git a/slo_generator/utils.py b/src/slo_generator/utils.py similarity index 99% rename from slo_generator/utils.py rename to src/slo_generator/utils.py index b00dca5c..4beaa1e4 100644 --- a/slo_generator/utils.py +++ b/src/slo_generator/utils.py @@ -210,7 +210,7 @@ def get_human_time(timestamp: int, timezone: Optional[str] = None) -> str: str: Formatted human-readable date in ISO format. Example: - >>> get_human_time(1702660513.987654, timezone='Europe/Paris') + >>> get_human_time(1702660513.987654, timezone="Europe/Paris") >>> 2023-12-15T18:15:13.987654+01:00 which corresponds to the timestamp in ISO format """ diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py index 8f73adb4..f2a163c1 100644 --- a/tests/unit/test_cli.py +++ b/tests/unit/test_cli.py @@ -31,7 +31,7 @@ class TestCLI(unittest.TestCase): def setUp(self): for key, value in CTX.items(): os.environ[key] = value - slo_config = f"{root}/samples/cloud_monitoring/slo_gae_app_availability.yaml" # noqa: E501 + slo_config = f"{root}/samples/cloud_monitoring/slo_gae_app_availability.yaml" config = f"{root}/samples/config.yaml" self.slo_config = slo_config self.slo_metadata_name = load_config(slo_config, ctx=CTX)["metadata"]["name"]