Skip to content

Releases: syngenta/acai-python

v2.8.1 — dedupe equal RedactionFilters

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 06:37
89ae910

Fixed

  • logger: CommonLogger.register_callback now dedupes equal callbacks; RedactionFilter gained value equality (__eq__/__hash__). Registering the same filter from multiple handler entrypoints in one process is idempotent (no stacked redaction passes). Distinct callbacks still stack.

Full changelog: 2.8.0...2.8.1

v2.8.0

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 03:22
e876123

Added

  • logger: pluggable pre-print callback hook on CommonLogger (register_callback / reset_callbacks) — records pass through callbacks before emit (#328)
  • logger: RedactionFilter callback — opt-in scrubbing of matching field names (any depth) and regex value matches, redact_with configurable (#328)

Changed

  • logger: CommonLogger is now a singleton — configured once, reused across all logger.log() calls; callbacks are process-global (#329)

LOG_FORMAT / LOG_LEVEL continue to be read per call (env-driven). Fully backward compatible.

Full changelog: 2.7.0...2.8.0

v2.7.0

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 03:19
d8189fc

Added

  • apigateway: map request-contract errors to 400 instead of 500 (#327)

Fixed

  • logger: accept canonical Python level names (WARNING, DEBUG, CRITICAL) — shipped in interim tag 2.6.2

Full changelog: 2.6.1...2.7.0

v2.6.1

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 03:19
657bfe7

Build & CI

  • Switch from pipenv to uv
  • Tighten uv setup (locked install, pinned uv, setuptools-scm, [tool.uv])
  • Parallelize lint, test, and sonarcloud jobs
  • Use full checkout for the sonarcloud-scan job

Full changelog: 2.6.0...2.6.1

v2.6.0

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 03:19
f1a479a

Added

  • ALB Router with full API Gateway routing parity

Docs

  • Document alb.Router for HTTP routing on ALB Lambda targets

Full changelog: 2.5.1...2.6.0

v2.5.1

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 06:07
6f6a3cd

Bug Fix

validate_record_body crashed with TypeError when body is non-dict and required_body is a Pydantic model.

When a record body was not a dict (e.g., empty string "", None, or a list) and required_body pointed to a Pydantic BaseModel, the resolved(**body) unpacking raised TypeError instead of producing a validation error.

Now returns {'key_path': 'body', 'message': 'Expected JSON object body'} cleanly, which flows through all failure_mode options correctly.

Found during

Downstream integration with service-payroll-kyc where ALB records can arrive with empty-string bodies.

v2.5.0

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 06:07
7bf46ec

What's New

Pydantic BaseModel support for all records events

required_body now accepts a Pydantic BaseModel subclass on every event source (SQS, Kinesis, DynamoDB, MSK, SNS, S3, Firehose, MQ, DocumentDB, ALB) — not just API Gateway.

from pydantic import BaseModel
from acai_aws.sqs.requirements import requirements

class OrderEvent(BaseModel):
    order_id: str
    amount: float

@requirements(required_body=OrderEvent)
def handler(event):
    for record in event.records:
        process(record.body)

Unified failure_mode enum

Replaces the overlapping raise_body_error / raise_operation_error booleans with a single failure_mode kwarg:

Mode Behavior
FailureMode.SILENT_IGNORE Default — invalid records silently filtered (unchanged)
FailureMode.LOG_WARN Filter + structured WARN log per invalid record
FailureMode.RAISE_ERROR First invalid record raises RecordException
FailureMode.RETURN_FAILURE Auto-merge validation failures into batchItemFailures response
from acai_aws.base.event import FailureMode

@requirements(required_body=OrderEvent, failure_mode=FailureMode.RETURN_FAILURE)
def handler(event):
    # Framework auto-merges validation failures into batchItemFailures.
    # SQS/Kinesis/DynamoDB retries malformed messages instead of losing them.
    ...

ALB automatic HTTP 400

When required_body is set on an ALB handler, invalid bodies produce an HTTP 400 response matching the API Gateway error shape — handler is never called.

Eager validation

Validation now runs before the handler executes (was lazy on event.records access). All four modes are deterministic regardless of whether the handler accesses records.

Per-source batch_item_identifier

Records expose batch_item_identifier for partial batch response: SQS → messageId, Kinesis/DDB → sequenceNumber, MSK → topic-partition-offset.

100% line coverage

575 tests, pylint 10.00/10, 2382/2382 lines covered.

Deprecations

  • raise_body_error=True → use failure_mode=FailureMode.RAISE_ERROR
  • raise_operation_error=True → use failure_mode=FailureMode.RAISE_ERROR

Both still work with a one-time deprecation warning. Will be removed in the next major version.

Internal

  • validate_record_body error field renamed keykey_path (internal only, no external consumers)
  • S3 and MSK Event classes refactored to use _build_records / _post_operation_hook hooks
  • Deleted dead _reset_records helper

v2.4.0

Choose a tag to compare

@paulcruse3 paulcruse3 released this 30 Mar 17:18
f6d7fa0

What's New

ALB Event Source Support

Added Application Load Balancer as a new event source module (acai_aws.alb).

ALB sends a single Lambda proxy integration event (not a Records array). The new module wraps it for compatibility with the existing base class pattern.

Record properties:

  • body - JSON-parsed body (handles base64-encoded bodies)
  • operation - Maps HTTP methods to operations (POST=CREATED, PUT/PATCH=UPDATED, DELETE=DELETED)
  • http_method - Raw HTTP method
  • path - Request path
  • headers - Request headers dict
  • query_params - Query string parameters
  • source_ip - x-forwarded-for header
  • target_group_arn - ALB target group ARN

Usage:

from acai_aws.alb.requirements import requirements

@requirements()
def handler(records):
    for record in records.records:
        handle_request(record.http_method, record.body, record.source_ip)

Detected automatically via requestContext.elb in the event, registered as aws:elb event source.

v2.3.8

Choose a tag to compare

@paulcruse3 paulcruse3 released this 17 Jun 06:07
310a64a

What's Changed

Features

  • response_codes support in OpenAPI generator — Endpoints can now declare multiple HTTP status codes (e.g. 200/204) via @requirements(response_codes={200: 'User exists', 204: 'User does not exist'}). The existing required_response schema is applied to non-204 codes; 204 responses are emitted without a body. Fully backwards compatible — falls back to the original behavior when response_codes is not set.

Fixes

  • Resolve all pylint issues in openapi module — Added encoding='utf-8' to file writer open() calls, fixed missing final newline, removed unnecessary elif after return, added consistent return statements, and replaced broad Exception with ValueError in input validator. Pylint score now 10.00/10.

Full Changelog: 2.3.7...2.3.8

2.3.7

Choose a tag to compare

@paulcruse3 paulcruse3 released this 26 Mar 19:35
ab71c6a

fix: inline $defs from pydantic model_json_schema in OpenAPI generator. Produces universally compatible output without $defs references.