import textwrap import gradio as gr def md(text: str) -> str: """ Utility helper: - Lets us write long multi-line markdown strings with indentation in the code - Removes the extra left-side whitespace before Gradio renders it This makes the file much easier to read and maintain. """ return textwrap.dedent(text).strip() # ============================================================ # KNOWLEDGE BASE # ------------------------------------------------------------ # This dictionary is the heart of the teaching app. # The key is what appears in the dropdown. # The value is the markdown shown to the user. # # This pattern is important to understand: # - UI asks for a topic # - Python uses that topic as a dictionary key # - App returns the matching explanation # # That is a very common software pattern: # "user selection -> lookup -> render result" # ============================================================ TOPIC_DB = { "Git & GitHub": md(""" ## Git & GitHub **What this is:** Git is version control. GitHub is a remote home for your code, history, branches, pull requests, and automation. **Mental model:** - Your laptop is your working lab bench. - Git is the notebook that records exactly what changed and when. - GitHub is the shared lab vault where other people and automation can see the notebook. **Why it matters for AI builders:** - You cannot do CI/CD cleanly without a repository. - You cannot safely experiment without branches. - You cannot collaborate well without pull requests and commit history. **Core commands to understand:** ```bash git clone git status git add . git commit -m "Describe the change" git push origin main git checkout -b feature/my-new-idea ``` **What you should know cold:** 1. `clone` brings a remote repo to your machine. 2. `status` tells you what changed. 3. `add` stages changes. 4. `commit` saves a checkpoint in history. 5. `push` sends commits to GitHub. 6. Branches let you experiment without breaking main. **Common mistakes:** - Editing directly on `main` for risky changes. - Committing secrets like API keys. - Waiting too long between commits. **Mini-project:** Make a repo called `ml-platform-lab`, add one `README.md`, one `app.py`, and commit three times as you refine it. **Free references:** - Pro Git: https://git-scm.com/book/en/v2 - GitHub Actions docs: https://docs.github.com/actions """), "HTTP, APIs, and Requests": md(""" ## HTTP, APIs, and Requests **What this is:** An API is a contract for how software talks to software. Most modern app integrations happen over HTTP. **Mental model:** - A client sends a request. - A server receives it. - The server returns a response, often JSON. **The verbs that matter:** - `GET` = read data - `POST` = create or trigger something - `PUT` / `PATCH` = update - `DELETE` = remove **Python example:** ```python import requests response = requests.get("https://example.com/api/health", timeout=15) print(response.status_code) print(response.text) ``` **What good API thinking looks like:** - Clear inputs - Clear outputs - Explicit status codes - Validation before work happens - Logging when things fail **Why this matters for ML engineers:** Models are rarely used by calling Python functions directly in production. They are usually wrapped behind APIs. **Mini-project:** Call a public API, parse JSON, and render a simplified result in a Gradio textbox. **Free references:** - Requests docs: https://requests.readthedocs.io/ - FastAPI tutorial: https://fastapi.tiangolo.com/tutorial/ """), "FastAPI & Pydantic": md(""" ## FastAPI & Pydantic **What this is:** FastAPI is a Python web framework for building APIs quickly. Pydantic gives you structured, validated input and output models. **Mental model:** - FastAPI turns functions into web endpoints. - Pydantic defines what valid data looks like. **Very small example:** ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class PredictionRequest(BaseModel): age: int income: float @app.post("/predict") def predict(payload: PredictionRequest): score = 0.6 if payload.income > 50000 else 0.3 return {"score": score} ``` **Why it matters:** - You already know Python. - Type hints and schemas reduce ambiguity. - The framework auto-generates docs, which is great for learning and debugging. **What to understand deeply:** 1. Path operation decorators like `@app.get` and `@app.post` 2. Request body vs query parameters 3. Validation errors 4. JSON in, JSON out 5. Separation of app layer from model layer **Mini-project:** Put a toy model or even a rules engine behind `/predict`, then call it from a notebook or another Python script. **Free references:** - FastAPI main docs: https://fastapi.tiangolo.com/ - FastAPI tutorial: https://fastapi.tiangolo.com/tutorial/ """), "Docker": md(""" ## Docker **What this is:** Docker packages your app and its runtime into a container so it runs more consistently across machines. **Mental model:** - Your code alone is not enough. - You also need the right Python version, packages, and startup command. - A container bundles those together. **Useful distinction:** - **Image** = blueprint - **Container** = running instance from the blueprint **Tiny Dockerfile example:** ```dockerfile FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "app.py"] ``` **Why it matters for you:** Docker is the bridge between "it works on my laptop" and "it works in a deployment target." **Mini-project:** Containerize a FastAPI hello-world app and run it locally. **Free references:** - Docker overview: https://docs.docker.com/get-started/docker-overview/ - Docker getting started: https://docs.docker.com/get-started/ """), "CI/CD with GitHub Actions": md(""" ## CI/CD with GitHub Actions **What this is:** CI/CD automates build, test, and deployment workflows. GitHub Actions runs those workflows from your repository. **Mental model:** - A code change happens. - Automation wakes up. - Tests run. - Optional deployment happens only if checks pass. **Minimal workflow example:** ```yaml name: ci on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.10' - run: python -m pip install --upgrade pip - run: pip install -r requirements.txt - run: python -m py_compile app.py ``` **Why it matters:** - Catch issues before deployment. - Standardize checks. - Create trust in main branch. **Mini-project:** Add the above workflow to a repo and make sure every push at least syntax-checks your app. **Free references:** - GitHub Actions quickstart: https://docs.github.com/actions/quickstart - GitHub Actions docs: https://docs.github.com/actions """), "Kubernetes": md(""" ## Kubernetes **What this is:** Kubernetes orchestrates containers across machines. It helps with scaling, rolling updates, service discovery, health checks, and resilience. **Mental model:** Docker gives you one packaged app. Kubernetes manages many running containers in a controlled cluster environment. **What not to do:** Do not start here unless you already understand local Python apps, APIs, Git, containers, and one simple deployment target. **Terms you should recognize:** - Pod - Deployment - Service - Ingress - ConfigMap - Secret **Why it matters:** Even if you are not the platform engineer, you need to be able to read deployment conversations and debug the shape of a service. **Mini-project:** Read one minimal deployment YAML and explain it line by line. That is enough for a first pass. **Free references:** - Kubernetes docs: https://kubernetes.io/docs/home/ """), "MCP": md(""" ## MCP (Model Context Protocol) **What this is:** MCP is a standard for connecting AI applications to tools, resources, and prompts. **Mental model:** - A normal REST API exposes endpoints for software-to-software use. - An MCP server exposes capabilities that an AI client can discover and use more natively. **Three ideas to know:** - **Resources**: readable context, like files or database-derived information - **Tools**: callable actions - **Prompts**: pre-defined reusable instructions **Why it matters:** As AI products become more tool-using and context-rich, MCP gives a cleaner interoperability model than one-off custom glue code. **Mini-project:** Read the architecture overview and build one mental map showing client, server, tools, and resources. **Free references:** - MCP home: https://modelcontextprotocol.io/ - Architecture overview: https://modelcontextprotocol.io/docs/learn/architecture - Build a server: https://modelcontextprotocol.io/docs/develop/build-server """), "MLOps & Deployment Thinking": md(""" ## MLOps & Deployment Thinking **What this is:** MLOps is the set of practices for getting models and AI systems into reliable operation. **Mental model:** Training a model is only one stage. Real systems need: 1. data ingestion 2. feature logic 3. model or prompting layer 4. validation 5. serving 6. logging 7. monitoring 8. iteration **For your background:** You already have the quantitative side. The gap is usually on packaging, interfaces, environments, and lifecycle reliability. **Your shortest path to competence:** - build a toy rule-based service - convert it to a FastAPI endpoint - wrap it in Docker - add CI - deploy it - explain the architecture in plain English **Free references:** - Full Stack Deep Learning: https://fullstackdeeplearning.com/ - Hugging Face Learn: https://huggingface.co/learn """) } REFERENCE_LIBRARY = md(""" # Free references inside this app ## Official docs and free learning resources - Git / Pro Git: https://git-scm.com/book/en/v2 - Requests: https://requests.readthedocs.io/ - FastAPI: https://fastapi.tiangolo.com/ - Docker Get Started: https://docs.docker.com/get-started/ - GitHub Actions: https://docs.github.com/actions - Kubernetes docs: https://kubernetes.io/docs/home/ - Model Context Protocol: https://modelcontextprotocol.io/ - Hugging Face Learn: https://huggingface.co/learn - Full Stack Deep Learning: https://fullstackdeeplearning.com/ ## Suggested order for you 1. Git basics 2. HTTP + requests 3. FastAPI + Pydantic 4. Docker 5. GitHub Actions 6. Deploy a Space or small web service 7. Kubernetes fundamentals 8. MCP fundamentals """) DEPLOY_GUIDE = md(""" # How to deploy this app to a Gradio Space 1. Create a new Hugging Face Space. 2. Pick **Gradio** as the SDK. 3. Replace the repo's `README.md` with a metadata block that includes `sdk: gradio` and `app_file: app.py`. 4. Add this `app.py` file. 5. Add the `requirements.txt` file provided with this package. 6. Commit the files. 7. Open the Space once the build finishes. ## Why the files matter - `README.md` contains the Space metadata block. - `app.py` is the main application file. - `requirements.txt` lists the Python dependencies. ## Next level Once you understand this app, create a second repo where you replace the pure-Python recommendation functions with a real FastAPI backend or a model-serving layer. """) def render_topic(topic: str) -> str: return TOPIC_DB.get(topic, "Select a topic.") def recommend_stack(primary_goal, deployment_target, data_type, team_size, hours_per_week): if primary_goal == "Ship ML/AI demos reliably": order = [ "Gradio app -> Git -> GitHub -> Docker basics -> GitHub Actions -> hosted deployment", "Then repeat the same project as a FastAPI service.", "Only after that, learn Kubernetes vocabulary and deployment anatomy.", ] first_project = "Build one demo that takes input, returns a decision, and logs edge cases." elif primary_goal == "Build real APIs for models": order = [ "HTTP fundamentals -> requests -> FastAPI -> Pydantic -> local testing", "Then containerize with Docker and add CI.", "Deploy after the local and container versions both work cleanly.", ] first_project = "Create `/health` and `/predict` endpoints for a toy model or rules engine." elif primary_goal == "Understand platform / DevOps conversations": order = [ "Git and CI/CD language first.", "Docker concepts second.", "Kubernetes objects third: pod, deployment, service, ingress, secret.", "MCP after you already understand tools, services, and interfaces.", ] first_project = "Take one deployment diagram and explain every box, arrow, and environment variable." else: order = [ "Git -> APIs -> FastAPI -> Docker -> CI/CD -> deployment -> Kubernetes basics -> MCP", "Do not split attention across five stacks at once.", "Use one project as the backbone for every new concept.", ] first_project = "Build a single project repeatedly in deeper forms instead of many unrelated mini-projects." complexity = "solo-friendly" if team_size == "Solo / 1-2 people" else "team-process aware" time_note = ( "You have enough time each week to make real progress; prioritize shipping one working artifact weekly." if hours_per_week >= 8 else "Keep the scope tiny and focus on one working deliverable per week." ) if deployment_target == "Hugging Face Space": deploy_note = "Start with Gradio Spaces for speed and confidence, then graduate to Dockerized apps." elif deployment_target == "Cloud VM / simple host": deploy_note = "Bias toward FastAPI + Docker because that stack transfers better to generic hosting." else: deploy_note = "Learn Docker deeply before touching cluster-level concepts." data_note = { "Mostly tabular / structured": "Tabular data makes it easy to prototype small prediction or scoring services.", "Mostly text / documents": "Text workflows pair naturally with LLM-style apps, extraction, routing, and summarization.", "Mixed / multimodal": "Mixed inputs are powerful but easier to overcomplicate. Start with one narrow slice.", }[data_type] bullets = "\n".join([f"- {line}" for line in order]) return md(f""" ## Recommended pathway **Primary goal:** {primary_goal} **Recommended learning/build order:** {bullets} **First project:** {first_project} **Deployment note:** {deploy_note} **Data note:** {data_note} **Process note:** You are working in a **{complexity}** mode. **Time note:** {time_note} ## What success looks like after 30 days 1. You can explain the difference between a script, an API, a container, CI/CD, and orchestration. 2. You can deploy one Gradio app and one FastAPI-style service prototype. 3. You can read a Dockerfile and a GitHub Actions workflow without feeling lost. 4. You can follow an MCP tutorial without the terminology feeling alien. """) SCAFFOLDS = { "Gradio teaching app": md(""" ## Blueprint: Gradio teaching app ```text project/ ├── README.md ├── app.py └── assets/ # optional images or data files ``` **Purpose:** Best first deployment target when speed matters more than backend purity. **What to practice:** - UI layout - Python functions as app logic - deployment flow on Hugging Face Spaces - simple input/output design **Good first extension:** Add a logging area, examples, or a quiz tab. """), "FastAPI microservice": md(""" ## Blueprint: FastAPI microservice ```text project/ ├── README.md ├── requirements.txt ├── app/ │ ├── main.py │ ├── schemas.py │ ├── services.py │ └── utils.py └── tests/ └── test_smoke.py ``` **Purpose:** Best when you need explicit API endpoints and cleaner production migration. **What to practice:** - request/response models - validation - separation of business logic from web layer - testability **Good first extension:** Add `/health` and `/predict`, then call the service from a notebook or a Gradio front end. """), "Dockerized ML service": md(""" ## Blueprint: Dockerized ML service ```text project/ ├── README.md ├── requirements.txt ├── Dockerfile ├── .dockerignore ├── app/ │ ├── main.py │ ├── model_logic.py │ └── schemas.py └── tests/ └── test_api.py ``` **Purpose:** Best bridge from local development to reliable deployment. **What to practice:** - image creation - environment management - startup commands - reproducibility **Good first extension:** Add CI that syntax-checks and builds the container automatically. """), "CI/CD-ready repo": md(""" ## Blueprint: CI/CD-ready repo ```text project/ ├── README.md ├── requirements.txt ├── app.py └── .github/ └── workflows/ └── ci.yml ``` **Purpose:** Best for learning automated quality gates early. **What to practice:** - event triggers on push and pull request - deterministic install steps - automated syntax checks or tests **Good first extension:** Add Docker build or deployment steps after the basic checks pass. """) } def render_scaffold(name: str) -> str: return SCAFFOLDS.get(name, "Select a blueprint.") QUIZ_KEY = { "q1": "An app contract for software-to-software communication", "q2": "A package blueprint used to create running containers", "q3": "Automating build, test, and deployment workflows", "q4": "A Python framework for building APIs", "q5": "The main file path for the Space app", "q6": "A standard for exposing AI tools, resources, and prompts", } def grade_quiz(q1, q2, q3, q4, q5, q6): answers = {"q1": q1, "q2": q2, "q3": q3, "q4": q4, "q5": q5, "q6": q6} score = sum(1 for key, value in answers.items() if value == QUIZ_KEY[key]) feedback = [] for key, expected in QUIZ_KEY.items(): status = "✅" if answers[key] == expected else "❌" feedback.append(f"{status} {key.upper()}: {expected}") feedback_md = "\n".join([f"- {item}" for item in feedback]) if score == 6: verdict = "Excellent. You are reading the platform vocabulary correctly." elif score >= 4: verdict = "Good. You are close, but a few terms still need repetition." else: verdict = "This is normal early on. Revisit the Concept Explorer and do one small build step next." return md(f""" ## Score: {score}/6 **Verdict:** {verdict} **Answer key:** {feedback_md} """) INTRO = md(""" # AI Platform Engineering Accelerator This Space is built for a technically strong ML/physics person who wants to close the gap on software engineering, APIs, deployment, CI/CD, containers, Kubernetes, and MCP. ## How to use this app 1. Start in **Concept Explorer** and read one topic at a time. 2. Go to **Architecture Lab** and let the app recommend an order of operations. 3. Use **Repo Blueprint** to understand what a minimal project should look like. 4. Use **Self-Check** to make sure the vocabulary is sticking. 5. Read **Deploy This Space** so you understand how the app itself is hosted. ## Important learning philosophy Do not try to become a Kubernetes wizard first. Become the person who can reliably ship one small Python service end to end. """) with gr.Blocks(title="AI Platform Engineering Accelerator") as demo: gr.Markdown(INTRO) with gr.Tab("Concept Explorer"): topic = gr.Dropdown(list(TOPIC_DB.keys()), value="Git & GitHub", label="Pick a topic") topic_btn = gr.Button("Explain this topic") topic_out = gr.Markdown(value=render_topic("Git & GitHub")) topic_btn.click(render_topic, inputs=topic, outputs=topic_out) with gr.Tab("Architecture Lab"): primary_goal = gr.Radio( [ "Ship ML/AI demos reliably", "Build real APIs for models", "Understand platform / DevOps conversations", "Become end-to-end technical as fast as possible", ], value="Become end-to-end technical as fast as possible", label="What is your main goal right now?", ) deployment_target = gr.Radio( ["Hugging Face Space", "Cloud VM / simple host", "Kubernetes later"], value="Hugging Face Space", label="What deployment target feels most realistic first?", ) data_type = gr.Radio( ["Mostly tabular / structured", "Mostly text / documents", "Mixed / multimodal"], value="Mostly text / documents", label="What kind of AI work are you most likely to build first?", ) team_size = gr.Radio( ["Solo / 1-2 people", "Small team / cross-functional"], value="Solo / 1-2 people", label="What is your current working mode?", ) hours_per_week = gr.Slider(2, 20, value=8, step=1, label="Hours per week you can seriously invest") plan_btn = gr.Button("Generate my pathway") plan_out = gr.Markdown() plan_btn.click( recommend_stack, inputs=[primary_goal, deployment_target, data_type, team_size, hours_per_week], outputs=plan_out, ) with gr.Tab("Repo Blueprint"): scaffold = gr.Radio(list(SCAFFOLDS.keys()), value="Gradio teaching app", label="Choose a project blueprint") scaffold_btn = gr.Button("Show blueprint") scaffold_out = gr.Markdown(value=render_scaffold("Gradio teaching app")) scaffold_btn.click(render_scaffold, inputs=scaffold, outputs=scaffold_out) with gr.Tab("Self-Check"): q1 = gr.Radio( [ "A database schema", "An app contract for software-to-software communication", "A container orchestrator", ], label="1) What is an API?", ) q2 = gr.Radio( [ "A package blueprint used to create running containers", "A live cluster node", "A Git branch", ], label="2) What is a Docker image?", ) q3 = gr.Radio( [ "A way to label datasets", "Automating build, test, and deployment workflows", "A Python package manager", ], label="3) What is CI/CD?", ) q4 = gr.Radio( [ "A Python framework for building APIs", "A GPU runtime", "A GitHub feature for branches", ], label="4) What is FastAPI?", ) q5 = gr.Radio( [ "The name of the Space owner", "The main file path for the Space app", "A private token", ], label="5) In a Hugging Face Space README metadata block, what is `app_file` for?", ) q6 = gr.Radio( [ "A standard for exposing AI tools, resources, and prompts", "A Linux package manager", "A database migration strategy", ], label="6) What is MCP?", ) quiz_btn = gr.Button("Grade quiz") quiz_out = gr.Markdown() quiz_btn.click(grade_quiz, inputs=[q1, q2, q3, q4, q5, q6], outputs=quiz_out) with gr.Tab("Deploy This Space"): gr.Markdown(DEPLOY_GUIDE) with gr.Tab("References"): gr.Markdown(REFERENCE_LIBRARY) demo.launch()