Running Python Code in UV Projects with AI
Why Environment Isolation Matters
Before you run any Python code in a UV project, you need to understand one critical concept: environment isolation.
Imagine you're working on two different projects:
- Project A: Needs
requestsversion 2.28 to work correctly - Project B: Needs
requestsversion 2.31 for some new features
If you installed packages globally (the old way), installing version 2.31 for Project B would break Project A. This is called the "dependency conflict" problem, and it's one of the main reasons virtual environments exist.
UV solves this with automatic environment isolation:
- Each UV project gets its own separate "toolbox" of packages
- Project A's packages don't affect Project B
- You can have different versions of the same library in different projects
- No conflicts, no "works on my machine but not on yours" problems
The command uv run is what activates this isolation automatically. When you type uv run python script.py, UV:
- Checks if the project has a virtual environment set up
- Activates that environment (without you typing activation commands)
- Runs your script in that isolated environment
- Everything just works
This is the core difference between uv run python and just typing python at your terminal.
The Difference: uv run vs. System Python
Let's see this in action.
Scenario: You have a project with the requests library installed via UV. Your system doesn't have requests installed globally.
Without uv run (fails):
python -c "import requests; print(requests.__version__)"
Result:
ModuleNotFoundError: No module named 'requests'
Why? You're using system Python, which doesn't have your project's packages.
With uv run (works):
# This uses UV's project environment instead of system Python
uv run python -c "import requests; print(requests.__version__)"
Output:
2.31.0
What happened:
uv runactivated your project's isolated environment- Python accessed the
requestslibrary from that environment - No manual activation needed—UV handles everything
Running Scripts in Your Project
Now let's run actual Python scripts stored in your project.
Scenario 1: Running a Simple Script
You have a file called main.py in your project that uses the requests library.
main.py:
import requests
# Fetch data from a public API
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
print(f"Status: {response.status_code}")
print(f"Title: {response.json()['title']}")
Run it:
uv run python main.py
Expected Output:
Status: 200
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
What happened:
uv runactivated your project environment- Python executed
main.py - The
requestslibrary was available (from your project, not system) - The API call succeeded and printed results
Running Tests with Pytest
First, ensure pytest is installed (from Lesson 4):
uv add --dev pytest
Create a test file test_math.py:
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
Run tests:
# Run all tests
uv run pytest
# Run specific test file
uv run pytest test_math.py
# Run with verbose output
uv run pytest -v
Expected Output:
test_math.py::test_add PASSED [100%]
1 passed in 0.03s
Environment Isolation in Action: Side-by-Side Comparison
Let's make the isolation concept crystal clear with a concrete example.
Project A (web-client/):
cd web-client
uv add requests==2.28.0
uv run python -c "import requests; print(requests.__version__)"
# Output: 2.28.0
Project B (data-processor/):
cd ../data-processor
uv add requests==2.31.0
uv run python -c "import requests; print(requests.__version__)"
# Output: 2.31.0
Back to Project A:
cd ../web-client
uv run python -c "import requests; print(requests.__version__)"
# Output: 2.28.0 (unchanged - Project A's version still safe)
Without UV (old approach):
pip install requests==2.28.0 # Install globally
pip install requests==2.31.0 # Overwrites global version!
python -c "import requests; print(requests.__version__)"
# Output: 2.31.0 (Project A breaks because global version changed)
This is why environment isolation is non-negotiable in professional development.
Common Execution Errors
Error 1: ModuleNotFoundError
ModuleNotFoundError: No module named 'requests'
Fix:
# Add the missing package
uv add requests
# Run your script again
uv run python your_script.py
Error 2: Permission Denied (Mac/Linux)
bash: ./my_script.py: Permission denied
Fix:
# Don't run scripts directly - use uv run
# ❌ This fails: ./my_script.py
# ✅ This works:
uv run python my_script.py
When to use AI: For complex errors or debugging test failures, ask your AI tool to analyze the error message and suggest solutions.
Running Web Servers (Optional)
You can use uv run to start web servers with hot reload:
# Add web framework
uv add fastapi uvicorn
# Start development server with auto-reload
uv run uvicorn main:app --reload
The --reload flag restarts the server automatically when you save code changes—useful for development, but don't use in production.
Key Takeaways (For Your Mental Model)
-
uv runis magic — It activates your project environment automatically. No manual activation commands needed. -
Isolation prevents conflicts — Each project has its own package versions. Changing one project doesn't break another.
-
AI is your execution partner — Tell your AI tool what you want to run; it provides the command. You focus on understanding, not syntax.
-
Scripts, tests, servers—same pattern — Whether running
main.py,pytest, oruvicorn, the pattern is the same:uv run <command> -
Errors are learning opportunities — ModuleNotFoundError, version mismatches, permission issues—all are solvable with AI guidance.
-
Environment isolation is non-negotiable — Professional Python development requires it. UV makes it invisible and automatic.
Try With AI
Use your AI companion (ChatGPT, Claude Code, Gemini CLI, etc.) for these exercises.
Prompt 1: Understanding Environment Isolation
Explain why `python main.py` fails but `uv run python main.py` works when my script imports requests. What is environment isolation and why does it matter?
Expected outcome: You'll understand how uv run activates your project environment and why bare python doesn't have access to project packages.
Prompt 2: Debugging a Failed Test
I have a test that's failing with this error:
test_math.py::test_divide FAILED
AssertionError: assert 4.0 == 4
What does this mean? How do I fix it? Explain the difference between float and integer comparison in Python tests.
Expected outcome: You'll learn how to read test output and work with AI to diagnose and fix test failures.
Prompt 3: Multi-Project Isolation
I have two UV projects on my computer:
- project-a needs requests==2.28.0
- project-b needs requests==2.31.0
Show me how UV keeps these isolated so they don't conflict. Create a demonstration showing both projects maintaining their own versions.
Expected outcome: You'll see concrete proof that environment isolation prevents version conflicts between projects.