diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0cde0ac --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +.git +.github +.venv +__pycache__ +.pytest_cache +.ruff_cache +.mypy_cache +.langgraph_api +tests +docs +*.pyc +*.pyo +*.pyd +*.log +.env +.env.* +README.md +TEMPLATE_README.md +drawkit.xml diff --git a/.github/workflows/publish-ghcr.yml b/.github/workflows/publish-ghcr.yml new file mode 100644 index 0000000..9751d7a --- /dev/null +++ b/.github/workflows/publish-ghcr.yml @@ -0,0 +1,55 @@ +name: Build and Publish Container + +on: + push: + branches: [main] + tags: ["v*"] + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set image name + id: image + run: echo "name=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract image metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ steps.image.outputs.name }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4c306e6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + UV_LINK_MODE=copy + +WORKDIR /app + +RUN pip install --no-cache-dir uv + +COPY pyproject.toml uv.lock ./ +COPY casts ./casts +COPY app ./app + +RUN uv sync --frozen --no-dev --all-packages + +EXPOSE 8000 + +CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/README.md b/README.md index 3a9c6d1..41e6e27 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,107 @@ -# Act: Interview Graph +# 🙋‍♂️ InterviewGraph -A LangGraph-based Act project scaffolded with Act Operator. +InterviewGraph is a LangGraph-based service that generates structured interview questions from resume content. -## Quick Start +It accepts either resume text or a PDF file, extracts relevant signals, and returns 15 questions with difficulty ratings. + +The response includes both structured JSON and Markdown for interviewer-friendly review. + +> This project was developed through Act-Operator. +> +> [😺 Act-Operator Github](https://github.com/Proact0/act-operator) + +## What It Does + +- Accepts resume text or PDF input +- Parses resume sections (summary, skills, experience, projects, education) +- Extracts signals (skills, projects, keywords) +- Generates 15 interview questions +- Rates question difficulty (1-5) +- Formats output as JSON and Markdown + +## Architecture (MVP) + +Pipeline: + +`extract_text -> parse_sections -> extract_signals -> generate_questions -> rate_difficulty -> format_output` + +## Quick Start (Local) 1. Install dependencies: - ```bash - uv sync --all-packages - ``` -2. Run the development server: - ```bash - uv run langgraph dev - ``` +```bash +uv sync --all-packages +``` + +1. Run API server: + +```bash +uv run uvicorn app.main:app --reload +``` + +1. Open API docs: + +- `http://127.0.0.1:8000/docs` + +## API Usage + +- `POST /api/v1/interview-questions` for text input +- `POST /api/v1/interview-questions/upload` for PDF upload (multipart/form-data) + +Example JSON payload: + +```json +{ + "resume_text": "Summary ... Skills ... Projects ..." +} +``` + +## Container Usage + +Build image: + +```bash +docker build -t interviewgraph:local . +``` + +Run container: + +```bash +docker run --rm -p 8000:8000 interviewgraph:local +``` + +Open docs: + +- `http://127.0.0.1:8000/docs` + +## GHCR Publishing + +This repository includes `.github/workflows/publish-ghcr.yml`. + +- On push to `main`, the workflow builds and publishes to `ghcr.io//`. +- On push tag `v*`, it also publishes versioned tags. +- You can manually trigger publishing with `workflow_dispatch`. + +Pull from GHCR: + +```bash +docker pull ghcr.io//:latest +docker run --rm -p 8000:8000 ghcr.io//:latest +``` + +## Current Scope (MVP) + +- Text-extractable PDF support +- Resume-grounded question generation pipeline +- Structured error payloads + +## Out of Scope (MVP) -3. Access Studio UI: - - Studio UI: https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024 - - API: http://127.0.0.1:2024 - - API Docs: http://127.0.0.1:2024/docs +- OCR for scanned PDFs +- Vector DB / RAG +- Multi-agent orchestration +- Mock interview answer scoring -For detailed documentation, see [TEMPLATE_README.md](TEMPLATE_README.md). +## License +Apache License 2.0 - see [LICENSE](https://www.apache.org/licenses/LICENSE-2.0) for details.