szbadge 1.0.2
A defensive, dependency-free text->SVG badge API for AWS Lambda
License: MIT
Requires Python: <4.0,>=3.12

# SZBadge

A **dead-simple, fuzz-hardened text → SVG badge service** for AWS Lambda.  
Lightweight, dependency-free, and built to survive hostile input.

<!---
After deployment, I'll put a dynamic badge here showing the current version.
Maybe something meta and cheeky like "40% Valdezium"? I'll have to check my notes.
--->

## Features

- ✅ **Lambda Function URL** ready (no API Gateway needed)  
- ✅ **Dependency-free** (pure Python stdlib)  
- ✅ **Strict sanitizers** (regex + bounded ints)  
- ✅ **Safe defaults & limits** (length caps, clamping, fallbacks)

## Routes

### Path mode

```url
/badge/<label>/<message>?color=<hex>&labelColor=<hex>&style=<flat|plastic>&scale=<1-3>
```

#### Path Mode Example

```url
/badge/Hello/World?color=ff3e00&labelColor=444&style=plastic&scale=2
```

### Query mode

```url
/badge?label=<label>&message=<message>&color=<hex>&labelColor=<hex>&style=<flat|plastic>&scale=<1-3>
```

#### Query Mode Example

```url
/badge?label=Build&message=passing&color=4c1
```

## Parameters

| Param        | Type   | Default  | Notes                                |
|--------------|--------|----------|--------------------------------------|
| `label`      | string | *(req’d)*| Max 128 chars                        |
| `message`    | string | *(req’d)*| Max 256 chars                        |
| `color`      | hex    | `4c1`    | Background of right side             |
| `labelColor` | hex    | `555555` | Background of left side              |
| `style`      | enum   | `flat`   | Either `flat` or `plastic`           |
| `scale`      | int    | `1`      | Bounded to `[1–3]`                   |

## Local testing

### 0) Clone repo

```bash
git clone https://github.com/djstompzone/szbadge.git
cd szbadge
pip install .[dev]
```

### 1) Run inline harness

```bash
szbadge-demo
```

Generates `test.svg` next to the script.

### 2) Local HTTP server (optional)

```bash
szbadge-serve
# Visit http://localhost:8080/badge/Sup/Dude?color=ff3e00
```

> You can also install with poetry and run `poetry run python -m szbadge` from the project directory

## Deploy to AWS Lambda

### 0) Prepare `trust.json` (assume role policy)

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "lambda.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

### 1) Create role & attach basic execution

```bash

export ROLE_NAME="szbadge-exec"
aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust.json

aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
```

### 2) Package code

```bash
zip -r code.zip szbadge/awslambda.py szbadge/config.py szbadge/render.py szbadge/utils.py
```

> Keep the deployment package minimal for fast cold starts, zip only the files Lambda needs.

### 3) Create function

```bash
export REGION=us-east-2
export ROLE_NAME="szbadge-exec"
export FUNCTION_NAME="szbadge"
export ROLE_ARN=$(aws iam get-role --role-name $ROLE_NAME --query "Role.Arn" --output text)

aws lambda create-function --function-name "$FUNCTION_NAME" --runtime python3.12 --role "$ROLE_ARN" --handler awslambda.lambda_handler --zip-file fileb://code.zip --region "$REGION"
```

### 4) Create a public **Function URL**

```bash
aws lambda create-function-url-config --function-name "$FUNCTION_NAME" --auth-type NONE --region "$REGION"

# allow public invoke via Function URL
aws lambda add-permission \
  --function-name "$FUNCTION_NAME" \
  --statement-id FunctionURLAllowPublic \
  --action lambda:InvokeFunctionUrl \
  --principal "*" \
  --function-url-auth-type NONE \
  --region "$REGION"
```

Fetch your URL:

```bash
export FUNCTION_URL=$(aws lambda get-function-url-config --function-name "$FUNCTION_NAME" --region "$REGION" --query FunctionUrl --output text)
echo "Your Function URL: $FUNCTION_URL"
```

### 5) Testing

- Simple "Sup Bro" badge

```bash
curl "$FUNCTION_URL/badge/Sup/Bro" -o hello.svg
```

- Full‑params "Valdezium" badge

```bash
curl "$FUNCTION_URL/badge/40%25/Valdezium?color=dc143c&labelColor=b0b0b0&style=plastic&scale=3" -o valdezium.svg
```

## Security

Fuzz‑hardened by design:

- **Regex‑validated hex** (`^[0-9a-fA-F]{3,6}$`)
- **Bounded ints** (`scale` clamped to `[1–3]`)
- **Length caps** (`label ≤ 128`, `message ≤ 256`)
- **Escaped XML** before rendering
- **Safe defaults** for missing/invalid params
- **Stdlib‑only** to keep attack surface minimal

## Roadmap

- [ ] Optional PNG output (`?format=png`)
- [ ] Preset colors (`?preset=success|warning|danger|info`)
- [ ] Icons / emoji on left side (`?icon=github`)
- [ ] CloudFront cache layer for global perf
- [ ] Docker container image for local dev / testing

## License

MIT © 2025 DJ Stomp  
See the [LICENSE](LICENSE) file for details.