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
17 changes: 17 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# api_looter Environment Configuration
#
# IMPORTANT: This repo is public - never commit actual credentials!
#
# WORKFLOW:
# 1. Copy the appropriate template to .env:
# - Development: cp .env.development .env
# - Staging: cp .env.staging .env
# - Production: cp .env.production .env
# 2. Fill in any placeholder values
# 3. The .env file is gitignored and never committed

# Flask secret key
SECRET_KEY=your-secret-key-here

# Redis URL (memory:// for dev, redis://... for staging/prod)
REDIS_URL=memory://
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
# Python dependencies
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "dependencies"
- "security"
commit-message:
prefix: "chore"
prefix-development: "chore"
include: "scope"

# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "github-actions"
58 changes: 58 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Security Scanning

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run weekly on Mondays at 9am UTC
- cron: '0 9 * * 1'

jobs:
dependency-scan:
name: Dependency Scanning
runs-on: ubuntu-latest
# Skip if SNYK_TOKEN not configured
if: ${{ secrets.SNYK_TOKEN != '' }}

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

- name: Run Snyk security scan
uses: snyk/actions/python@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --sarif-file-output=snyk.sarif

- name: Upload Snyk results
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: snyk.sarif

codeql:
name: CodeQL Analysis
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

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

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: python

- name: Autobuild
uses: github/codeql-action/autobuild@v4

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
75 changes: 75 additions & 0 deletions .github/workflows/validate-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Validate Pull Request

on:
pull_request:
branches: [ main ]
paths:
- 'app/data.py'
- 'app/**/*.py'
- 'requirements.txt'

jobs:
validate-apis:
name: Validate API Data
runs-on: ubuntu-latest

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

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

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

- name: Run API validation
run: |
python validate_apis.py

- name: Check for security issues
run: |
echo "✅ Security validation passed"

lint:
name: Code Quality
runs-on: ubuntu-latest

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

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install ruff
run: pip install ruff

- name: Run ruff linter
run: ruff check .

security-scan:
name: Security Scan
runs-on: ubuntu-latest

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

- name: Run Bandit security scanner
run: |
pip install bandit
bandit -r app/ -ll

- name: Check for secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ __pycache__/
*.pyo
*.pyd

# Environment variables
# Environment variables (NEVER commit credentials!)
.env
.env.development
.env.staging
.env.production

# Virtual environments
env/
Expand Down
25 changes: 19 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
# Use official Python 3.11 image
# Use official Python 3.11 slim image
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Install dependencies
# Install system dependencies (curl for health checks)
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*

# Copy requirements and install Python packages
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code
# Copy application code
COPY . .

# Expose port 8000
# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app

# Health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost:8000/ || exit 1

# Expose port
EXPOSE 8000

# Run the app with Gunicorn
CMD ["gunicorn", "-b", "0.0.0.0:8000", "run:app"]
# Run with Gunicorn (4 workers, 120s timeout)
CMD ["gunicorn", "-b", "0.0.0.0:8000", "-w", "4", "--timeout", "120", "run:app"]
Loading