2022-01-18 18:00:00+00:00

In a microservices ecosystem, code duplication is a constant risk. Multiple services often require identical logic for config parsing, logging layouts, custom error types, and database engines. However, importing files directly across folders breaks boundaries. A modular solution is to build a local shared package.

Developing a central library like core-library ensures uniform configuration patterns while letting individual teams move independently.


1. Structuring the Shared Repository

A shared package should contain pure utilities, settings schemas, and common middleware wrappers. The repository layout uses a standard python package structure with a setup.py or pyproject.toml file:

# Example shared config base in core-library/Config.py
import os
from pydantic import BaseSettings

class GlobalConfig(BaseSettings):
    ENVIRONMENT: str = os.getenv("ENV", "development")
    DATABASE_URL: str = os.getenv("DATABASE_URL", "postgresql+asyncpg://postgres:postgres@localhost:5432/postgres")
    ELASTICSEARCH_URL: str = os.getenv("ELASTICSEARCH_URL", "http://localhost:9200")
    
    class Config:
        case_sensitive = True

2. Integration and Dependency Management

To use the shared package in other microservices during development, include it in requirements.txt or via poetry as an editable path, or compile it to wheel files in your CI/CD pipeline:

# Installing the shared package in crm-service Dockerfile
COPY --from=builder /app/wheels/core-library-0.1.0-py3-none-any.whl /tmp/
RUN pip install /tmp/core-library-0.1.0-py3-none-any.whl

This guarantees that every microservice imports the exact same configuration schema, preventing system mismatches.