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

+ +
+ +
+ +
+ + {categories.map(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

+ + + + + + + +
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" +}