diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..3bb0c7e --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 100 +exclude = .git,__pycache__,dist,*.egg-info,venv +extend-ignore = E203 \ No newline at end of file diff --git a/.gitignore b/.gitignore index cd4609c..e3da943 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,42 @@ -env +# Environment +env/ .env +venv/ +ENV/ + +# Python +__pycache__/ +*.py[cod] +*$py.class +.Python +*.so +.pytest_cache/ +.coverage +.coverage.* +coverage.xml +*.cover +htmlcov/ + +# IDEs and editors +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# Project specific test.py -__pycache__ \ No newline at end of file +*.log +.pip-cache/ + +# Temporary files +*.tmp +.DS_Store + +# Distribution / packaging +dist/ +build/ +*.egg-info/ + +# Docker +.docker/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..b546ea9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,70 @@ +image: python:3.10-slim + +variables: + PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache" + PYTHONPATH: "$CI_PROJECT_DIR" + +cache: + paths: + - .pip-cache + - venv/ + +stages: + - setup + - lint + - test + +before_script: + - python --version + - pip install virtualenv + - virtualenv venv + - source venv/bin/activate + +setup: + stage: setup + script: + - pip install --no-cache-dir -r requirements.txt + artifacts: + paths: + - venv/ + expire_in: 1 hour + +lint: + stage: lint + needs: + - setup + script: + - black --check app/ main.py tests/ + - flake8 app/ main.py tests/ --max-line-length=100 + +test: + stage: test + needs: + - setup + script: + # Run all tests + - pytest tests/ -v + # Start FastAPI server + - uvicorn main:app --host 0.0.0.0 --port 8000 & + # Wait for server to start + - sleep 10 + # Test health endpoint + - | + RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health) + if [ "$RESPONSE" = "200" ]; then + echo "✅ Health check passed" + else + echo "❌ Health check failed with status $RESPONSE" + exit 1 + fi + +build: + stage: build + needs: + - test + - lint + script: + - docker build -t fact-check-api . + only: + - master + - dev \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f7bc893..459c6e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ annotated-types==0.7.0 anyio==4.7.0 attrs==24.3.0 beautifulsoup4==4.12.3 +black==24.10.0 certifi==2024.12.14 charset-normalizer==3.4.0 click==8.1.7 @@ -13,14 +14,20 @@ dataclasses-json==0.6.7 dnspython==2.7.0 email_validator==2.2.0 fastapi==0.115.6 +fastapi-cli==0.0.7 +flake8==7.1.1 frozenlist==1.5.0 greenlet==3.1.1 gunicorn==23.0.0 h11==0.14.0 httpcore==1.0.7 +httptools==0.6.4 httpx==0.28.1 httpx-sse==0.4.0 idna==3.10 +iniconfig==2.0.0 +itsdangerous==2.2.0 +Jinja2==3.1.4 jsonpatch==1.33 jsonpointer==3.0.0 langchain==0.3.12 @@ -28,17 +35,29 @@ langchain-community==0.3.12 langchain-core==0.3.25 langchain-text-splitters==0.3.3 langsmith==0.2.3 +markdown-it-py==3.0.0 +MarkupSafe==3.0.2 marshmallow==3.23.1 +mccabe==0.7.0 +mdurl==0.1.2 multidict==6.1.0 mypy-extensions==1.0.0 numpy==2.2.0 openai==0.28.0 orjson==3.10.12 packaging==24.2 +pathspec==0.12.1 +platformdirs==4.3.6 +pluggy==1.5.0 propcache==0.2.1 +pycodestyle==2.12.1 pydantic==2.10.3 +pydantic-extra-types==2.10.1 pydantic-settings==2.7.0 pydantic_core==2.27.1 +pyflakes==3.2.0 +Pygments==2.18.0 +pytest==8.3.4 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 python-json-logger==3.2.1 @@ -46,6 +65,9 @@ python-multipart==0.0.20 PyYAML==6.0.2 requests==2.32.3 requests-toolbelt==1.0.0 +rich==13.9.4 +rich-toolkit==0.12.0 +shellingham==1.5.4 six==1.17.0 sniffio==1.3.1 soupsieve==2.6 @@ -53,9 +75,13 @@ SQLAlchemy==2.0.36 starlette==0.41.3 tenacity==9.0.0 tqdm==4.67.1 +typer==0.15.1 typing-inspect==0.9.0 typing_extensions==4.12.2 ujson==5.10.0 urllib3==2.2.3 uvicorn==0.34.0 +uvloop==0.21.0 +watchfiles==1.0.3 +websockets==14.1 yarl==1.18.3 diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 0000000..2298bfc --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,18 @@ +from fastapi.testclient import TestClient +from main import app + +client = TestClient(app) + +def test_root_endpoint(): + response = client.get("/") + assert response.status_code == 200 + assert response.json() == {"message": "Welcome to your FastAPI application"} + +def test_health_endpoint(): + response = client.get("/health") + assert response.status_code == 200 + assert response.json() == {"status": "healthy"} + +def test_cors_headers(): + response = client.get("/", headers={"Origin": "http://localhost:5173"}) + assert response.headers["access-control-allow-origin"] == "http://localhost:5173" \ No newline at end of file