Created
December 10, 2025 13:55
-
-
Save WxBDM/2ad9c681c1c0deea65f724d0f9383876 to your computer and use it in GitHub Desktop.
A very basic REST API - Python Snacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # To run this application, you'll need to install 3 packages: | |
| # pip install pandas | |
| # pip install fastapi | |
| # pip install uvicorn | |
| # In the command line to run the application, type `uvicorn app:app --reload` | |
| # Note: if using uv: | |
| # uv bare --init | |
| # uv add pandas fastapi uvicorn | |
| # uv run uvicorn app:app --reload | |
| from fastapi import FastAPI, HTTPException | |
| import pandas as pd | |
| from pathlib import Path | |
| import uvicorn | |
| CSV_FILE = Path("items.csv") | |
| app = FastAPI() | |
| def load_df(): | |
| return pd.read_csv(CSV_FILE) | |
| def save_df(df): | |
| df.to_csv(CSV_FILE, index=False) | |
| @app.get("/items") | |
| def get_items(): | |
| df = load_df() | |
| return df.to_dict(orient="records") | |
| @app.get("/items/{item_id}") | |
| def get_item(item_id: int): | |
| df = load_df() | |
| match = df[df["id"] == item_id] | |
| if match.empty: | |
| raise HTTPException(404, "Item not found") | |
| return match.iloc[0].to_dict() | |
| @app.post("/items") | |
| def create_item(item: dict): | |
| df = load_df() | |
| if df[df["id"] == item.get("id")].shape[0] > 0: | |
| raise HTTPException(400, "ID already exists") | |
| df = pd.concat([df, pd.DataFrame([item])], ignore_index=True) | |
| save_df(df) | |
| return item | |
| @app.put("/items/{item_id}") | |
| def replace_item(item_id: int, item: dict): | |
| df = load_df() | |
| if item_id not in df["id"].values: | |
| raise HTTPException(404, "Item not found") | |
| # Get row index to update | |
| row_index = df.index[df["id"] == item_id][0] | |
| # Replace the entire row explicitly | |
| df.loc[row_index, "id"] = item["id"] | |
| df.loc[row_index, "name"] = item["name"] | |
| df.loc[row_index, "description"] = item["description"] | |
| save_df(df) | |
| return item | |
| @app.patch("/items/{item_id}") | |
| def update_item(item_id: int, updates: dict): | |
| df = load_df() | |
| if item_id not in df["id"].values: | |
| raise HTTPException(404, "Item not found") | |
| row_index = df.index[df["id"] == item_id][0] | |
| for key, value in updates.items(): | |
| df.at[row_index, key] = value | |
| save_df(df) | |
| return df.iloc[row_index].to_dict() | |
| @app.delete("/items/{item_id}") | |
| def delete_item(item_id: int): | |
| df = load_df() | |
| if item_id not in df["id"].values: | |
| raise HTTPException(404, "Item not found") | |
| df = df[df["id"] != item_id] | |
| save_df(df) | |
| return {"status": "deleted"} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| id | name | description | |
|---|---|---|---|
| 1 | Apple | A tasty red fruit | |
| 2 | Banana | A long yellow fruit |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This code is the driver code to get data from your server without | |
| # ever having to worry about HOW to access the database. | |
| # You'll need to install requests: | |
| # pip install requests | |
| # If using uv: | |
| # uv add requests | |
| import requests | |
| BASE_URL = "http://127.0.0.1:8000" | |
| # Fetch every item from the API | |
| def get_all_items(): | |
| resp = requests.get(f"{BASE_URL}/items") | |
| return resp.json() | |
| # Fetch a single item by its ID | |
| def get_item(item_id: int): | |
| resp = requests.get(f"{BASE_URL}/items/{item_id}") | |
| return resp.json() | |
| # Add a brand new item to the CSV via the API | |
| def create_item(item: dict): | |
| resp = requests.post(f"{BASE_URL}/items", json=item) | |
| return resp.json() | |
| # Replace an existing item completely (all fields) | |
| def replace_item(item_id: int, item: dict): | |
| resp = requests.put(f"{BASE_URL}/items/{item_id}", json=item) | |
| return resp.json() | |
| # Update only specific fields of an item | |
| def update_item(item_id: int, updates: dict): | |
| resp = requests.patch(f"{BASE_URL}/items/{item_id}", json=updates) | |
| return resp.json() | |
| # Delete an item from the CSV by ID | |
| def delete_item(item_id: int): | |
| resp = requests.delete(f"{BASE_URL}/items/{item_id}") | |
| return resp.json() | |
| if __name__ == "__main__": | |
| print("\n--- Initial GET (all items) ---") | |
| print(get_all_items()) | |
| print("\n--- POST: Create a new item ---") | |
| new_item = {"id": 10, "name": "Pear", "description": "Green fruit"} | |
| print(create_item(new_item)) | |
| print("\n--- GET: Fetch the new item ---") | |
| print(get_item(10)) | |
| print("\n--- PUT: Replace the item entirely ---") | |
| replaced_item = {"id": 10, "name": "Pear", "description": "Fully updated pear"} | |
| print(replace_item(10, replaced_item)) | |
| print("\n--- PATCH: Update only one field ---") | |
| print(update_item(10, {"description": "Pear with new description"})) | |
| print("\n--- DELETE: Remove the item ---") | |
| print(delete_item(10)) | |
| print("\n--- Final GET (all items) ---") | |
| print(get_all_items()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment