Metadata-Version: 2.4
Name: aws-console-app
Version: 0.5.9
Summary: Console app for Amazon Bedrock chat and model discovery
Author-email: Shan Konduru <shan.konduru@example.com>
License: MIT
Keywords: aws,bedrock,llm,claude,console,chat,boto3
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# AWS Bedrock Console App (Python)

A reusable, customizable, and extendable console application for interacting with Amazon Bedrock LLMs using AWS named profiles.

The app is designed for local development on both Windows and Linux, supports AWS SSO profiles, and can run from a self-managed `.venv` using the provided launcher scripts.

## Features

- Cross-platform runtime (Windows/Linux)
- Reads AWS profile/region from CLI or `.env` fallback
- Reads account/auth settings from your local `.aws` folder (`config`, `credentials`, `sso/cache`)
- AWS SSO-friendly authentication behavior:
  - Reuses cached token when valid
  - Triggers `aws sso login --profile <profile> --no-browser --use-device-code` when needed
- Bedrock chat support with model adapters:
  - Anthropic Claude
  - Amazon Titan Text
  - Amazon Nova
- List available Bedrock text models and embedding models for a region
- OOP architecture for easy extension
- Pytest unit tests with coverage gate
- CI workflows for tests, pip-audit, and Trivy FS scan
- Automated publishing workflows for TestPyPI and PyPI

## Project Structure

```text
aws_console_app/
|-- main.py
|-- run.bat
|-- run.sh
|-- requirements.txt
|-- requirements-dev.txt
|-- pyproject.toml
|-- src/
|   |-- auth/
|   |   |-- aws_auth.py
|   |   `-- token_manager.py
|   |-- bedrock/
|   |   |-- bedrock_client.py
|   |   |-- model_catalog.py
|   |   `-- models/
|   |       |-- base_model.py
|   |       |-- claude_model.py
|   |       |-- titan_model.py
|   |       `-- nova_model.py
|   |-- config/
|   |   `-- aws_config.py
|   |-- session/
|   |   `-- conversation.py
|   `-- ui/
|       `-- console_ui.py
|-- tests/
`-- .github/workflows/
```

## Prerequisites

- Python 3.11+
- AWS CLI v2 configured
- Access to Amazon Bedrock in your AWS account/region
- For SSO profiles: profile configured with `aws configure sso`

## Setup

### Option A: Windows launcher

```powershell
.\run.bat --help
```

### Option B: Linux launcher

```bash
chmod +x run.sh
./run.sh --help
```

Launchers will:

1. Create `.venv` if missing
2. Install dependencies from `requirements.txt` on first run
3. Execute `main.py` using `.venv` Python

## Run In Docker Desktop

Yes, this app reads AWS settings and SSO cache from the home `.aws` directory.

Paths used by the app:

- `~/.aws/config`
- `~/.aws/credentials`
- `~/.aws/sso/cache`

To run inside Docker while reusing your host AWS profile/session, mount your host `.aws` into `/root/.aws` in the container.

### Build image

```powershell
docker build -t aws-console-app:0.5.3 .
```

### Run interactive chat (Windows PowerShell)

```powershell
docker run --rm -it `
  -v "$HOME/.aws:/root/.aws" `
  aws-console-app:0.5.3 `
  python main.py --profile <your-profile> --region <your-region> --model claude
```

### List models from container

```powershell
docker run --rm -it `
  -v "$HOME/.aws:/root/.aws" `
  aws-console-app:0.5.3 `
  python main.py --profile <your-profile> --region <your-region> --list-models
```

### Optional: pass `.env` from host

If you rely on `.env` profile/region fallback, mount it too:

```powershell
docker run --rm -it `
  -v "$HOME/.aws:/root/.aws" `
  -v "${PWD}/.env:/app/.env" `
  aws-console-app:0.5.3 `
  python main.py
```

Notes:

- Keep the `.aws` mount read-write for SSO refresh flows.
- If SSO is expired, run `aws sso login --profile <your-profile>` on host first, or let the container perform device-code login interactively.

### Docker Compose and helper scripts

Added files:

- `Dockerfile`
- `docker-compose.yml`
- `docker_build_image.bat`
- `docker_build_image.sh`
- `docker_create_container.bat`
- `docker_create_container.sh`
- `docker_run_app.bat`
- `docker_run_app.sh`
- `docker_check_mount.bat`
- `docker_check_mount.sh`

Build image with helper scripts:

```powershell
.\docker_build_image.bat
```

```bash
chmod +x docker_build_image.sh
./docker_build_image.sh
```

Create/start container with helper scripts:

```powershell
.\docker_create_container.bat
```

```bash
chmod +x docker_create_container.sh
./docker_create_container.sh
```

Run the app inside created container:

```powershell
docker exec -it aws-console-app python main.py --profile <your-profile> --region <your-region> --model claude
```

Or use helper scripts:

```powershell
.\docker_run_app.bat --profile <your-profile> --region <your-region> --model claude
```

```bash
chmod +x docker_run_app.sh
./docker_run_app.sh --profile <your-profile> --region <your-region> --model claude
```

Stop and remove the compose container:

```powershell
docker compose -f docker-compose.yml down
```

### Quick mount validation (host <-> container)

Use these scripts to validate both directions on the mounted `.aws` path:

1. Create file on host and verify inside container.
2. Create file in container and verify on host.
3. Clean up the test files.

Windows:

```powershell
.\docker_check_mount.bat
```

Linux/macOS:

```bash
chmod +x docker_check_mount.sh
./docker_check_mount.sh
```

## Switching GitHub Account Per Repo

## Package Publishing

The repository now uses two separate GitHub Actions workflows for publishing:

- TestPyPI publishes on every branch push using a unique `.dev<run_number>` version so repeated uploads do not collide.
- PyPI publishes only when the pushed git tag matches both `pyproject.toml` and `VERSION`.

Required publishing setup:

- Configure GitHub Actions trusted publishing for the TestPyPI project.
- Configure GitHub Actions trusted publishing for the PyPI project.

Recommended release flow:

```bash
# 1. Update both version sources to the same release number
#    pyproject.toml -> project.version
#    VERSION -> same value

# 2. Commit and push your changes
git push

# 3. Create a release tag that matches the version
git tag v0.5.5
git push origin v0.5.5
```

Accepted release tag formats:

- `vX.Y.Z`
- `X.Y.Z`

If you use multiple GitHub accounts, use the helper scripts to switch the current repository identity without changing your global git config.

Windows:

```powershell
.\set_git_account.bat shankonduru
.\set_git_account.bat shankondurucoforge shan.konduru@company.com https
```

Linux/macOS:

```bash
./set_git_account.sh shankonduru
./set_git_account.sh shankondurucoforge shan.konduru@company.com https
```

What these scripts update in the current repository:

- `user.name`
- `user.email`
- `credential.username`
- `remote.origin.url` (rewritten for the selected account)

Optional SSH mode:

```powershell
.\set_git_account.bat shankonduru "" ssh
```

```bash
./set_git_account.sh shankonduru "" ssh
```

In SSH mode, ensure your `~/.ssh/config` contains host aliases (`github-shankonduru`, `github-shankondurucoforge`) mapped to the correct keys.

## Configuration

### 1) `.aws` files

The app reads profile metadata from:

- `~/.aws/config`
- `~/.aws/credentials`
- `~/.aws/sso/cache` (for SSO token cache checks)

### 2) `.env` fallback (optional)

If CLI `--profile` / `--region` are omitted, values can come from `.env` in project root.

Supported profile keys (priority order after CLI):

- `PROFILE`
- `AWS_PROFILE`
- `AWS_PROFILE_NAME`

Supported region keys:

- `REGION`
- `AWS_REGION`

Example:

```dotenv
AWS_PROFILE_NAME=my-bedrock-profile
AWS_REGION=us-west-2
```

## CLI Usage

```bash
python main.py [options]
```

### Core options

- `--profile <name>` AWS named profile
- `--region <region>` AWS region (for example `us-west-2`)
- `--model <claude|titan|nova>` model family (default `claude`)
- `--model-id <full-bedrock-model-id>` explicit model id override
- `--max-tokens <int>` max generated tokens
- `--temperature <float>` generation temperature
- `--system-prompt <text>` custom system prompt
- `--max-history <int>` max chat turns kept in context
- `--list-profiles` list local AWS profiles and exit
- `--list-models` list available Bedrock text, embedding, and image models for region and exit

### Examples

Chat (values from `.env`):

```bash
python main.py
```

Chat (explicit):

```bash
python main.py --profile my-profile --region us-west-2 --model claude
```

List available models/embeddings:

```bash
python main.py --profile my-profile --region us-west-2 --list-models
```

## AWS SSO Behavior

For SSO-enabled profiles, the app checks token cache validity and only triggers login when needed.

Behavior summary:

1. If cached token is valid, continue without login
2. If not valid, run `aws sso login --profile <profile> --no-browser --use-device-code`
3. Build boto3 session and continue
4. If Bedrock call later fails due to expired auth, app re-authenticates and retries once

### Linux-safe SSO flow (device code)

The app uses AWS CLI device authorization flags to avoid local browser dependency issues on Linux hosts, headless environments, and remote terminals:

- `--no-browser`
- `--use-device-code`

This means login is completed by opening the provided verification URL on any device and entering the shown code.

### Flowchart

```mermaid
flowchart TD
  A[Start app] --> B[Resolve profile and region]
  B --> C[Read ~/.aws config and credentials]
  C --> D{SSO profile?}
  D -- No --> E[Build boto3 session]
  D -- Yes --> F{Valid cached SSO token?}
  F -- Yes --> E
  F -- No --> G[Run aws sso login --profile ... --no-browser --use-device-code]
  G --> H{Login command success?}
  H -- No --> I[Exit with auth error]
  H -- Yes --> J[Build boto3 session]
  E --> K[Invoke Bedrock]
  J --> K
  K --> L{Expired/Unauthorized/InvalidSignature?}
  L -- No --> M[Return model response]
  L -- Yes --> N[Re-authenticate once]
  N --> O[Retry Bedrock call once]
  O --> M
```

### Sequence diagram: active token found

```mermaid
sequenceDiagram
  participant User
  participant App
  participant TokenCache as ~/.aws/sso/cache
  participant AWS as Bedrock Runtime

  User->>App: Start app
  App->>TokenCache: Check token validity (>5 min remaining)
  TokenCache-->>App: Valid token found
  App->>App: Build boto3 session
  App->>AWS: invoke_model(...)
  AWS-->>App: Response payload
  App-->>User: Answer
```

### Sequence diagram: token missing or expired

```mermaid
sequenceDiagram
  participant User
  participant App
  participant TokenCache as ~/.aws/sso/cache
  participant CLI as aws sso login
  participant Device as Browser on any device
  participant AWS as Bedrock Runtime

  User->>App: Start app
  App->>TokenCache: Check token validity
  TokenCache-->>App: Missing/expired token
  App->>CLI: aws sso login --profile X --no-browser --use-device-code
  CLI-->>User: Show verification URL + device code
  User->>Device: Open URL and enter code
  Device-->>CLI: Authorization complete
  CLI-->>App: Exit code 0
  App->>App: Build boto3 session
  App->>AWS: invoke_model(...)
  AWS-->>App: Response payload
  App-->>User: Answer
```

### Scenario mapping

1. User did not complete SSO login:
The CLI command exits non-zero and the app exits with authentication error.

2. Active token is found:
Login is skipped and the session is built immediately.

3. Active token is not found:
Device-code login is triggered, then session is built on success.

4. Other situations:
If Bedrock returns expired/unauthorized/signature errors during runtime, the app re-authenticates once and retries the call.

## Extending with New Models

Implement a new adapter by subclassing `BaseBedrockModel`:

- `model_id`
- `build_request_body(messages)`
- `parse_response(response_body)`

Then register it in `main.py` model map.

## Development

Install dev dependencies:

```bash
python -m pip install -r requirements.txt -r requirements-dev.txt
```

Run tests:

```bash
pytest
```

Run tests with coverage report:

```bash
pytest --cov=src --cov=main --cov-report=term-missing
```

## Security and CI

Workflows include:

- Unit tests + 100% coverage gate
- `pip-audit` dependency vulnerability scan
- Trivy filesystem scan
- TestPyPI/PyPI publish workflow placeholders (currently disabled)

## Notes

- Ensure your selected region has Bedrock access and models enabled.
- `--list-models` output depends on account permissions and regional availability.
- If using SSO, complete browser login when prompted on first auth refresh.
