{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# Module 0 — Dev Environment Setup\n\nBefore writing any code, you need three things working:\n\n1. **VS Code** as your editor\n2. **Jupyter notebooks** for interactive development\n3. The **Anthropic Python SDK** connected to a valid API key\n\nThis module gets all three running and ends with a verified \"Hello Claude\" test."
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. What You'll Need\n",
    "\n",
    "- **Python 3.9 or later** — check with `python --version` or `python3 --version`\n",
    "- **VS Code** — download from [code.visualstudio.com](https://code.visualstudio.com)\n",
    "- **An Anthropic API key** — from [console.anthropic.com](https://console.anthropic.com)\n",
    "- **~10 minutes** and a terminal\n",
    "\n",
    "Run the cell below to confirm your Python version is 3.9+:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "print(f\"Python version: {sys.version}\")\n",
    "print(f\"Executable:     {sys.executable}\")\n",
    "\n",
    "assert sys.version_info >= (3, 9), \"Python 3.9 or later is required\"\n",
    "print(\"\\nPython version check passed.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Install VS Code Extensions\n",
    "\n",
    "Open VS Code and install these two extensions from the Extensions panel (`Ctrl+Shift+X` / `Cmd+Shift+X`):\n",
    "\n",
    "| Extension | Publisher | Why |\n",
    "|---|---|---|\n",
    "| **Python** | `ms-python` | Python language support, linting, virtual environment detection |\n",
    "| **Jupyter** | `ms-toolsai` | Run `.ipynb` notebooks directly inside VS Code without launching a browser |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Create Your Project Folder\n",
    "\n",
    "Pick a home for your lab files. All 10 modules build on the same notebook, so one folder is all you need.\n",
    "\n",
    "```bash\n",
    "mkdir claude-architect-lab\n",
    "cd claude-architect-lab\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Set Up a Virtual Environment\n",
    "\n",
    "A virtual environment keeps the SDK and its dependencies isolated from the rest of your system — important when you're working with multiple Python projects.\n",
    "\n",
    "```bash\n",
    "# Create the environment\n",
    "python -m venv .venv\n",
    "\n",
    "# Activate it\n",
    "# macOS / Linux:\n",
    "source .venv/bin/activate\n",
    "\n",
    "# Windows (PowerShell):\n",
    ".venv\\Scripts\\Activate.ps1\n",
    "\n",
    "# Windows (Command Prompt):\n",
    ".venv\\Scripts\\activate.bat\n",
    "```\n",
    "\n",
    "Your terminal prompt should now show `(.venv)` to confirm it's active."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Install Dependencies\n",
    "\n",
    "```bash\n",
    "pip install anthropic python-dotenv ipykernel\n",
    "```\n",
    "\n",
    "- **`anthropic`** — official Python SDK for the Claude API\n",
    "- **`python-dotenv`** — loads your `.env` file so the API key is never hardcoded\n",
    "- **`ipykernel`** — registers your virtual environment as a Jupyter kernel so VS Code can find it\n",
    "\n",
    "Verify the install by running the cell below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import importlib.metadata\n",
    "\n",
    "for pkg in (\"anthropic\", \"python-dotenv\", \"ipykernel\"):\n",
    "    try:\n",
    "        version = importlib.metadata.version(pkg)\n",
    "        print(f\"{pkg:<15} {version}\")\n",
    "    except importlib.metadata.PackageNotFoundError:\n",
    "        print(f\"{pkg:<15} NOT INSTALLED — run: pip install {pkg}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Get Your API Key\n",
    "\n",
    "1. Go to [console.anthropic.com](https://console.anthropic.com) and sign in (or create a free account).\n",
    "2. Navigate to **API Keys** in the left sidebar.\n",
    "3. Click **Create Key**, give it a name like `architect-lab`, and copy the key — it starts with `sk-ant-`.\n",
    "\n",
    "> **You only see the full key once**, so copy it immediately."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7. Store Your Key Safely\n",
    "\n",
    "Create two files in your project folder:\n",
    "\n",
    "**`.env`**\n",
    "```\n",
    "ANTHROPIC_API_KEY=sk-ant-api03-YOUR-KEY-HERE\n",
    "```\n",
    "\n",
    "**`.gitignore`**\n",
    "```\n",
    ".env\n",
    ".venv/\n",
    "__pycache__/\n",
    "*.pyc\n",
    ".ipynb_checkpoints/\n",
    "```\n",
    "\n",
    "> **Never commit your API key.** The `.gitignore` above ensures `.env` stays local. If you accidentally push a key, **rotate it immediately** in the Anthropic console — old keys can be used by anyone who finds them in your git history."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8. Create Your Lab Notebook\n",
    "\n",
    "1. Open your project folder in VS Code: **File → Open Folder**\n",
    "2. Create a new file named `lab.ipynb` (**File → New File**, then save with the `.ipynb` extension).\n",
    "3. VS Code will open it as a notebook. In the top-right corner, click **Select Kernel**.\n",
    "4. Choose **Python Environments** → select the `.venv` you just created. If it doesn't appear, run **Python: Select Interpreter** from the command palette first."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9. Hello Claude — Your First Cell\n",
    "\n",
    "Run the cell below with `Shift+Enter`. If everything is configured correctly, you should see a one-sentence response from Claude. That's your environment confirmed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import anthropic\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()  # reads ANTHROPIC_API_KEY from your .env file\n",
    "\n",
    "client = anthropic.Anthropic()\n",
    "\n",
    "message = client.messages.create(\n",
    "    model=\"claude-sonnet-4-6\",\n",
    "    max_tokens=256,\n",
    "    messages=[\n",
    "        {\"role\": \"user\", \"content\": \"In one sentence, what is the Claude API?\"}\n",
    "    ],\n",
    ")\n",
    "\n",
    "print(message.content[0].text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## 10. Understanding the Response Object\n\nBefore moving to Module 1, it's worth knowing what the API returned.\n\n- **`stop_reason`** — `\"end_turn\"` means Claude finished naturally. The exam tests this heavily.\n- **`usage`** — input and output token counts used to calculate cost.\n- **`model`** — confirms which model version actually ran your request."
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Stop reason: \", message.stop_reason)\n",
    "print(\"Input tokens:\", message.usage.input_tokens)\n",
    "print(\"Output tokens:\", message.usage.output_tokens)\n",
    "print(\"Model:        \", message.model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Other stop_reason values to know\n",
    "\n",
    "| Value | Meaning |\n",
    "|---|---|\n",
    "| `end_turn` | Claude finished its response naturally |\n",
    "| `max_tokens` | Hit the `max_tokens` cap — response was truncated |\n",
    "| `stop_sequence` | A custom stop sequence you supplied was matched |\n",
    "| `tool_use` | Claude wants to call a tool (covered in later modules) |\n",
    "| `pause_turn` | Long-running turn paused — resume by sending it back |\n",
    "| `refusal` | Claude declined for safety reasons |\n",
    "\n",
    "> Keep your notebook cells small and purposeful. Each lab module adds new cells to this same `lab.ipynb`. A well-structured notebook with clear headings and focused cells is also good practice for the structured-output modules later in the lab."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Troubleshooting\n",
    "\n",
    "| Problem | Most likely cause | Fix |\n",
    "|---|---|---|\n",
    "| `AuthenticationError` | `.env` not found or key is wrong | Check the file is in the project root, not a subfolder. Confirm no extra spaces around the `=`. |\n",
    "| Kernel not listed | `.venv` not registered with Jupyter | Run `python -m ipykernel install --user --name .venv` inside your activated environment. |\n",
    "| `ModuleNotFoundError: anthropic` | Wrong Python environment active | Confirm `(.venv)` is in your terminal prompt, then re-run `pip install anthropic`. |\n",
    "| VS Code shows \"No kernel\" | Jupyter extension not installed | Install the Jupyter extension from the Extensions panel and reload VS Code. |\n",
    "\n",
    "The cell below runs a quick diagnostic if anything above fails:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "checks = []\n",
    "\n",
    "# Python version\n",
    "checks.append((\"Python >= 3.9\", sys.version_info >= (3, 9), sys.version.split()[0]))\n",
    "\n",
    "# Inside a virtual environment\n",
    "in_venv = sys.prefix != getattr(sys, \"base_prefix\", sys.prefix)\n",
    "checks.append((\"Virtual environment active\", in_venv, sys.prefix))\n",
    "\n",
    "# .env file present in CWD\n",
    "env_path = Path.cwd() / \".env\"\n",
    "checks.append((\".env file found\", env_path.exists(), str(env_path)))\n",
    "\n",
    "# API key loaded and well-formed\n",
    "key = os.getenv(\"ANTHROPIC_API_KEY\", \"\")\n",
    "key_ok = key.startswith(\"sk-ant-\")\n",
    "checks.append((\"ANTHROPIC_API_KEY loaded\", key_ok, f\"{key[:10]}...\" if key else \"(missing)\"))\n",
    "\n",
    "# anthropic SDK importable\n",
    "try:\n",
    "    import anthropic\n",
    "    checks.append((\"anthropic SDK importable\", True, anthropic.__version__))\n",
    "except ImportError as e:\n",
    "    checks.append((\"anthropic SDK importable\", False, str(e)))\n",
    "\n",
    "for label, passed, detail in checks:\n",
    "    mark = \"PASS\" if passed else \"FAIL\"\n",
    "    print(f\"[{mark}] {label:<30} {detail}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}