from fastapi import FastAPI, Request
import gradio as gr
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Add CORS middleware to allow requests from Make.com or Postman
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all origins (you can restrict this in production)
allow_methods=["POST"],
allow_headers=["*"],
)
def bulletify(text_string, prefix="- "):
"""
Takes a comma-separated string (e.g. "Goal1, Goal2")
and returns multiple lines with the given prefix:
"- Goal1
- Goal2"
If text_string is empty, returns an empty string.
"""
items = [x.strip() for x in text_string.split(",") if x.strip()]
if not items:
return ""
return "
".join(f"{prefix}{item}" for item in items)
def numbered_listify(text_string):
"""
Takes a comma-separated string (e.g. "Strength1, Strength2")
and returns a numbered list:
"1. Strength1
2. Strength2"
"""
items = [x.strip() for x in text_string.split(",") if x.strip()]
if not items:
return ""
lines = []
for i, item in enumerate(items, start=1):
lines.append(f"{i}. {item}")
return "
".join(lines)
def generate_cv(
email,
date_of_birth,
mbti,
sustainable_dev_goals, # e.g. "8. Decent Work, 9. Industry Innovation"
via_strengths, # e.g. "Creativity, Curiosity, Leadership, ..."
disc_d,
disc_i,
disc_s,
disc_c,
big5_openness, # a.k.a. "Big5 - Openness" or "Big5 - Extroversion," etc.
big5_conscientiousness,
big5_extraversion,
big5_agreeableness,
big5_emotional_stability,
past_project,
influences,
main_passions,
preferred_location,
ideal_work_environment,
productive_time,
partner_qualities,
vision
):
"""
Generates a text-based CV (Markdown tables) with bullet lists for multi-select fields.
NOTE: Make.com should combine multi-select choices into comma-separated strings
before sending here.
"""
# Convert multi-select fields into bullet/numbered lines:
sdg_bullets = bulletify(sustainable_dev_goals) # each item -> separate bullet
via_bullets = numbered_listify(via_strengths) # each item -> separate numbered line
productive_time_bullets = bulletify(productive_time) # if multiple time blocks
main_passions_bullets = bulletify(main_passions) # optional if multi-select
cv_text = f"""
# CV Template
## Essential Information
| Field | Details |
|-----------------------------------|--------------------------------------------------------------|
| **Email Address** | {email} |
| **Date of Birth** | {date_of_birth} |
| **16 Personalities (MBTI)** | {mbti} |
| **Sustainable Development Goals** | {sdg_bullets if sdg_bullets else "N/A"} |
| **VIA Strengths (Top 5)** | {via_bullets if via_bullets else "N/A"} |
## Personality Profile
| Field | Details |
|---------------------|-----------------------------------------------------------------------------------------------------|
| **DISC (D, I, S, C)** | D: {disc_d}%
I: {disc_i}%
S: {disc_s}%
C: {disc_c}% |
| **Big Five (OCEAN)** | Openness: {big5_openness}%
Conscientiousness: {big5_conscientiousness}%
Extraversion: {big5_extraversion}%
Agreeableness: {big5_agreeableness}%
Emotional Stability: {big5_emotional_stability}% |
## Interests & Passions
| Field | Details |
|------------------------------------------------------|----------------------------------------------|
| **Past Project or Workplace You Loved (Why)** | {past_project} |
| **People, Books, Courses, or Resources That Shaped You (Why)** | {influences} |
| **Main Passions & Topics of Interest** | {main_passions_bullets if main_passions_bullets else main_passions} |
## Collaboration Preferences
| Field | Details |
|---------------------------------------------------|-----------------------------------------------------|
| **Preferred Country & Town for Meetups** | {preferred_location} |
| **Ideal Work Environment** | {ideal_work_environment} |
| **Most Productive Time of Day/Night** | {productive_time_bullets if productive_time_bullets else productive_time} |
| **Qualities in an Ideal Partner (Professional/Personal)** | {partner_qualities} |
| **Vision for Future Collaboration or Partnership** | {vision} |
"""
return cv_text.strip()
# GRADIO INTERFACE
demo = gr.Interface(
fn=generate_cv,
inputs=[
"text", # email
"text", # date_of_birth
"text", # mbti
"text", # sustainable_dev_goals
"text", # via_strengths
"text", # disc_d
"text", # disc_i
"text", # disc_s
"text", # disc_c
"text", # big5_openness
"text", # big5_conscientiousness
"text", # big5_extraversion
"text", # big5_agreeableness
"text", # big5_emotional_stability
"text", # past_project
"text", # influences
"text", # main_passions
"text", # preferred_location
"text", # ideal_work_environment
"text", # productive_time
"text", # partner_qualities
"text" # vision
],
outputs="text",
title="CV Template with Markdown Tables + Bullets"
)
# FastAPI endpoint for POST requests
@app.post("/run/predict")
async def predict(request: Request):
data = await request.json()
cv_output = generate_cv(
email=data.get("email"),
date_of_birth=data.get("date_of_birth"),
mbti=data.get("mbti"),
sustainable_dev_goals=data.get("sustainable_dev_goals"),
via_strengths=data.get("via_strengths"),
disc_d=data.get("disc_d"),
disc_i=data.get("disc_i"),
disc_s=data.get("disc_s"),
disc_c=data.get("disc_c"),
big5_openness=data.get("big5_openness"),
big5_conscientiousness=data.get("big5_conscientiousness"),
big5_extraversion=data.get("big5_extraversion"),
big5_agreeableness=data.get("big5_agreeableness"),
big5_emotional_stability=data.get("big5_emotional_stability"),
past_project=data.get("past_project"),
influences=data.get("influences"),
main_passions=data.get("main_passions"),
preferred_location=data.get("preferred_location"),
ideal_work_environment=data.get("ideal_work_environment"),
productive_time=data.get("productive_time"),
partner_qualities=data.get("partner_qualities"),
vision=data.get("vision")
)
return {"cv_output": cv_output}
# Launch Gradio and FastAPI
demo.launch(server_name="0.0.0.0", server_port=7860, share=True)