Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ubuntu Docker tag to v24 (master) #2240

Merged
merged 6 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: '3.12'
python-version: '3.11'
- run: python3 -m pip install --requirement=ci/requirements.txt

- uses: actions/cache@v4
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ repos:
- --output-format=pylint
additional_dependencies:
- prospector-profile-duplicated==1.6.0 # pypi
- prospector-profile-utils==1.9.1 # pypi
- repo: https://github.com/sbrunner/jsonschema-validator
rev: 0.1.0
hooks:
Expand Down
51 changes: 10 additions & 41 deletions .prospector.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
inherits:
- utils:base
- utils:no-design-checks
- utils:fix
- duplicated
strictness: veryhigh
max-line-length: 110

doc-warnings: true

ignore-paths:
Expand All @@ -15,56 +17,23 @@ pylint:
- ujson
- lxml
disable:
- too-many-return-statements
- too-many-arguments
- too-many-branches
- too-many-instance-attributes
- too-few-public-methods
- global-statement
- line-too-long
- import-outside-toplevel
- invalid-name
- no-else-return
- no-else-raise
- no-self-use
- import-error
- unused-argument
- use-symbolic-message-instead
- missing-module-docstring
- missing-function-docstring
- missing-timeout # A default timeout is set

pycodestyle:
options:
max-line-length: 110
disable:
- E722 # do not use bare 'except', duplicated with pylint
- E261 # at least two spaces before inline comment, duplicated with black

pydocstyle:
disable:
- D102 # Missing docstring in public method
- D104 # Missing docstring in public package
- D105 # Missing docstring in magic method
- D107 # Missing docstring in __init__
- D202 # No blank lines allowed after function docstring (found 1)
- D203 # 1 blank line required before class docstring (found 0)
- D212 # Multi-line docstring summary should start at the first line
- D407 # Missing dashed underline after section ('Arguments')
- D412 # No blank lines allowed between a section header and its content ('Arguments')
mypy:
run: true

pycodestyle:
disable:
# Buggy checks with Python 3.12
- E221 # multiple spaces before operator
- E702 # multiple statements on one line (semicolon)

bandit:
run: true
options:
config: .bandit.yaml

pyroma:
run: true

mccabe:
run: false

dodgy:
run: false
11 changes: 7 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
FROM ubuntu:22.04 AS base-all-0
FROM ubuntu:24.04 AS base-all-0
LABEL maintainer Camptocamp "info@camptocamp.com"
SHELL ["/bin/bash", "-o", "pipefail", "-cux"]

RUN --mount=type=cache,target=/var/lib/apt/lists \
--mount=type=cache,target=/var/cache,sharing=locked \
apt-get update \
&& apt-get upgrade --assume-yes \
&& apt-get install --assume-yes --no-install-recommends python3-pip
&& apt-get install --assume-yes --no-install-recommends python3-pip python3-venv \
&& python3 -m venv /venv

ENV PATH=/venv/bin:$PATH

# Used to convert the locked packages by poetry to pip requirements format
# We don't directly use `poetry install` because it force to use a virtual environment.
Expand Down Expand Up @@ -40,7 +43,7 @@ RUN --mount=type=cache,target=/var/lib/apt/lists \
libpq5 curl postgresql-client net-tools iputils-ping gnupg apt-transport-https \
$DEV_PACKAGES \
&& python3 -m pip install --disable-pip-version-check --no-deps --requirement=/poetry/requirements.txt \
&& strip /usr/local/lib/python3.*/dist-packages/*/*.so \
&& strip /venv/lib/python3.*/site-packages/*/*.so \
&& apt-get remove --purge --autoremove --yes $DEV_PACKAGES binutils

ENV LOG_TYPE=console \
Expand Down Expand Up @@ -95,7 +98,7 @@ ENV C2C_BASE_PATH=/c2c \
SENTRY_CLIENT_RELEASE=latest \
SENTRY_TAG_SERVICE=app

CMD ["/usr/local/bin/gunicorn"]
CMD ["/venv/bin/gunicorn"]

COPY production.ini /app/

Expand Down
207 changes: 50 additions & 157 deletions acceptance_tests/app/poetry.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion acceptance_tests/app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ coverage = "7.6.1"

[tool.poetry.dev-dependencies]
# pylint = { version = "2.15.6" }
prospector = { extras = ["with_bandit", "with_mypy"], version = "1.11.0" }
prospector = { extras = ["with_bandit", "with_mypy"], version = "1.12.0" }
prospector-profile-duplicated = "1.6.0"
prospector-profile-utils = "1.9.1"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
2 changes: 1 addition & 1 deletion acceptance_tests/tests/tests/test_db_maintenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

LOG = logging.getLogger(__name__)
_LOG = logging.getLogger(__name__)


def _query(app_connection, params, expected=None):
Expand Down
4 changes: 2 additions & 2 deletions c2cwsgiutils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from configparser import SectionProxy
from typing import Any

LOG = logging.getLogger(__name__)
_LOG = logging.getLogger(__name__)


def get_config_defaults() -> dict[str, str]:
Expand All @@ -22,7 +22,7 @@ def get_config_defaults() -> dict[str, str]:
lowercase_keys: set[str] = set()
for key, value in os.environ.items():
if key.lower() in lowercase_keys:
LOG.warning("The environment variable '%s' is duplicated with different case, ignoring", key)
_LOG.warning("The environment variable '%s' is duplicated with different case, ignoring", key)
continue
lowercase_keys.add(key.lower())
result[key] = value.replace("%", "%%")
Expand Down
5 changes: 2 additions & 3 deletions c2cwsgiutils/acceptance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import typing
from functools import wraps

LOG = logging.getLogger(__name__)
_LOG = logging.getLogger(__name__)


def retry(
Expand All @@ -16,7 +16,6 @@ def retry(
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry

Arguments:

exception_to_check: the exception to check. may be a tuple of exceptions to check
tries: number of times to try (not retry) before giving up
delay: initial delay between retries in seconds
Expand All @@ -32,7 +31,7 @@ def f_retry(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
return f(*args, **kwargs)
except exception_to_check as e:
msg = f"{e:s}, Retrying in {mdelay:d} seconds..."
LOG.warning(msg)
_LOG.warning(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
Expand Down
3 changes: 1 addition & 2 deletions c2cwsgiutils/acceptance/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def get_xml(
**kwargs: Any,
) -> Any:
"""Get the given URL (relative to the root of API)."""

from lxml import etree # nosec
from lxml import etree # nosec # pylint: disable=import-outside-toplevel

with self.session.get(
self.base_url + url,
Expand Down
13 changes: 6 additions & 7 deletions c2cwsgiutils/acceptance/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import subprocess # nosec
from typing import TYPE_CHECKING, Any, Optional

import numpy as np
import skimage.color
import skimage.io
import skimage.metrics
import skimage.transform
import numpy as np # pylint: disable=import-error
import skimage.color # pylint: disable=import-error
import skimage.io # pylint: disable=import-error
import skimage.metrics # pylint: disable=import-error
import skimage.transform # pylint: disable=import-error

if TYPE_CHECKING:
from typing import TypeAlias
Expand Down Expand Up @@ -189,7 +189,7 @@ def check_screenshot(

See also `check_image` for the other parameters.

Args:
Arguments:
url: The URL to screenshot
width: The width of the generated screenshot
height: The height of the generated screenshot
Expand All @@ -202,7 +202,6 @@ def check_screenshot(
generate_expected_image: See `check_image`
use_mask: See `check_image`
"""

if headers is None:
headers = {}
if media is None:
Expand Down
10 changes: 7 additions & 3 deletions c2cwsgiutils/acceptance/print.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from c2cwsgiutils.acceptance import connection, utils

LOG = logging.getLogger(__name__)
_LOG = logging.getLogger(__name__)


class PrintConnection(connection.Connection):
Expand All @@ -30,22 +30,25 @@ def wait_ready(self, timeout: int = 60, app: str = "default") -> None:
utils.retry_timeout(functools.partial(self.get_capabilities, app=app), timeout=timeout)

def get_capabilities(self, app: str) -> Any:
"""Get the capabilities for the given application."""
return self.get_json(app + "/capabilities.json", cache_expected=connection.CacheExpected.YES)

def get_example_requests(self, app: str) -> dict[str, Any]:
"""Get the example requests for the given application."""
samples = self.get_json(app + "/exampleRequest.json", cache_expected=connection.CacheExpected.YES)
out = {}
for name, value in samples.items():
out[name] = json.loads(value)
return out

def get_pdf(self, app: str, request: dict[str, Any], timeout: int = 60) -> requests.Response:
"""Create a report and wait for it to be ready."""
create_report = self.post_json(app + "/report.pdf", json=request)
LOG.debug("create_report=%s", create_report)
_LOG.debug("create_report=%s", create_report)
ref = create_report["ref"]

status = utils.retry_timeout(functools.partial(self._check_completion, ref), timeout=timeout)
LOG.debug("status=%s", repr(status))
_LOG.debug("status=%s", repr(status))
assert status["status"] == "finished"

report = self.get_raw("report/" + ref)
Expand All @@ -59,4 +62,5 @@ def _check_completion(self, ref: str) -> Optional[Any]:
return None

def get_apps(self) -> Any:
"""Get the list of available applications."""
return self.get_json("apps.json", cache_expected=connection.CacheExpected.YES)
4 changes: 1 addition & 3 deletions c2cwsgiutils/acceptance/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ def retry_timeout(what: Callable[[], Any], timeout: float = _DEFAULT_TIMEOUT, in
Retry the function until the timeout.

Arguments:

what: the function to try
timeout: the timeout to get a success
interval: the interval between try
"""

timeout = time.perf_counter() + timeout
while True:
error = ""
Expand All @@ -58,7 +56,7 @@ def approx(struct: Any, **kwargs: Any) -> Any:

See pytest.approx
"""
import boltons.iterutils
import boltons.iterutils # pylint: disable=import-outside-toplevel

if isinstance(struct, float):
return pytest.approx(struct, **kwargs)
Expand Down
Loading
Loading