Managing Environment Variables
REPL
A Python REPL environment is an interactive programming tool where you can write and execute Python code line-by-line and immediately see the results. REPL stands for:
- Read - accepts your input (Python code)
- Eval - evaluates/executes that code
- Print - displays the output
- Loop - returns to accept more input
Class/Method Abstraction
Abstract base classes use Python’s abc module. This serves as a blueprint for class and method implementations, ensuring consistency across subclasses. Key reasons for abstraction:
- Interface Enforcement: Abstract methods must be implemented by any concrete subclass, preventing incomplete implementations.
- Polymorphism: Allows treating different class instances uniformly (e.g., calling completion() on any object).
- Maintainability: Centralizes the API, making it easier to add new features or modify behavior across all implementations.
- Type Safety: Provides clear type hints for context (list of strings, string, or dict) and return types, aiding IDE support and reducing errors.
Example Abstraction Class:
from abc import ABC, abstractmethod
class RLM(ABC):
@abstractmethod
def completion(self, context: list[str] | str | dict[str, str], query: str) -> str:
pass
@abstractmethod
def cost_summary(self) -> dict[str, float]:
pass
@abstractmethod
def reset(self):
pass
Code from https://github.com/alexzhang13/rlm.
__init__.py
In Python, __init__.py is a special file that serves two primary purposes within a package:
-
Marking a Directory as a Package: When a directory contains an
__init__.pyfile, Python treats that directory as a package. This allows you to import modules and subpackages from within that directory using standard import statements. Even an empty__init__.pyfile suffices to declare a directory as a package. -
Package Initialization and Namespace Management: The code within
__init__.pyis executed automatically the first time the package or any module within it is imported. This allows for:- Initialization Code: Running setup or configuration code, such as establishing database connections, loading configuration files, or setting up package-level variables.
- Simplifying Imports: Importing specific modules, functions, or classes from submodules directly into the package’s namespace. This allows users to import these elements directly from the package instead of needing to specify the submodule.
- Defining
__all__: The__all__variable (a list of strings) can be defined in__init__.pyto control which names are imported when a “star import” (from package import *) is used. This allows for explicit control over the package’s public API.
Context Manager Protocol (with statement)
Context managers provide setup/cleanup guarantees using the with statement.
Execution Order
with expression as variable:
# body
expression.__enter__()runs → returns value bound tovariablebodyexecutesexpression.__exit__()always runs (even if exception occurs)Implementation:
@contextmanagerDecoratorConverts a generator function into a context manager:
from contextlib import contextmanager
@contextmanager
def my_context():
# Setup code runs first
resource = setup()
try:
yield resource # ← Pauses; value goes to 'as' variable
# Execution jumps to 'with' body
finally:
cleanup(resource) # ← Always runs on exit
Usage:
with my_context() as resource:
# Use resource here
...
# cleanup() called automatically
Why Use a Context Manager?
- Fail-safe cleanup:
finallyblock guarantees cleanup even on exceptions. Ensure exit code always runs. - No decorator needed: Manual implementation requires
__enter__and__exit__methods
Without
@contextmanagerA generator alone cannot be used in awithstatement, it crashes. The decorator bridges this gap automatically.
def my_gen():
yield resource # Just a generator, NOT a context manager
with my_gen(): # ❌ TypeError: object does not support context manager protocol
pass
Package Management with `uv
Docs: https://docs.astral.sh/uv/
cd your-project
uv venv # Creates .venv in project directory
source .venv/bin/activate # or: . .venv/bin/activate
uv pip install pandas numpy
Advantages over managing with conda: conda can introduce dependency duplication. uv uses aggressive caching to avoid re-downloading (and re-building) dependencies that have already been accessed in prior runs. Let’s say two projects are using the same ‘pandas’ version. Even if you have a separate environments for the projects, uv does not install the dependency twice (like it would do with conda environments).
Additional uv commands:
# Install uv (first time)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Setup project
uv init && uv venv --python 3.12
# Activate environment
source .venv/bin/activate
# Install project in editable mode
uv pip install -e .