엔터프라이즈 FastAPI 앱을 위한 10개의 Python 패키지 구축: 내가 배운 점
Source: Dev.to – Building 10 Python Packages for Enterprise FastAPI Apps: What I Learned

1년 동안 엔터프라이즈 플랫폼을 구축하면서, 나는 같은 문제들을 계속해서 해결하고 있었다:
- 실제로 확장 가능한 RBAC와 함께 JWT 인증을 어떻게 처리할까?
- 왜 모든 프로젝트마다 자체 로깅 설정이 필요할까?
- Azure Key Vault와 로컬 개발 환경에서 비밀 정보를 어떻게 관리할까?
- 데이터베이스 연결 풀링을 가장 깔끔하게 처리하는 방법은?
그래서 나는 이러한 패턴들을 10개의 재사용 가능한 패키지로 추출하고 오픈소스로 공개했다.
Netrun 서비스 라이브러리
모든 패키지는 MIT‑라이선스를 따르며 PyPI에서 사용할 수 있습니다:
pip install netrun-auth netrun-logging netrun-config
기본 레이어
netrun-logging – 구조화된 로깅, 이제는 별로 안 지루하게
- structlog 기반으로 표준 라이브러리 대비 약 2.9× 성능 향상.
- 주요 기능: 민감한 필드 자동 마스킹.
from netrun_logging import get_logger
logger = get_logger(__name__)
# The password field is automatically redacted
logger.info(
"user_login",
username="daniel",
password="secret123", # Logged as "password": "[REDACTED]"
ip_address="192.168.1.1",
)
netrun-errors – HTTP와 매핑되는 예외 계층 구조
Exception대신 타입이 지정된 오류를 사용합니다.- 각 오류 클래스는 해당 HTTP 상태 코드와 매핑됩니다.
from netrun_errors import NotFoundError, ValidationError
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: str):
user = await db.get_user(user_id)
if not user:
# Raises a 404 response automatically
raise NotFoundError("User", user_id)
return user
인증 레이어
netrun-auth – JWT + RBAC + 멀티‑테넌트 격리
가장 어려운 구성 요소였습니다. 정책 기반 접근 제어를 위해 Casbin을 사용합니다.
from netrun_auth import JWTAuthenticator, require_permission
auth = JWTAuthenticator(
secret_key="your-secret",
algorithm="HS256"
)
@app.get("/admin/users")
@require_permission("users:read")
async def list_users(user=Depends(auth.get_current_user)):
# Only users with the `users:read` permission can access this endpoint
return await get_users()
멀티‑테넌트 격리를 통해 사용자는 자신이 속한 테넌트의 데이터만 접근할 수 있습니다:
@require_tenant_access
async def get_tenant_data(tenant_id: str, user=Depends(auth.get_current_user)):
# Automatically validates: user.tenant_id == tenant_id
return await db.get_tenant_data(tenant_id)
JWTAuthenticator– 토큰 생성/검증을 담당합니다.require_permission– 필요한 Casbin 권한을 확인하는 데코레이터입니다.require_tenant_access– 테넌트 수준 격리를 강제하는 데코레이터입니다.
Config 레이어
netrun-config – Azure Key Vault와 로컬 폴백
프로덕션에서는 Azure Key Vault를 사용하고 로컬에서는 .env 파일을 사용합니다:
from netrun_config import AzureKeyVaultConfig
config = AzureKeyVaultConfig(
vault_url="https://my-vault.vault.azure.net",
cache_ttl=300, # Cache secrets for 5 minutes
)
# In production: fetches from Key Vault
# Locally: falls back to environment variables
db_password = await config.get_secret("database-password")
- 프로덕션 – 비밀은 Azure Key Vault에서 직접 가져옵니다.
- 로컬 개발 – Vault에 접근할 수 없을 경우, 구성은 환경 변수(예:
.env파일에서 로드된 변수)로 대체됩니다.
LLM 레이어
netrun-llm – 다중 제공자 오케스트레이션
netrun‑llm은 LLM 제공자 간의 차이를 추상화하여, 원활하게 전환하거나 백업할 수 있게 합니다.
from netrun_llm import LLMOrchestrator
llm = LLMOrchestrator(
providers=["azure-openai", "ollama", "claude"],
fallback_enabled=True,
)
# Automatically fails over if the primary provider is down
response = await llm.complete(
prompt="Summarize this document",
model="gpt-4",
fallback_model="llama2", # Use Ollama if Azure is down
)
데이터 레이어
netrun-db-pool – 연결 폭풍을 처리하는 비동기 SQLAlchemy
자동 건강 검사를 포함한 연결 풀링
from netrun_db_pool import DatabasePool
pool = DatabasePool(
url="postgresql+asyncpg://...",
pool_size=20,
max_overflow=10,
health_check_interval=30,
)
async with pool.session() as session:
result = await session.execute(query)
url– 데이터베이스 연결 문자열.pool_size– 영구적으로 유지되는 연결 수.max_overflow– 풀에 연결이 부족할 때 생성될 수 있는 추가 연결 수.health_check_interval– 연결을 유지하기 위한 자동 건강 검사 ping 간격(초).
디자인 철학
소프트 의존성
각 패키지는 독립적으로 동작하지만, 여러 패키지를 함께 설치하면 자동으로 서로 통합됩니다:
| 패키지 | 결과 |
|---|---|
netrun-auth + netrun-logging | 인증 이벤트가 자동으로 기록됩니다 |
netrun-config + netrun-logging | 비밀 접근이 감사됩니다 |
netrun-db-pool + netrun-errors | 연결 오류가 타입으로 표시됩니다 |
통합은 간단한 탐지 패턴을 사용해 런타임에 수행됩니다:
try:
from netrun_logging import get_logger
logger = get_logger(__name__)
except ImportError: # Fallback to the standard library
import logging
logger = logging.getLogger(__name__)
제로 설정 기본값
모든 패키지는 합리적인 기본값을 제공하므로 별도의 설정 없이 바로 사용할 수 있습니다:
from netrun_auth import JWTAuthenticator
# 바로 사용할 수 있음
auth = JWTAuthenticator()
# 필요할 때 전체 커스터마이징
auth = JWTAuthenticator(
secret_key="…",
algorithm="RS256",
issuer="my-app",
audience=["api", "web"]
)
테스트 우선
netrun-pyte – 테스트‑우선 유틸리티로, 스위트에 포함되어 있습니다(내용은 간략히 생략).
…여기에 테스트 접근 방식에 대한 추가 세부 사항이 이어집니다…
st‑fixtures – 통합 테스트 픽스처
# conftest.py
pytest_plugins = ["netrun_pytest_fixtures"]
# Your tests automatically get:
# - mock_auth: Pre‑configured auth bypass
# - mock_db: In‑memory SQLite
# - mock_config: Environment‑based config
# - mock_llm: Deterministic LLM responses
다음에 할 일
저는 이 패키지들을 적극적으로 유지 보수하고 있습니다. 현재 우선순위는 다음과 같습니다:
- 더 나은 문서화 – READMEs는 시작에 불과하지만, 전체 문서 사이트가 곧 제공될 예정입니다.
- 더 많은 LLM 제공자 – Anthropic Claude API, Google Gemini 등 추가 중입니다.
- OpenTelemetry 추적 – 모든 패키지에 걸친 통합 추적.
시도해 보기
pip install netrun-auth netrun-logging netrun-config
GitHub: https://github.com/your‑org/st‑fixtures
PyPI: https://pypi.org/project/st‑fixtures/
MIT 라이선스. 이슈와 PR을 환영합니다!
FastAPI 애플리케이션에서 교차 관심사에 대해 어떤 패턴을 사용하시나요? 제가 놓친 부분을 알려주시면 좋겠습니다.
