> ## Documentation Index
> Fetch the complete documentation index at: https://fastapi2day.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Modules, Packages & the Standard Library Guide

> Create modules and packages, use essential Standard Library tools like pathlib and json, and install third-party packages with pip.

As your Python programs grow, keeping everything in a single file becomes unmanageable. **Modules** let you split code across multiple files, and **packages** let you organise related modules into directories. Python's "batteries included" philosophy means the Standard Library ships with powerful modules for file paths, dates, UUIDs, JSON, and more — all ready to use without installing anything extra. This page shows you how to organise your code effectively and leverage the tools Python provides out of the box.

## What is a Module?

A **module** is simply a Python file (`.py`) containing variables, functions, or classes that you want to reuse across your project.

Create a file named `calculator.py`:

```python theme={null}
# calculator.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

PI = 3.14159
```

Import and use it from another file in the same directory:

```python theme={null}
# main.py
import calculator

result = calculator.add(5, 3)
print(result)           # 8
print(calculator.PI)    # 3.14159
```

## What is a Package?

A **package** is a directory containing multiple modules. To turn a folder into a Python package, add an `__init__.py` file inside it.

### The Role of `__init__.py`

`__init__.py` serves four purposes:

1. **Marks the directory** as an importable package.

2. **Runs initialisation code** when the package is first imported.

3. **Creates a public API** by re-exporting sub-modules:

   ```python theme={null}
   # mypackage/__init__.py
   from .utils import format_text
   ```

   Consumers can now write `from mypackage import format_text` instead of the full path.

4. **Controls wildcard imports** using `__all__`:

   ```python theme={null}
   __all__ = ["utils"]
   ```

## Python's Standard Library Essentials

### `pathlib` — Modern File Paths

Use `pathlib` for object-oriented, cross-platform path handling:

```python theme={null}
from pathlib import Path

current_dir = Path.cwd()
file_path = current_dir / "data" / "users.json"

print(file_path.exists())   # True or False

if file_path.exists():
    content = file_path.read_text()
```

### `os` — Operating System Interface

```python theme={null}
import os

print(os.getcwd())   # Current working directory

# Safely read an environment variable with a fallback
database_url = os.environ.get("DATABASE_URL", "sqlite:///local.db")
```

### `datetime` — Dates and Times

```python theme={null}
import datetime

now = datetime.datetime.now()
print(now)

# Format to string
formatted = now.strftime("%Y-%m-%d %H:%M:%S")

# Parse from string
parsed = datetime.datetime.strptime("2026-07-20", "%Y-%m-%d")
```

### `uuid` — Unique Identifiers

```python theme={null}
import uuid

unique_id = uuid.uuid4()
print(unique_id)   # e.g. d3b07384-d113-4956-a5cc-484d2d476100
```

### `json` — JSON Serialisation

```python theme={null}
import json

data = {"name": "Alice", "role": "admin"}

# Dict → JSON string
json_str = json.dumps(data)
print(json_str)   # {"name": "Alice", "role": "admin"}

# JSON string → Dict
parsed_data = json.loads(json_str)
print(parsed_data["name"])   # Alice
```

### `string` — String Constants

The `string` module provides useful predefined character sets:

| Constant                 | Contents |
| ------------------------ | -------- |
| `string.ascii_lowercase` | `a-z`    |
| `string.ascii_uppercase` | `A-Z`    |
| `string.ascii_letters`   | `a-zA-Z` |
| `string.digits`          | `0-9`    |
| `string.punctuation`     | `!@#$…`  |

```python theme={null}
import string

print(string.ascii_letters)   # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.digits)          # 0123456789
print(string.punctuation)     # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
```

**Generate a random password:**

```python theme={null}
import random
import string

characters = string.ascii_letters + string.digits + string.punctuation
password = "".join(random.choice(characters) for _ in range(12))
print(password)
```

## Third-Party Packages — `requests`

While Python's `urllib` handles HTTP, the community standard is the `requests` library for its clean, human-friendly API.

Install it inside your virtual environment first:

```bash theme={null}
pip install requests
```

### Making HTTP Requests

```python theme={null}
import requests

# GET request
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
if response.status_code == 200:
    post_data = response.json()
    print("Title:", post_data["title"])

# POST request
payload = {
    "title": "Hello FastAPI",
    "body": "Learning about modules and packages",
    "userId": 1
}
post_response = requests.post(
    "https://jsonplaceholder.typicode.com/posts",
    json=payload,
    headers={"Content-Type": "application/json"}
)
print("Status Code:", post_response.status_code)   # 201 Created
print("Response JSON:", post_response.json())
```

<Tip>
  Always check `response.status_code` before accessing `response.json()`. A successful response returns `200` for GET and `201` for POST. Use `response.raise_for_status()` to automatically raise an exception for `4xx`/`5xx` responses.
</Tip>
