Cheat SheetsPython A–ZImportant Libraries

Important Libraries — Cheat Sheet

Python A–Z · 6 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
Important Libraries
Python A–Z6 topicsQuick revision reference
1

requests & httpx — Calling APIs

requests is the de-facto HTTP client: get/post with params and JSON, status checks with raise_for_status, timeouts ALWAYS, and Sessions for connection reuse.

  • ALWAYS pass timeout= — the default waits forever and hangs services
  • raise_for_status() converts 4xx/5xx into catchable HTTPError
  • json= to send, .json() to receive; params= builds query strings safely
  • Session = pooling + shared headers + retry mounting; httpx = same API + async
The production checklist: timeout, raise_for_status, json=
import requests

# GET with query parameters
r = requests.get(
    "https://api.github.com/search/repositories",
    params={"q": "fastapi", "per_page": 3},   # ?q=fastapi&per_page=3
    timeout=10,                                # ALWAYS set a timeout
)
r.raise_for_status()                           # raises on 4xx/5xx
data = r.json()                                # parsed JSON body
print(r.status_code, data["total_count"])

# POST JSON
payload = {"name": "Asha", "plan": "pro"}
r = requests.post(
    "https://httpbin.org/post",
    json=payload,                              # serializes + sets header
    headers={"Authorization": "Bearer TOKEN"},
    timeout=10,
)
print(r.json()["json"])                        # {'name': 'Asha', 'plan': 'pro'}

# Error handling that distinguishes failure modes
try:
    r = requests.get("https://api.example.com/health", timeout=5)
    r.raise_for_status()
except requests.Timeout:
    print("service too slow")
except requests.HTTPError as e:
    print("bad status:", e.response.status_code)
except requests.ConnectionError:
    print("network/DNS problem")
2

Pydantic — Data Validation from Type Hints

Pydantic models validate and convert external data using type annotations — the engine behind FastAPI request validation, with field constraints, custom validators, and clean JSON round-trips.

  • Type hints become runtime validation; sensible coercion ("42" → 42), precise errors
  • Field(ge=, le=, min_length=...) for constraints; EmailStr and friends for formats
  • field_validator for one field, model_validator for cross-field rules
  • model_dump()/model_dump_json() serialize; nested models validate whole JSON trees
Validate + convert + report all errors at once
from pydantic import BaseModel, EmailStr, Field, ValidationError

class SignupRequest(BaseModel):
    name: str = Field(min_length=2, max_length=50)
    email: EmailStr
    age: int = Field(ge=16, le=100)
    skills: list[str] = []
    referral: str | None = None            # optional

ok = SignupRequest(
    name="Asha", email="asha@x.com",
    age="21",                              # str -> int, coerced!
    skills=["python"],
)
print(ok.age, type(ok.age))                # 21 <class 'int'>
print(ok.model_dump())                     # dict
print(ok.model_dump_json())                # JSON string

try:
    SignupRequest(name="A", email="not-an-email", age=12)
except ValidationError as e:
    for err in e.errors():
        print(err["loc"], err["msg"])
# ('name',)  String should have at least 2 characters
# ('email',) value is not a valid email address
# ('age',)   Input should be greater than or equal to 16
3

SQLAlchemy — Python's Database Toolkit

SQLAlchemy maps classes to tables (ORM), builds queries in Python (select/where/join), and manages transactions with Sessions — the standard DB layer under FastAPI apps.

  • Session = unit of work: add/modify objects, commit() writes one transaction
  • 2.0 style: select(Model).where(...) with session.scalars() — parameterized, injection-safe
  • relationship() navigates foreign keys as attributes; back_populates links both sides
  • Know the N+1 problem and its fix (selectinload/joinedload) — a favourite interview probe
Define → add → commit → select: the core loop
from sqlalchemy import create_engine, String, select
from sqlalchemy.orm import (DeclarativeBase, Mapped, mapped_column,
                            Session)

class Base(DeclarativeBase): ...

class Student(Base):
    __tablename__ = "students"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(50))
    branch: Mapped[str] = mapped_column(String(10))
    cgpa: Mapped[float]

engine = create_engine("sqlite:///college.db", echo=False)
Base.metadata.create_all(engine)          # CREATE TABLE

with Session(engine) as session:
    session.add_all([
        Student(name="Asha", branch="CS", cgpa=8.7),
        Student(name="Ravi", branch="IT", cgpa=7.9),
    ])
    session.commit()                       # one transaction

    # Query — 2.0 style
    stmt = (select(Student)
            .where(Student.cgpa >= 8.0)    # parameterized — no injection
            .order_by(Student.cgpa.desc()))
    for s in session.scalars(stmt):
        print(s.name, s.cgpa)              # Asha 8.7

    # Update & delete are just object operations
    asha = session.scalar(select(Student).where(Student.name == "Asha"))
    asha.cgpa = 9.0
    session.commit()
4

pytest — Testing Like a Professional

pytest turns plain assert into a test framework: test_ functions, parametrize for tables of cases, fixtures for setup/teardown, and raises for exception paths.

  • Discovery by convention: test_*.py files, test_* functions, plain assert
  • pytest.raises(Error, match=...) tests failure paths explicitly
  • parametrize = table-driven tests; each row reports separately
  • Fixtures inject setup by parameter name; yield fixtures guarantee teardown; conftest.py shares them
Plain assert + raises — that's the whole API
# calculator.py
def apply_discount(price, percent):
    if not 0 <= percent <= 100:
        raise ValueError("percent must be 0-100")
    return round(price * (1 - percent / 100), 2)

# test_calculator.py
import pytest
from calculator import apply_discount

def test_basic_discount():
    assert apply_discount(1000, 10) == 900.0

def test_zero_percent_returns_price():
    assert apply_discount(500, 0) == 500.0

def test_invalid_percent_raises():
    with pytest.raises(ValueError, match="0-100"):
        apply_discount(1000, 150)

# $ pytest -v
# test_calculator.py::test_basic_discount PASSED
# ...
# On failure, pytest shows values:
#   assert apply_discount(1000, 10) == 901
#   AssertionError: assert 900.0 == 901
5

NumPy Essentials — Arrays & Vectorization

NumPy arrays store homogeneous data in contiguous memory and operate on whole arrays at C speed — vectorization, broadcasting and boolean masks replace Python loops.

  • ndarray = one dtype, contiguous memory — 10-100x faster than list loops
  • Vectorize: arr * 2, arr >= 40, arr.mean(axis=...) — loops are a smell in NumPy
  • Boolean masks filter and assign: arr[arr < 40] = 40
  • Slices are views (share memory); .copy() when you need independence
No loops: vectorize, mask, aggregate by axis
import numpy as np

marks = np.array([67, 82, 45, 91, 38, 74])   # dtype=int64

# Vectorized ops — whole array at once, C speed
curved = marks + 5                    # add to every element
print(curved.mean(), curved.max())    # 71.16... 96

# Boolean masking — filter in one expression
passed = marks[marks >= 40]           # array([67, 82, 45, 91, 74])
print((marks >= 40).sum())            # 5 — True counts as 1
marks[marks < 40] = 40                # grace marks, in place!

# 2D — rows = students, cols = subjects
scores = np.array([[80, 90, 70],
                   [60, 85, 95]])
print(scores.shape)                   # (2, 3)
print(scores.mean(axis=0))            # per-subject: [70. 87.5 82.5]
print(scores.mean(axis=1))            # per-student: [80. 80.]

# Speed: sum of 10 million squares
big = np.arange(10_000_000)
total = (big ** 2).sum()              # ~30x faster than a Python loop
6

pandas Essentials — DataFrames for Real Data

pandas DataFrames load, filter, transform and aggregate tabular data — read_csv, boolean filters, groupby/agg, and merge cover the analytics loop every engineer eventually needs.

  • DataFrame = table; Series = column; read_csv/to_csv for I/O
  • Filter with boolean expressions — & and | with parentheses, never and/or
  • groupby().agg() ≈ GROUP BY; merge(on=, how=) ≈ JOIN
  • Check df.info() and isna() first — real data always has holes
The everyday loop: read, inspect, filter, derive
import pandas as pd

df = pd.DataFrame({
    "name":   ["Asha", "Ravi", "Neha", "Kiran"],
    "branch": ["CS", "IT", "CS", "ME"],
    "cgpa":   [8.7, 7.2, 9.4, 6.8],
    "backlogs": [0, 1, 0, 3],
})
# In real life: df = pd.read_csv("students.csv")

print(df.head())            # first rows
print(df.shape)             # (4, 4)
df.info()                   # dtypes + nulls — ALWAYS check first

# Filtering — & | with parentheses (not and/or!)
eligible = df[(df.cgpa >= 7.0) & (df.backlogs == 0)]
print(eligible.name.tolist())        # ['Asha', 'Neha']

# Derived column
df["grade"] = df.cgpa.apply(lambda c: "A" if c >= 8.5 else "B")

# loc: rows by condition, specific columns
print(df.loc[df.branch == "CS", ["name", "cgpa"]])

# Sort + top-k
print(df.sort_values("cgpa", ascending=False).head(2))
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/python