Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Python Lint

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
python-lint:
name: Lint Python Code
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'

- name: Install linters
run: |
python -m pip install --upgrade pip
pip install flake8 black isort

- name: Run flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics

- name: Check import sorting with isort
run: |
isort . --check-only
43 changes: 43 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Python Tests with Coverage

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
if: false # disables the job temporary
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ['3.11', '3.12', '3.13']

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov

- name: Run tests with coverage
run: |
pytest --cov=your_package_name --cov-report=term --cov-report=xml --cov-fail-under=80

# Optional: Upload coverage report to Codecov (for public repos or with CODECOV_TOKEN)
- name: Upload to Codecov
uses: codecov/codecov-action@v3
with:
files: coverage.xml
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # Only needed for private repos
24 changes: 24 additions & 0 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Trivy Security Scan

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
trivy-scan:
runs-on: ubuntu-latest
name: Trivy FS Scan

steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Run Trivy vulnerability scanner on file system
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln,secret,config'
ignore-unfixed: true
4 changes: 1 addition & 3 deletions app/alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from logging.config import fileConfig

from sqlalchemy import engine_from_config
from sqlalchemy import pool

from alembic import context
from sqlalchemy import engine_from_config, pool

from app.config.database import Base
from app.models import * # noqa: F401, F403
Expand Down
8 changes: 7 additions & 1 deletion app/api/routes/questions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from fastapi import APIRouter
from app.services.questions import generate_daily_question as generate_daily_question_service, add_daily_question_to_store as add_question_in_chroma_db, add_daily_question_to_mongodb, get_most_recent_daily_question

from app.schemas.utils import UserPrompt
from app.services.questions import add_daily_question_to_mongodb
from app.services.questions import \
add_daily_question_to_store as add_question_in_chroma_db
from app.services.questions import \
generate_daily_question as generate_daily_question_service
from app.services.questions import get_most_recent_daily_question

router = APIRouter()

Expand Down
5 changes: 4 additions & 1 deletion app/config/config_mongo_fb.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from asyncio.log import logger
from app.config.database import SessionLocal

from pymongo import MongoClient

from app.config.database import SessionLocal


class MongoDB:
def __init__(self, uri: str, db_name: str):
self.client = MongoClient(uri)
Expand Down
7 changes: 5 additions & 2 deletions app/config/vectorestore.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from typing import List, Optional, Dict, Any
from typing import Any, Dict, List, Optional

from chromadb import PersistentClient
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.documents import Document
from langchain_huggingface import HuggingFaceEmbeddings

from app.settings import settings


# Using singleton pattern for ChromaDB to ensure a single instance is used across the application
class ChromaDB:
"""Singleton class for managing ChromaDB collections and operations."""
Expand Down
3 changes: 3 additions & 0 deletions app/llm/provider.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import time
from typing import Any, Dict

from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint

from app.settings import settings


def build_chat_model() -> ChatHuggingFace:
"""Builds and returns a ChatHuggingFace model instance configured with the settings from the app."""
llm = HuggingFaceEndpoint(
Expand Down
1 change: 1 addition & 0 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from app.api.main import api_router
from app.settings import settings

Expand Down
8 changes: 6 additions & 2 deletions app/pipelines/daily_question_pipeline.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from typing import Dict
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate

from langchain_core.prompts import (ChatPromptTemplate,
HumanMessagePromptTemplate,
SystemMessagePromptTemplate)
from langchain_core.runnables import RunnableParallel
from app.prompts.daily_question_prompt import system_template, human_template

from app.config.vectorestore import chroma_db
from app.llm.provider import build_chat_model
from app.prompts.daily_question_prompt import human_template, system_template
from app.settings import settings

# using tech_description collection to retrieve context.
Expand Down
1 change: 1 addition & 0 deletions app/schemas/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pydantic import BaseModel


class UserPrompt(BaseModel):
"""Schema for user prompt input."""
user_prompt: str | None = None
11 changes: 7 additions & 4 deletions app/services/questions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from datetime import datetime

from langchain_core.documents import Document
from app.pipelines.daily_question_pipeline import daily_question_chain
from app.llm.provider import invoke_with_retries
from app.config.vectorestore import chroma_db

from app.config.config_mongo_fb import questions_collection
from datetime import datetime
from app.config.vectorestore import chroma_db
from app.llm.provider import invoke_with_retries
from app.pipelines.daily_question_pipeline import daily_question_chain


def generate_daily_question(user_prompt: str = None) -> str:
"""Generate a daily question using the LLM pipeline."""
Expand Down