Environment & API Key Setup for AI Projects
Set up a Python or Node project safely for AI development, including virtual environments, .env files, and keeping API keys out of source control.
Introduction
Every lesson from here on assumes a working project with a valid API key. Getting this step wrong is the single most common reason a first AI project fails to run — either the key is missing, or it accidentally ends up committed to a public GitHub repository. This lesson covers doing it correctly, once, in a way that works for the rest of the course.
- Why an isolated environment matters even more for AI projects than typical ones.
- How to load an API key from a .env file with python-dotenv.
- The Node.js equivalent pattern for JavaScript/TypeScript projects.
- How to make sure a secret never gets committed to version control.
A Real-Life Analogy First
An API key behaves exactly like a house key. Whoever holds a copy of it can walk in and use whatever is inside — in this case, your account's ability to make paid calls to an AI provider. You would never tape your house key to your front door where anyone walking by could take it. Yet that is exactly what happens when a key gets typed directly into a script and pushed to a public GitHub repository: it is now taped to the front door of the entire internet.
A .env file is the locked drawer you keep your house key in, inside your own home, instead of leaving it in plain sight. Your code asks the drawer for the key at runtime (load_dotenv()) instead of having the key written directly on the door for anyone to read. .gitignore is the rule "never photograph the inside of this drawer and post it publicly" — covered later in this lesson.
Isolating Your Environment
Use case: a Python virtual environment (or a Node project's local node_modules) keeps one project's installed packages — and their exact versions — separate from every other project on your machine. Think of it as giving each project its own private toolbox instead of sharing one big communal toolbox where tools might go missing or get swapped for a different version. AI SDKs update frequently, so pinning versions per project avoids a working script suddenly breaking because a global package was upgraded for an unrelated project.
python -m venv .venvsource .venv/bin/activate # on Windows: .venv\Scripts\activatepip install openai python-dotenvClick Run to see what this code prints.
Loading API Keys with python-dotenv
Use case: python-dotenv reads key-value pairs from a local .env file and loads them into environment variables, so your code can read a secret via os.environ without ever hardcoding it as a string.
# .envOPENAI_API_KEY=sk-your-real-key-herefrom dotenv import load_dotenvimport osfrom openai import OpenAI
load_dotenv() # reads .env into the process environment
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "Say hello in one short sentence."}],)print(response.choices[0].message.content)Click Run to see what this code prints.
Most provider SDKs, including openai and anthropic, automatically look for their expected environment variable name (OPENAI_API_KEY, ANTHROPIC_API_KEY) if you just call load_dotenv() and construct the client with no arguments — the explicit os.environ[...] above is shown once to make the mechanism visible.
The Node.js Equivalent
Use case: modern Node.js (v20.6+) reads a .env file natively with the --env-file flag, or you can use the dotenv package for wider compatibility — the pattern is identical to Python: keep secrets in .env, load them into process.env, never hardcode them.
npm install openai dotenvimport 'dotenv/config';import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const response = await client.chat.completions.create({ model: 'gpt-4o-mini', messages: [{ role: 'user', content: 'Say hello in one short sentence.' }],});
console.log(response.choices[0].message.content);Click Run to see what this code prints.
Keeping Secrets Out of Git
A .env file must never be committed to version control — anyone with access to the repository (or its history, even after a later deletion) could read the key and rack up usage on your account. The fix is a single line added before your first commit.
# .gitignore.env.venv/node_modules/Day-to-Day Habits That Prevent Disasters
This is one of the very few lessons in this course where getting it wrong has a real financial consequence, not just a bug — so it is worth a few habits that cost almost nothing but prevent almost every incident beginners run into.
- Treat every new project the same way you'd treat a new bank account: set up the .gitignore before writing the first real line of code, not after.
- When copy-pasting a code example from a tutorial (including this course), double check it is reading from an environment variable and not a hardcoded placeholder you forgot to remove.
- Set a spending limit in your provider's billing dashboard the same day you get your very first API key — this one habit, done once, prevents the vast majority of "surprise bill" horror stories beginners run into.
- If you ever share your screen (for a tutorial, a stream, a demo) with your code editor open, close any file containing a real key first — this is a surprisingly common accidental leak.
Common Mistakes
- Committing a .env file before adding it to .gitignore — check git status before your very first commit on a new project.
- Pasting an API key directly into a script "just for testing" and forgetting to remove it before pushing.
- Reusing the same API key across a personal project and a production project — use separate keys so one can be revoked without affecting the other.
Best Practices
- Add .env to .gitignore before writing a single line of code that uses a real key.
- Commit a .env.example file with placeholder values so collaborators know which variables they need to set.
- Set spending limits or usage alerts in your provider's dashboard, especially while learning.
Frequently Asked Questions
Revoke and regenerate the key immediately in your provider dashboard — removing it from a later commit does not remove it from Git history, which may already be public.
No — any method that gets the key into os.environ (a shell export, a cloud provider's secret manager, a Docker environment variable) works the same way from the SDK's point of view.
It is optional for a single throwaway script, but strongly recommended the moment you have a requirements.txt or more than one dependency, to avoid version conflicts with other projects.
It varies, but there are well-documented cases of leaked keys running up hundreds or thousands of dollars in usage within hours, usually from automated scripts that scan GitHub specifically for exposed keys — this is not a hypothetical risk, which is why this lesson exists before any other tool in the course.
No, never. Any code that runs in a user's browser can be read by that user, which means your key would be visible to anyone who opens their browser's developer tools. Provider calls must always be made from a server you control — this comes up again explicitly in lesson 20.
Key Takeaways
- A virtual environment isolates a project's dependencies and their exact versions.
- python-dotenv (or Node's built-in --env-file) loads secrets from a local .env file into environment variables.
- Provider SDKs read their expected environment variable automatically once it is loaded.
- .env must always be listed in .gitignore before your first commit.
- A leaked key is a real financial risk, not just a style mistake — set a spending cap on day one.
Summary
A safe, isolated environment with correctly-loaded secrets is the foundation every later lesson in this course builds on. Getting it right once here means every following example just works.
- You can set up an isolated project environment.
- You can load an API key safely with python-dotenv or Node's env-file support.
- You know how to keep secrets out of version control, and why it genuinely matters.