github-actions[bot] commited on
Commit ·
69a3f71
1
Parent(s): 39438ca
chore: format README for Hugging Face [skip ci]
Browse files
README.md
CHANGED
|
@@ -1,363 +1,12 @@
|
|
| 1 |
-
# Joule Dynamics Real Estate Intelligence Server (Pulse AI)
|
| 2 |
-
|
| 3 |
-
[](https://fastapi.tiangolo.com)
|
| 4 |
-
[](https://www.python.org)
|
| 5 |
-
[](https://groq.com)
|
| 6 |
-
[](https://supabase.com)
|
| 7 |
-
[](https://resend.com)
|
| 8 |
-
[](https://langfuse.com)
|
| 9 |
-
[](https://huggingface.co/spaces)
|
| 10 |
-
|
| 11 |
-
---
|
| 12 |
-
|
| 13 |
-
## 1. Executive Summary
|
| 14 |
-
|
| 15 |
-
**Joule Dynamics Server** is a high-throughput, agentic inference backend engineered specifically to power the **Real Estate Telemetry & Rate Intelligence Dashboard (Pulse AI)**.
|
| 16 |
-
|
| 17 |
-
Operating far beyond standard CRUD paradigms, this server functions as an autonomous reasoning engine that compiles unstructured, natural-language investor queries into deterministic, parameterized **PostgreSQL PL/pgSQL stored procedures**, **window function aggregations**, and **pgvector semantic scans**. By combining ultra-low-latency LPU inference (Groq) with hierarchical schema gating, Server-Sent Events (SSE), and an autonomous double opt-in alert dispatch engine, the system delivers real-time market snapshots, rate change notifications, and geographic proximity analytics with sub-second time-to-first-token.
|
| 18 |
-
|
| 19 |
-
---
|
| 20 |
-
|
| 21 |
-
## 2. System Architecture (The AI Pipeline)
|
| 22 |
-
|
| 23 |
-
The telemetry backend utilizes an asynchronous, non-blocking pipeline spanning intent classification, localized dynamic tool retrieval, database execution, and streaming synthesis.
|
| 24 |
-
|
| 25 |
-
```
|
| 26 |
-
┌─────────────────────────────────────────────────────────────┐
|
| 27 |
-
│ Client Query via SSE Protocol │
|
| 28 |
-
│ POST /api/v1/real-estate/chat/stream │
|
| 29 |
-
└──────────────────────────────┬──────────────────────────────┘
|
| 30 |
-
│
|
| 31 |
-
▼
|
| 32 |
-
┌─────────────────────────────────────────────────────────────┐
|
| 33 |
-
│ 1. INTENT ROUTING & CATEGORY GATING │
|
| 34 |
-
│ Model: openai/gpt-oss-20b (~150ms) │
|
| 35 |
-
│ • Classifies: PATH_A | PATH_B | BOTH | etc. │
|
| 36 |
-
│ • Tags Domain: ["MARKET", "ANOMALY", "GEO"...] │
|
| 37 |
-
│ • Alert Shortcut: Direct Gating to Subscription │
|
| 38 |
-
└──────────────────────────────┬──────────────────────────────┘
|
| 39 |
-
│
|
| 40 |
-
▼
|
| 41 |
-
┌─────────────────────────────────────────────────────────────┐
|
| 42 |
-
│ 2. DYNAMIC TOOL DISCOVERY (Embedding Engine) │
|
| 43 |
-
│ Model: all-MiniLM-L6-v2 (Local, ~20ms latency) │
|
| 44 |
-
│ • Filters registry by domain categories │
|
| 45 |
-
│ • Cosine similarity ranking on tool descriptions │
|
| 46 |
-
│ • Injects Top-3 Tools + Universal Action Tools │
|
| 47 |
-
└──────────────────────────────┬──────────────────────────────┘
|
| 48 |
-
│
|
| 49 |
-
▼
|
| 50 |
-
┌───────────────────────────��─────────────────────────────────┐
|
| 51 |
-
│ 3. BRAIN & AGENTIC SYNTHESIS LOOP │
|
| 52 |
-
│ Model: openai/gpt-oss-120b │
|
| 53 |
-
│ • Multi-step tool orchestration (max 2 rounds) │
|
| 54 |
-
│ • Single-turn terminal tool break & directive │
|
| 55 |
-
│ • Parameter clamping & alias normalization │
|
| 56 |
-
│ • Execution via PostgREST RPC & pgvector RAG │
|
| 57 |
-
└──────────────────────────────┬──────────────────────────────┘
|
| 58 |
-
│
|
| 59 |
-
▼
|
| 60 |
-
┌─────────────────────────────────────────────────────────────┐
|
| 61 |
-
│ 4. SERVER-SENT EVENTS (SSE) STREAMING │
|
| 62 |
-
│ • event: status (Routing state) │
|
| 63 |
-
│ • event: tool_call (Active DB RPC payload) │
|
| 64 |
-
│ • event: token (Live Markdown tokens) │
|
| 65 |
-
│ • event: done (Final + Action Chips) │
|
| 66 |
-
└──────────────────────────────┬──────────────────────────────┘
|
| 67 |
-
│
|
| 68 |
-
▼
|
| 69 |
-
┌─────────────────────────────────────────────────────────────┐
|
| 70 |
-
│ 5. ACTION RESOLVER ENGINE (Modular Fallback) │
|
| 71 |
-
│ • Dynamically infers relevant action button chips │
|
| 72 |
-
│ • Contextual follow-up suggestions per domain │
|
| 73 |
-
└─────────────────────────────────────────────────────────────┘
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
-
### Pipeline Lifecycle:
|
| 77 |
-
1. **Routing & Intent Disambiguation:** Fast-path classifier (`openai/gpt-oss-20b`) categorizes the query into one of 6 pathways (`PATH_A` Live Data, `PATH_B` Methodology/RAG, `BOTH` Hybrid, `GREETING`, `COMMERCIAL_HANDOFF`, `OUT_OF_SCOPE`) and tags domain categories. When a user provides alert monitoring parameters (criteria + email), the router bypasses general retrieval and gates directly to `create_alert_subscription`.
|
| 78 |
-
2. **Context-Aware Dynamic Schema Gating:** To prevent token bloat (saving >75% of prompt tokens), a local sentence-transformer (`all-MiniLM-L6-v2`) ranks tool schemas against the user prompt (enriched with conversational history) and exposes strictly the Top-3 relevant tools + universal actions.
|
| 79 |
-
3. **Autonomous Execution Loop (Max 2 Rounds):** The synthesis engine (`openai/gpt-oss-120b`) generates JSON function call payloads and dispatches them against Supabase PostgREST RPC endpoints. For terminal tools (`create_alert_subscription`, `generate_data_export`, `generate_contact_buttons`, `suggest_actions`), the loop executes immediately in 1 turn, injecting an `_ACTION_DIRECTIVE` to deliver a clean confirmation without regenerating past tables.
|
| 80 |
-
4. **Action Resolver Engine:** Decoupled in `services/action_resolver.py`, the system guarantees that interactive follow-up chips (`suggest_actions`) are always dispatched to the UI even if the LLM omits them in its generation.
|
| 81 |
-
|
| 82 |
-
---
|
| 83 |
-
|
| 84 |
-
## 3. Tool Registry & Agentic Framework
|
| 85 |
-
|
| 86 |
-
The agent has direct access to specialized tools mapping to PostgreSQL PL/pgSQL stored procedures, geospatial calculations, background file exporters, and subscription provisioning:
|
| 87 |
-
|
| 88 |
-
| Category | Tool Name | Database / Execution Target | Technical Function & Capabilities |
|
| 89 |
-
|---|---|---|---|
|
| 90 |
-
| **Market & KPIs** | `get_real_estate_kpis` | `public.get_real_estate_kpis` | Aggregates portfolio KPIs (active properties, 7d delta, 25%+ price surge count, scrape health). |
|
| 91 |
-
| **Market & KPIs** | `get_market_averages` | `public.get_market_averages` | Calculates nightly rates and 7-day trailing baseline averages using SQL window functions. |
|
| 92 |
-
| **Market & KPIs** | `get_market_snapshot` | `public.get_market_snapshot` | Single-day comprehensive summary: active inventory, min/max rates, and occupancy rate %. |
|
| 93 |
-
| **Market & KPIs** | `get_market_trend` | `public.get_market_trend` | Multi-day historical rate trajectory (up to 90 days) across tracked market regions. |
|
| 94 |
-
| **Market & KPIs** | `get_market_rate_changes` | `public.get_market_rate_changes` | Counts properties with ANY nightly rate increase or decrease over lookback window (not just spikes). |
|
| 95 |
-
| **Market & KPIs** | `get_tracked_markets` | `public.get_tracked_markets` | Returns platform coverage, listing volumes, and operational regions in the database. |
|
| 96 |
-
| **Market & KPIs** | `get_recently_changed_tracking` | `public.get_recently_changed_tracking` | Audit log of listings newly activated or paused in the scraping registry. |
|
| 97 |
-
| **Anomalies** | `get_spike_alerts` | `public.get_spike_alerts` | Scans for sudden rate spikes exceeding configurable threshold (default 25% over 7d baseline). |
|
| 98 |
-
| **Anomalies** | `get_rate_anomaly_report` | `public.get_rate_anomaly_report` | Deep pricing anomaly investigation: lists previous rates, baseline delta, and deviation %. |
|
| 99 |
-
| **Anomalies** | `get_most_volatile_properties` | `public.get_most_volatile_properties` | Ranks properties with the highest dynamic pricing frequency and variance over lookback window. |
|
| 100 |
-
| **Listings & Rates** | `get_property_snapshot` | `public.get_property_snapshot` | Single-listing telemetry: bedrooms, coordinates, current rate, 7d baseline, and availability. |
|
| 101 |
-
| **Listings & Rates** | `get_property_detail` | `public.get_property_detail` | Comprehensive listing metadata, room configurations, amenities, host details, and current pricing. |
|
| 102 |
-
| **Listings & Rates** | `get_property_rate_changes` | `public.get_property_rate_changes` | Chronological price revision log tracking exact host rate adjustments over time. |
|
| 103 |
-
| **Listings & Rates** | `compare_properties` | `public.compare_properties` | Multi-property side-by-side comparison across pricing, occupancy, and bedroom configurations. |
|
| 104 |
-
| **Listings & Rates** | `search_properties` | `public.search_properties` | Multi-parameter search filtered by market, bedroom count, platform, availability, and search terms. |
|
| 105 |
-
| **Listings & Rates** | `get_availability_rate` | `public.get_availability_rate` | Computes calendar booking ratios, vacancy percentage, and active inventory metrics. |
|
| 106 |
-
| **Geospatial** | `geocode_address` | *Mapbox Geocoding Worker* | Translates natural language addresses/landmarks into decimal latitude/longitude coordinates. |
|
| 107 |
-
| **Geospatial** | `get_nearby_properties` | `public.get_nearby_properties` | Executes Haversine radius queries on geographic coordinates to find nearest listings. |
|
| 108 |
-
| **Geospatial** | `get_distance_km` | `public.get_distance_km` | PostGIS / mathematical straight-line distance computation between two property UUIDs. |
|
| 109 |
-
| **Universal Actions** | `generate_data_export` | *Appwrite Storage Worker* | Compiles structured real estate analysis into downloadable Markdown (`.md`) or CSV reports. |
|
| 110 |
-
| **Universal Actions** | `suggest_actions` | *SSE UI Protocol* | Dispatches native interactive action chips/buttons to guide user follow-ups and next steps. |
|
| 111 |
-
| **Universal Actions** | `generate_contact_buttons` | *Local Worker* | Generates interactive Email and WhatsApp contact buttons for bespoke engineering inquiries. |
|
| 112 |
-
| **Alerts & Monitor** | `create_alert_subscription` | *Alert Service Worker* | Provisions double opt-in subscriptions for market anomalies, price thresholds, availability shifts, or scheduled digests. |
|
| 113 |
-
|
| 114 |
-
---
|
| 115 |
-
|
| 116 |
-
## 4. Alert Subscriptions & Background Workers Subsystem
|
| 117 |
-
|
| 118 |
-
Pulse AI features an autonomous alert monitoring and notification engine that monitors live market telemetry and dispatches emails via double opt-in verification.
|
| 119 |
-
|
| 120 |
-
```
|
| 121 |
-
┌────────────────────────────────────────────────────────┐
|
| 122 |
-
│ User Requests Alert via Chat or API │
|
| 123 |
-
│ "Alert me when Miami rates spike" │
|
| 124 |
-
└───────────────────────────┬────────────────────────────┘
|
| 125 |
-
│
|
| 126 |
-
▼
|
| 127 |
-
┌────────────────────────────────────────────────────────┐
|
| 128 |
-
│ 1. PROVISION PENDING SUBSCRIPTION │
|
| 129 |
-
│ • Status: pending_confirmation │
|
| 130 |
-
│ • Secure Token: secrets.token_urlsafe(32) │
|
| 131 |
-
│ • Expiry: 48 hours │
|
| 132 |
-
└───────────────────────────┬────────────────────────────┘
|
| 133 |
-
│
|
| 134 |
-
▼
|
| 135 |
-
┌────────────────────────────────────────────────────────┐
|
| 136 |
-
│ 2. VERIFICATION EMAIL DISPATCH │
|
| 137 |
-
│ • Primary: Resend REST API (HTTPS Port 443) │
|
| 138 |
-
│ • Fallback: Gmail SMTP (Port 587/465) │
|
| 139 |
-
└───────────────────────────┬────────────────────────────┘
|
| 140 |
-
│ User clicks link:
|
| 141 |
-
│ GET /api/v1/alerts/confirm?token=...
|
| 142 |
-
▼
|
| 143 |
-
┌────────────────────────────────────────────────────────┐
|
| 144 |
-
│ 3. ACTIVATION & WELCOME PREVIEW │
|
| 145 |
-
│ • Status: active │
|
| 146 |
-
│ • Sends Instant Welcome & Diagnostic Email │
|
| 147 |
-
└───────────────────────────┬────────────────────────────┘
|
| 148 |
-
│
|
| 149 |
-
▼
|
| 150 |
-
┌────────────────────────────────────────────────────────┐
|
| 151 |
-
│ 4. AUTONOMOUS WORKER EVALUATION │
|
| 152 |
-
│ • POST /api/v1/internal/evaluate-alerts │
|
| 153 |
-
│ • POST /api/v1/internal/send-digests │
|
| 154 |
-
│ • POST /api/v1/internal/cleanup-alerts │
|
| 155 |
-
│ • Cooldown Safeguard: 24h per subscription │
|
| 156 |
-
│ • Max Cap: 5 subscriptions per email │
|
| 157 |
-
└────────────────────────────────────────────────────────┘
|
| 158 |
-
```
|
| 159 |
-
|
| 160 |
-
### Supported Criteria Types (10 Monitors)
|
| 161 |
-
- `spike`: Rate surges exceeding configurable % threshold over 7-day baseline.
|
| 162 |
-
- `rate_change`: Any nightly rate adjustment (increases or decreases) in target market.
|
| 163 |
-
- `price_threshold`: Nightly rate crossing above or below a specific numerical target.
|
| 164 |
-
- `availability_change`: Specific listing transitions to available, booked, or any state change.
|
| 165 |
-
- `new_listing`: New properties indexed in target market region.
|
| 166 |
-
- `tracking_removed`: Active properties paused or removed from telemetry.
|
| 167 |
-
- `anomaly`: Statistical pricing deviations beyond standard deviations.
|
| 168 |
-
- `volatility`: High-frequency dynamic rate fluctuations.
|
| 169 |
-
- `trend_reversal`: Trajectory shift (e.g., market transitioning from falling to rising).
|
| 170 |
-
- `digest`: Scheduled daily or weekly market intelligence summary.
|
| 171 |
-
|
| 172 |
-
### Dual-Transport Email Dispatch Subsystem
|
| 173 |
-
Cloud container environments (such as Hugging Face Spaces, AWS, and GCP) frequently block outbound TCP traffic on traditional SMTP ports (`587` and `465`). To guarantee 100% email deliverability:
|
| 174 |
-
1. **Primary Transport — Resend REST API:** Operates strictly over **HTTPS port 443**, bypassing all firewall restrictions.
|
| 175 |
-
2. **Fallback Transport — SMTP:** Standard TLS/SSL dispatch for environments with open SMTP ports.
|
| 176 |
-
|
| 177 |
-
---
|
| 178 |
-
|
| 179 |
-
## 5. Observability & Diagnostics
|
| 180 |
-
|
| 181 |
-
Every request and worker job passing through `joule-dynamics-server` is instrumented with **Langfuse** and **OpenTelemetry**:
|
| 182 |
-
|
| 183 |
-
```
|
| 184 |
-
[Trace: chat-session-001]
|
| 185 |
-
├── [Span: router-classification] Model: openai/gpt-oss-20b Tokens: 210 Latency: 148ms
|
| 186 |
-
├── [Span: dynamic-tool-discovery] Model: all-MiniLM-L6-v2 Ranked: 19 Latency: 22ms
|
| 187 |
-
├── [Generation: agent-round-1] Model: openai/gpt-oss-120b Tokens: 480 Latency: 610ms
|
| 188 |
-
│ └── [Tool: get_market_snapshot] Status: success Rows: 1 Latency: 45ms
|
| 189 |
-
└── [Generation: agent-synthesis] Model: openai/gpt-oss-120b Tokens: 320 Latency: 410ms
|
| 190 |
-
```
|
| 191 |
-
|
| 192 |
-
- **Step-by-Step Trajectory Tracking:** Captures multi-round LLM tool calls, arguments, database query responses, and final streaming text.
|
| 193 |
-
- **Worker & Email Telemetry:** Traces background alert evaluations, digest dispatches, and token cleanups.
|
| 194 |
-
- **Diagnostic Network Probe:** Real-time endpoint (`GET /api/v1/internal/diagnose-smtp`) verifies Resend API key status, HTTP 443 connectivity, and socket reachability on ports 587 and 465.
|
| 195 |
-
|
| 196 |
-
---
|
| 197 |
-
|
| 198 |
-
## 6. API Contracts & Streaming Protocol
|
| 199 |
-
|
| 200 |
-
### Chat Endpoints
|
| 201 |
-
|
| 202 |
-
#### 1. Streaming Chat: `POST /api/v1/real-estate/chat/stream`
|
| 203 |
-
- **Headers:** `Content-Type: application/json`, `Accept: text/event-stream`
|
| 204 |
-
- **Request Body:**
|
| 205 |
-
```json
|
| 206 |
-
{
|
| 207 |
-
"message": "What is the average nightly rate in Miami for 2-bedroom listings?",
|
| 208 |
-
"session_id": "usr_session_8f92a",
|
| 209 |
-
"context": {
|
| 210 |
-
"market": "Miami"
|
| 211 |
-
}
|
| 212 |
-
}
|
| 213 |
-
```
|
| 214 |
-
|
| 215 |
-
##### Event Stream Chunks:
|
| 216 |
-
- `event: status` -> `{"classification": "PATH_A"}`
|
| 217 |
-
- `event: tool_call` -> `{"tool": "get_market_averages", "args": {"market_param": "Miami"}}`
|
| 218 |
-
- `event: token` -> `{"text": "In Miami, the average rate..."}`
|
| 219 |
-
- `event: done` -> Final payload including `reply`, `tools_called`, and `suggested_actions`.
|
| 220 |
-
|
| 221 |
-
#### 2. Non-Streaming Chat: `POST /api/v1/real-estate/chat`
|
| 222 |
-
Returns complete JSON payload for non-streaming consumers.
|
| 223 |
-
|
| 224 |
-
#### 3. Starter Suggestions: `GET /api/v1/real-estate/chat/starters`
|
| 225 |
-
Returns curated prompt starter buttons tailored to current market conditions.
|
| 226 |
-
|
| 227 |
-
---
|
| 228 |
-
|
| 229 |
-
### Alert & Subscription Endpoints
|
| 230 |
-
|
| 231 |
-
#### 1. Confirm Subscription: `GET /api/v1/alerts/confirm?token={token}`
|
| 232 |
-
Activates a pending subscription when clicked by the user from their confirmation email. Returns styled HTML confirmation and dispatches the welcome preview email.
|
| 233 |
-
|
| 234 |
-
#### 2. Unsubscribe: `GET /api/v1/alerts/unsubscribe?token={token}`
|
| 235 |
-
Immediately cancels an active subscription.
|
| 236 |
-
|
| 237 |
---
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
| `POST` | `/api/v1/internal/send-digests` | Compiles and dispatches pending daily/weekly market digests. |
|
| 246 |
-
| `POST` | `/api/v1/internal/cleanup-alerts` | Deletes unconfirmed subscriptions older than 48 hours. |
|
| 247 |
-
| `POST` | `/api/v1/internal/run-all-workers` | Master trigger executing evaluate, digest, and cleanup sequentially. |
|
| 248 |
-
| `GET` | `/api/v1/internal/diagnose-smtp` | Network connectivity probe for Resend HTTPS and SMTP port status. |
|
| 249 |
-
|
| 250 |
---
|
| 251 |
|
| 252 |
-
#
|
| 253 |
-
|
| 254 |
-
- `GET /api/v1/health`: Versioned health status check.
|
| 255 |
-
- `POST /api/v1/rag/chat`: Amara Home & Kitchen customer support RAG chat.
|
| 256 |
-
|
| 257 |
-
---
|
| 258 |
-
|
| 259 |
-
## 7. Local Development & Environment Setup
|
| 260 |
-
|
| 261 |
-
### 1. Prerequisites
|
| 262 |
-
- Python 3.10+
|
| 263 |
-
- Git & Virtualenv
|
| 264 |
-
|
| 265 |
-
### 2. Installation
|
| 266 |
-
```bash
|
| 267 |
-
# Clone repository
|
| 268 |
-
git clone https://github.com/JohnJodinho/joule-dynamics-server.git
|
| 269 |
-
cd joule-dynamics-server
|
| 270 |
-
|
| 271 |
-
# Create and activate virtual environment
|
| 272 |
-
python -m venv venv
|
| 273 |
-
|
| 274 |
-
# On Linux/macOS:
|
| 275 |
-
source venv/bin/activate
|
| 276 |
-
|
| 277 |
-
# On Windows (PowerShell):
|
| 278 |
-
.\venv\Scripts\Activate.ps1
|
| 279 |
-
```
|
| 280 |
-
|
| 281 |
-
```bash
|
| 282 |
-
# Install dependencies
|
| 283 |
-
pip install -r requirements.txt
|
| 284 |
-
```
|
| 285 |
-
|
| 286 |
-
### 3. Environment Configuration (`.env`)
|
| 287 |
-
Create a `.env` file in the project root with the following parameters:
|
| 288 |
-
|
| 289 |
-
```env
|
| 290 |
-
# ── Core Server Configuration ──
|
| 291 |
-
PORT=7860
|
| 292 |
-
HOST=0.0.0.0
|
| 293 |
-
ALLOWED_ORIGINS=*
|
| 294 |
-
|
| 295 |
-
# ── Groq LPU Inference ──
|
| 296 |
-
GROQ_API_KEY=gsk_your_groq_api_key_here
|
| 297 |
-
GROQ_ROUTE_MODEL=openai/gpt-oss-20b
|
| 298 |
-
GROQ_FALLBACK_ROUTE_MODEL=groq/compound-mini
|
| 299 |
-
GROQ_SYNTHESIS_MODEL=openai/gpt-oss-120b
|
| 300 |
-
GROQ_FALLBACK_SYNTHESIS_MODEL=qwen/qwen3.6-27b
|
| 301 |
-
|
| 302 |
-
# ── Supabase Database & Vectors ──
|
| 303 |
-
SUPABASE_URL=https://your-project.supabase.co
|
| 304 |
-
SUPABASE_KEY=your_supabase_anon_key
|
| 305 |
-
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
|
| 306 |
-
|
| 307 |
-
# ── Resend Email Dispatch (Primary - HTTPS 443) ──
|
| 308 |
-
RESEND_API_KEY=re_your_resend_api_key_here
|
| 309 |
-
RESEND_FROM_ADDRESS=Pulse AI <onboarding@resend.dev>
|
| 310 |
-
|
| 311 |
-
# ── Alert Subscriptions Configuration ──
|
| 312 |
-
ALERT_BASE_URL=https://johnalbarkaibrahim-sentimentscope.hf.space
|
| 313 |
-
INTERNAL_API_KEY=your_secure_internal_cron_key
|
| 314 |
-
ALERT_COOLDOWN_HOURS=24
|
| 315 |
-
MAX_SUBSCRIPTIONS_PER_EMAIL=5
|
| 316 |
-
CONFIRMATION_EXPIRY_HOURS=48
|
| 317 |
-
|
| 318 |
-
# ── Fallback SMTP Configuration (Optional) ──
|
| 319 |
-
EMAIL_SMTP_HOST=smtp.gmail.com
|
| 320 |
-
EMAIL_SMTP_PORT=587
|
| 321 |
-
EMAIL_FROM_ADDRESS=jouledynamicscto@gmail.com
|
| 322 |
-
EMAIL_SMTP_PASSWORD=your_app_specific_password
|
| 323 |
-
|
| 324 |
-
# ── Langfuse Observability ──
|
| 325 |
-
LANGFUSE_PUBLIC_KEY=pk-lf-your_public_key
|
| 326 |
-
LANGFUSE_SECRET_KEY=sk-lf-your_secret_key
|
| 327 |
-
LANGFUSE_HOST=https://cloud.langfuse.com
|
| 328 |
-
|
| 329 |
-
# ── Appwrite Storage (Report Exports) ──
|
| 330 |
-
APP_WRITE_PROJECT_ID=your_project_id
|
| 331 |
-
APP_WRITE_API_ENDPOINT=https://cloud.appwrite.io/v1
|
| 332 |
-
APP_WRITE_API_KEY=your_appwrite_api_key
|
| 333 |
-
APP_WRITE_BUCKET_ID=your_bucket_id
|
| 334 |
-
|
| 335 |
-
# ── Geospatial & Contacts ──
|
| 336 |
-
MAPBOX_ACCESS_TOKEN=your_mapbox_token
|
| 337 |
-
CONTACT_EMAIL=hello@jouledynamics.com
|
| 338 |
-
CONTACT_WHATSAPP=1234567890
|
| 339 |
-
```
|
| 340 |
-
|
| 341 |
-
### 4. Run Development Server
|
| 342 |
-
```bash
|
| 343 |
-
uvicorn main:app --host 0.0.0.0 --port 7860 --reload
|
| 344 |
-
```
|
| 345 |
-
|
| 346 |
-
Interactive Swagger documentation will be accessible at `http://localhost:7860/docs`.
|
| 347 |
-
|
| 348 |
-
---
|
| 349 |
-
|
| 350 |
-
## 8. Deployment & CI/CD Workflow
|
| 351 |
-
|
| 352 |
-
### Multi-Target Repository Architecture
|
| 353 |
-
This project utilizes a dual-README CI/CD strategy to maintain rich GitHub documentation while strictly satisfying Hugging Face Space metadata requirements:
|
| 354 |
-
|
| 355 |
-
1. **GitHub (`origin/main`):** Hosts the complete source code and this comprehensive, enterprise-grade `README.md`.
|
| 356 |
-
2. **Hugging Face Spaces (`hf/main`):** Requires a concise YAML frontmatter header to initialize its Docker SDK container.
|
| 357 |
-
3. **Automated CI/CD Workflow (`.github/workflows/sync_to_hf.yml`):**
|
| 358 |
-
- Triggers automatically upon push to `main` on GitHub.
|
| 359 |
-
- Replaces the Space root `README.md` with [`README_HF.md`](file:///c:/Users/user/Desktop/python_projects/AI_Engineering_And_Automation/WhatsApp%20Sentiment/whatsapp_sentiment_backend_HF/SentimentScope/README_HF.md) strictly during the deployment sync step.
|
| 360 |
-
- Pushes the build artifacts to Hugging Face Spaces without overwriting or dirtying the GitHub repository.
|
| 361 |
-
|
| 362 |
-
> [!NOTE]
|
| 363 |
-
> Never merge `hf/main` into your local `main` branch. All development and documentation updates occur on GitHub (`origin/main`), with automated downstream deployment to Hugging Face Spaces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: SentimentScope
|
| 3 |
+
emoji: 📊
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: indigo
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
+
pinned: false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# Joule Dynamics RAG Demo
|
| 12 |
+
Backend API for the Amara Home & Kitchen RAG chatbot.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|