best / backend /app /scripts /seed.py
anky2002's picture
fix: Import all ORM relationship models before seeding
f1d7f93 verified
Raw
History Blame Contribute Delete
12.9 kB
"""
Seed database with sample data for local development.
Run: python -m app.scripts.seed
"""
import asyncio
import uuid
from datetime import datetime, timedelta, timezone
from sqlalchemy import select
from app.core.database import async_session_factory
from app.core.security import hash_password
# Import all ORM modules so SQLAlchemy string relationships resolve on Windows/local runs.
import app.models.application # noqa: F401
import app.models.resume # noqa: F401
import app.models.alerts # noqa: F401
import app.models.llm # noqa: F401
import app.api.routes.bookmarks # noqa: F401
import app.api.routes.cover_letters # noqa: F401
import app.api.routes.reminders # noqa: F401
import app.api.routes.qa_bank # noqa: F401
import app.api.routes.webhooks # noqa: F401
import app.services.analytics # noqa: F401
from app.models.job import Company, Job
from app.models.scraper import JobSource
from app.models.user import Profile, User
SAMPLE_COMPANIES = [
{"name": "Google", "slug": "google", "domain": "google.com", "industry": "Technology", "size_range": "10000+", "headquarters": "Mountain View, CA", "company_type": "public", "tech_stack": ["C++", "Python", "Go", "Kubernetes", "TensorFlow"]},
{"name": "Stripe", "slug": "stripe", "domain": "stripe.com", "industry": "Fintech", "size_range": "5001-10000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["Ruby", "Java", "Scala", "PostgreSQL"]},
{"name": "Vercel", "slug": "vercel", "domain": "vercel.com", "industry": "Developer Tools", "size_range": "201-500", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["TypeScript", "Next.js", "React", "Rust"]},
{"name": "Anthropic", "slug": "anthropic", "domain": "anthropic.com", "industry": "AI/ML", "size_range": "501-1000", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["Python", "PyTorch", "Kubernetes", "Rust"]},
{"name": "Linear", "slug": "linear", "domain": "linear.app", "industry": "Developer Tools", "size_range": "51-200", "headquarters": "San Francisco, CA", "company_type": "startup", "tech_stack": ["TypeScript", "React", "GraphQL", "PostgreSQL"]},
{"name": "Figma", "slug": "figma", "domain": "figma.com", "industry": "Design", "size_range": "1001-5000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["TypeScript", "React", "WebGL", "Rust"]},
{"name": "Datadog", "slug": "datadog", "domain": "datadoghq.com", "industry": "DevOps", "size_range": "5001-10000", "headquarters": "New York, NY", "company_type": "public", "tech_stack": ["Go", "Python", "Kubernetes", "Kafka"]},
{"name": "Notion", "slug": "notion", "domain": "notion.so", "industry": "Productivity", "size_range": "501-1000", "headquarters": "San Francisco, CA", "company_type": "private", "tech_stack": ["TypeScript", "React", "Node.js", "PostgreSQL"]},
]
SAMPLE_JOBS = [
{"title": "Senior Frontend Engineer", "company": "Vercel", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 180000, "salary_max": 250000, "skills_required": ["React", "Next.js", "TypeScript", "CSS"], "description_text": "Join our frontend team to build the future of web development. You'll work on Next.js, Turbopack, and our deployment platform used by millions of developers."},
{"title": "Staff Software Engineer - AI Infrastructure", "company": "Anthropic", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 300000, "salary_max": 450000, "skills_required": ["Python", "Distributed Systems", "ML Infrastructure", "Kubernetes"], "description_text": "Build the infrastructure powering Claude. Work on training pipelines, inference systems, and developer APIs at scale."},
{"title": "Product Engineer", "company": "Linear", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 150000, "salary_max": 200000, "skills_required": ["React", "TypeScript", "Node.js", "PostgreSQL"], "description_text": "Build features end-to-end for our project management tool used by the best product teams. Own features from conception to deployment."},
{"title": "Backend Engineer - Payments", "company": "Stripe", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 175000, "salary_max": 250000, "skills_required": ["Ruby", "Java", "Distributed Systems", "SQL"], "description_text": "Build the economic infrastructure for the internet. Work on payment processing, fraud detection, and financial services APIs."},
{"title": "Senior Software Engineer - Search", "company": "Google", "remote_type": "onsite", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 200000, "salary_max": 350000, "skills_required": ["C++", "Python", "Distributed Systems", "Information Retrieval"], "description_text": "Improve search quality for billions of users. Work on ranking algorithms, knowledge graphs, and AI-powered features."},
{"title": "Full Stack Engineer", "company": "Notion", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 160000, "salary_max": 220000, "skills_required": ["React", "TypeScript", "Node.js", "PostgreSQL"], "description_text": "Build collaborative features for Notion's workspace platform. Work across the stack from real-time sync to UI components."},
{"title": "Design Engineer", "company": "Figma", "remote_type": "hybrid", "employment_type": "full_time", "seniority_level": "mid", "salary_min": 170000, "salary_max": 240000, "skills_required": ["React", "TypeScript", "WebGL", "Design Systems"], "description_text": "Bridge design and engineering at Figma. Build interactive UI components, design system primitives, and creative tools."},
{"title": "Senior Site Reliability Engineer", "company": "Datadog", "remote_type": "remote", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 190000, "salary_max": 280000, "skills_required": ["Kubernetes", "Terraform", "Go", "Observability"], "description_text": "Keep Datadog running at scale. Own service reliability, incident response, and infrastructure automation for our monitoring platform."},
{"title": "Machine Learning Engineer - NLP", "company": "Google", "remote_type": "onsite", "employment_type": "full_time", "seniority_level": "senior", "salary_min": 220000, "salary_max": 380000, "skills_required": ["Python", "PyTorch", "Transformers", "NLP"], "description_text": "Work on large language models and NLP systems. Apply cutting-edge research to production systems serving billions of queries."},
{"title": "Software Engineering Intern", "company": "Stripe", "remote_type": "hybrid", "employment_type": "internship", "seniority_level": "intern", "salary_min": 80000, "salary_max": 100000, "skills_required": ["Python", "JavaScript", "SQL"], "description_text": "12-week summer internship. Work on real projects alongside experienced engineers. Past interns have shipped features used by millions."},
]
SAMPLE_SOURCES = [
{"name": "Greenhouse - Vercel", "source_type": "ats_api", "domain": "vercel.com", "base_url": "https://boards-api.greenhouse.io/v1/boards/vercel/jobs", "ats_vendor": "greenhouse", "ats_config": {"board_token": "vercel"}},
{"name": "Greenhouse - Anthropic", "source_type": "ats_api", "domain": "anthropic.com", "base_url": "https://boards-api.greenhouse.io/v1/boards/anthropic/jobs", "ats_vendor": "greenhouse", "ats_config": {"board_token": "anthropic"}},
{"name": "Lever - Linear", "source_type": "ats_api", "domain": "linear.app", "base_url": "https://api.lever.co/v0/postings/linear", "ats_vendor": "lever", "ats_config": {"company_slug": "linear"}},
{"name": "Ashby - Notion", "source_type": "ats_api", "domain": "notion.so", "base_url": "https://api.ashbyhq.com/posting-api/job-board", "ats_vendor": "ashby", "ats_config": {"board_slug": "notion"}},
]
async def seed():
"""Seed the database with sample data."""
async with async_session_factory() as db:
print("🌱 Seeding database...")
# Avoid duplicate seed runs.
existing = await db.scalar(select(User).where(User.email == "demo@jobportal.dev"))
if existing:
print("✅ Seed data already exists. Skipping.")
return
# 1. Create admin user
admin = User(
email="admin@jobportal.dev",
hashed_password=hash_password("admin123"),
full_name="Admin User",
role="admin",
is_active=True,
is_verified=True,
is_superuser=True,
)
db.add(admin)
# 2. Create demo user
demo = User(
email="demo@jobportal.dev",
hashed_password=hash_password("demo123"),
full_name="Demo User",
role="candidate",
is_active=True,
is_verified=True,
)
db.add(demo)
await db.flush()
# 3. Create demo profile
profile = Profile(
user_id=demo.id,
headline="Full Stack Engineer",
location="San Francisco, CA",
summary="Passionate full-stack engineer with 5 years of experience building web applications.",
skills=[
{"name": "React", "category": "Frameworks", "level": 5},
{"name": "TypeScript", "category": "Languages", "level": 5},
{"name": "Python", "category": "Languages", "level": 4},
{"name": "Node.js", "category": "Frameworks", "level": 4},
{"name": "PostgreSQL", "category": "Databases", "level": 4},
{"name": "AWS", "category": "Cloud", "level": 3},
{"name": "Docker", "category": "Tools", "level": 4},
{"name": "Next.js", "category": "Frameworks", "level": 5},
],
experience=[
{
"company": "TechCorp",
"title": "Senior Software Engineer",
"location": "San Francisco, CA",
"start_date": "2022-01",
"end_date": "",
"is_current": True,
"bullets": [
"Led development of real-time collaboration features serving 100K+ daily active users",
"Reduced page load time by 40% through code splitting and performance optimization",
"Mentored 3 junior engineers and led weekly architecture reviews",
],
},
],
remote_preference="remote",
salary_min=180000,
salary_max=250000,
salary_currency="USD",
open_to_work=True,
)
db.add(profile)
# 4. Create companies
company_map = {}
for c in SAMPLE_COMPANIES:
company = Company(**c)
db.add(company)
company_map[c["name"]] = company
await db.flush()
# 5. Create jobs
now = datetime.now(timezone.utc)
for i, j in enumerate(SAMPLE_JOBS):
company = company_map.get(j["company"])
job = Job(
title=j["title"],
company_id=company.id if company else None,
company_name=j["company"],
source_url=f"https://{company.domain}/careers/{uuid.uuid4().hex[:8]}" if company else "https://example.com/jobs/1",
source_domain=company.domain if company else "example.com",
source_type="seed",
remote_type=j.get("remote_type"),
employment_type=j.get("employment_type"),
seniority_level=j.get("seniority_level"),
salary_min=j.get("salary_min"),
salary_max=j.get("salary_max"),
salary_currency="USD",
salary_interval="yearly",
skills_required=j.get("skills_required"),
description_text=j.get("description_text"),
status="active",
date_posted=now - timedelta(days=i * 2),
locations=[{"raw": "San Francisco, CA", "city": "San Francisco", "state": "CA", "country": "US"}],
)
db.add(job)
# 6. Create sources
for s in SAMPLE_SOURCES:
source = JobSource(**s)
db.add(source)
await db.commit()
print("✅ Database seeded successfully!")
print(" Admin: admin@jobportal.dev / admin123")
print(" Demo: demo@jobportal.dev / demo123")
print(f" Companies: {len(SAMPLE_COMPANIES)}")
print(f" Jobs: {len(SAMPLE_JOBS)}")
print(f" Sources: {len(SAMPLE_SOURCES)}")
if __name__ == "__main__":
asyncio.run(seed())