Complete Setup Guide - From Opening VS Code to Running Your API
- Prerequisites
- Phase 1: Environment Setup
- Phase 2: Create Project Files
- Phase 3: Run Your API
- Phase 4: Test Everything
- Troubleshooting
Before starting:
- ✅ Python 3.8+ installed
- ✅ VS Code installed
- ✅ A folder on Desktop called
fastapi
- Click VS Code icon
- VS Code opens
✅ Expected: VS Code window is open
- File → Open Folder
- Navigate to Desktop
- Select folder:
fastapi - Click "Select Folder"
✅ Expected: Left sidebar shows "FASTAPI" folder (empty)
- Terminal menu → New Terminal
- Black/gray box appears at bottom
✅ Expected:
C:\Users\YourName\Desktop\fastapi>
PowerShell has issues. Use Command Prompt instead.
- Click dropdown arrow next to
+in terminal - Select "Command Prompt"
- Close PowerShell tab (X button)
✅ Expected:
C:\Users\...\fastapi>
Type:
python -m venv fastapiWait 30 seconds (nothing shows - normal!)
✅ Expected: Prompt returns
Type:
fastapi\Scripts\activate✅ Expected:
(fastapi) C:\Users\...\fastapi>
Notice (fastapi) at start = activated! ✨
Type:
pip install fastapi uvicornWait 1-2 minutes
✅ Expected:
Successfully installed fastapi-0.x.x uvicorn-0.x.x ...
What: Blueprint for Products
In Explorer:
- Right-click empty space
- New File
- Type:
models.py - Press Enter
Copy and Paste this code:
from pydantic import BaseModel
class Product(BaseModel):
id: int
name: str
desc: str
price: int
quantity: intExplanation:
id: int= Product ID (unique number)name: str= Product name (text)desc: str= Description (text)price: int= Price in rupees (number)quantity: int= Stock quantity (number)
Save: Ctrl + S
✅ Expected: No red errors
What: All your API endpoints (routes)
In Explorer:
- Right-click empty space
- New File
- Type:
main.py - Press Enter
Copy and Paste ENTIRE code below:
from fastapi import FastAPI
from models import Product
app = FastAPI()
# ========================================
# IN-MEMORY DATABASE (LIST)
# Data stored in RAM - resets when server stops
# ========================================
products_db = [
Product(id=1, name="Notebook A4", desc="100 pages ruled notebook", price=150, quantity=50),
Product(id=2, name="Pen Set", desc="Pack of 10 quality pens", price=300, quantity=30),
Product(id=3, name="Pencil Set", desc="12 HB pencils", price=120, quantity=40),
Product(id=4, name="Highlighters", desc="5 neon color highlighters", price=250, quantity=25),
Product(id=5, name="Eraser", desc="Rubber erasers (pack of 5)", price=80, quantity=100),
]
# ========================================
# ROOT ENDPOINT
# ========================================
@app.get("/")
def home():
"""
GET / endpoint
Returns welcome message
"""
return {
"message": "Welcome to Stationary Store API!",
"total_products": len(products_db)
}
# ========================================
# CREATE - Add new product
# ========================================
@app.post("/products/")
def create_product(product: Product):
"""
POST /products/ endpoint
Add new product to database
Input: Product object (id, name, desc, price, quantity)
Output: Confirmation message
"""
# Check if product with this ID already exists
for p in products_db:
if p.id == product.id:
return {"error": f"Product with id={product.id} already exists"}
# Add new product
products_db.append(product)
return {
"message": "Product created successfully",
"product": product,
"total_products": len(products_db)
}
# ========================================
# READ - Get all products
# ========================================
@app.get("/products/")
def get_all_products():
"""
GET /products/ endpoint
Returns all products from database
"""
return {
"total": len(products_db),
"products": products_db
}
# ========================================
# READ - Get one product by ID
# ========================================
@app.get("/products/{product_id}")
def get_product(product_id: int):
"""
GET /products/{product_id} endpoint
Returns single product by ID
Example: /products/1 → returns product with id=1
"""
for product in products_db:
if product.id == product_id:
return {
"found": True,
"product": product
}
return {
"found": False,
"error": f"Product with id={product_id} not found"
}
# ========================================
# UPDATE - Modify existing product
# ========================================
@app.put("/products/{product_id}")
def update_product(product_id: int, product: Product):
"""
PUT /products/{product_id} endpoint
Update existing product (replace all fields)
"""
for i in range(len(products_db)):
if products_db[i].id == product_id:
products_db[i] = product
return {
"message": "Product updated successfully",
"product": product
}
return {
"error": f"Product with id={product_id} not found"
}
# ========================================
# DELETE - Remove product
# ========================================
@app.delete("/products/{product_id}")
def delete_product(product_id: int):
"""
DELETE /products/{product_id} endpoint
Remove product from database
"""
global products_db
initial_count = len(products_db)
products_db = [p for p in products_db if p.id != product_id]
if len(products_db) < initial_count:
return {
"message": f"Product with id={product_id} deleted successfully",
"remaining_products": len(products_db)
}
else:
return {
"error": f"Product with id={product_id} not found"
}
# ========================================
# BONUS - Filter by price range
# ========================================
@app.get("/products/price-range/{min_price}/{max_price}")
def get_products_by_price(min_price: int, max_price: int):
"""
GET /products/price-range/{min_price}/{max_price} endpoint
Find products within price range
Example: /products/price-range/100/200 → products between 100-200 rupees
"""
filtered = [p for p in products_db if min_price <= p.price <= max_price]
return {
"price_range": f"{min_price}-{max_price}",
"count": len(filtered),
"products": filtered
}
# ========================================
# BONUS - Find low stock products
# ========================================
@app.get("/products/low-stock/{threshold}")
def get_low_stock(threshold: int):
"""
GET /products/low-stock/{threshold} endpoint
Find products with quantity below threshold
Example: /products/low-stock/30 → products with less than 30 in stock
"""
low_stock = [p for p in products_db if p.quantity < threshold]
return {
"threshold": threshold,
"count": len(low_stock),
"products": low_stock
}Key Points:
- In-memory database =
products_db = [...](list in RAM) - 5 Stationary Products pre-loaded:
- Notebook A4 - 150 rupees - 50 qty
- Pen Set - 300 rupees - 30 qty
- Pencil Set - 120 rupees - 40 qty
- Highlighters - 250 rupees - 25 qty
- Eraser - 80 rupees - 100 qty
- 8 Endpoints (routes): GET, POST, PUT, DELETE + 2 bonus filters
Save: Ctrl + S
✅ Expected: No red errors
In terminal (with (fastapi) showing)
Type:
uvicorn main:app --reloadWait 3-5 seconds
✅ Expected:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Application startup complete
Keep terminal open - server runs here!
Open your browser
Visit:
http://127.0.0.1:8000/docs
✅ Expected:
- Swagger UI page loads
- All 8 endpoints visible:
- GET /
- POST /products/
- GET /products/
- GET /products/{product_id}
- PUT /products/{product_id}
- DELETE /products/{product_id}
- GET /products/price-range/{min_price}/{max_price}
- GET /products/low-stock/{threshold}
- Click endpoint
GET / - Click "Try it out"
- Click "Execute"
✅ Response:
{
"message": "Welcome to Stationary Store API!",
"total_products": 5
}- Click
GET /products/ - Click "Try it out"
- Click "Execute"
✅ Response:
{
"total": 5,
"products": [
{
"id": 1,
"name": "Notebook A4",
"desc": "100 pages ruled notebook",
"price": 150,
"quantity": 50
},
{
"id": 2,
"name": "Pen Set",
"desc": "Pack of 10 quality pens",
"price": 300,
"quantity": 30
},
{
"id": 3,
"name": "Pencil Set",
"desc": "12 HB pencils",
"price": 120,
"quantity": 40
},
{
"id": 4,
"name": "Highlighters",
"desc": "5 neon color highlighters",
"price": 250,
"quantity": 25
},
{
"id": 5,
"name": "Eraser",
"desc": "Rubber erasers (pack of 5)",
"price": 80,
"quantity": 100
}
]
}✅ What this means: All 5 stationary products loaded!
- Click
GET /products/{product_id} - Click "Try it out"
- In field
product_id, type:2 - Click "Execute"
✅ Response:
{
"found": true,
"product": {
"id": 2,
"name": "Pen Set",
"desc": "Pack of 10 quality pens",
"price": 300,
"quantity": 30
}
}✅ What this means: Found Pen Set (id=2)!
- Click
POST /products/ - Click "Try it out"
- In Request body, paste:
{
"id": 6,
"name": "Calculator",
"desc": "Scientific calculator with 240 functions",
"price": 499,
"quantity": 15
}- Click "Execute"
✅ Response:
{
"message": "Product created successfully",
"product": {
"id": 6,
"name": "Calculator",
"desc": "Scientific calculator with 240 functions",
"price": 499,
"quantity": 15
},
"total_products": 6
}✅ What this means: New product added! Now 6 total.
- Click
GET /products/ - Click "Try it out"
- Click "Execute"
✅ Response includes all 6 products (original 5 + Calculator)
Let's update product #1 (Notebook A4)
- Click
PUT /products/{product_id} - Click "Try it out"
- In field
product_id, type:1 - In Request body, paste:
{
"id": 1,
"name": "Notebook A4 Premium",
"desc": "200 pages premium ruled notebook",
"price": 200,
"quantity": 45
}- Click "Execute"
✅ Response:
{
"message": "Product updated successfully",
"product": {
"id": 1,
"name": "Notebook A4 Premium",
"desc": "200 pages premium ruled notebook",
"price": 200,
"quantity": 45
}
}✅ What this means: Notebook updated with new name, price, and quantity!
Let's delete product #3 (Pencil Set)
- Click
DELETE /products/{product_id} - Click "Try it out"
- In field
product_id, type:3 - Click "Execute"
✅ Response:
{
"message": "Product with id=3 deleted successfully",
"remaining_products": 5
}✅ What this means: Pencil Set deleted! Only 5 products left.
- Click
GET /products/ - Click "Try it out"
- Click "Execute"
✅ Response: Only 5 products (Pencil Set is gone!)
- Click
GET /products/{product_id} - Click "Try it out"
- In field
product_id, type:3 - Click "Execute"
✅ Response:
{
"found": false,
"error": "Product with id=3 not found"
}✅ What this means: Confirms deletion worked!
Find products between 100-200 rupees
- Click
GET /products/price-range/{min_price}/{max_price} - Click "Try it out"
- In field
min_price, type:100 - In field
max_price, type:200 - Click "Execute"
✅ Response: Products in 100-200 range
{
"price_range": "100-200",
"count": 2,
"products": [
{
"id": 1,
"name": "Notebook A4 Premium",
"price": 200,
"quantity": 45
},
{
"id": 3,
"name": "Pencil Set",
"price": 120,
"quantity": 40
}
]
}Find products with less than 30 in stock
- Click
GET /products/low-stock/{threshold} - Click "Try it out"
- In field
threshold, type:30 - Click "Execute"
✅ Response: Products with quantity < 30
{
"threshold": 30,
"count": 2,
"products": [
{
"id": 4,
"name": "Highlighters",
"quantity": 25
},
{
"id": 5,
"name": "Eraser",
"quantity": 100
}
]
}In terminal with server running:
Press Ctrl + C
✅ Result: Server stops
Every time you work on project:
fastapi\Scripts\activateThen:
uvicorn main:app --reloadThen visit: http://127.0.0.1:8000/docs
After completing:
fastapi/
├── models.py ← Product blueprint
├── main.py ← API with 8 endpoints
├── fastapi/ ← Virtual environment
│ ├── Scripts/
│ ├── Lib/
│ └── ...
├── pyvenv.cfg
└── .gitignore
What you're using:
products_db = [
Product(id=1, name="Notebook A4", ...),
Product(id=2, name="Pen Set", ...),
# ... more products
]Advantages:
- ✅ Super fast (data in RAM)
- ✅ Simple to understand
- ✅ Perfect for learning
Disadvantages:
- ❌ Data lost when server stops
- ❌ Not for production
- ❌ Only works on one server
Future: Replace with SQLite or PostgreSQL for permanent storage
| Concept | What It Is |
|---|---|
| Virtual Environment | Isolated Python space |
| FastAPI | Web framework for APIs |
| Uvicorn | Server that runs your API |
| Pydantic Models | Data blueprints (Product class) |
| Routes/Endpoints | URLs that do different things |
| @app.get() | GET endpoint (retrieve data) |
| @app.post() | POST endpoint (add data) |
| @app.put() | PUT endpoint (update data) |
| @app.delete() | DELETE endpoint (remove data) |
| CRUD | Create, Read, Update, Delete |
| In-Memory DB | Data storage in RAM |
| Swagger UI | Interactive API documentation |
| Problem | Solution |
|---|---|
Scripts\activate not found |
Run python -m venv fastapi first |
ModuleNotFoundError: fastapi |
Make sure venv activated (shows (fastapi)), then pip install fastapi uvicorn |
The system cannot find the path |
Use Command Prompt, not PowerShell |
| Can't import models | Make sure models.py in same folder as main.py |
| Port 8000 already in use | Run: uvicorn main:app --port 8001 --reload |
| Swagger UI blank | Refresh browser (Ctrl+R). Check terminal for errors. |
| Changes not showing | Save Python file (Ctrl+S). Server auto-restarts with --reload. |
| Tried to create product with same ID | Error message appears: "Product with id=X already exists" |
- Python installed
- VS Code installed
-
fastapifolder on Desktop - Virtual environment created
- Virtual environment activated (shows
(fastapi)) - FastAPI + Uvicorn installed
-
models.pycreated (Product class) -
main.pycreated (all endpoints) - Both files saved
- Terminal shows
Uvicorn running on http://127.0.0.1:8000 - Browser shows Swagger UI at
http://127.0.0.1:8000/docs
- TEST 1: GET / works
- TEST 2: GET /products/ shows 5 products
- TEST 3: GET /products/2 returns Pen Set
- TEST 4: POST /products/ creates Calculator
- TEST 5: Verify new product in list (6 total)
- TEST 6: PUT /products/1 updates Notebook
- TEST 7: DELETE /products/3 deletes Pencil Set
- TEST 8: Verify product deleted
- TEST 9: GET deleted product returns error
- TEST 10: Price range filter works
- TEST 11: Low stock filter works
- All tests passing
- Server stops/starts correctly
- Understanding CRUD operations
- Code backup made
| ID | Product | Price | Stock |
|---|---|---|---|
| 1 | Notebook A4 | ₹150 | 50 |
| 2 | Pen Set | ₹300 | 30 |
| 3 | Pencil Set | ₹120 | 40 |
| 4 | Highlighters | ₹250 | 25 |
| 5 | Eraser | ₹80 | 100 |
- Add Real Database → SQLite, PostgreSQL, MongoDB
- Add Validation → Check prices, quantities
- Add Authentication → User login system
- Add Categories → Group products by type
- Deploy to Cloud → Make public (Heroku, Railway)