libcore-hng
libcore-hng は、設定管理・ロギング・例外処理・暗号化・ファイル操作を共通化するための Python コアライブラリです。Web アプリケーション本体ではなく、他の Python アプリケーションから利用するための基盤として設計されています。さらに、設計ドキュメントや Copilot 向けの指示ファイルを含め、別のプロジェクトでもそのままひな型として再利用しやすい構成にもなっています。
このライブラリでできること
- 設定ファイルの読み込みと共通化
- ログ出力の統一
- 独自例外の整理
- 設定ファイルの暗号化・復号化
- GCP Secret Manager との連携
- Excel / JSON / ファイル操作の補助
利用上の注意
- このリポジトリは共通ライブラリであり、業務ロジックを持つアプリケーション本体ではありません。
- 機密情報は平文でコミットしないでください。暗号化ファイルと Secret Manager を使って管理してください。
- 設定や秘密情報の扱いは、既存の共通基盤を通じて行ってください。
- 実装の詳細や開発ルールは docs 配下を参照してください。
- 設計書・ルール文書・.github/copilot-instructions.md は、他プロジェクトでの雛形としても活用できます。
- ログのローテーションは
TimedRotatingFileHandlerベースで、既定設定でwhen="midnight"、interval=1により日次で切り替わる構成です。 - アーカイブ済ログファイルの保持件数は
log_backupCountにより制御され、古いログはdoRollover()実行時に削除対象として扱われます。
参考ドキュメント
- docs/architecture.md
- docs/business_rules.md
- docs/architecture_rules.md
- docs/coding_rules.md
- docs/directory_rules.md
- docs/naming_rules.md
- docs/testing_rules.md
アプリ初期処理サンプル
このプロジェクトでは、AppInitializer を用いてアプリケーションの初期化処理を行います。
初期化は一度だけ実行し、以降はグローバルインスタンス app_core を参照してください。
アプリ初期化方法
test_013_appinit.py
from libcore_hng.utils.app_core import AppInitializer
from test_013_config import DerivedConfig
class DerivedAppInitializer(AppInitializer[DerivedConfig]):
"""
AppInitializer拡張クラス
"""
def __init__(self, base_file: str = __file__, *config_file: str):
# 基底コンストラクタに拡張Configクラスを渡す
super().__init__(DerivedConfig, base_file, *config_file)
ins: DerivedAppInitializer | None = None
""" AppInitializer拡張クラスインスタンス """
def init_app(base_file: str = __file__, *config_file: str) -> DerivedAppInitializer:
"""
アプリケーション初期化
"""
global ins
ins = DerivedAppInitializer(base_file, *config_file)
return ins
test_013_config.py
from pydantic import BaseModel
from libcore_hng.core.base_config import BaseConfig
from libcore_hng.utils.app_logger_mixin import LoggingMixin
class Test(BaseModel, LoggingMixin):
"""
テスト設定クラスモデル
"""
append_member: str = "A"
""" 追加メンバー """
class DerivedConfig(BaseConfig):
"""
BaseConfig拡張クラス
"""
test: Test = Test()
""" テスト設定クラス """
@classmethod
def load_config(cls, base_file, *config_file) -> "DerivedConfig":
"""
BaseConfigのload_configをoverrride
戻り値の型は自身とする
"""
# 基底側のload_configを実行してjsonファイルを読み込む
base = super().load_config(base_file, *config_file)
# BaseConfigのインスタンスが持つ属性を取り出してDerivedConfigのインスタンスを返す
# **はキーワード引数に展開する構文(属性をclsに引数渡しする)
return cls(**base.__dict__)
test_013.py
import test_013_appinit as app
import test_013_sub as t013
# アプリ初期化(最初の一度だけ呼び出す)
app.init_app(__file__, "app_config.json")
# 別ファイルのメソッド
t013.test013()
test_013_sub.py
import test_013_appinit as app
def test013():
# 拡張Configクラスのメンバーをprint
print(app.ins.config.test.append_member)
設定ファイルの暗号化と復号鍵の管理
機密情報を含む設定ファイルを保護するため、ファイルを暗号化し、その復号鍵を Google Cloud Secret Manager に安全に保存して管理します。開発環境と本番環境で同じ仕組みを使用することで、セキュアで統一された運用が可能です。詳細な運用方針は docs/business_rules.md を参照してください。
手順
- 設定ファイルの暗号化:
libcore_hng.utils.crypto.create_encryption_fileを使用して、既存のJSONファイルを暗号化します。これにより、元のファイル名に.encが付いた暗号化ファイルが生成され、標準出力に復号鍵が表示されます。 - 復号鍵の登録: コンソールに表示された鍵をコピーし、GCP Secret Manager に登録します(例:
my-app-secret-dev,my-app-secret-prod)。
実装例 (tests/test_016_enc_file.py)
import libcore_hng.utils.app_core as app
import libcore_hng.utils.crypto as crypto
from libcore_hng.core.base_config import BaseConfig
# アプリ初期化
app.init_app(BaseConfig, __file__, "logger.json")
# 設定ファイルを暗号化して新規ファイル (.enc) として作成
# 戻り値として復号鍵が得られます
key = crypto.create_encryption_file("configs/test-config.json")
# 生成された鍵を表示
print("以下の鍵を GCP Secret Manager に登録してください:")
print(key.decode("utf-8"))
BaseConfig.load_config は拡張子が .enc のファイルを自動的に検知し、暗号化ファイルとして復号・ロードする機能を備えています。実装上の詳細や制約は docs/architecture.md と docs/architecture_rules.md を参照してください。
復号に必要なGCP設定は、以下の環境変数、またはapp_config.jsonで設定された値から自動的に取得されます。
GCP_PROJECT_ID: GCPのプロジェクトID。WIF無効時に使用。GCP_SECRET_NAME: GCP Secret Manager に登録したシークレットのベース名。WIF無効時に使用。APP_ENV: 環境名(例:dev,prod)。シークレット名のサフィックスとして使用されます(デフォルト:dev)。
GCP Workload Identity Federation (WIF) を利用した鍵の取得
libcore-hng は、GCP Workload Identity Federation (WIF) を利用して Google Secret Manager から復号鍵を安全に取得する機能をサポートしています。これにより、CI/CD環境や異なるクラウドプロバイダーなど、GCP外の環境から直接サービスアカウントキーを配布することなく、GCPリソースにセキュアにアクセスできます。
仕組み
secret_manager.py 内の _get_secret_with_wif 関数がこのプロセスを管理します。主な流れは以下の通りです。
- 自前JWT (Subject Token) の生成:
libcore-hngは、設定された発行者 (issuer) と秘密鍵 (WIF_PRIVATE_KEY_PATH環境変数またはデフォルトパスから取得) を使用して、自身の認証情報を示す JWT を生成します。この JWT は、WIF プールとプロバイダーをオーディエンスとして指定します。 - Google STS (Security Token Service) との連携: 生成された自前 JWT は、Google STS エンドポイントに送信されます。STS はこの JWT を検証し、GCP が信頼する一時的なフェデレーテッドトークンに交換します。
- サービスアカウントの偽装 (Impersonation): フェデレーテッドトークンを使用して、指定されたサービスアカウント (
service_account_email) を偽装するためのアクセスキーを IAM Credentials API から取得します。これにより、libcore-hngはそのサービスアカウントが持つ権限で GCP リソースにアクセスできるようになります。 - Secret Manager からシークレットを取得: サービスアカウントとして取得した最終的なアクセスキーを用いて、Google Secret Manager クライアントを初期化し、指定されたシークレット (
secret_nameとapp_envから構成される) から復号鍵を取得します。
必要な設定
WIF を利用するには、app_config.json の gcp セクションで以下の設定を行うか、対応する環境変数を設定する必要があります。
wif_enabled:trueに設定して WIF を有効にします。project_number: Workload Identity Pool が属する GCP プロジェクトの番号。pool_id: Workload Identity Pool の ID。provider_id: Workload Identity Provider の ID。service_account_email: 偽装する GCP サービスアカウントのメールアドレス。issuer: 自前 JWT の発行者。通常は WIF プロバイダーの設定と一致させます。kid: 自前 JWT の署名に使用するキーID。sts_url: Security Token Service (STS) のエンドポイントURL。デフォルト値が設定されています。iam_credentials_url_base: IAM Credentials API のベースURL。デフォルト値が設定されています。
また、自前 JWT の署名に使用する秘密鍵のパスを環境変数 WIF_PRIVATE_KEY_PATH で指定する必要があります(例: /path/to/your/private_key.pem)。指定がない場合は、デフォルトで ~/.ssh/uw_private_key.pem が使用されます。
※ 例: GCP_SECRET_NAME=my-app-secret, APP_ENV=prod の場合、GCPから my-app-secret-prod のシークレットを取得します。WIF を使用する場合、GCP_PROJECT_ID と GCP_SECRET_NAME は WIF 無効時のフォールバックとしてのみ機能します。
環境変数設定例(Docker/ローカル開発)
環境変数を使用して、GCP Secret Manager へのアクセス情報、WIF 関連の設定、またはCI/CD・ローカル用の一時的な復号鍵を直接渡すことができます。app_config.json での設定値よりも環境変数が優先されます。
docker-compose.yml での設定例を以下に示します。
services:
app:
image: your-app-image
environment:
# --- GCP Workload Identity Federation (WIF) を利用する場合 ---
- WIF_ENABLED=true
- GCP_PROJECT_NUMBER=${GCP_PROJECT_NUMBER}
- GCP_POOL_ID=${GCP_POOL_ID}
- GCP_PROVIDER_ID=${GCP_PROVIDER_ID}
- GCP_SERVICE_ACCOUNT_EMAIL=${GCP_SERVICE_ACCOUNT_EMAIL}
- GCP_ISSUER=${GCP_ISSUER}
- GCP_KID=${GCP_KID}
- WIF_PRIVATE_KEY_PATH=/path/to/your/private_key.pem
- APP_ENV=prod # 開発時は dev などを指定
# --- または、従来の GCP Secret Manager 連携 (WIF無効時) ---
# WIF_ENABLED を false にするか、未設定の場合に適用されます。
- GCP_PROJECT_ID=${GCP_PROJECT_ID}
- GCP_SECRET_NAME=${GCP_SECRET_NAME}
# - APP_ENV=prod は WIF の場合と共通
# --- または、復号鍵を直接指定する場合 (GCP設定より優先されます) ---
- APP_SECRET_KEY=${APP_SECRET_KEY}
※ 開発時やデプロイ時には、Docker Composeが読み込む .env ファイルなどにこれらの変数を記述しておくことで、安全に鍵情報や設定をコンテナへ渡すことができます。
他プロジェクトでも再利用しやすい構成
このリポジトリでは、実装本体だけでなく、設計書・ルール文書・Copilot 向けの指示ファイルを一緒に管理しています。これらは、別の Python プロジェクトで同じような構成を作る際の参考実装やひな型として利用できます。
特に、以下のファイル群は再利用を意識した構成です。
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file libcore_hng-2.0.28.tar.gz.
File metadata
- Download URL: libcore_hng-2.0.28.tar.gz
- Upload date:
- Size: 43.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35acd3e191eb223708972ecec6c627259529f3716f09ea4bab0f0a2648e1b570
|
|
| MD5 |
4fb1954af593dfa31b161715bc2a60a3
|
|
| BLAKE2b-256 |
20b48d40103c08ebe9802753ccff8925de25e5f731b6c9a57dc00ae919e65f66
|
Provenance
The following attestation bundles were made for libcore_hng-2.0.28.tar.gz:
Publisher:
release.yml on kaioman/libcore-hng
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libcore_hng-2.0.28.tar.gz -
Subject digest:
35acd3e191eb223708972ecec6c627259529f3716f09ea4bab0f0a2648e1b570 - Sigstore transparency entry: 2377166304
- Sigstore integration time:
-
Permalink:
kaioman/libcore-hng@9cf0208ae682d15f1c03a1edd342edebe0e3437b -
Branch / Tag:
refs/tags/v2.0.28 - Owner: https://github.com/kaioman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9cf0208ae682d15f1c03a1edd342edebe0e3437b -
Trigger Event:
push
-
Statement type:
File details
Details for the file libcore_hng-2.0.28-py3-none-any.whl.
File metadata
- Download URL: libcore_hng-2.0.28-py3-none-any.whl
- Upload date:
- Size: 43.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0b14bad749bb0b354ffe66bbff2e2bcaa0274dac87f675db44748cc9db07a1a
|
|
| MD5 |
11c76295c78333f451366c3f00deabbf
|
|
| BLAKE2b-256 |
9e541a763c5d040088c4097d28098537631b1573444776de4833a6da43493e4f
|
Provenance
The following attestation bundles were made for libcore_hng-2.0.28-py3-none-any.whl:
Publisher:
release.yml on kaioman/libcore-hng
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
libcore_hng-2.0.28-py3-none-any.whl -
Subject digest:
b0b14bad749bb0b354ffe66bbff2e2bcaa0274dac87f675db44748cc9db07a1a - Sigstore transparency entry: 2377166591
- Sigstore integration time:
-
Permalink:
kaioman/libcore-hng@9cf0208ae682d15f1c03a1edd342edebe0e3437b -
Branch / Tag:
refs/tags/v2.0.28 - Owner: https://github.com/kaioman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9cf0208ae682d15f1c03a1edd342edebe0e3437b -
Trigger Event:
push
-
Statement type: