From 4ee34abc65e20b282c2b6f9b533abf9e4232229c Mon Sep 17 00:00:00 2001 From: Muna Nasher Date: Wed, 3 Jun 2026 15:30:33 +0200 Subject: [PATCH] add CI workflow --- Dockerfile | 23 +++++------------------ src/pipeline.py | 43 ++++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index d665b11..cd49d19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,11 @@ -# Task 4: Write a cache-friendly Dockerfile. -# -# Requirements (in order): -# 1. Use python:3.11-slim as the base image. -# 2. Copy requirements.txt BEFORE copying source code. -# 3. Install dependencies from requirements.txt. -# 4. Copy src/ into the image. -# 5. Set the CMD to run the pipeline: python -m src.pipeline -# -# Replace each TODO comment with the correct Dockerfile instruction. - -# TODO: set the base image -FROM TODO +FROM python:3.11-slim WORKDIR /app -# TODO: copy requirements.txt (before source — this keeps the install layer cached) +COPY requirements.txt . -# TODO: install dependencies +RUN pip install --no-cache-dir -r requirements.txt -# TODO: copy source code +COPY src/ src/ -# TODO: set the command that runs when the container starts -CMD ["TODO"] +CMD ["python", "-m", "src.pipeline"] \ No newline at end of file diff --git a/src/pipeline.py b/src/pipeline.py index 1cd17a4..3c90498 100644 --- a/src/pipeline.py +++ b/src/pipeline.py @@ -9,6 +9,7 @@ """ import logging +import os from pathlib import Path logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") @@ -21,40 +22,56 @@ def get_config() -> dict: Required variable: API_KEY Optional variable: OUTPUT_DIR (default "output") - - Raise RuntimeError with a clear message if a required variable is missing. """ - raise NotImplementedError("Task 5: read API_KEY and OUTPUT_DIR from the environment") + api_key = os.getenv("API_KEY") + + if not api_key: + raise RuntimeError("API_KEY is missing") + + output_dir = os.getenv("OUTPUT_DIR", "output") + + return { + "api_key": api_key, + "output_dir": output_dir, + } def fetch_data(api_key: str) -> list[dict]: """ Simulate fetching records from an external API. - - Return a list of at least one dict representing a record. - In a real pipeline you would call requests.get(...) here. """ - raise NotImplementedError("Task 1: return at least one sample record") + return [ + {"id": 1, "name": "Muna", "city": "Amsterdam"}, + {"id": 2, "name": "Ali", "city": "Rotterdam"}, + ] def save_results(records: list[dict], output_dir: Path) -> None: """ - Write each record as a line to output_dir/results.txt. - - Create output_dir if it does not exist. - Log the number of records written. + Write each record as a line to output_dir/results.txt """ - raise NotImplementedError("Task 1: write records to output_dir/results.txt") + output_dir.mkdir(parents=True, exist_ok=True) + + file_path = output_dir / "results.txt" + + with open(file_path, "w", encoding="utf-8") as f: + for record in records: + f.write(f"{record}\n") + + logger.info("%s records written", len(records)) def run() -> None: config = get_config() logger.info("starting pipeline") + records = fetch_data(config["api_key"]) output_dir = Path(config["output_dir"]) + save_results(records, output_dir) + logger.info("pipeline complete") if __name__ == "__main__": - run() + run() \ No newline at end of file