# python-aws-testing-utils
This repository contains common classes for use in integration testing aws infrastructure such as lambdas, step functions, sqs queues etc

## Installation

Install the package using pip:
```bash
pip install aws_testing_utils
```

Or add to your `pyproject.toml`:
```toml
dependencies = [
    "aws_testing_utils~=5.5"
]
```

## Type Annotations

This package ships with type annotations and a `py.typed` marker (PEP 561), so mypy and other type checkers will automatically pick up types when you import it. The package is checked with `mypy --strict`, so all public APIs have complete type coverage.

For richer IDE autocompletion on AWS client attributes, install the optional boto3 stubs in your dev environment:
```bash
pip install 'boto3-stubs[s3,sqs,dynamodb,lambda,logs,stepfunctions]'
```

## Usage

### `LambdaHandler.invoke`

`invoke` wraps boto3's `invoke` with success assertions. Any extra keyword
arguments are passed straight through to boto3, so new boto3 parameters need no
library release:

```python
from aws_testing_utils.lambda_handler import LambdaHandler

handler = LambdaHandler()

# Synchronous (RequestResponse) invoke, asserts StatusCode == 200.
response = handler.invoke('my-function', {'job_id': 123})

# Async invoke: boto3 returns 202, so set expected_status.
handler.invoke('my-function', {'job_id': 123},
               InvocationType='Event', expected_status=202)

# Expecting a failure? Skip the assertions.
handler.invoke('my-function', {'bad': 'input'}, assertion=False)
```

The response `Payload` is buffered before returning, so callers can read it
themselves (`response['Payload'].read()`).

**Running against a local RIE endpoint:** set `LAMBDA_ENDPOINT_URL` (e.g.
`http://localhost:9000/2015-03-31/functions/function/invocations`) and
`LambdaHandler` targets it instead of real AWS — no handler subclass needed.

### `StepFunctionHandler.execute`

`execute` also forwards extra keyword arguments to boto3's `start_execution`:

```python
from aws_testing_utils.step_function_handler import StepFunctionHandler

handler = StepFunctionHandler('my-state-machine')
handler.execute({'job_id': 123}, execution_name='run-1', traceHeader='trace-abc')
```

## 📦 Publishing

When changes are made to the code, a new version of the package must be published. Follow these steps:

1. Run the publishing pipeline at https://pipeline.theorchard.io/job/publish-pypi-package-v2/
   - The first run creates a release candidate (`rc`) version.
   - Run it a **second** time with the **release** option to promote the `rc` to a full release.
2. Update dependencies:
   - After publishing, update your project dependencies to reference the latest version of the package.
3. Learn more about the publishing process: [here](https://github.com/theorchard/docs/blob/master/boilerplates/pypi.md).

## Style Guide

We use `ruff` for linting and formatting, and `mypy` for type checking. Please run the following before committing your code.
```bash
# Auto-format with ruff
make format

# Check for linting issues
make lint

# Run mypy type checking
make type_check

# Run lint, type check, and tests together
make lint_and_test
```
