Spaces:
Runtime error
Runtime error
Commit ·
99b4bd2
1
Parent(s): 8f19c79
Remove some errors
Browse files- app/main.py +68 -17
app/main.py
CHANGED
|
@@ -11,6 +11,7 @@ from postgrest.types import CountMethod
|
|
| 11 |
from dotenv import load_dotenv
|
| 12 |
import json
|
| 13 |
from pydantic import BaseModel
|
|
|
|
| 14 |
|
| 15 |
# --- Import Anthropic ---
|
| 16 |
from anthropic import AsyncAnthropic, APIError
|
|
@@ -386,7 +387,7 @@ async def ask_paul_graham(request: Request, prompt: str = Form(...)):
|
|
| 386 |
# (Define these based on your logic - fixed for now)
|
| 387 |
model_name = "claude-3-5-sonnet-20240620"
|
| 388 |
system_prompt = "You are an AI assistant that writes essays in the style of Paul Graham. Focus on insights about startups, technology, programming, and contrarian thinking. Be concise and clear."
|
| 389 |
-
max_tokens = 3500
|
| 390 |
# Mean: 3284.29, Median: 2052, Mode: 3292
|
| 391 |
# Min: 104, Max: 17718, SD: 3086.28
|
| 392 |
prompt_text = f"Write a Paul Graham essay about {short_description}"
|
|
@@ -425,7 +426,10 @@ async def ask_paul_graham(request: Request, prompt: str = Form(...)):
|
|
| 425 |
new_prompt_result = (
|
| 426 |
supabase.table("prompts")
|
| 427 |
.insert(
|
| 428 |
-
{
|
|
|
|
|
|
|
|
|
|
| 429 |
returning="representation", # type: ignore
|
| 430 |
)
|
| 431 |
.execute()
|
|
@@ -435,9 +439,7 @@ async def ask_paul_graham(request: Request, prompt: str = Form(...)):
|
|
| 435 |
logger.error(
|
| 436 |
f"Failed to insert prompt for description: {short_description}"
|
| 437 |
)
|
| 438 |
-
raise HTTPException(
|
| 439 |
-
status_code=500, detail="Failed to create prompt."
|
| 440 |
-
)
|
| 441 |
|
| 442 |
prompt_info = new_prompt_result.data[0]
|
| 443 |
prompt_id = prompt_info["prompt_id"]
|
|
@@ -633,31 +635,80 @@ async def get_essays(sort_by: str = "time", order: str = "desc"):
|
|
| 633 |
for resp in responses_linking_resp.data:
|
| 634 |
prompt_id = resp["prompt_id"]
|
| 635 |
response_id = resp["response_id"]
|
| 636 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
|
| 638 |
# Combine data
|
| 639 |
final_data = []
|
| 640 |
for pid, prompt_info in prompts_map.items():
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 646 |
final_data.append(
|
| 647 |
{
|
| 648 |
"prompt": prompt_info.get("short_description"),
|
| 649 |
-
"created_at": created_at_iso,
|
|
|
|
| 650 |
"view_count": views_per_prompt.get(pid, 0),
|
| 651 |
}
|
| 652 |
)
|
| 653 |
logger.info(f"Processed {len(final_data)} prompts with aggregated views.")
|
| 654 |
# -------------------------------------------------- #
|
| 655 |
|
| 656 |
-
# Sort results in Python
|
| 657 |
-
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 661 |
|
| 662 |
return JSONResponse(content=final_data)
|
| 663 |
|
|
|
|
| 11 |
from dotenv import load_dotenv
|
| 12 |
import json
|
| 13 |
from pydantic import BaseModel
|
| 14 |
+
from datetime import datetime # Add datetime import
|
| 15 |
|
| 16 |
# --- Import Anthropic ---
|
| 17 |
from anthropic import AsyncAnthropic, APIError
|
|
|
|
| 387 |
# (Define these based on your logic - fixed for now)
|
| 388 |
model_name = "claude-3-5-sonnet-20240620"
|
| 389 |
system_prompt = "You are an AI assistant that writes essays in the style of Paul Graham. Focus on insights about startups, technology, programming, and contrarian thinking. Be concise and clear."
|
| 390 |
+
max_tokens = 3500 # GPT 2 token statistics on PG essays as of 2025-04-14
|
| 391 |
# Mean: 3284.29, Median: 2052, Mode: 3292
|
| 392 |
# Min: 104, Max: 17718, SD: 3086.28
|
| 393 |
prompt_text = f"Write a Paul Graham essay about {short_description}"
|
|
|
|
| 426 |
new_prompt_result = (
|
| 427 |
supabase.table("prompts")
|
| 428 |
.insert(
|
| 429 |
+
{
|
| 430 |
+
"short_description": short_description,
|
| 431 |
+
"prompt_text": prompt_text,
|
| 432 |
+
},
|
| 433 |
returning="representation", # type: ignore
|
| 434 |
)
|
| 435 |
.execute()
|
|
|
|
| 439 |
logger.error(
|
| 440 |
f"Failed to insert prompt for description: {short_description}"
|
| 441 |
)
|
| 442 |
+
raise HTTPException(status_code=500, detail="Failed to create prompt.")
|
|
|
|
|
|
|
| 443 |
|
| 444 |
prompt_info = new_prompt_result.data[0]
|
| 445 |
prompt_id = prompt_info["prompt_id"]
|
|
|
|
| 635 |
for resp in responses_linking_resp.data:
|
| 636 |
prompt_id = resp["prompt_id"]
|
| 637 |
response_id = resp["response_id"]
|
| 638 |
+
# Ensure prompt_id exists before incrementing
|
| 639 |
+
if prompt_id in views_per_prompt:
|
| 640 |
+
views_per_prompt[prompt_id] += views_per_response.get(
|
| 641 |
+
response_id, 0
|
| 642 |
+
)
|
| 643 |
+
else:
|
| 644 |
+
# This case might indicate an inconsistency if a response links
|
| 645 |
+
# to a prompt_id not fetched initially. Log a warning.
|
| 646 |
+
logger.warning(
|
| 647 |
+
f"Response {response_id} links to prompt {prompt_id} which was not in the initial prompt fetch."
|
| 648 |
+
)
|
| 649 |
|
| 650 |
# Combine data
|
| 651 |
final_data = []
|
| 652 |
for pid, prompt_info in prompts_map.items():
|
| 653 |
+
created_at_str = prompt_info.get("created_at")
|
| 654 |
+
dt_obj = None
|
| 655 |
+
created_at_iso = None
|
| 656 |
+
if created_at_str:
|
| 657 |
+
try:
|
| 658 |
+
# Handle potential 'Z' timezone indicator which Python < 3.11 doesn't parse directly
|
| 659 |
+
if created_at_str.endswith("Z"):
|
| 660 |
+
created_at_str_parsed = created_at_str[:-1] + "+00:00"
|
| 661 |
+
else:
|
| 662 |
+
created_at_str_parsed = created_at_str
|
| 663 |
+
dt_obj = datetime.fromisoformat(created_at_str_parsed)
|
| 664 |
+
created_at_iso = (
|
| 665 |
+
dt_obj.isoformat()
|
| 666 |
+
) # Format back for JSON if needed, keeps original offset
|
| 667 |
+
except ValueError:
|
| 668 |
+
logger.warning(
|
| 669 |
+
f"Could not parse created_at string: {created_at_str}. Leaving as is."
|
| 670 |
+
)
|
| 671 |
+
created_at_iso = (
|
| 672 |
+
created_at_str # Keep original string if parse fails
|
| 673 |
+
)
|
| 674 |
+
|
| 675 |
final_data.append(
|
| 676 |
{
|
| 677 |
"prompt": prompt_info.get("short_description"),
|
| 678 |
+
"created_at": created_at_iso, # Use the potentially re-formatted ISO string for consistency in JSON
|
| 679 |
+
"_created_at_dt": dt_obj, # Internal field for sorting
|
| 680 |
"view_count": views_per_prompt.get(pid, 0),
|
| 681 |
}
|
| 682 |
)
|
| 683 |
logger.info(f"Processed {len(final_data)} prompts with aggregated views.")
|
| 684 |
# -------------------------------------------------- #
|
| 685 |
|
| 686 |
+
# --- Sort results in Python --- #
|
| 687 |
+
# Define sort key functions
|
| 688 |
+
def get_sort_key(item):
|
| 689 |
+
if sort_key == "created_at":
|
| 690 |
+
# Handle None values appropriately for sorting
|
| 691 |
+
dt_val = item.get("_created_at_dt")
|
| 692 |
+
if dt_val is None:
|
| 693 |
+
# Place None values at the beginning if ascending, end if descending
|
| 694 |
+
return datetime.min if not reverse_sort else datetime.max
|
| 695 |
+
return dt_val
|
| 696 |
+
elif sort_key == "prompt":
|
| 697 |
+
return item.get("prompt") or ""
|
| 698 |
+
elif sort_key == "view_count":
|
| 699 |
+
return item.get("view_count") or 0
|
| 700 |
+
else: # Default to created_at if sort_key is invalid
|
| 701 |
+
dt_val = item.get("_created_at_dt")
|
| 702 |
+
if dt_val is None:
|
| 703 |
+
return datetime.min if not reverse_sort else datetime.max
|
| 704 |
+
return dt_val
|
| 705 |
+
|
| 706 |
+
final_data.sort(key=get_sort_key, reverse=reverse_sort)
|
| 707 |
+
|
| 708 |
+
# Remove the internal sorting key before returning
|
| 709 |
+
for item in final_data:
|
| 710 |
+
del item["_created_at_dt"]
|
| 711 |
+
# ------------------------------ #
|
| 712 |
|
| 713 |
return JSONResponse(content=final_data)
|
| 714 |
|