diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml
new file mode 100644
index 0000000..5ff4ddc
--- /dev/null
+++ b/.github/workflows/deploy-pages.yml
@@ -0,0 +1,54 @@
+name: Deploy to GitHub Pages
+
+on:
+ push:
+ branches: [ master ]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+ cache-dependency-path: docs/package-lock.json
+
+ - name: Setup Pages
+ uses: actions/configure-pages@v4
+
+ - name: Install dependencies
+ run: cd docs && npm install
+
+ - name: Build site
+ run: cd docs && npm run build
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./dist
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/README.md b/README.md
index f8f9275..1a73868 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,8 @@ It is a way for me to remember and hopefully get others started.
Start your Python journey in Python 3. Onward and upward.
+**๐ [View the documentation site โ](https://james-see.github.io/python-examples/)**
+
## ๐ Quick Start
This project uses [uv](https://github.com/astral-sh/uv) for modern Python package management.
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..f5e2ae6
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,22 @@
+# Dependencies
+node_modules/
+
+# Build output
+dist/
+.astro/
+
+# Environment
+.env
+.env.local
+
+# IDE
+.vscode/
+.idea/
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Logs
+*.log
+npm-debug.log*
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..aeaf55d
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,79 @@
+# Python Examples Documentation Site
+
+This is the source for the GitHub Pages documentation site for python-examples.
+
+## ๐ Built With
+
+- **Astro** - Fast, content-focused static site generator
+- **Academic Paper Design** - Clean, professional typography inspired by research papers
+- **Interactive Filtering** - Search and filter examples by category
+- **Personality** - Easter eggs and touches that show character
+
+## ๐ ๏ธ Development
+
+```bash
+cd docs
+
+# Install dependencies
+npm install
+
+# Start dev server
+npm run dev
+
+# Build for production
+npm run build
+
+# Preview production build
+npm run preview
+```
+
+## ๐ Structure
+
+```
+docs/
+โโโ src/
+โ โโโ layouts/ # Page layouts
+โ โโโ pages/ # Astro pages
+โ โโโ styles/ # Global CSS
+โ โโโ components/ # Reusable components (future)
+โโโ public/ # Static assets
+โโโ astro.config.mjs # Astro configuration
+```
+
+## ๐จ Design Philosophy
+
+- **Academic aesthetic** - Serif fonts, paper-like background, numbered sections
+- **Monospace code** - JetBrains Mono for all code examples
+- **Accent color** - Burnt orange (#d35400) for personality
+- **Clean typography** - Crimson Pro for body, Inter for UI elements
+- **Interactive** - Search, filters, and easter eggs for engagement
+
+## ๐ Deployment
+
+The site automatically deploys to GitHub Pages when changes are pushed to master via GitHub Actions.
+
+## ๐ฏ Features
+
+- โ
Responsive design
+- โ
Search functionality
+- โ
Category filtering
+- โ
Print-friendly (for actual paper)
+- โ
Easter egg (Konami code)
+- โ
Fast static site generation
+- โ
Academic paper styling
+
+## ๐ Adding New Examples
+
+Edit `src/pages/index.astro` and add to the `examples` array:
+
+```javascript
+{
+ title: 'your-example.py',
+ description: 'What it does',
+ category: 'Category Name',
+ tags: ['tag1', 'tag2'],
+ difficulty: 'beginner' // or 'intermediate', 'advanced'
+}
+```
+
+The site will automatically update filters and search.
diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs
new file mode 100644
index 0000000..beb20b4
--- /dev/null
+++ b/docs/astro.config.mjs
@@ -0,0 +1,10 @@
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ site: 'https://james-see.github.io',
+ base: '/python-examples',
+ outDir: '../dist',
+ build: {
+ assets: '_assets'
+ }
+});
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 0000000..c847f9a
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "python-examples-docs",
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview"
+ },
+ "dependencies": {
+ "astro": "^4.16.18"
+ }
+}
diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg
new file mode 100644
index 0000000..1b22700
--- /dev/null
+++ b/docs/public/favicon.svg
@@ -0,0 +1,4 @@
+
+
+ $
+
diff --git a/docs/src/layouts/Layout.astro b/docs/src/layouts/Layout.astro
new file mode 100644
index 0000000..d6255ee
--- /dev/null
+++ b/docs/src/layouts/Layout.astro
@@ -0,0 +1,27 @@
+---
+interface Props {
+ title: string;
+}
+
+const { title } = Astro.props;
+---
+
+
+
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
diff --git a/docs/src/pages/index.astro b/docs/src/pages/index.astro
new file mode 100644
index 0000000..09abab6
--- /dev/null
+++ b/docs/src/pages/index.astro
@@ -0,0 +1,291 @@
+---
+import Layout from '../layouts/Layout.astro';
+
+const examples = [
+ // LLM & AI
+ {
+ title: 'openai_gpt-example.py',
+ description: 'Chat completions, streaming, function calling, JSON mode with GPT-4',
+ category: 'LLM & AI',
+ tags: ['openai', 'gpt', 'chat', 'streaming'],
+ difficulty: 'intermediate'
+ },
+ {
+ title: 'anthropic_claude-example.py',
+ description: 'Claude 3.5 integration with vision, streaming, and extended thinking',
+ category: 'LLM & AI',
+ tags: ['anthropic', 'claude', 'vision', 'ai'],
+ difficulty: 'intermediate'
+ },
+ {
+ title: 'langchain-example.py',
+ description: 'LangChain framework: chains, memory, RAG, and prompt templates',
+ category: 'LLM & AI',
+ tags: ['langchain', 'rag', 'agents', 'chains'],
+ difficulty: 'advanced'
+ },
+ {
+ title: 'instructor-example.py',
+ description: 'Type-safe structured outputs from LLMs using Pydantic',
+ category: 'LLM & AI',
+ tags: ['instructor', 'pydantic', 'structured', 'validation'],
+ difficulty: 'intermediate'
+ },
+ // Network & APIs
+ {
+ title: 'grpcio-example.py',
+ description: 'gRPC client-server implementation with protocol buffers',
+ category: 'Network & APIs',
+ tags: ['grpc', 'rpc', 'protobuf', 'api'],
+ difficulty: 'advanced'
+ },
+ {
+ title: 'requests-example.py',
+ description: 'HTTP requests library examples for API interactions',
+ category: 'Network & APIs',
+ tags: ['http', 'requests', 'api', 'rest'],
+ difficulty: 'beginner'
+ },
+ {
+ title: 'flask-example.py',
+ description: 'Flask web framework with file uploads and routing',
+ category: 'Network & APIs',
+ tags: ['flask', 'web', 'server', 'api'],
+ difficulty: 'intermediate'
+ },
+ // Web Scraping
+ {
+ title: 'scrapy-spider.py',
+ description: 'Scrapy spider for crawling and extracting web data',
+ category: 'Web Scraping',
+ tags: ['scrapy', 'crawling', 'spider', 'web'],
+ difficulty: 'intermediate'
+ },
+ {
+ title: 'bs4-example.py',
+ description: 'BeautifulSoup HTML parsing and DOM manipulation',
+ category: 'Web Scraping',
+ tags: ['beautifulsoup', 'html', 'parsing', 'dom'],
+ difficulty: 'beginner'
+ },
+ // Data & ML
+ {
+ title: 'sentiment_analysis_nltk-example.py',
+ description: 'NLTK sentiment analysis on text data',
+ category: 'Data & ML',
+ tags: ['nltk', 'nlp', 'sentiment', 'ml'],
+ difficulty: 'intermediate'
+ },
+ {
+ title: 'opencv_facial_recognition-example.py',
+ description: 'OpenCV face detection and recognition',
+ category: 'Data & ML',
+ tags: ['opencv', 'cv', 'face-detection', 'ml'],
+ difficulty: 'advanced'
+ },
+ // Security
+ {
+ title: 'tor-example.py',
+ description: 'Tor network integration for anonymous browsing',
+ category: 'Security',
+ tags: ['tor', 'privacy', 'anonymity', 'network'],
+ difficulty: 'advanced'
+ },
+ {
+ title: 'shodan-example.py',
+ description: 'Shodan API for internet-connected device search',
+ category: 'Security',
+ tags: ['shodan', 'osint', 'security', 'api'],
+ difficulty: 'intermediate'
+ },
+ {
+ title: 'hashing_example.py',
+ description: 'Cryptographic hashing with SHA-256 and other algorithms',
+ category: 'Security',
+ tags: ['crypto', 'hashing', 'sha', 'security'],
+ difficulty: 'beginner'
+ },
+ // File Processing
+ {
+ title: 'pdfquery-example.py',
+ description: 'PDF text extraction and querying',
+ category: 'File Processing',
+ tags: ['pdf', 'text', 'extraction', 'files'],
+ difficulty: 'beginner'
+ },
+ {
+ title: 'exif_reader-example.py',
+ description: 'EXIF metadata extraction from images',
+ category: 'File Processing',
+ tags: ['exif', 'images', 'metadata', 'photos'],
+ difficulty: 'beginner'
+ }
+];
+
+const categories = [...new Set(examples.map(e => e.category))];
+const totalExamples = examples.length;
+---
+
+
+
+
+
+
Abstract
+
+ This repository presents a comprehensive collection of Python examples demonstrating
+ modern development patterns, from cutting-edge LLM integrations to classic data processing.
+ Each example prioritizes security, type safety, and real-world applicability.
+ Built for developers who value clarity, efficiency, and getting things done.
+
+
+
+
+
+ {totalExamples}+
+ Examples
+
+
+ {categories.length}
+ Categories
+
+
+ 3.12+
+ Python
+
+
+
+ Examples
+
+
+
+
+
+
+ All
+ {categories.map(category => (
+ {category}
+ ))}
+
+
+
+ {examples.map(example => (
+
+
{example.title}
+
{example.description}
+
+ {example.tags.map(tag => (
+ {tag}
+ ))}
+
+
+ ))}
+
+
+ Quick Start
+ # Clone the repository
+git clone https://github.com/james-see/python-examples.git
+cd python-examples
+
+# Install dependencies (using uv)
+uv sync --dev
+
+# Run an example
+cd python-examples
+python openai_gpt-example.py
+
+ Features
+
+ Modern Python 3.12+ - Leveraging latest language features
+ Type Safety - Pydantic models and type hints throughout
+ Security First - Input validation, secure defaults, CodeQL verified
+ Production Ready - Error handling, logging, and best practices
+ Well Documented - Clear docstrings and usage examples
+
+
+
+
+
+
+
+
diff --git a/docs/src/styles/global.css b/docs/src/styles/global.css
new file mode 100644
index 0000000..dffe47a
--- /dev/null
+++ b/docs/src/styles/global.css
@@ -0,0 +1,396 @@
+/* Academic Paper-ish Design with Personality */
+
+:root {
+ --paper: #fffef9;
+ --ink: #1a1a1a;
+ --ink-light: #4a4a4a;
+ --accent: #d35400;
+ --accent-light: #e67e22;
+ --code-bg: #f5f5f0;
+ --border: #e0e0d8;
+ --shadow: rgba(0, 0, 0, 0.08);
+
+ /* Typography */
+ --font-serif: 'Crimson Pro', 'Georgia', serif;
+ --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+}
+
+@import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=JetBrains+Mono:wght@400;500;700&family=Inter:wght@400;500;600&display=swap');
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 16px;
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: var(--font-serif);
+ background: var(--paper);
+ color: var(--ink);
+ line-height: 1.7;
+ font-size: 1.125rem;
+}
+
+/* Academic Paper Container */
+.paper-container {
+ max-width: 850px;
+ margin: 0 auto;
+ padding: 4rem 2rem;
+ background: white;
+ box-shadow: 0 0 80px var(--shadow);
+ min-height: 100vh;
+}
+
+/* Header - Academic Title Style */
+.site-header {
+ text-align: center;
+ border-bottom: 2px solid var(--ink);
+ padding-bottom: 2rem;
+ margin-bottom: 3rem;
+}
+
+.site-title {
+ font-family: var(--font-mono);
+ font-size: 2.5rem;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ margin-bottom: 0.5rem;
+ color: var(--ink);
+}
+
+.site-title .accent {
+ color: var(--accent);
+}
+
+.site-subtitle {
+ font-family: var(--font-sans);
+ font-size: 1rem;
+ color: var(--ink-light);
+ font-weight: 400;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+}
+
+/* Meta info (author, date style) */
+.meta {
+ font-family: var(--font-sans);
+ font-size: 0.9rem;
+ color: var(--ink-light);
+ font-style: italic;
+ margin-top: 1rem;
+}
+
+.meta a {
+ color: var(--accent);
+ text-decoration: none;
+ border-bottom: 1px solid transparent;
+ transition: border-color 0.2s;
+}
+
+.meta a:hover {
+ border-bottom-color: var(--accent);
+}
+
+/* Abstract/Intro Section */
+.abstract {
+ background: var(--code-bg);
+ border-left: 4px solid var(--accent);
+ padding: 1.5rem;
+ margin: 2rem 0;
+ font-size: 1rem;
+ line-height: 1.6;
+}
+
+.abstract-title {
+ font-family: var(--font-sans);
+ font-size: 0.875rem;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ font-weight: 600;
+ margin-bottom: 0.75rem;
+ color: var(--ink);
+}
+
+/* Section Headings */
+h2 {
+ font-family: var(--font-sans);
+ font-size: 1.75rem;
+ font-weight: 600;
+ margin: 3rem 0 1.5rem;
+ counter-increment: section;
+ color: var(--ink);
+}
+
+h2::before {
+ content: counter(section) ". ";
+ color: var(--accent);
+ font-weight: 700;
+}
+
+h3 {
+ font-family: var(--font-sans);
+ font-size: 1.25rem;
+ font-weight: 600;
+ margin: 2rem 0 1rem;
+ color: var(--ink);
+}
+
+/* Reset counter for first h2 */
+.paper-container {
+ counter-reset: section;
+}
+
+/* Code blocks */
+code {
+ font-family: var(--font-mono);
+ font-size: 0.9rem;
+ background: var(--code-bg);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ color: var(--accent);
+}
+
+pre {
+ font-family: var(--font-mono);
+ font-size: 0.85rem;
+ background: var(--code-bg);
+ padding: 1.5rem;
+ border-radius: 4px;
+ overflow-x: auto;
+ margin: 1.5rem 0;
+ border-left: 3px solid var(--accent);
+ line-height: 1.5;
+}
+
+pre code {
+ background: none;
+ padding: 0;
+ color: var(--ink);
+}
+
+/* Links */
+a {
+ color: var(--accent);
+ text-decoration: none;
+ border-bottom: 1px solid var(--accent-light);
+ transition: all 0.2s;
+}
+
+a:hover {
+ color: var(--accent-light);
+ border-bottom-color: var(--accent);
+}
+
+/* Example Cards */
+.example-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 1.5rem;
+ margin: 2rem 0;
+}
+
+.example-card {
+ background: white;
+ border: 1px solid var(--border);
+ padding: 1.5rem;
+ border-radius: 4px;
+ transition: all 0.2s;
+ cursor: pointer;
+}
+
+.example-card:hover {
+ border-color: var(--accent);
+ box-shadow: 0 4px 12px var(--shadow);
+ transform: translateY(-2px);
+}
+
+.example-card h4 {
+ font-family: var(--font-mono);
+ font-size: 1rem;
+ margin-bottom: 0.75rem;
+ color: var(--ink);
+}
+
+.example-card p {
+ font-family: var(--font-sans);
+ font-size: 0.9rem;
+ color: var(--ink-light);
+ line-height: 1.5;
+}
+
+.example-card .tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin-top: 1rem;
+}
+
+.tag {
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ background: var(--code-bg);
+ color: var(--accent);
+ padding: 0.25rem 0.5rem;
+ border-radius: 3px;
+ border: 1px solid var(--border);
+}
+
+/* Search Bar */
+.search-container {
+ margin: 2rem 0;
+}
+
+.search-input {
+ width: 100%;
+ font-family: var(--font-mono);
+ font-size: 1rem;
+ padding: 1rem;
+ border: 2px solid var(--border);
+ border-radius: 4px;
+ background: white;
+ transition: border-color 0.2s;
+}
+
+.search-input:focus {
+ outline: none;
+ border-color: var(--accent);
+}
+
+.search-input::placeholder {
+ color: var(--ink-light);
+ opacity: 0.6;
+}
+
+/* Filter Pills */
+.filter-pills {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+ margin: 1.5rem 0;
+}
+
+.filter-pill {
+ font-family: var(--font-sans);
+ font-size: 0.875rem;
+ padding: 0.5rem 1rem;
+ border: 2px solid var(--border);
+ border-radius: 20px;
+ background: white;
+ cursor: pointer;
+ transition: all 0.2s;
+ color: var(--ink);
+}
+
+.filter-pill:hover,
+.filter-pill.active {
+ background: var(--accent);
+ color: white;
+ border-color: var(--accent);
+}
+
+/* Footer - Citation Style */
+.site-footer {
+ margin-top: 4rem;
+ padding-top: 2rem;
+ border-top: 1px solid var(--border);
+ font-family: var(--font-sans);
+ font-size: 0.875rem;
+ color: var(--ink-light);
+ text-align: center;
+}
+
+.site-footer .citation {
+ font-family: var(--font-mono);
+ font-size: 0.8rem;
+ color: var(--ink-light);
+ font-style: italic;
+ margin-top: 1rem;
+ padding: 1rem;
+ background: var(--code-bg);
+ border-radius: 4px;
+}
+
+/* Easter Egg - Konami Code Ready */
+.easter-egg {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ opacity: 0;
+ transition: opacity 0.3s;
+ pointer-events: none;
+}
+
+.easter-egg.active {
+ opacity: 1;
+ pointer-events: all;
+}
+
+/* Stats */
+.stats {
+ display: flex;
+ justify-content: space-around;
+ margin: 2rem 0;
+ padding: 1.5rem;
+ background: var(--code-bg);
+ border-radius: 4px;
+}
+
+.stat {
+ text-align: center;
+}
+
+.stat-number {
+ font-family: var(--font-mono);
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: var(--accent);
+ display: block;
+}
+
+.stat-label {
+ font-family: var(--font-sans);
+ font-size: 0.875rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--ink-light);
+}
+
+/* Responsive */
+@media (max-width: 768px) {
+ .paper-container {
+ padding: 2rem 1.5rem;
+ }
+
+ .site-title {
+ font-size: 2rem;
+ }
+
+ .example-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .stats {
+ flex-direction: column;
+ gap: 1.5rem;
+ }
+}
+
+/* Print styles - because academic papers should print well */
+@media print {
+ .paper-container {
+ box-shadow: none;
+ max-width: 100%;
+ }
+
+ .search-container,
+ .filter-pills,
+ .site-footer {
+ display: none;
+ }
+}
diff --git a/docs/tsconfig.json b/docs/tsconfig.json
new file mode 100644
index 0000000..d78f81e
--- /dev/null
+++ b/docs/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "astro/tsconfigs/base"
+}