Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d77ba8e
adding github build
ayushsinghal90 Sep 14, 2025
2758435
fixing docker yml
ayushsinghal90 Sep 14, 2025
db03098
Remove gamma
ayushsinghal90 Sep 14, 2025
ba2c563
adding build folder
ayushsinghal90 Sep 16, 2025
56d4e45
adding gracefful shutdown
ayushsinghal90 Sep 16, 2025
e56bb25
Merge pull request #29 from druling/build
ayushsinghal90 Sep 16, 2025
afdd6ad
adding default env value
ayushsinghal90 Sep 17, 2025
45fea95
Merge pull request #30 from druling/small_change
ayushsinghal90 Sep 17, 2025
18924a2
integration credit api from backen
ayushsinghal90 Sep 28, 2025
93347ce
Merge branch 'small_change' into cost_credit
ayushsinghal90 Sep 28, 2025
f679bdb
adding credit cost inc dec
ayushsinghal90 Sep 28, 2025
ae32c81
adding cost for llm calls
ayushsinghal90 Sep 28, 2025
bcda377
Merge pull request #31 from druling/cost_credit
ayushsinghal90 Sep 28, 2025
1ff6bab
adding credit cost deducation
ayushsinghal90 Sep 28, 2025
ba749ea
Merge pull request #32 from druling/cost_credit
ayushsinghal90 Sep 28, 2025
41449fa
update service name for deployment
ayushsinghal90 Oct 9, 2025
89df521
Merge pull request #33 from druling/update_build
ayushsinghal90 Oct 9, 2025
2946ce7
fixing default backend url
ayushsinghal90 Oct 9, 2025
93a04fb
Merge pull request #34 from druling/bug_fixes
ayushsinghal90 Oct 9, 2025
e13b6d6
Fixing profile id set in request
ayushsinghal90 Oct 9, 2025
ca285f8
Merge pull request #35 from druling/bug_fixes
ayushsinghal90 Oct 9, 2025
30d70db
fixing error for credit inc and dec
ayushsinghal90 Oct 10, 2025
95f05b9
removing wrapper on exception
ayushsinghal90 Oct 10, 2025
c2d3bad
adding 429 response in respone factory
ayushsinghal90 Oct 10, 2025
05eec09
removing credit call on llm services
ayushsinghal90 Oct 11, 2025
b2701ad
change url for credit api
ayushsinghal90 Oct 11, 2025
97a84c9
Merge pull request #36 from druling/prod_ready
ayushsinghal90 Oct 11, 2025
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
25 changes: 7 additions & 18 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PORT=300
PORT=3000

# Postgres Credentials
DATABASE_NAME=druling
Expand All @@ -9,24 +9,13 @@ DATABASE_PORT=5432

INTERNAL_SECRET=drulinghere

OPENAI_API_KEY="openai key here"
ANTHROPIC_API_KEY="anthropic key here"
GOOGLE_API_KEY="google key here"
OPENAI_API_KEY=key_here
ANTHROPIC_API_KEY=key_here
GOOGLE_API_KEY=key_here

BACKEND_URL=http://localhost:8000/internal/v1

# Environment-specific configuration (.env)
# Development
LOG_LEVEL=DEBUG
LOG_LEVEL=INFO
LOG_FORMAT=standard

# Production
# LOG_LEVEL=INFO
# LOG_FORMAT=json
# SENTRY_DSN=your_sentry_dsn_here

# Staging
# LOG_LEVEL=DEBUG
# LOG_FORMAT=json
BACKEND_URL=http://localhost:8000/internal/v1

SECRET_ENCRYPTION_KEY=secret_key_here
SECRET_ENCRYPTION_KEY=secure_key_here
85 changes: 85 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Build, Push, and Deploy

on:
push:
branches:
- dev
- master

jobs:
build-and-push:
name: Build and Push
runs-on: ubuntu-latest
environment: ${{ github.ref == 'refs/heads/master' && 'prod' || (github.ref == 'refs/heads/dev' && 'dev' || 'staging') }}

permissions:
id-token: write
contents: read

env:
AWS_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}

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

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build \
-t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
-t $ECR_REGISTRY/$ECR_REPOSITORY:latest \
-f build/docker/Dockerfile .

docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

update-ecs-service:
name: Update ECS Service
runs-on: ubuntu-latest
needs: build-and-push
environment: ${{ github.ref == 'refs/heads/master' && 'prod' || (github.ref == 'refs/heads/dev' && 'dev' || 'staging') }}

permissions:
id-token: write
contents: read

env:
AWS_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
ECS_CLUSTER: ${{ secrets.ECS_NAME }}
ECS_SERVICE: ${{ secrets.ECS_NAME }}
IMAGE: ${{ needs.build-and-push.outputs.image }}

steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}

- name: Update ECS service
run: |
aws ecs update-service \
--cluster $ECS_CLUSTER \
--service ${ECS_SERVICE}-web \
--force-new-deployment \
--region $AWS_REGION \
--no-cli-pager \
> /dev/null 2>&1

echo "Started Deployment"
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ __pycache__/
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
Expand Down
34 changes: 34 additions & 0 deletions build/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Use an official Python runtime as a base image
FROM python:3.10-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1 # Prevent Python from writing .pyc files
ENV PYTHONUNBUFFERED 1 # Force the stdout and stderr streams to be unbuffered

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
postgresql-client && \
apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install dependencies
COPY ../../../requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the entire project structure
COPY ../../.. .

# Copy and make entrypoint script executable
COPY build/docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

# Add the current directory to Python path
ENV PYTHONPATH=/app

# Expose the port FastAPI runs on
EXPOSE 8000

# Use entrypoint script for proper signal handling
ENTRYPOINT ["/entrypoint.sh"]
28 changes: 28 additions & 0 deletions build/docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

# Enable exit on error
set -e

# Function to handle shutdown signals
shutdown() {
echo "Received shutdown signal, gracefully stopping uvicorn..."
if [ ! -z "$UVICORN_PID" ]; then
kill -TERM "$UVICORN_PID"
wait "$UVICORN_PID"
fi
echo "Application stopped gracefully"
exit 0
}

# Trap SIGTERM and SIGINT signals
trap shutdown SIGTERM SIGINT

# Start the FastAPI application
echo "Starting FastAPI application..."
uvicorn src.main:app --host 0.0.0.0 --port 8000 &

# Store the PID of uvicorn process
UVICORN_PID=$!

# Wait for the process to complete
wait "$UVICORN_PID"
9 changes: 6 additions & 3 deletions Dockerfile → build/stack/web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ FROM python:3.11-slim
WORKDIR /app

# Install dependencies
COPY requirements.txt .
COPY ../../../requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the project files
COPY src/ src/
# Copy the entire project structure
COPY ../../.. .

# Add the current directory to Python path
ENV PYTHONPATH=/app

# Expose the port FastAPI runs on
EXPOSE 8000
Expand Down
65 changes: 16 additions & 49 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,64 +1,31 @@
version: '3.9'

services:
api:
build:
context: .
dockerfile: Dockerfile
dockerfile: build/stack/web/Dockerfile
ports:
- "8000:8000"
env_file:
- .env
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/cleanfastapi
DATABASE_NAME: druling
DATABASE_USER: druling
DATABASE_PASSWORD: password
DATABASE_HOST: db
DATABASE_PORT: 5432
depends_on:
- db
volumes:
- ./src:/src/src
command: uvicorn src.main:src --host 0.0.0.0 --port 8000 --reload
- ./src:/app/src

db:
image: postgres:17
environment:
- POSTGRES_DB=cleanfastapi
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"

volumes:
postgres_data:

# version: '3.8'
# services:
# app:
# build: .
# ports:
# - "8000:8000"
# environment:
# - LOG_LEVEL=INFO
# - LOG_FORMAT=json
# volumes:
# - ./logs:/app/logs
# depends_on:
# - elasticsearch
#
# elasticsearch:
# image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
# environment:
# - discovery.type=single-node
# - xpack.security.enabled=false
# ports:
# - "9200:9200"
# volumes:
# - elasticsearch_data:/usr/share/elasticsearch/data
#
# filebeat:
# image: docker.elastic.co/beats/filebeat:8.11.0
# user: root
# volumes:
# - ./logs:/app/logs:ro
# - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
# depends_on:
# - elasticsearch
#
# volumes:
# elasticsearch_data:
environment:
POSTGRES_PASSWORD: password
POSTGRES_USER: druling
POSTGRES_PORT: 5432
POSTGRES_DB: druling
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ frozenlist==1.6.0
fsspec==2025.7.0
functions==0.7.0
generativeai==0.0.1
google-ai-generativelanguage==0.7.0
google-ai-generativelanguage==0.6.18
google-api-core==2.25.1
google-api-python-client==2.181.0
google-auth==2.40.3
Expand All @@ -60,7 +60,7 @@ jsonpointer==3.0.0
langchain==0.3.25
langchain-anthropic==0.3.12
langchain-community==0.3.23
langchain-core==0.3.58
langchain-core==0.3.62
langchain-deepseek==0.1.3
langchain-google-genai==2.1.5
langchain-openai==0.3.16
Expand Down Expand Up @@ -118,7 +118,7 @@ stack-data==0.6.3
starlette==0.46.2
tabulate==0.9.0
tenacity==9.1.2
tiktoken==0.3.3
tiktoken==0.8.0
tomli==2.2.1
tqdm==4.67.1
traitlets==5.14.3
Expand Down
2 changes: 2 additions & 0 deletions src/app/asset_conversation/schemas/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AssetChatResponse(BaseModel):
tokens_used: Optional[int] = None
confidence_score: Optional[float] = None
metadata: Optional[Dict[str, Any]] = None
credit_used: Optional[int] = None


class FileProcessingResponse(BaseModel):
Expand All @@ -17,3 +18,4 @@ class FileProcessingResponse(BaseModel):
extracted_text: Optional[str] = None
extracted_data: Optional[Dict[str, Any]] = None
processing_status: Optional[str]
credit_used: Optional[int] = None
13 changes: 10 additions & 3 deletions src/app/asset_conversation/services/asset.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import logging

from sqlalchemy.ext.asyncio import AsyncSession

from src.core.exceptions.internal_service import InternalServer
from src.services.asset_operation import AssetFactory, AssetOperationService
from src.services.asset_operation.types import PdfService

logger = logging.getLogger(__name__)


class AssetConversationService:
def __init__(self, db: AsyncSession, **kwargs):
Expand All @@ -14,20 +19,22 @@ async def asset_service(self, request) -> AssetOperationService:
asset_service = await AssetFactory.get_parser_service(self.db, request)
return asset_service
except Exception as e:
raise Exception(f"Error getting LLM service: {e}")
raise InternalServer(f"Error getting LLM service: {e}")

async def analyze_asset(self, request):
"""Analyze an asset using LLM"""
try:
asset_service = await self.asset_service(request)
return await asset_service.analyze()
except Exception as e:
raise Exception(f"Error analyzing asset: {e}")
logger.error(f"Error analyzing assert: {e}")
raise e

async def generate_asset(self, request):
"""Generate an asset using LLM"""
try:
asset_service = await self.asset_service(request)
return await asset_service.generate()
except Exception as e:
raise Exception(f"Error generating asset: {e}")
logger.error(f"Error generating asset: {e}")
raise e
Loading