apala-api 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apala_api-1.0.1/.claude/settings.local.json +9 -0
- apala_api-1.0.1/.gitignore +10 -0
- apala_api-1.0.1/.python-version +1 -0
- apala_api-1.0.1/CLAUDE.md +97 -0
- apala_api-1.0.1/PKG-INFO +530 -0
- apala_api-1.0.1/README.md +478 -0
- apala_api-1.0.1/VERIFICATION_RESULTS.md +127 -0
- apala_api-1.0.1/apala_client/__init__.py +55 -0
- apala_api-1.0.1/apala_client/client.py +334 -0
- apala_api-1.0.1/apala_client/metadata.py +133 -0
- apala_api-1.0.1/apala_client/models.py +183 -0
- apala_api-1.0.1/debug_test.py +101 -0
- apala_api-1.0.1/docs/Makefile +32 -0
- apala_api-1.0.1/docs/_build/html/.buildinfo +4 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/api/client.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/api/models.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/api/types.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/authentication.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/environment.pickle +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/examples.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/feedback_tracking.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/index.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/message_processing.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/.doctrees/quickstart.doctree +0 -0
- apala_api-1.0.1/docs/_build/html/_modules/apala_client/client.html +392 -0
- apala_api-1.0.1/docs/_build/html/_modules/apala_client/models.html +319 -0
- apala_api-1.0.1/docs/_build/html/_modules/index.html +112 -0
- apala_api-1.0.1/docs/_build/html/_sources/api/client.rst.txt +137 -0
- apala_api-1.0.1/docs/_build/html/_sources/api/models.rst.txt +187 -0
- apala_api-1.0.1/docs/_build/html/_sources/api/types.rst.txt +275 -0
- apala_api-1.0.1/docs/_build/html/_sources/authentication.rst.txt +278 -0
- apala_api-1.0.1/docs/_build/html/_sources/examples.rst.txt +553 -0
- apala_api-1.0.1/docs/_build/html/_sources/feedback_tracking.rst.txt +391 -0
- apala_api-1.0.1/docs/_build/html/_sources/index.rst.txt +124 -0
- apala_api-1.0.1/docs/_build/html/_sources/message_processing.rst.txt +384 -0
- apala_api-1.0.1/docs/_build/html/_sources/quickstart.rst.txt +289 -0
- apala_api-1.0.1/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js +123 -0
- apala_api-1.0.1/docs/_build/html/_static/basic.css +906 -0
- apala_api-1.0.1/docs/_build/html/_static/css/badge_only.css +1 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg +2671 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-bold.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-normal.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/css/theme.css +4 -0
- apala_api-1.0.1/docs/_build/html/_static/doctools.js +149 -0
- apala_api-1.0.1/docs/_build/html/_static/documentation_options.js +13 -0
- apala_api-1.0.1/docs/_build/html/_static/file.png +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bold.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bold.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bold.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bold.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-italic.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-italic.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-italic.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-italic.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-regular.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-regular.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-regular.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/Lato/lato-regular.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
- apala_api-1.0.1/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
- apala_api-1.0.1/docs/_build/html/_static/jquery.js +2 -0
- apala_api-1.0.1/docs/_build/html/_static/js/badge_only.js +1 -0
- apala_api-1.0.1/docs/_build/html/_static/js/theme.js +1 -0
- apala_api-1.0.1/docs/_build/html/_static/js/versions.js +228 -0
- apala_api-1.0.1/docs/_build/html/_static/language_data.js +192 -0
- apala_api-1.0.1/docs/_build/html/_static/minus.png +0 -0
- apala_api-1.0.1/docs/_build/html/_static/plus.png +0 -0
- apala_api-1.0.1/docs/_build/html/_static/pygments.css +75 -0
- apala_api-1.0.1/docs/_build/html/_static/searchtools.js +635 -0
- apala_api-1.0.1/docs/_build/html/_static/sphinx_highlight.js +154 -0
- apala_api-1.0.1/docs/_build/html/api/client.html +643 -0
- apala_api-1.0.1/docs/_build/html/api/models.html +996 -0
- apala_api-1.0.1/docs/_build/html/api/types.html +941 -0
- apala_api-1.0.1/docs/_build/html/authentication.html +394 -0
- apala_api-1.0.1/docs/_build/html/examples.html +660 -0
- apala_api-1.0.1/docs/_build/html/feedback_tracking.html +521 -0
- apala_api-1.0.1/docs/_build/html/genindex.html +386 -0
- apala_api-1.0.1/docs/_build/html/index.html +323 -0
- apala_api-1.0.1/docs/_build/html/message_processing.html +505 -0
- apala_api-1.0.1/docs/_build/html/objects.inv +0 -0
- apala_api-1.0.1/docs/_build/html/py-modindex.html +140 -0
- apala_api-1.0.1/docs/_build/html/quickstart.html +410 -0
- apala_api-1.0.1/docs/_build/html/search.html +130 -0
- apala_api-1.0.1/docs/_build/html/searchindex.js +1 -0
- apala_api-1.0.1/docs/api/client.rst +137 -0
- apala_api-1.0.1/docs/api/models.rst +187 -0
- apala_api-1.0.1/docs/api/types.rst +275 -0
- apala_api-1.0.1/docs/authentication.rst +278 -0
- apala_api-1.0.1/docs/conf.py +111 -0
- apala_api-1.0.1/docs/examples.rst +553 -0
- apala_api-1.0.1/docs/feedback_tracking.rst +391 -0
- apala_api-1.0.1/docs/index.rst +124 -0
- apala_api-1.0.1/docs/make.bat +35 -0
- apala_api-1.0.1/docs/message_processing.rst +384 -0
- apala_api-1.0.1/docs/quickstart.rst +289 -0
- apala_api-1.0.1/main.py +6 -0
- apala_api-1.0.1/notebooks/apala_demo.py +786 -0
- apala_api-1.0.1/notebooks/apala_demo_marimo.py +1138 -0
- apala_api-1.0.1/pyproject.toml +98 -0
- apala_api-1.0.1/test_core_functionality.py +87 -0
- apala_api-1.0.1/test_typed_responses.py +75 -0
- apala_api-1.0.1/tests/__init__.py +1 -0
- apala_api-1.0.1/tests/conftest.py +157 -0
- apala_api-1.0.1/tests/test_client.py +477 -0
- apala_api-1.0.1/tests/test_integration.py +241 -0
- apala_api-1.0.1/tests/test_models.py +244 -0
- apala_api-1.0.1/tox.ini +84 -0
- apala_api-1.0.1/uv.lock +3604 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
This is `apala-api`, a Python API project in its early stages. The codebase is minimal and appears to be a starter template for a loan/financial AI API service.
|
|
8
|
+
|
|
9
|
+
## Development Environment
|
|
10
|
+
|
|
11
|
+
- **Python Version**: 3.12 (specified in `.python-version`)
|
|
12
|
+
- **Package Manager**: Uses `uv` for Python package management
|
|
13
|
+
- **Project Structure**: Simple flat structure with main entry point in `main.py`
|
|
14
|
+
|
|
15
|
+
## Common Commands
|
|
16
|
+
|
|
17
|
+
### Environment Setup
|
|
18
|
+
```bash
|
|
19
|
+
# Install specific Python version if needed
|
|
20
|
+
uv python install 3.12
|
|
21
|
+
|
|
22
|
+
# Create virtual environment (uv handles this automatically)
|
|
23
|
+
uv sync
|
|
24
|
+
|
|
25
|
+
# Add dependencies
|
|
26
|
+
uv add <package-name>
|
|
27
|
+
|
|
28
|
+
# Add development dependencies
|
|
29
|
+
uv add --dev pytest ruff mypy
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Running the Application
|
|
33
|
+
```bash
|
|
34
|
+
# Run the main application
|
|
35
|
+
uv run python main.py
|
|
36
|
+
|
|
37
|
+
# Or run directly
|
|
38
|
+
uv run main.py
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Testing
|
|
42
|
+
```bash
|
|
43
|
+
# Run tests (once pytest is added)
|
|
44
|
+
uv run pytest
|
|
45
|
+
|
|
46
|
+
# Run tests with coverage
|
|
47
|
+
uv run pytest --cov
|
|
48
|
+
|
|
49
|
+
# Run specific test file
|
|
50
|
+
uv run pytest tests/test_example.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Development Tools
|
|
54
|
+
```bash
|
|
55
|
+
# Run linting
|
|
56
|
+
uv run ruff check .
|
|
57
|
+
|
|
58
|
+
# Run type checking
|
|
59
|
+
uv run mypy .
|
|
60
|
+
|
|
61
|
+
# Format code
|
|
62
|
+
uv run ruff format .
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Documentation Commands
|
|
66
|
+
```bash
|
|
67
|
+
# Build HTML documentation
|
|
68
|
+
uv run sphinx-build -b html docs docs/_build/html
|
|
69
|
+
|
|
70
|
+
# Clean documentation build directory
|
|
71
|
+
uv run python -c "import shutil; shutil.rmtree('docs/_build', ignore_errors=True)"
|
|
72
|
+
|
|
73
|
+
# Live documentation with auto-reload (opens on http://localhost:8001)
|
|
74
|
+
uv run sphinx-autobuild docs docs/_build/html --port 8001
|
|
75
|
+
|
|
76
|
+
# Check for broken links in documentation
|
|
77
|
+
uv run sphinx-build -b linkcheck docs docs/_build/linkcheck
|
|
78
|
+
|
|
79
|
+
# Open documentation in browser (macOS)
|
|
80
|
+
open docs/_build/html/index.html
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
The current codebase is minimal:
|
|
86
|
+
- `main.py`: Contains a simple entry point with a "Hello World" style function
|
|
87
|
+
- `pyproject.toml`: Basic Python project configuration with no dependencies yet
|
|
88
|
+
- No additional modules, tests, or complex architecture present
|
|
89
|
+
|
|
90
|
+
This appears to be a greenfield project ready for API development, likely intended for loan/financial AI services based on the project name.
|
|
91
|
+
|
|
92
|
+
## Key Files
|
|
93
|
+
|
|
94
|
+
- `main.py`: Application entry point
|
|
95
|
+
- `pyproject.toml`: Python project configuration and dependencies
|
|
96
|
+
- `.python-version`: Specifies Python 3.12 requirement
|
|
97
|
+
- `.gitignore`: Standard Python gitignore patterns
|
apala_api-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apala-api
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Python SDK for Phoenix Message Analysis Services - Loan/Financial AI API Client
|
|
5
|
+
Author: MessageAnalysis Team
|
|
6
|
+
Keywords: ai,api,financial,loans,messaging,phoenix
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Requires-Dist: marimo>=0.16.5
|
|
19
|
+
Requires-Dist: pydantic>=2.12.3
|
|
20
|
+
Requires-Dist: requests>=2.28.0
|
|
21
|
+
Provides-Extra: all
|
|
22
|
+
Requires-Dist: jupyter>=1.0.0; extra == 'all'
|
|
23
|
+
Requires-Dist: marimo>=0.3.0; extra == 'all'
|
|
24
|
+
Requires-Dist: mypy>=1.0.0; extra == 'all'
|
|
25
|
+
Requires-Dist: myst-parser>=3.0.1; extra == 'all'
|
|
26
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'all'
|
|
27
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'all'
|
|
28
|
+
Requires-Dist: pytest>=7.0.0; extra == 'all'
|
|
29
|
+
Requires-Dist: ruff>=0.1.0; extra == 'all'
|
|
30
|
+
Requires-Dist: sphinx-autodoc-typehints>=2.3.0; extra == 'all'
|
|
31
|
+
Requires-Dist: sphinx-rtd-theme>=3.0.2; extra == 'all'
|
|
32
|
+
Requires-Dist: sphinx>=7.4.7; extra == 'all'
|
|
33
|
+
Requires-Dist: tox>=4.0.0; extra == 'all'
|
|
34
|
+
Requires-Dist: types-requests>=2.28.0; extra == 'all'
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: tox>=4.0.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: types-requests>=2.28.0; extra == 'dev'
|
|
43
|
+
Provides-Extra: docs
|
|
44
|
+
Requires-Dist: myst-parser>=3.0.1; extra == 'docs'
|
|
45
|
+
Requires-Dist: sphinx-autodoc-typehints>=2.3.0; extra == 'docs'
|
|
46
|
+
Requires-Dist: sphinx-rtd-theme>=3.0.2; extra == 'docs'
|
|
47
|
+
Requires-Dist: sphinx>=7.4.7; extra == 'docs'
|
|
48
|
+
Provides-Extra: notebook
|
|
49
|
+
Requires-Dist: jupyter>=1.0.0; extra == 'notebook'
|
|
50
|
+
Requires-Dist: marimo>=0.3.0; extra == 'notebook'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# Apala API - Python SDK
|
|
54
|
+
|
|
55
|
+
[](https://www.python.org/downloads/)
|
|
56
|
+
[](https://docs.python.org/3/library/typing.html)
|
|
57
|
+
[](https://opensource.org/licenses/MIT)
|
|
58
|
+
|
|
59
|
+
A modern, type-safe Python SDK for interacting with Phoenix Message Analysis Services for loan/financial AI applications.
|
|
60
|
+
|
|
61
|
+
## 🚀 Quick Start
|
|
62
|
+
|
|
63
|
+
### Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Install the package
|
|
67
|
+
pip install apala-api
|
|
68
|
+
|
|
69
|
+
# Or install from source with development tools
|
|
70
|
+
git clone <repository-url>
|
|
71
|
+
cd apala_api
|
|
72
|
+
pip install -e ".[dev]"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Basic Usage
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from apala_client import ApalaClient, Message, MessageFeedback
|
|
79
|
+
|
|
80
|
+
# Initialize client
|
|
81
|
+
client = ApalaClient(
|
|
82
|
+
api_key="your-api-key",
|
|
83
|
+
base_url="https://your-server.com"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Authenticate (automatic JWT token management)
|
|
87
|
+
client.authenticate()
|
|
88
|
+
|
|
89
|
+
# Create customer message history
|
|
90
|
+
messages = [
|
|
91
|
+
Message(content="Hi, I need help with my loan application.", channel="EMAIL"),
|
|
92
|
+
Message(content="What are the current interest rates?", channel="SMS"),
|
|
93
|
+
Message(content="When will I hear back about approval?", channel="EMAIL")
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
# Create your candidate response
|
|
97
|
+
candidate = Message(
|
|
98
|
+
content="Thank you for your inquiry! Our current rates start at 3.5% APR for qualified borrowers. We'll review your application and respond within 2 business days.",
|
|
99
|
+
channel="EMAIL"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Process messages through the AI system
|
|
103
|
+
response = client.message_process(
|
|
104
|
+
message_history=messages,
|
|
105
|
+
candidate_message=candidate,
|
|
106
|
+
customer_id="550e8400-e29b-41d4-a716-446655440000",
|
|
107
|
+
zip_code="90210",
|
|
108
|
+
company_guid="550e8400-e29b-41d4-a716-446655440001"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
print(f"Processed message ID: {response['candidate_message']['message_id']}")
|
|
112
|
+
|
|
113
|
+
# Submit feedback after customer interaction
|
|
114
|
+
feedback = MessageFeedback(
|
|
115
|
+
original_message_id=response["candidate_message"]["message_id"],
|
|
116
|
+
sent_message_content=response["candidate_message"]["content"],
|
|
117
|
+
customer_responded=True,
|
|
118
|
+
quality_score=85,
|
|
119
|
+
time_to_respond_ms=1800000 # 30 minutes
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
feedback_result = client.submit_single_feedback(feedback)
|
|
123
|
+
print(f"Feedback submitted: {feedback_result['feedback_id']}")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 🎯 Core Features
|
|
127
|
+
|
|
128
|
+
### ✅ **Type-Safe API**
|
|
129
|
+
- Full **TypedDict** responses with IDE autocomplete
|
|
130
|
+
- **mypy** integration catches errors at development time
|
|
131
|
+
- **No runtime surprises** - all response fields are typed
|
|
132
|
+
|
|
133
|
+
### ✅ **Complete Functionality**
|
|
134
|
+
- **Message Processing**: Analyze customer conversations and candidate responses
|
|
135
|
+
- **Message Optimization**: Enhance messages for maximum engagement
|
|
136
|
+
- **Feedback Tracking**: Monitor message performance and customer responses
|
|
137
|
+
- **Authentication**: Automatic JWT token management with refresh
|
|
138
|
+
|
|
139
|
+
### ✅ **Production Ready**
|
|
140
|
+
- **Multi-Python Support**: Python 3.9, 3.10, 3.11, 3.12
|
|
141
|
+
- **Comprehensive Testing**: Unit tests, integration tests, type checking
|
|
142
|
+
- **Error Handling**: Uses standard `requests` exceptions (no custom exceptions)
|
|
143
|
+
- **Validation**: Client-side validation of UUIDs, zip codes, channels
|
|
144
|
+
|
|
145
|
+
### ✅ **Developer Experience**
|
|
146
|
+
- **Interactive Demo**: Marimo notebook with complete workflow
|
|
147
|
+
- **Documentation**: Full Sphinx docs with examples
|
|
148
|
+
- **Code Quality**: Ruff formatting, mypy type checking, tox multi-version testing
|
|
149
|
+
|
|
150
|
+
## 📖 Documentation
|
|
151
|
+
|
|
152
|
+
### Authentication
|
|
153
|
+
|
|
154
|
+
The SDK uses a secure two-tier authentication system:
|
|
155
|
+
|
|
156
|
+
1. **API Key**: Your long-lived company credentials
|
|
157
|
+
2. **JWT Tokens**: Short-lived session tokens for API calls (auto-managed)
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# Authentication is automatic - just provide your API key
|
|
161
|
+
client = ApalaClient(api_key="your-api-key")
|
|
162
|
+
auth_response = client.authenticate()
|
|
163
|
+
|
|
164
|
+
# JWT tokens are automatically refreshed when needed
|
|
165
|
+
# No manual token management required!
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Message Processing Workflow
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
# 1. Create message objects with validation
|
|
172
|
+
customer_messages = [
|
|
173
|
+
Message(
|
|
174
|
+
content="I'm interested in a home loan",
|
|
175
|
+
channel="EMAIL",
|
|
176
|
+
reply_or_not=False
|
|
177
|
+
),
|
|
178
|
+
Message(
|
|
179
|
+
content="What documents do I need?",
|
|
180
|
+
channel="SMS",
|
|
181
|
+
reply_or_not=False
|
|
182
|
+
)
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
# 2. Define your candidate response
|
|
186
|
+
candidate_response = Message(
|
|
187
|
+
content="Great! For a home loan, you'll need: income verification, credit report, and bank statements. We offer competitive rates starting at 3.2% APR.",
|
|
188
|
+
channel="EMAIL"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# 3. Process through AI system
|
|
192
|
+
result = client.message_process(
|
|
193
|
+
message_history=customer_messages,
|
|
194
|
+
candidate_message=candidate_response,
|
|
195
|
+
customer_id="customer-uuid-here",
|
|
196
|
+
zip_code="12345",
|
|
197
|
+
company_guid="company-uuid-here"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# 4. Get typed response with IDE completion
|
|
201
|
+
message_id = result["candidate_message"]["message_id"] # Type: str
|
|
202
|
+
company = result["company"] # Type: str
|
|
203
|
+
customer = result["customer_id"] # Type: str
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Message Optimization
|
|
207
|
+
|
|
208
|
+
Enhance your messages for better customer engagement:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# Optimize your message for maximum engagement
|
|
212
|
+
optimization = client.optimize_message(
|
|
213
|
+
message_history=customer_messages,
|
|
214
|
+
candidate_message=candidate_response,
|
|
215
|
+
customer_id="customer-uuid",
|
|
216
|
+
zip_code="12345",
|
|
217
|
+
company_guid="company-uuid"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
print(f"Original: {optimization['original_message']}")
|
|
221
|
+
print(f"Optimized: {optimization['optimized_message']}")
|
|
222
|
+
print(f"Recommended channel: {optimization['recommended_channel']}")
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Feedback Tracking
|
|
226
|
+
|
|
227
|
+
Monitor message performance and learn from customer interactions:
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
# Track how customers respond to your messages
|
|
231
|
+
feedback = MessageFeedback(
|
|
232
|
+
original_message_id="message-id-from-processing",
|
|
233
|
+
sent_message_content="The actual message you sent",
|
|
234
|
+
customer_responded=True,
|
|
235
|
+
quality_score=88, # 0-100 quality rating
|
|
236
|
+
time_to_respond_ms=1200000 # 20 minutes in milliseconds
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
result = client.submit_single_feedback(feedback)
|
|
240
|
+
print(f"Feedback recorded with ID: {result['feedback_id']}")
|
|
241
|
+
|
|
242
|
+
# Or submit multiple feedback items at once
|
|
243
|
+
feedback_list = [(message1, feedback1), (message2, feedback2)]
|
|
244
|
+
results = client.message_feedback(feedback_list)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## 🔧 Configuration
|
|
248
|
+
|
|
249
|
+
### Environment Variables
|
|
250
|
+
|
|
251
|
+
Set these for production deployment:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Required
|
|
255
|
+
export APALA_API_KEY="your-production-api-key"
|
|
256
|
+
export APALA_BASE_URL="https://your-phoenix-server.com"
|
|
257
|
+
export APALA_COMPANY_GUID="your-company-uuid"
|
|
258
|
+
|
|
259
|
+
# Optional
|
|
260
|
+
export APALA_CUSTOMER_ID="default-customer-uuid" # For testing
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Client Configuration
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
# Basic configuration
|
|
267
|
+
client = ApalaClient(
|
|
268
|
+
api_key="your-key",
|
|
269
|
+
base_url="https://api.yourcompany.com"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Advanced usage with custom session
|
|
273
|
+
import requests
|
|
274
|
+
session = requests.Session()
|
|
275
|
+
session.timeout = 30 # Custom timeout
|
|
276
|
+
client = ApalaClient(api_key="your-key")
|
|
277
|
+
client._session = session
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## 🧪 Testing & Development
|
|
281
|
+
|
|
282
|
+
### Setup
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
# Clone and install in development mode with uv
|
|
286
|
+
git clone <repository-url>
|
|
287
|
+
cd apala_api
|
|
288
|
+
uv sync --group dev
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Running Tests
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Run unit tests
|
|
295
|
+
uv run pytest tests/test_models.py tests/test_client.py -v
|
|
296
|
+
|
|
297
|
+
# Run with coverage
|
|
298
|
+
uv run pytest --cov=apala_client --cov-report=html
|
|
299
|
+
|
|
300
|
+
# Run integration tests (requires running server)
|
|
301
|
+
# In Fish shell:
|
|
302
|
+
env RUN_INTEGRATION_TESTS=1 APALA_API_KEY=test-key APALA_COMPANY_GUID=test-company-uuid uv run pytest tests/test_integration.py
|
|
303
|
+
|
|
304
|
+
# In Bash/Zsh:
|
|
305
|
+
export RUN_INTEGRATION_TESTS=1 APALA_API_KEY=test-key APALA_COMPANY_GUID=test-company-uuid
|
|
306
|
+
uv run pytest tests/test_integration.py
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Code Quality
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Static type checking
|
|
313
|
+
uv run mypy .
|
|
314
|
+
|
|
315
|
+
# Linting
|
|
316
|
+
uv run ruff check .
|
|
317
|
+
|
|
318
|
+
# Code formatting
|
|
319
|
+
uv run ruff format .
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Documentation
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Build HTML documentation
|
|
326
|
+
uv run sphinx-build -b html docs docs/_build/html
|
|
327
|
+
|
|
328
|
+
# Build with live reload (auto-refreshes on changes)
|
|
329
|
+
uv run sphinx-autobuild docs docs/_build/html --port 8001
|
|
330
|
+
|
|
331
|
+
# Clean build directory
|
|
332
|
+
uv run python -c "import shutil; shutil.rmtree('docs/_build', ignore_errors=True)"
|
|
333
|
+
|
|
334
|
+
# Check for broken links
|
|
335
|
+
uv run sphinx-build -b linkcheck docs docs/_build/linkcheck
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Multi-Python Testing
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Test across Python versions
|
|
342
|
+
uv run tox
|
|
343
|
+
|
|
344
|
+
# Test specific version
|
|
345
|
+
uv run tox -e py311
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## 📊 Interactive Demo
|
|
349
|
+
|
|
350
|
+
Try the complete workflow in an interactive notebook:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# Install notebook dependencies
|
|
354
|
+
pip install -e ".[notebook]"
|
|
355
|
+
|
|
356
|
+
# Run the interactive demo
|
|
357
|
+
cd notebooks
|
|
358
|
+
marimo run apala_demo.py
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The demo covers:
|
|
362
|
+
- 🔐 Authentication setup
|
|
363
|
+
- 📤 Message processing workflow
|
|
364
|
+
- 🎯 Message optimization
|
|
365
|
+
- 📊 Feedback submission
|
|
366
|
+
- ⚡ Error handling examples
|
|
367
|
+
|
|
368
|
+
## 🛡️ Error Handling
|
|
369
|
+
|
|
370
|
+
The SDK uses standard Python exceptions - no custom error types to learn:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
import requests
|
|
374
|
+
from apala_client import ApalaClient
|
|
375
|
+
|
|
376
|
+
client = ApalaClient(api_key="your-key")
|
|
377
|
+
|
|
378
|
+
try:
|
|
379
|
+
# All SDK methods may raise requests exceptions
|
|
380
|
+
response = client.message_process(...)
|
|
381
|
+
|
|
382
|
+
except requests.HTTPError as e:
|
|
383
|
+
# HTTP errors (4xx, 5xx responses)
|
|
384
|
+
print(f"HTTP {e.response.status_code}: {e}")
|
|
385
|
+
|
|
386
|
+
except requests.ConnectionError as e:
|
|
387
|
+
# Network connectivity issues
|
|
388
|
+
print(f"Connection failed: {e}")
|
|
389
|
+
|
|
390
|
+
except requests.Timeout as e:
|
|
391
|
+
# Request timeout
|
|
392
|
+
print(f"Request timed out: {e}")
|
|
393
|
+
|
|
394
|
+
except requests.RequestException as e:
|
|
395
|
+
# Any other requests-related error
|
|
396
|
+
print(f"Request error: {e}")
|
|
397
|
+
|
|
398
|
+
except ValueError as e:
|
|
399
|
+
# Data validation errors (invalid UUIDs, etc.)
|
|
400
|
+
print(f"Invalid data: {e}")
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## 🔍 API Reference
|
|
404
|
+
|
|
405
|
+
### ApalaClient
|
|
406
|
+
|
|
407
|
+
Main client class for all API interactions.
|
|
408
|
+
|
|
409
|
+
#### Constructor
|
|
410
|
+
```python
|
|
411
|
+
ApalaClient(api_key: str, base_url: str = "http://localhost:4000")
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
#### Methods
|
|
415
|
+
|
|
416
|
+
| Method | Return Type | Description |
|
|
417
|
+
|--------|-------------|-------------|
|
|
418
|
+
| `authenticate()` | `AuthResponse` | Exchange API key for JWT tokens |
|
|
419
|
+
| `refresh_access_token()` | `RefreshResponse` | Refresh access token |
|
|
420
|
+
| `message_process(...)` | `MessageProcessingResponse` | Process customer messages |
|
|
421
|
+
| `optimize_message(...)` | `MessageOptimizationResponse` | Optimize message content |
|
|
422
|
+
| `submit_single_feedback(...)` | `FeedbackResponse` | Submit single feedback |
|
|
423
|
+
| `message_feedback(...)` | `List[FeedbackResponse]` | Submit multiple feedback items |
|
|
424
|
+
| `close()` | `None` | Close HTTP session |
|
|
425
|
+
|
|
426
|
+
### Data Models
|
|
427
|
+
|
|
428
|
+
#### Message
|
|
429
|
+
Customer or candidate message with validation.
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
@dataclass
|
|
433
|
+
class Message:
|
|
434
|
+
content: str # Message text
|
|
435
|
+
channel: str # "SMS", "EMAIL", "OTHER"
|
|
436
|
+
message_id: Optional[str] = None # Auto-generated if None
|
|
437
|
+
send_timestamp: Optional[str] = None # Auto-generated if None
|
|
438
|
+
reply_or_not: bool = False # Whether this is a reply
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### MessageFeedback
|
|
442
|
+
Performance feedback for processed messages.
|
|
443
|
+
|
|
444
|
+
```python
|
|
445
|
+
@dataclass
|
|
446
|
+
class MessageFeedback:
|
|
447
|
+
original_message_id: str # ID from message processing
|
|
448
|
+
sent_message_content: str # Actual message sent to customer
|
|
449
|
+
customer_responded: bool # Did customer respond?
|
|
450
|
+
quality_score: int # Quality rating 0-100
|
|
451
|
+
time_to_respond_ms: Optional[int] = None # Response time in milliseconds
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Response Types
|
|
455
|
+
|
|
456
|
+
All API responses are fully typed with TypedDict:
|
|
457
|
+
|
|
458
|
+
#### AuthResponse
|
|
459
|
+
```python
|
|
460
|
+
class AuthResponse(TypedDict):
|
|
461
|
+
access_token: str
|
|
462
|
+
refresh_token: str
|
|
463
|
+
token_type: str
|
|
464
|
+
expires_in: int
|
|
465
|
+
company_id: str
|
|
466
|
+
company_name: str
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
#### MessageProcessingResponse
|
|
470
|
+
```python
|
|
471
|
+
class MessageProcessingResponse(TypedDict):
|
|
472
|
+
company: str
|
|
473
|
+
customer_id: str
|
|
474
|
+
candidate_message: CandidateMessageResponse
|
|
475
|
+
|
|
476
|
+
class CandidateMessageResponse(TypedDict):
|
|
477
|
+
content: str
|
|
478
|
+
channel: str
|
|
479
|
+
message_id: str
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
*See full API documentation for complete type definitions.*
|
|
483
|
+
|
|
484
|
+
## 🤝 Contributing
|
|
485
|
+
|
|
486
|
+
We welcome contributions! Please see our contributing guidelines:
|
|
487
|
+
|
|
488
|
+
1. **Fork** the repository
|
|
489
|
+
2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
|
|
490
|
+
3. **Add tests** for new functionality
|
|
491
|
+
4. **Run the test suite** (`pytest` and `mypy apala_client`)
|
|
492
|
+
5. **Commit** your changes (`git commit -m 'Add amazing feature'`)
|
|
493
|
+
6. **Push** to your branch (`git push origin feature/amazing-feature`)
|
|
494
|
+
7. **Create** a Pull Request
|
|
495
|
+
|
|
496
|
+
### Development Setup
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
git clone <your-fork>
|
|
500
|
+
cd apala_api
|
|
501
|
+
pip install -e ".[dev]"
|
|
502
|
+
|
|
503
|
+
# Run all checks before submitting
|
|
504
|
+
pytest # Unit tests
|
|
505
|
+
mypy apala_client # Type checking
|
|
506
|
+
ruff check apala_client # Linting
|
|
507
|
+
ruff format apala_client # Formatting
|
|
508
|
+
tox # Multi-Python testing
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
## 📄 License
|
|
512
|
+
|
|
513
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
514
|
+
|
|
515
|
+
## 🔗 Links
|
|
516
|
+
|
|
517
|
+
- **Documentation**: [Full API Documentation](docs/)
|
|
518
|
+
- **Source Code**: [GitHub Repository](#)
|
|
519
|
+
- **Issue Tracker**: [GitHub Issues](#)
|
|
520
|
+
- **PyPI Package**: [apala-api](#)
|
|
521
|
+
|
|
522
|
+
## 💬 Support
|
|
523
|
+
|
|
524
|
+
- **GitHub Issues**: For bugs and feature requests
|
|
525
|
+
- **Documentation**: Complete API reference and guides
|
|
526
|
+
- **Type Safety**: Full mypy support for development-time error catching
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
*Built with ❤️ for the loan/financial AI community*
|