# Hive Text Recognition lambda

AWS Lambda that listens to `stream.asset.mezzanine.coverart` events from MSK, retrieves the image from ows-assets, runs Hive text recognition synchronously, and stores the extracted `block_text` back in ows-assets.

## Overview

For each Kafka record, it:

1. Deserializes the MSK event payload.
2. Extracts `ASSET_FINAL_ID` from the message.
3. Requests a presigned download URL from ows-assets.
4. Sends that URL to Hive's synchronous text-recognition endpoint.
5. Extracts `block_text` from the Hive response.
6. Posts the result to the ows-assets `hive-text-recognition` endpoint.

## Input Event

The function expects an MSK event in the standard AWS Kafka event shape. Each record's `value` must be a base64-encoded JSON object.

Example event:

```json
{
	"eventSource": "aws:kafka",
	"records": {
		"stream-asset-mezzanine-coverart-0": [
			{
				"topic": "stream.asset.mezzanine.coverart",
				"partition": 0,
				"offset": 0,
				"timestamp": 1700000000000,
				"timestampType": "CREATE_TIME",
				"value": "eyJBU1NFVF9GSU5BTF9JRCI6IDMwNzIwMzc1LCAiQVNTRVRfVVBMT0FEX0lEIjogMTk1NTc5OTgsICJBU1NFVF9TVUJUWVBFIjogImxhcmdlX2NvdmVyIiwgIkFTU0VUX1RZUEUiOiAiSlBHIiwgIkZJTEVOQU1FIjogImltYWdlcy92Mi9wcm9kdWN0L2xhcmdlX2NvdmVyL2U2OWRkYmQ3MGJjMjQ5YzViZTZhMzM4ODUzMDVmMzMyXzdkNmZmYzk4X2RiZTBfNDU4ZF9hMzZmXzc2OGZlZTUxOGJiYy5qcGVnIiwgIkJVQ0tFVCI6ICJxYS1hc3NldC1zdG9yYWdlIn0="
			}
		]
	}
}
```

Decoded message body:

```json
{
	"ASSET_FINAL_ID": 30720375,
	"ASSET_UPLOAD_ID": 19557998,
	"ASSET_SUBTYPE": "large_cover",
	"ASSET_TYPE": "JPG",
	"FILENAME": "images/v2/product/large_cover/example.jpeg",
	"BUCKET": "qa-asset-storage"
}
```

Relevant fields consumed by this lambda:

- `ASSET_FINAL_ID`: used to fetch the download URL and save the final OCR result.
- `ASSET_UPLOAD_ID`: present on some events but not used in processing.
- `ASSET_TYPE`: informational only.
- `ASSET_SUBTYPE`: informational only.
- `FILENAME`: informational only.
- `BUCKET`: informational only.
- `METADATA`: accepted if present, but not used.

## External Dependencies

### OWS Assets

The lambda calls ows-assets twice:

- `GET /v2/asset/download_url` with `asset_final_id` and `expires_in=300`
- `POST /hive-text-recognition` with:

```json
{
	"asset_final_id": 30720375,
	"block_text": "Extracted text from Hive"
}
```

### Hive

The lambda calls Hive's synchronous task endpoint:

- `POST https://api.thehive.ai/api/v2/task/sync`

Request body:

```json
{
	"url": "<presigned asset url>"
}
```

The function expects a response containing a nested `block_text` value. If that structure is missing, the lambda raises an exception.


## Local Development

Build and start the lambda container:

```bash
docker compose up --build function
```

Invoke the lambda locally through the Lambda Runtime Interface Emulator:

```bash
curl -XPOST \
	"http://localhost:9000/2015-03-31/functions/function/invocations" \
	-d @tests/sample_event_local.json
```

Notes:

- The container mounts `src/` and `config.py` for iterative local development.
- An optional `.env` file can be used for local environment variables.
- Local execution still requires valid credentials and secrets access unless the relevant calls are mocked.

## Testing

Run linting and unit tests in Docker:

```bash
docker compose run --rm lint-and-test
```

Useful flags:

- `SKIP_LINT=1` to skip yamllint and Ruff checks
- `COV_REPORT=html` to generate HTML coverage output in `htmlcov/`
- `TEST_ARGS='-v'` for verbose pytest output

The test runner ignores `tests/integration/` by default.
