Skip to content
This repository was archived by the owner on Jun 26, 2025. It is now read-only.
Open
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
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ steps:
- sonar-scanner
commands:
- pip install -U pip==24.0
- pip install --quiet awscli twine==4.0.2 packaging==24.0 importlib-metadata==4.8.1
- pip install --quiet awscli twine==4.0.2 packaging==24.0
- export version=$(cat .bumpversion.cfg | awk '/current_version / {print $3}')
- aws codeartifact login --tool pip --repository globality-pypi-local --domain globality --domain-owner $AWS_ACCOUNT_ID --region us-east-1
- python setup.py sdist bdist_wheel
Expand All @@ -99,7 +99,7 @@ steps:
TWINE_REPOSITORY: https://upload.pypi.org/legacy/
commands:
- pip install -U pip==24.0
- pip install --quiet awscli twine==4.0.2 importlib-metadata==4.8.1
- pip install --quiet awscli twine==4.0.2
- export version=$(cat .bumpversion.cfg | awk '/current_version / {print $3}')
- echo "Publishing ${version}"
- python setup.py sdist bdist_wheel
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ nosetests.xml
coverage.xml
*,cover
cover
junit.xml

# Translations
*.mo
Expand All @@ -98,10 +99,12 @@ target/

.mypy_cache

/coverage/
# direnv
.envrc

# Python Virtual Environments
venv/
.venv/

/coverate/
**/coverage/**/*
5 changes: 4 additions & 1 deletion .globality/build.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{
"params": {
"docker": {
"docker_tag": "python:3.11-slim-buster"
},
"name": "microcosm-flask",
"pypi": {
"repository": "pypi"
}
},
"type": "python-library",
"version": "2024.52.0"
"version": "2024.54.0"
}
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ FROM python:3.11-slim-buster as deps
ARG EXTRA_INDEX_URL
ENV EXTRA_INDEX_URL ${EXTRA_INDEX_URL}

ENV CORE_PACKAGES locales libpq-dev
ENV CORE_PACKAGES locales
ENV BUILD_PACKAGES build-essential libffi-dev
ENV OTHER_PACKAGES libssl-dev

Expand Down Expand Up @@ -108,4 +108,4 @@ ARG SHA1
ENV MICROCOSM_FLASK__BUILD_INFO_CONVENTION__BUILD_NUM ${BUILD_NUM}
ENV MICROCOSM_FLASK__BUILD_INFO_CONVENTION__SHA1 ${SHA1}
COPY $NAME /src/$NAME/
RUN pip install --no-cache-dir --extra-index-url "${EXTRA_INDEX_URL}" -e .
RUN pip install --no-cache-dir --extra-index-url $EXTRA_INDEX_URL -e .
16 changes: 10 additions & 6 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@


if [ "$1" = "test" ]; then
pip --quiet install .\[test\]
pip --quiet install .
pytest ${NAME}
# Install standard test dependencies; YMMV
pip --quiet install \
.[test] pytest pytest-cov PyHamcrest
pytest
elif [ "$1" = "lint" ]; then
pip --quiet install .\[lint\]
# Install standard linting dependencies; YMMV
pip --quiet install \
.[lint]
flake8 ${NAME}
elif [ "$1" = "typehinting" ]; then
pip --quiet install .\[typehinting\]
mypy ${NAME}
# Install standard type-linting dependencies
pip --quiet install mypy types-simplejson types-python-dateutil
exec mypy ${NAME} --ignore-missing-imports
else
echo "Cannot execute $@"
exit 3
Expand Down
6 changes: 3 additions & 3 deletions microcosm_flask/audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""
from collections import namedtuple
from contextlib import contextmanager
from distutils.util import strtobool
from functools import wraps
from json import loads
from logging import DEBUG, getLogger
Expand All @@ -17,6 +16,7 @@
from microcosm.config.types import boolean
from microcosm_logging.timing import elapsed_time

from microcosm_flask.converters import str_to_bool
from microcosm_flask.errors import (
extract_context,
extract_error_message,
Expand Down Expand Up @@ -63,7 +63,7 @@ def should_skip_logging(func):
Should we skip logging for this handler?

"""
disabled = strtobool(request.headers.get("x-request-nolog", "false"))
disabled = str_to_bool(request.headers.get("x-request-nolog", "false"))
return disabled or getattr(func, SKIP_LOGGING, False)


Expand All @@ -75,7 +75,7 @@ def logging_levels():
Supports setting per-request debug logging using the `X-Request-Debug` header.

"""
enabled = strtobool(request.headers.get("x-request-debug", "false"))
enabled = str_to_bool(request.headers.get("x-request-debug", "false"))
level = None
try:
if enabled:
Expand Down
3 changes: 2 additions & 1 deletion microcosm_flask/cloning.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ class DAGSchema(Schema):
Nodes should be overridden with a non-raw schema.

"""
# Nb. using fields.Raw inside fields.Nested trips up mypy. documentation doesnt clarify.
nodes = fields.Nested(
fields.Raw,
fields.Raw, # type: ignore[arg-type]
required=True,
attribute="nodes_map",
)
Expand Down
4 changes: 2 additions & 2 deletions microcosm_flask/conventions/health.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using HTTP 200/503 status codes to indicate healthiness.

"""
from distutils.util import strtobool
from functools import wraps
from itertools import chain
from logging import Logger
Expand All @@ -18,6 +17,7 @@
from microcosm_flask.conventions.base import Convention
from microcosm_flask.conventions.build_info import BuildInfo
from microcosm_flask.conventions.encoding import load_query_string_data, make_response
from microcosm_flask.converters import str_to_bool
from microcosm_flask.errors import extract_error_message
from microcosm_flask.namespaces import Namespace
from microcosm_flask.operations import Operation
Expand Down Expand Up @@ -158,7 +158,7 @@ def configure_health(graph):
subject=Health,
)

include_build_info = strtobool(graph.config.health_convention.include_build_info)
include_build_info = str_to_bool(graph.config.health_convention.include_build_info)
convention = HealthConvention(graph, include_build_info)
convention.configure(ns, retrieve=tuple())
return convention.health
13 changes: 4 additions & 9 deletions microcosm_flask/conventions/landing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
Landing Page convention.

"""
from distutils import dist
from io import StringIO
from importlib.metadata import PackageNotFoundError, metadata
from json import dumps
from pkg_resources import DistributionNotFound, get_distribution

from jinja2 import Template

Expand All @@ -29,12 +27,9 @@ def get_properties_and_version():

"""
try:
distribution = get_distribution(graph.metadata.name)
metadata_str = distribution.get_metadata(distribution.PKG_INFO)
package_info = dist.DistributionMetadata()
package_info.read_pkg_file(StringIO(metadata_str))
return package_info
except DistributionNotFound:
package_metadata = metadata(graph.metadata.name)
return package_metadata
except PackageNotFoundError:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice @salmanmashayekh looks like almost 1-to-1 replacement

return None

def get_swagger_versions():
Expand Down
12 changes: 12 additions & 0 deletions microcosm_flask/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ def configure_uuid(graph):

"""
return FlaskUUID(graph.flask)


def str_to_bool(value):
"""
Convert a string value to boolean.
Similar to distutils.util.strtobool, it returns an int.
"""
if str(value).lower() in ('yes', 'true', 't', 'y', '1'):
return 1
elif str(value).lower() in ('no', 'false', 'f', 'n', '0'):
return 0
raise ValueError(f"Invalid boolean value: {value}")
6 changes: 3 additions & 3 deletions microcosm_flask/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class ErrorContextSchema(Schema):


class ErrorSchema(Schema):
message = fields.String(required=True, default="Unknown Error")
code = fields.Integer(required=True, default=500)
retryable = fields.Boolean(required=True, default=False)
message = fields.String(required=True, dump_default="Unknown Error")
code = fields.Integer(required=True, dump_default=500)
retryable = fields.Boolean(required=True, dump_default=False)
context = fields.Nested(ErrorContextSchema, required=False) # type: ignore


Expand Down
4 changes: 2 additions & 2 deletions microcosm_flask/swagger/parameters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections.abc import Mapping
from functools import lru_cache
from pkg_resources import iter_entry_points
from importlib.metadata import entry_points
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now using importlib instead of pkg_resources, this was last remaining references to this now deprecated package.

from typing import Any

from marshmallow.fields import Field
Expand Down Expand Up @@ -54,7 +54,7 @@ def builder_types(cls) -> list[type[ParameterBuilder]]:
Define the available builder types.

"""
return [entry_point.load() for entry_point in iter_entry_points(ENTRY_POINT)]
return [entry_point.load() for entry_point in entry_points(group=ENTRY_POINT)]

@classmethod
def default_builder_type(cls) -> type[ParameterBuilder]:
Expand Down
7 changes: 4 additions & 3 deletions microcosm_flask/tests/swagger/parameters/test_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@


class FooSchema(Schema):
deprecated_constant_list = fields.Constant(constant=[], dump_only=True)
deprecated_constant_string = fields.Constant(constant="HELLO", dump_only=True)
deprecated_constant_int = fields.Constant(constant=123, dump_only=True)
# Nb. mypy wants type annotations for these fields, unclear what those would be. Disable checks below.
deprecated_constant_list = fields.Constant(constant=[], dump_only=True) # type: ignore[var-annotated]
deprecated_constant_string = fields.Constant(constant="HELLO", dump_only=True) # type: ignore[var-annotated]
deprecated_constant_int = fields.Constant(constant=123, dump_only=True) # type: ignore[var-annotated]


def test_field_constant_list():
Expand Down
2 changes: 1 addition & 1 deletion microcosm_flask/tests/swagger/parameters/test_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class FooSchema(Schema):
id = fields.UUID()
foo = fields.String(metadata={"description": "Foo"}, default="bar")
foo = fields.String(metadata={"description": "Foo"}, dump_default="bar")
payload = fields.Dict()
datetime = fields.DateTime()

Expand Down
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ force_grid_wrap = 4
float_to_top = True
include_trailing_comma = True
known_first_party = microcosm_flask
extra_standard_library = pkg_resources
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no longer needed now that we switched to importlib

line_length = 99
lines_after_imports = 2
multi_line_output = 3
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"jsonschema>=3.2.0",
"marshmallow>=3.0.0",
"microcosm>=4.0.0",
"microcosm-logging>=2.0.0",
"microcosm-logging>=2.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once this is merged and released this version will be available - should fix remaining test-failures in CI for this PR cc/ @salmanmashayekh @lfmoisa-globality

"openapi>=2.0.0",
"python-dateutil>=2.7.3",
"PyYAML>=3.13",
Expand All @@ -53,9 +53,9 @@
"lint": [
"mypy",
"flake8",
"flake8-print",
"flake8-logging-format>=1.0.0",
"flake8-isort",
"flake8-logging-format>=1.0.0",
"flake8-print",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just sorting deps

"types-python-dateutil",
"types-setuptools",
],
Expand Down