Note: This is a quick-reference Python guide focused on AI/ML workflows. For a comprehensive Python course, see our Complete Python Crash Course.
Getting Started
1. Install Python
Download Python 3.11+ from python.org. Verify installation:2. Set Up Virtual Environment
Virtual environments are like separate toolboxes for each project. Without them, installing a package for Project A might break Project B because they need different versions of the same library. This is not a theoretical concern — it will happen to you within your first week of AI development, because LLM libraries update frequently and often have conflicting dependencies.3. Install AI Packages
4. Manage Dependencies
Python Core Syntax (AI Context)
These are the Python fundamentals you will use daily in AI engineering. We focus on what matters for working with LLM APIs, data processing, and async workflows — not the full breadth of Python.Variables & Types
Functions
Control Flow
Error Handling
Error handling is not optional in AI engineering — LLM APIs fail regularly due to rate limits, network issues, and content policy violations. Every API call should be wrapped in try/except. The pattern below catches errors from most specific to most general, which is important because Python matches the first except block that fits.Data Structures for AI
Working with JSON
JSON is the lingua franca of LLM APIs. Every request you send is JSON, every response you receive is JSON, and structured outputs are JSON. Masteringjson.loads() and json.dumps() is as fundamental to AI engineering as knowing how to read and write.
List Operations
Dictionary Operations
Object-Oriented Python for AI
Classes & Dataclasses
Type Hints (Modern Python)
Dependency Management: pip vs. Poetry vs. uv
Choosing the right tool for managing Python packages will save you hours of debugging dependency conflicts — a common occurrence in AI projects because libraries likelangchain, transformers, and torch have deep and sometimes conflicting dependency trees.
| Tool | Speed | Lock File | Best For | Watch Out For |
|---|---|---|---|---|
| pip + requirements.txt | Slow | Manual (pip freeze) | Simple projects, tutorials | No true dependency resolution; pip freeze captures everything including transitive deps |
| pip + pip-tools | Moderate | requirements.in -> requirements.txt | Production projects needing reproducibility | Extra step to compile lock file |
| Poetry | Moderate | poetry.lock (automatic) | Libraries, projects needing publishing | Slow resolver, can conflict with conda |
| uv | Very fast (10-100x pip) | uv.lock (automatic) | New projects in 2025+, fast iteration | Newer tool, some edge cases with exotic packages |
| conda | Slow | environment.yml | Data science, GPU/CUDA deps, cross-platform binaries | Heavy, dependency resolution can be painfully slow |
uv (fast, modern) and fall back to conda only if you need binary packages that pip cannot install (e.g., specific CUDA toolkit versions). For everything else, uv or pip-tools gives you speed and reproducibility.
Advanced Patterns for AI Engineering
Decorators (Reusable Logic)
Decorators are functions that wrap other functions to add behavior — think of them as “middleware for functions.” They are everywhere in AI engineering:@retry for handling flaky API calls, @timer for profiling, @cache for avoiding redundant LLM calls, and @observe for tracing. If you understand decorators, you can read (and write) production AI code. If you do not, they will look like magic.
@timer- Profile slow functions@retry- Handle flaky API calls@cache_result- Avoid redundant LLM calls
Context Managers (Resource Management)
Context managers ensure resources are properly managed—files closed, connections released, timers stopped.- File I/O
- Database connections
- Timing code blocks
- Temporary state changes
Async/Await (Concurrency)
Async is the single most important advanced Python pattern for AI engineering. Here is why: a typical LLM API call takes 1-5 seconds, and during that time your program is just waiting for a network response. Without async, processing 10 prompts takes 10-50 seconds. With async, all 10 run concurrently and you get results in 1-5 seconds total. That is a 10x speedup for free. The mental model:async def declares a function that can pause (at await points) and let other tasks run while it waits. asyncio.gather runs multiple async tasks concurrently.
File Operations
Environment Variables (.env)
API keys are the crown jewels of your AI application. A leaked OpenAI key can rack up thousands of dollars in charges before you notice. The.env pattern keeps secrets out of your code and out of git history. This is not a suggestion — it is a hard requirement for any project that will ever be shared, deployed, or committed to a repository.
.env files! Add .env to your .gitignore immediately when you create a new project — before you make your first commit. If you accidentally commit a key, rotate it immediately; removing it from git history is difficult and unreliable.
Essential Libraries for AI
HTTP Requests
Data Manipulation (Pandas)
Date & Time
Common AI Patterns
These patterns appear in virtually every AI application. They are worth memorizing because you will use them dozens of times.Loading Environment Variables
Building Prompts
Batching Requests
Batching is essential when you have hundreds or thousands of items to process. Sending them all at once will hit rate limits; sending them one at a time is painfully slow. Batching gives you the best of both worlds: controlled throughput that stays within API limits while processing efficiently. Theyield keyword makes this a generator, which means it processes one batch at a time and does not load all results into memory.
Rate Limiting
OpenAI, Anthropic, and other providers enforce rate limits (typically measured in requests per minute and tokens per minute). Exceeding them results in 429 errors and temporary bans. This simple rate limiter adds a fixed delay between calls to keep you under the limit. For production use, consider thetenacity library for more sophisticated retry-with-backoff patterns.
Sync vs. Async: When to Use What
| Scenario | Use Sync | Use Async | Why |
|---|---|---|---|
| Single LLM call | Yes | No | No concurrency benefit; simpler code |
| Batch of 10+ LLM calls | No | Yes | 10x speedup from concurrent I/O |
| FastAPI endpoint | Either | Preferred | FastAPI is async-native; mixing sync blocks the event loop |
| Jupyter notebook | Yes | Tricky | Notebooks already run an event loop; asyncio.run() will fail — use await directly or nest_asyncio |
| CLI script | Yes | Yes (for batch) | Sync is simpler; use async only if you have batch processing |
| Streaming response | Either | Preferred | Async generators (async for) integrate cleanly with streaming APIs |
requests.get()) from inside an async function, it blocks the entire event loop. Use httpx (async HTTP) instead of requests, or wrap sync calls in asyncio.to_thread() to run them in a thread pool without blocking.
Next Steps
Next Steps
- Complete Python Course - Deep dive into Python fundamentals, data structures, OOP, and more
- FastAPI Crash Course - Build production APIs for AI applications
- Async Patterns - Master concurrent programming for AI workloads
- LLM Fundamentals - Start building with language models
Quick Reference
Common Commands
Style Guidelines (PEP 8)
Type Hints Quick Reference
Common Python Gotchas in AI Work
These are the mistakes that burn hours of debugging time specifically in AI engineering contexts:| Gotcha | What Happens | Fix |
|---|---|---|
| Mutable default arguments | def f(items=[]) shares the same list across all calls — appended items persist | Use def f(items=None): items = items or [] |
| Shallow copy of dicts | config2 = config1 means both point to the same dict; changing one changes both | Use config2 = config1.copy() or copy.deepcopy() for nested dicts |
| f-string with dicts | f"value: {d['key']}" fails with single quotes inside f-string braces | Use double quotes: f"value: {d[\"key\"]}" or assign to variable first |
JSON dumps vs dump | json.dumps() returns a string; json.dump() writes to a file. Mixing them up produces cryptic errors | Remember: the s stands for “string” |
asyncio.run() in Jupyter | Raises RuntimeError: cannot run nested event loop | Use await directly in cells, or pip install nest_asyncio; nest_asyncio.apply() |
| Float precision in cost calculations | 0.1 + 0.2 == 0.30000000000000004 | Use round() or Decimal for financial calculations |
Forgetting await | result = async_func() returns a coroutine object, not the result | Always result = await async_func() — linters catch this if you use type hints |
Troubleshooting
”Module not found” error
”pip: command not found”
Import errors in VS Code
- Select correct Python interpreter:
Ctrl+Shift+P→ “Python: Select Interpreter” - Choose the one in your
venvfolder
Slow pip installs
Pro Tips:
- Use virtual environments for EVERY project
- Pin package versions in production (
package==1.2.3)- Use type hints—they catch bugs before runtime
- Learn list/dict comprehensions—they’re faster and more Pythonic
- Use
python-dotenvfor API keys and secrets