Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OPENAI_API_KEY=your_openai_api_key_here
42 changes: 42 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual Environment
venv/
ENV/
env/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# Environment variables
.env
.env.local

# Testing
.pytest_cache/
.coverage
htmlcov/
156 changes: 156 additions & 0 deletions IMPLEMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Implementation Summary

## Problem Statement (Turkish)
The requirement was to create a FastAPI endpoint with the following specifications:

1. **Input Parameters:**
- user adı (user name)
- user hedefleri ama liste şeklinde (user goals as a list)
- user vücut bilgileri (dict olarak, örneğin {weight: 76.8,..}) (user body info as dict)
- user input'u (user input)

2. **Two-Step Process:**

**Step 1:** Use the user input to ask the model if it's fitness-related, returning a boolean or score value.

**Step 2:** Based on the value:
- If failed: return error response
- If successful: include user information in prompt and send to AI, return AI response

## Implementation

### Files Created

1. **main.py** - Main FastAPI application
- `/process-fitness-input` endpoint (POST) - Main endpoint for processing user input
- `/` endpoint (GET) - Root endpoint with API info
- `/health` endpoint (GET) - Health check
- `validate_fitness_input()` - Step 1: Validates if input is fitness-related
- `generate_ai_response()` - Step 2: Generates personalized AI response

2. **models.py** - Pydantic data models
- `UserInput` - Request model with user_name, user_goals, user_body_info, user_input
- `FitnessValidationResponse` - Internal model for validation results
- `ErrorResponse` - Error response model
- `SuccessResponse` - Success response model with AI response and fitness score

3. **requirements.txt** - Project dependencies
- fastapi==0.104.1
- uvicorn[standard]==0.24.0
- pydantic==2.5.0
- openai==1.3.0
- python-dotenv==1.0.0

4. **test_app.py** - Test script to validate implementation
5. **example_usage.py** - Example script showing API usage
6. **.gitignore** - Python gitignore file
7. **.env.example** - Example environment variables file
8. **README.md** - Comprehensive documentation

### Implementation Details

#### Step 1: Fitness Validation
Uses OpenAI's **structured output** feature (gpt-4o-2024-08-06 model) with the `response_format` parameter:

```python
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[...],
response_format=FitnessValidationResponse, # Structured output
)
```

Returns a `FitnessValidationResponse` object with:
- `is_fitness_related`: Boolean
- `score`: Float (0-1) confidence score

#### Step 2: Conditional Processing

**If validation fails (score < 0.5 or is_fitness_related = False):**
```json
HTTP 400 Bad Request
{
"detail": {
"error": "Input is not fitness-related",
"details": "The provided input does not appear to be related to fitness..."
}
}
```

**If validation succeeds:**
- User information (name, goals, body info) is included in the prompt
- OpenAI generates a personalized fitness response
- Returns success response:
```json
HTTP 200 OK
{
"response": "AI-generated personalized fitness advice...",
"fitness_score": 0.95
}
```

### API Usage

**Request:**
```bash
curl -X POST "http://localhost:8000/process-fitness-input" \
-H "Content-Type: application/json" \
-d '{
"user_name": "John Doe",
"user_goals": ["lose weight", "build muscle"],
"user_body_info": {"weight": 76.8, "height": 180},
"user_input": "I want to start a workout routine"
}'
```

**Success Response (200):**
```json
{
"response": "Based on your goals of losing weight and building muscle, and your current weight of 76.8kg and height of 180cm...",
"fitness_score": 0.95
}
```

**Error Response (400):**
```json
{
"detail": {
"error": "Input is not fitness-related",
"details": "The provided input does not appear to be related to fitness, health, or wellness. Confidence score: 0.25"
}
}
```

## Configuration

1. Copy `.env.example` to `.env`
2. Add your OpenAI API key:
```
OPENAI_API_KEY=sk-...
```

## Testing

Run tests:
```bash
python test_app.py
```

Start the server:
```bash
python main.py
# or
uvicorn main:app --reload
```

## Features Implemented

✅ FastAPI endpoint accepting user name, goals (list), body info (dict), and input (string)
✅ Step 1: Fitness validation using OpenAI structured output (boolean + score)
✅ Step 2: Conditional processing based on validation
✅ Error response for non-fitness inputs
✅ Success response with personalized AI-generated content
✅ Comprehensive documentation
✅ Example scripts and tests
✅ Proper error handling
✅ OpenAPI/Swagger documentation (auto-generated at /docs)
135 changes: 134 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,134 @@
# demo-structured-output
# demo-structured-output

FastAPI application for validating fitness-related user inputs and generating personalized AI responses.

## Features

- **Fitness Input Validation**: Uses OpenAI's structured output to determine if user input is fitness-related
- **Personalized AI Responses**: Generates tailored fitness advice based on user information
- **Two-step Processing**:
1. Validates input relevance (fitness-related or not)
2. Generates personalized response using user data

## Requirements

- Python 3.8+
- OpenAI API key

## Installation

1. Clone the repository:
```bash
git clone https://github.com/lightningcell/demo-structured-output.git
cd demo-structured-output
```

2. Install dependencies:
```bash
pip install -r requirements.txt
```

3. Set up environment variables:
```bash
cp .env.example .env
# Edit .env and add your OpenAI API key
```

## Usage

### Start the server

```bash
python main.py
```

Or with uvicorn:
```bash
uvicorn main:app --reload
```

The API will be available at `http://localhost:8000`

### API Endpoints

#### POST /process-fitness-input

Processes user fitness input with validation.

**Request Body:**
```json
{
"user_name": "John Doe",
"user_goals": ["lose weight", "build muscle", "improve stamina"],
"user_body_info": {
"weight": 76.8,
"height": 180,
"age": 30
},
"user_input": "I want to start a workout routine"
}
```

**Success Response (200):**
```json
{
"response": "Based on your goals and current metrics...",
"fitness_score": 0.95
}
```

**Error Response (400):**
```json
{
"detail": {
"error": "Input is not fitness-related",
"details": "The provided input does not appear to be related to fitness, health, or wellness. Confidence score: 0.25"
}
}
```

### Example with curl

```bash
curl -X POST "http://localhost:8000/process-fitness-input" \
-H "Content-Type: application/json" \
-d '{
"user_name": "John Doe",
"user_goals": ["lose weight", "build muscle"],
"user_body_info": {"weight": 76.8, "height": 180},
"user_input": "What exercises should I do to lose weight?"
}'
```

## API Documentation

Once the server is running, visit:
- Swagger UI: `http://localhost:8000/docs`
- ReDoc: `http://localhost:8000/redoc`

## Project Structure

```
.
├── main.py # FastAPI application with endpoints
├── models.py # Pydantic models for request/response
├── requirements.txt # Python dependencies
├── .env.example # Example environment variables
└── README.md # This file
```

## Implementation Details

### Step 1: Fitness Validation
Uses OpenAI's structured output feature to parse responses into a `FitnessValidationResponse` model with:
- `is_fitness_related`: Boolean indicating if input is fitness-related
- `score`: Confidence score (0-1) for the classification

### Step 2: Response Generation
If validation passes (score >= 0.5):
- User information (name, goals, body info) is included in the prompt
- OpenAI generates a personalized fitness response
- Response is returned to the client

If validation fails:
- HTTP 400 error with details about why the input was rejected
Loading