Spaces:
Running
Running
| #!/usr/bin/env python | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Web API bridge script for handling inputs from the web interface | |
| and generating user personas following the logic in generate_profile.py. | |
| """ | |
| import json | |
| import argparse | |
| import sys | |
| import os | |
| from typing import Dict, Any, List, Optional | |
| # Import required modules | |
| from based_data import ( | |
| generate_age_info, | |
| generate_gender, | |
| generate_career_info, | |
| generate_location, | |
| generate_personal_values, | |
| generate_life_attitude, | |
| generate_personal_story, | |
| generate_interests_and_hobbies | |
| ) | |
| from generate_profile import generate_final_summary | |
| from select_attributes import get_selected_attributes, save_results | |
| def parse_input_data(input_file: str) -> Dict[str, Any]: | |
| """ | |
| Parse data from the input file | |
| Args: | |
| input_file: Path to the input JSON file | |
| Returns: | |
| Dict: Parsed input data | |
| """ | |
| try: | |
| with open(input_file, 'r', encoding='utf-8') as f: | |
| data = json.load(f) | |
| return data | |
| except Exception as e: | |
| print(f"Error parsing input file: {e}") | |
| return {} | |
| def generate_profile_from_input(input_data: Dict[str, Any], attribute_count: int = 200) -> Dict[str, Any]: | |
| """ | |
| Generate a complete user persona from input data | |
| Args: | |
| input_data: Input data containing basic information and optional custom values | |
| attribute_count: Number of attributes to generate (default: 200) | |
| Returns: | |
| Dict: Generated complete user persona | |
| """ | |
| try: | |
| # Extract basic information from input data | |
| basic_info = input_data.get('basic_info', {}) | |
| # Extract custom values if provided | |
| custom_values = input_data.get('custom_values', {}) | |
| # Use provided basic information or generate new basic information | |
| age = basic_info.get('age') | |
| if not age: | |
| print("β Age not provided, generating...") | |
| age_info = generate_age_info() | |
| age = age_info['age'] | |
| else: | |
| print(f"β Using provided age: {age}") | |
| gender = basic_info.get('gender') | |
| if not gender: | |
| print("β Gender not provided, generating...") | |
| gender = generate_gender() | |
| else: | |
| print(f"β Using provided gender: {gender}") | |
| occupation_info = basic_info.get('occupation', {}) | |
| occupation = occupation_info.get('status') | |
| if not occupation: | |
| print("β Occupation not provided, generating...") | |
| career_info = generate_career_info(age) | |
| occupation = career_info['status'] | |
| else: | |
| print(f"β Using provided occupation: {occupation}") | |
| location_info = basic_info.get('location', {}) | |
| if not location_info.get('city') or not location_info.get('country'): | |
| print("β Location not provided, generating...") | |
| location_info = generate_location() | |
| else: | |
| print(f"β Using provided location: {location_info.get('city')}, {location_info.get('country')}") | |
| # Use custom personal values if provided, otherwise generate them | |
| custom_personal_values = custom_values.get('personal_values') | |
| if custom_personal_values and custom_personal_values.strip(): | |
| print(f"β Using provided personal values: {custom_personal_values[:50]}...") | |
| values_orientation = custom_personal_values.strip() | |
| else: | |
| print("β Personal values not provided, generating based on inputs...") | |
| values_dict = generate_personal_values(age, gender, occupation, location_info) | |
| values_orientation = values_dict.get("values_orientation", "") if isinstance(values_dict, dict) else str(values_dict) | |
| # Use custom life attitude if provided, otherwise generate it | |
| custom_life_attitude = custom_values.get('life_attitude') | |
| if custom_life_attitude and custom_life_attitude.strip(): | |
| print(f"β Using provided life attitude: {custom_life_attitude[:50]}...") | |
| life_attitude = { | |
| "outlook": custom_life_attitude.strip(), | |
| "coping_mechanism": "Custom life attitude provided by user" | |
| } | |
| else: | |
| print("β Life attitude not provided, generating based on inputs...") | |
| life_attitude = generate_life_attitude(age, gender, occupation, location_info, values_orientation) | |
| # Use custom life story if provided, otherwise generate it | |
| custom_life_story = custom_values.get('life_story') | |
| if custom_life_story and custom_life_story.strip(): | |
| print(f"β Using provided life story: {custom_life_story[:50]}...") | |
| personal_story = {"personal_story": custom_life_story.strip()} | |
| else: | |
| print("β Life story not provided, generating based on inputs...") | |
| personal_story = generate_personal_story(age, gender, occupation, location_info, values_orientation, life_attitude) | |
| # Use custom interests/hobbies if provided, otherwise generate them | |
| custom_interests = custom_values.get('interests_hobbies') | |
| if custom_interests and custom_interests.strip(): | |
| print(f"β Using provided interests: {custom_interests}") | |
| # Split by comma and clean up | |
| interests_list = [i.strip() for i in custom_interests.split(',') if i.strip()] | |
| interests_and_hobbies = {"interests": interests_list} | |
| else: | |
| print("β Interests not provided, generating based on life story...") | |
| interests_and_hobbies = generate_interests_and_hobbies(personal_story) | |
| # Build complete user persona (matching reference version structure) | |
| profile = { | |
| "basic_info": { | |
| "age": age, | |
| "gender": gender, | |
| "occupation": {"status": occupation}, | |
| "location": location_info | |
| }, | |
| "values_orientation": values_orientation, | |
| "life_attitude": life_attitude, | |
| "personal_story": personal_story, | |
| "interests_and_hobbies": interests_and_hobbies | |
| } | |
| # Select attributes | |
| print(f"Selecting {attribute_count} attributes...") | |
| # Pass the profile directly to get_selected_attributes | |
| selected_paths = get_selected_attributes(profile, attribute_count) | |
| profile["selected_attributes"] = selected_paths | |
| # Save the selected attributes to output files | |
| print("Saving selected attributes...") | |
| save_results(profile, selected_paths) | |
| # Generate final summary | |
| print("Generating final summary...") | |
| summary = generate_final_summary(profile) | |
| profile["Summary"] = summary | |
| return profile | |
| except Exception as e: | |
| print(f"Error generating user persona: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return {} | |
| def main(): | |
| """Main function to process command line arguments and execute generation workflow""" | |
| parser = argparse.ArgumentParser(description="Generate user persona from input data") | |
| parser.add_argument('--input', type=str, required=True, help="Path to input JSON file") | |
| parser.add_argument('--attributes', type=int, default=200, help="Number of attributes to generate (default: 200)") | |
| args = parser.parse_args() | |
| # Parse input data | |
| input_data = parse_input_data(args.input) | |
| if not input_data: | |
| print("Unable to parse input data, exiting") | |
| sys.exit(1) | |
| # Generate user persona | |
| profile = generate_profile_from_input(input_data, attribute_count=args.attributes) | |
| if not profile: | |
| print("Failed to generate user persona, exiting") | |
| sys.exit(1) | |
| # Output results | |
| if "Summary" in profile: | |
| print("\n" + "="*50) | |
| print("Generated User Persona Summary:") | |
| print("="*50) | |
| print(profile["Summary"]) | |
| print("="*50) | |
| # Output the profile as JSON to stdout for the Next.js API to capture | |
| # Clean the summary for JSON output | |
| if "Summary" in profile: | |
| cleaned_summary = profile["Summary"].replace("`", "") | |
| cleaned_summary = cleaned_summary.replace('"', "'") | |
| profile["Summary"] = cleaned_summary | |
| # Format for API output - clean newlines for JSON compatibility | |
| if "Summary" in profile: | |
| profile["Summary"] = profile["Summary"].replace('\n', " ") | |
| print(f'\n{{"summary": "{profile["Summary"]}"}}\n') | |
| else: | |
| print("Failed to generate summary") | |
| sys.exit(1) | |
| # Output the full profile as JSON | |
| print(json.dumps(profile, ensure_ascii=False)) | |
| if __name__ == "__main__": | |
| main() | |