<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[AI Notebook]]></title><description><![CDATA[AI Notebook]]></description><link>https://ai-notebook.uk</link><image><url>https://cdn.hashnode.com/uploads/logos/6a1ed89dc5484173f87dd5bd/2a4af79e-551d-4bb6-80c4-099961c21faf.png</url><title>AI Notebook</title><link>https://ai-notebook.uk</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 02 Jun 2026 17:32:22 GMT</lastBuildDate><atom:link href="https://ai-notebook.uk/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I set up a Python AI project]]></title><description><![CDATA[This is my opinionated guide to setting up a Python AI project from scratch. There are plenty of alternatives out there, but this is what's been working well for me.

The Tools
Two things to install b]]></description><link>https://ai-notebook.uk/how-i-set-up-a-python-ai-project</link><guid isPermaLink="true">https://ai-notebook.uk/how-i-set-up-a-python-ai-project</guid><category><![CDATA[Python]]></category><category><![CDATA[UV ]]></category><category><![CDATA[dotenv]]></category><category><![CDATA[VS Code]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Robert McBryde]]></dc:creator><pubDate>Tue, 02 Jun 2026 15:03:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a1ed89dc5484173f87dd5bd/9f6145c6-fcac-44d6-b395-de281e74420e.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is my opinionated guide to setting up a Python AI project from scratch. There are plenty of alternatives out there, but this is what's been working well for me.</p>
<hr />
<h2>The Tools</h2>
<p>Two things to install before anything else:</p>
<ul>
<li><p><a href="https://docs.astral.sh/uv/getting-started/installation/"><strong>uv</strong></a> — a blazing-fast Python package manager that replaces both <code>pip</code> and <code>venv</code>. It handles Python versions, dependencies, and virtual environments in one tool.</p>
</li>
<li><p><a href="https://code.visualstudio.com/"><strong>VSCode</strong></a> — my editor of choice. Free, extensible, and excellent Python support. Pycharm is also excellent but for most of my learnings VSCode has been sufficient.</p>
</li>
</ul>
<h3>Installing uv</h3>
<p>On macOS or Linux, one line in your terminal:</p>
<pre><code class="language-bash">curl -LsSf https://astral.sh/uv/install.sh | sh
</code></pre>
<p>On Windows (PowerShell):</p>
<pre><code class="language-powershell">powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
</code></pre>
<p>Check it's working:</p>
<pre><code class="language-bash">uv --version
</code></pre>
<hr />
<h2>Getting Python 3.12</h2>
<p>Here's something I love about <code>uv</code> — you don't need a separate Python installation. <code>uv</code> manages Python versions for you:</p>
<pre><code class="language-bash">uv python install 3.12
</code></pre>
<p>Verify it's there:</p>
<pre><code class="language-bash">uv python list
</code></pre>
<p>That's it. No fighting with system Python, no Homebrew conflicts, no PATH headaches. If you've heard of <strong>pyenv</strong> as an alternative, it's a solid tool, but for most beginners it's one extra thing to learn. <code>uv</code> does it all.</p>
<blockquote>
<p><strong>Why Python 3.12?</strong> It's stable, widely supported, and every major AI/ML library works with it. Safe choice.</p>
</blockquote>
<hr />
<h2>Creating a New Project</h2>
<p>Navigate to wherever you keep your code and run:</p>
<pre><code class="language-bash">uv init my-project
cd my-project
</code></pre>
<p><code>uv</code> scaffolds a clean project structure for you:</p>
<pre><code class="language-plaintext">my-project/
├── .python-version   # pins the Python version
├── pyproject.toml    # project config &amp; dependencies
├── README.md
└── main.py
</code></pre>
<p><a>pyproject.toml</a> is the modern Python standard for project configuration — think of it as the project's passport. It declares the project name, which Python version it needs, and all its dependencies.</p>
<hr />
<h2>Pinning the Python Version</h2>
<p>Inside the project folder, tell <code>uv</code> to use 3.12:</p>
<pre><code class="language-bash">uv python pin 3.12
</code></pre>
<p>This writes <code>3.12</code> into the <a>.python-version</a> file. Now anyone who clones the repo uses the exact same version. No more "it works on my machine" surprises.</p>
<hr />
<h2>Creating the Virtual Environment</h2>
<p>A virtual environment isolates your project's packages from everything else on your machine. Without one, installing packages globally causes version conflicts across projects — it gets messy fast.</p>
<p>With <code>uv</code>, setup is a single command:</p>
<pre><code class="language-bash">uv sync
</code></pre>
<p>This creates a <a>.venv/</a> folder inside your project and installs all declared dependencies. The key thing: <strong>you never need to activate it manually</strong>. Use <code>uv run</code> to execute scripts and it handles the virtual environment automatically.</p>
<hr />
<h2>Opening in VSCode</h2>
<pre><code class="language-bash">code .
</code></pre>
<p>When VSCode opens, it might prompt you to <strong>"Select a Python Interpreter"</strong>. Choose the one inside <a>.venv</a> — it'll show a path like <code>./venv/bin/python</code>. This connects VSCode to your project's isolated environment.</p>
<hr />
<h2>Two Extensions Worth Installing</h2>
<p>Open the Extensions panel (<code>Cmd+Shift+X</code> on Mac, <code>Ctrl+Shift+X</code> on Windows) and add these two:</p>
<p><strong>Python</strong> by Microsoft — syntax highlighting, IntelliSense, the ability to run and debug Python files. Essential.</p>
<p><strong>Ruff</strong> by Astral Software — a linter and formatter that keeps your code consistent. It catches errors before you run code and auto-formats on save. I use this on every project.</p>
<hr />
<h2>Adding Dependencies</h2>
<p>Now for the actual project dependencies. I add two to every AI project:</p>
<p><strong>Ruff</strong> for linting:</p>
<pre><code class="language-bash">uv add ruff
</code></pre>
<p><strong>python-dotenv</strong> for loading environment variables from a <code>.env</code> file:</p>
<pre><code class="language-bash">uv add python-dotenv
</code></pre>
<p>Both commands automatically update <a>pyproject.toml</a> and <a>uv.lock</a>. Your config will look something like this:</p>
<pre><code class="language-toml">[project]
name = "my-project"
version = "0.1.0"
requires-python = "&gt;=3.12"
dependencies = [
    "python-dotenv&gt;=1.0.0",
    "ruff&gt;=0.9.0",
]
</code></pre>
<p><a>uv.lock</a> records the exact versions of every installed package. <strong>Commit this file</strong> — it makes the project perfectly reproducible on any machine.</p>
<hr />
<h2>Handling API Keys Safely</h2>
<p>This one matters a lot. AI projects almost always need API keys — for OpenAI, Anthropic, LangSmith, etc. You must <strong>never</strong> commit these to git.</p>
<p>My approach uses two files:</p>
<ul>
<li><p><a><strong>.env.example</strong></a> — committed to the repo, contains placeholder values showing what keys are needed</p>
</li>
<li><p><code>.env</code> — your real local file with actual secrets, never committed</p>
</li>
</ul>
<p>Start by copying the example:</p>
<pre><code class="language-bash">cp .env.example .env
</code></pre>
<p>Then open <code>.env</code> and fill in your real keys:</p>
<pre><code class="language-bash">OPENAI_API_KEY="your-real-key-here"
ANTHROPIC_API_KEY="your-real-key-here"
</code></pre>
<h3>Why is this safe?</h3>
<p>The <a>.gitignore</a> file contains <code>.env</code>, which instructs git to completely ignore that file. It never gets staged, never gets committed, never ends up on GitHub. Your secrets stay local.</p>
<h3>Loading the keys in Python</h3>
<p>With <code>python-dotenv</code> installed, two lines at the top of any file is all you need:</p>
<pre><code class="language-python">from dotenv import load_dotenv
import os

load_dotenv()

api_key = os.getenv("OPENAI_API_KEY")
</code></pre>
<p><code>load_dotenv()</code> reads the <code>.env</code> file and makes those variables available via <code>os.getenv()</code>.</p>
<hr />
<h2>Running Your Code</h2>
<p>Use <code>uv run</code> instead of calling <code>python</code> directly:</p>
<pre><code class="language-bash">uv run main.py
</code></pre>
<p><code>uv run</code> automatically picks up the virtual environment — no activation step needed.</p>
<hr />
<h2>What You End Up With</h2>
<p>After following these steps, your project looks like this:</p>
<pre><code class="language-plaintext">my-project/
├── .env              # ← your secrets (git-ignored, never commit this)
├── .env.example      # ← template showing required variables (commit this)
├── .gitignore        # ← tells git what to ignore
├── .python-version   # ← pins Python 3.12
├── .venv/            # ← virtual environment (git-ignored)
├── main.py
├── pyproject.toml    # ← project config and dependencies
└── uv.lock           # ← exact dependency versions (commit this)
</code></pre>
<p>Clean, reproducible, and safe. Every example in my <a href="https://github.com/rob212/ai-notebook">AI Notebook repo</a> follows this exact structure.</p>
<hr />
<h2>Quick Reference</h2>
<table>
<thead>
<tr>
<th>Task</th>
<th>Command</th>
</tr>
</thead>
<tbody><tr>
<td>Create new project</td>
<td><code>uv init my-project</code></td>
</tr>
<tr>
<td>Pin Python version</td>
<td><code>uv python pin 3.12</code></td>
</tr>
<tr>
<td>Install / sync dependencies</td>
<td><code>uv sync</code></td>
</tr>
<tr>
<td>Add a dependency</td>
<td><code>uv add &lt;package&gt;</code></td>
</tr>
<tr>
<td>Run a script</td>
<td><code>uv run main.py</code></td>
</tr>
<tr>
<td>Copy env template</td>
<td><code>cp .env.example .env</code></td>
</tr>
</tbody></table>
<hr />
<p>This is my personal starting point for every AI learning experiment I run. It's opinionated, but it's fast to set up and gets out of the way so I can focus on what actually matters — the code.</p>
<p>Always open to feedback and suggestions for alternatives or improvements. But so far, this setup has been working well for me. 🚀</p>
<p><em>This post is part of my</em> <a href="https://robmcbryde.hashnode.dev"><em>AI Notebook series</em></a> <em>— documenting my journey learning AI and agentic systems, one step at a time.</em></p>
]]></content:encoded></item><item><title><![CDATA[Welcome to AI Notebook: Documenting my journey AI]]></title><description><![CDATA[I'm a developer learning to build AI-powered applications, and this blog is where I document that journey. Every post covers something I've built and experimented with for my learning - sharing my lea]]></description><link>https://ai-notebook.uk/welcome-to-ai-notebook-documenting-my-journey-ai</link><guid isPermaLink="true">https://ai-notebook.uk/welcome-to-ai-notebook-documenting-my-journey-ai</guid><category><![CDATA[Python]]></category><category><![CDATA[AI]]></category><category><![CDATA[langchain]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Robert McBryde]]></dc:creator><pubDate>Tue, 02 Jun 2026 14:00:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a1ed89dc5484173f87dd5bd/154cb062-9fbb-4239-8234-5c85e2fae9e6.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I'm a developer learning to build AI-powered applications, and this blog is where I document that journey. Every post covers something I've built and experimented with for my learning - sharing my learnings for my benefit, but if it helps anyone else, then all the better.</p>
<p>The initial focus will primarily be on <strong>LangChain</strong> and <strong>LangGraph</strong>, two of the most widely used frameworks for building LLM-powered applications in Python. If you're on a similar path, I hope this saves you some of the head-scratching I went through.</p>
<p>All code is available in my GitHub repo: <a href="https://github.com/rob212/ai-notebook"><strong>ai-notebook</strong></a></p>
<hr />
<h2>My Setup</h2>
<p>Before diving into posts, here's the environment I'm using so you can code along.</p>
<p><strong>Language:</strong> Python 3.12<br /><strong>Editor:</strong> VSCode (with the Python and Ruff extensions)<br /><strong>Package manager:</strong> <a href="https://docs.astral.sh/uv/">uv</a> — a fast, modern replacement for pip/venv</p>
<p>If you don't have <code>uv</code> installed:</p>
<pre><code class="language-bash">curl -LsSf https://astral.sh/uv/install.sh | sh
</code></pre>
<p>To run any example from the repo:</p>
<pre><code class="language-bash">git clone https://github.com/rob212/ai-notebook.git
cd ai-notebook
uv sync
</code></pre>
<hr />
<h2>You'll need LLM API account(s</h2>
<p>Most examples use a cloud LLM. You'll need at least one of:</p>
<ul>
<li><p><a href="https://platform.openai.com/"><strong>OpenAI</strong></a> — GPT-4o-mini is cheap and capable</p>
</li>
<li><p><a href="https://console.anthropic.com/"><strong>Anthropic</strong></a> — Claude models, excellent for reasoning tasks</p>
</li>
</ul>
<p>Some examples use <a href="https://ollama.com/"><strong>Ollama</strong></a> to run models locally for free — I'll flag when that's an option.</p>
<hr />
<h2>Handling API Keys Safely with dotenv</h2>
<p>Never hardcode API keys in your source code or commit them to GitHub. I use the <a href="https://pypi.org/project/python-dotenv/">python-dotenv</a> pattern instead.</p>
<p><strong>1. Create a</strong> <code>.env</code> <strong>file</strong> (this is gitignored — never committed):</p>
<pre><code class="language-bash">cp .env.example .env
</code></pre>
<p>Then open <code>.env</code> and fill in your real keys:</p>
<pre><code class="language-bash">OPENAI_API_KEY="sk-..."
ANTHROPIC_API_KEY="sk-ant-..."
</code></pre>
<p><strong>2. The</strong> <a><strong>.env.example</strong></a> <strong>file</strong> is committed to the repo. It shows which variables are needed without exposing real values:</p>
<pre><code class="language-bash">OPENAI_API_KEY="insert_API_Key_Here"
ANTHROPIC_API_KEY="insert_API_Key_Here"
</code></pre>
<p><strong>3. Load them in your code:</strong></p>
<pre><code class="language-python">import os
from dotenv import load_dotenv

load_dotenv()

openai_api_key = os.getenv("OPENAI_API_KEY")
</code></pre>
<p>This pattern means you can share your code publicly without ever accidentally leaking credentials.</p>
<hr />
<h2>What's Coming</h2>
<p>Posts will follow the structure of my <code>ai-notebook</code> repo, building from the basics up:</p>
<ul>
<li><p><strong>LangChain</strong> — prompts, models, chains, agents, memory</p>
</li>
<li><p><strong>LangGraph</strong> — stateful multi-step agents and workflows</p>
</li>
</ul>
<p>Each post will have a link to the full working code in the repo. See you in the next one.</p>
]]></content:encoded></item></channel></rss>