Interfaces in Python with Protocol Classes

Python clean code tip:

Use Protocol to define the interface required by your function/method instead of using real objects. This way your function/method defines what it needs.

from typing import Protocol

class ApplicationConfig:
    DEBUG = False
    SECRET_KEY = "secret-key"
    EMAIL_API_KEY = "api-key"

# bad
def send_email(config: ApplicationConfig):
    print(f"Send email using API key: {config.EMAIL_API_KEY}")

# better
class EmailConfig(Protocol):
    EMAIL_API_KEY: str

def send_email_(config: EmailConfig):
    print(f"Send email using API key: {config.EMAIL_API_KEY}")