Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fee7ab0
chore: update devcontainer config
ivis-kuroda Jan 22, 2026
cf24d25
downgrade: require redis upto 6.4.0
ivis-kuroda Jan 22, 2026
c900557
Merge pull request #9 from ivis-kuroda/W2025-35
ivis-kuroda Jan 22, 2026
4b41ff4
docs: update coverage badge
ivis-kuroda Jan 22, 2026
81c275a
add signals for groups manager
ryoya-hayase Jan 27, 2026
e75fae3
Merge commit '81c275ad5aaba07d8bfd140d5b2176fbd24621b2' into W2025-35
ivis-kuroda Mar 9, 2026
721b235
docs: update coverage badge
ivis-kuroda Mar 9, 2026
ec056ef
update: refine configurations
ivis-kuroda Mar 9, 2026
28e9509
refactor: refine signals and support fqdn list
ivis-kuroda Mar 10, 2026
bc76470
update: add cache key function
ivis-kuroda Mar 10, 2026
e3b0b94
fix: updated value for signal
ivis-kuroda Mar 10, 2026
885fd44
chore: update to 1.0.0rc5
ivis-kuroda Mar 10, 2026
7e8bd73
feat: add progress status to signal args
ivis-kuroda Mar 10, 2026
1671671
chore: update to 1.0.0rc6
ivis-kuroda Mar 10, 2026
978da6b
Merge branch 'develop' into W2025-35
ivis-kuroda Mar 11, 2026
60a9b46
Merge pull request #11 from ivis-kuroda/W2025-35
ivis-kuroda Mar 11, 2026
a8d12f6
docs: update coverage badge
ivis-kuroda Mar 11, 2026
7046dbc
fix: send completed status in progress signal
ivis-kuroda Oct 26, 2026
059ce4e
doc: add description of signals
ivis-kuroda Oct 26, 2026
8fc3c82
chore: specify build backend
ivis-kuroda Oct 26, 2026
c79859d
style: update lint suppression comments
ivis-kuroda Oct 26, 2026
4720021
docs: update coverage badge
ivis-kuroda Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .devcontainer/dev.compose.yaml

This file was deleted.

33 changes: 23 additions & 10 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
{
"name": "weko-group-cache-db Dev Container",
"dockerComposeFile": [
"../compose.yaml",
"dev.compose.yaml"
],
"runServices": ["dev", "redis"],
"service": "dev",
"image": "mcr.microsoft.com/devcontainers/base:bookworm",
"remoteUser": "vscode",
"workspaceFolder": "/workspace",

"initializeCommand": "docker network create weko-group-cache-db_default || true",
"runArgs": [
"--network",
"weko-group-cache-db_default"
],

"features": {
"ghcr.io/devcontainers/features/python:1": {
"version": "3.14"
},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
"version": "latest",
"dockerDashComposeVersion": "latest",
"enableNonRootDocker": true,
"moby": false
}
},
"remoteEnv": {
"VIRTUAL_ENV": "/home/vscode/.venv",
"UV_PROJECT_ENVIRONMENT": "/home/vscode/.venv"
},
"postCreateCommand": "chmod +x .devcontainer/setup.sh && .devcontainer/setup.sh vscode",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],

"onCreateCommand": "/bin/sh .devcontainer/setup.sh install_deps",
"postAttachCommand": "/bin/sh .devcontainer/setup.sh compose_up",

"customizations": {
"vscode": {
"settings": {
"python.pythonPath": "/code/.venv/bin/python",
"python.languageServer": "Pylance",
"python.defaultInterpreterPath": "~/.venv/bin/python",
"[python]": {
"editor.rulers": [88],
"editor.formatOnSave": true,
Expand All @@ -33,7 +44,9 @@
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff"
}
},
"python.useEnvironmentsExtension": false,
"python.terminal.activateEnvironment": false
},
"extensions": [
"visualstudioexptteam.vscodeintellicode",
Expand Down
48 changes: 30 additions & 18 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
#!/bin/bash
set -e

REMOTE_USER=$1
BASHRC_FILE="/home/${REMOTE_USER}/.bashrc"
install_deps() {
# Install Python dependencies
pip install --upgrade pip && pip install uv
uv sync && uv pip install -e .

if [ -z "$REMOTE_USER" ]; then
echo "Error: User name argument is missing."
exit 1
fi
if ! grep -q "venv_activate_reload" ~/.bashrc 2>/dev/null; then
{
echo ""
echo "# venv_activate_reload"
echo "if [ -f ~/.venv/bin/activate ]; then"
echo " source ~/.venv/bin/activate"
echo "fi"
} >> ~/.bashrc
fi
}


compose_up() {
docker compose up -d --force-recreate redis
}

if ! grep -q "venv_activate_reload" "$BASHRC_FILE" 2>/dev/null; then
{
echo ""
echo "# venv_activate_reload"
echo "if [ -f /home/${REMOTE_USER}/.venv/bin/activate ]; then"
echo " source /home/${REMOTE_USER}/.venv/bin/activate"
echo "fi"
} >> "$BASHRC_FILE"
FUNCTION_NAME=$1

sudo chown ${REMOTE_USER}:${REMOTE_USER} "$BASHRC_FILE"
if [ -z "$FUNCTION_NAME" ]; then
echo "Error: Function name argument is missing."
exit 1
fi

shift

pip install --upgrade pip
pip install uv && uv sync && uv pip install -e .
if type -t "$FUNCTION_NAME" | grep -q 'function'; then
"$FUNCTION_NAME" "$@"
else
echo "Error: Function '$FUNCTION_NAME' not found."
exit 1
fi
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ FROM base AS production
ENV VIRTUAL_ENV="/code/.venv"
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN uv sync --no-dev --frozen && \
uv pip install .
RUN uv sync --no-dev --frozen

CMD ["sh", "-c", "COLUMNS=120 exec wgcd run -d /var/mnt -l /var/repositories.txt"]
59 changes: 49 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# weko-group-cache-db / グループ情報キャッシュ機能
<!-- Pytest Coverage Comment:Begin -->
<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/README.md"><img alt="Coverage" src="https://img.shields.io/badge/Coverage-100%25-brightgreen.svg" /></a><details><summary>Coverage Report </summary><table><tr><th>File</th><th>Stmts</th><th>Miss</th><th>Cover</th></tr><tbody><tr><td colspan="4"><b>weko_group_cache_db</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/cli.py">cli.py</a></td><td>52</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/config.py">config.py</a></td><td>84</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/exc.py">exc.py</a></td><td>9</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/groups.py">groups.py</a></td><td>86</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/loader.py">loader.py</a></td><td>111</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/logger.py">logger.py</a></td><td>25</td><td>0</td><td>100%</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/RCOSDP/weko-group-cache-db/blob/main/weko_group_cache_db/redis.py">redis.py</a></td><td>26</td><td>0</td><td>100%</td></tr><tr><td><b>TOTAL</b></td><td><b>393</b></td><td><b>0</b></td><td><b>100%</b></td></tr></tbody></table></details>
<!-- pytest-coverage-comment --><p><a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/README.md"><img alt="Coverage" src="https://img.shields.io/badge/Coverage-99%25-brightgreen.svg" /></a></p><details><summary>Coverage Report </summary><table><tr><th>File</th><th>Stmts</th><th>Miss</th><th>Branch</th><th>BrPart</th><th>Cover</th><th>Missing</th></tr><tbody><tr><td colspan="7"><b>weko_group_cache_db</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/cli.py">cli.py</a></td><td>52</td><td>0</td><td>12</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/config.py">config.py</a></td><td>74</td><td>0</td><td>8</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/exc.py">exc.py</a></td><td>9</td><td>0</td><td>0</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/groups.py">groups.py</a></td><td>117</td><td>0</td><td>18</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/loader.py">loader.py</a></td><td>117</td><td>1</td><td>24</td><td>1</td><td>1</td><td><a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/loader.py#L 99%"> 99%</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/logger.py">logger.py</a></td><td>24</td><td>0</td><td>2</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/redis.py">redis.py</a></td><td>26</td><td>0</td><td>2</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/ivis-weko3-dev/weko-group-cache-db/blob/main/weko_group_cache_db/signals.py">signals.py</a></td><td>22</td><td>0</td><td>0</td><td>0</td><td>100%</td><td>&nbsp;</td></tr><tr><td><b>TOTAL</b></td><td><b>441</b></td><td><b>1</b></td><td><b>66</b></td><td><b>1</b></td><td><b>99%</b></td><td>&nbsp;</td></tr></tbody></table></details>
<!-- Pytest Coverage Comment:End -->

## 概要
Expand Down Expand Up @@ -100,7 +100,7 @@ $ wgcd run --help
1つの機関に接続しているグループ情報を取得し、キャッシュDBへ登録する。
マウントされたディレクトリからFQDNリストファイルとSSL証明書・SSL鍵ファイルを使用して実行するディレクトリベースの実行方法と、機関情報を記述したTOMLファイルを使用して実行するファイルベースの実行方法がある。

### ヘルプ表示
#### ヘルプ表示

```
$ wgcd one --help
Expand Down Expand Up @@ -208,7 +208,6 @@ $ wgcd one --help

### カスタム設定値
[config.toml](./config.toml)に設定値を記載することで、実行時に設定値を反映して実行することが可能。
また、環境変数、`.env`ファイル、Kubernetesのシークレットマウントによっても設定値を反映することが可能。

`MAP_GROUPS_API_ENDPOINT`以外はデフォルトの設定値があるため、それ以外は必要に応じて上書きしたい設定値のみを記載すればよい。
`config.toml`に記述する場合、大文字小文字は区別されない.
Expand All @@ -227,7 +226,7 @@ $ wgcd one --help
| REQUEST_RETRY_BASE | 数値 | 4 | グループ情報取得・キャッシュDBへの登録処理のリトライ時の指数バックオフの基準時間(秒) |
| REQUEST_RETRY_FACTOR | 数値 | 5 | グループ情報取得・キャッシュDBへの登録処理のリトライ時の指数バックオフの係数(秒) |
| REQUEST_RETRY_MAX | 数値 | 90 | グループ情報取得・キャッシュDBへの登録処理のリトライ時の指数バックオフの最大時間(秒) |
| REDIS_TYPE | 文字列 | redis | 使用するRedisの種類<br>"redis", "sentinel"のうちから指定 |
| REDIS_TYPE | 文字列 | RedisCache | 使用するRedisの種類<br>"RedisCache", "RedisSentinelCache"のうちから指定 |
| REDIS_HOST | 文字列 | localhost | Redisのホスト名 |
| REDIS_PORT | 数値 | 6379 | Redisのポート番号 |
| REDIS_DB_INDEX | 数値 | 4 | グループ情報を格納するRedisのDBインデックス |
Expand All @@ -239,25 +238,65 @@ $ wgcd one --help
※ Redis Sentinel の設定値をTOMLファイルに記載する場合の例
```
[[sentinels]]
host = "sendinel-1"
host = "sentinel-1"
port = 26379

[[sentinels]]
host = "sendinel-2"
host = "sentinel-2"
port = 26378

[[sentinels]]
host = "sendinel-3"
host = "sentinel-3"
port = 26377
```

設定値の優先順位は以下の通り。

1. TOMLファイル
2. 環境変数
3. `.env`ファイル
4. Kubernetesのシークレットマウント
5. デフォルト値(`MAP_GROUPS_API_ENDPOINT`以外)
3. デフォルト値(`MAP_GROUPS_API_ENDPOINT`以外)


## シグナル

[blinker](https://blinker.readthedocs.io/) のシグナルにより、処理の進捗と各機関の処理結果を外部から受け取ることができる。

```python
from weko_group_cache_db.signals import executed_signal, progress_signal


@progress_signal.connect
def on_progress(sender, data):
print(f"{data.status}: {data.done}/{data.total}")
```

| シグナル | 送信タイミング | 対象コマンド | データ型 |
| ----------------- | --------------------------------------------------------- | -------------- | -------------- |
| `progress_signal` | 各機関の処理開始前、および全機関の処理完了後 | `run` | `ProgressData` |
| `executed_signal` | 各機関の処理の試行ごと(リトライを含む)の成功時・失敗時 | `run`, `one` | `ExecutedData` |

### progress_signal

| 項目 | 型 | 説明 |
| --------- | ------ | -------------------------------------------------------------------- |
| `status` | 文字列 | `started`:最初の機関の処理開始前<br>`in_progress`:2件目以降の機関の処理開始前<br>`completed`:全機関の処理完了後(失敗した機関があっても送信される) |
| `total` | 数値 | 処理対象の機関数 |
| `done` | 数値 | 処理済みの機関数 |
| `current` | 文字列 | これから処理する機関のFQDN(`completed` の場合は `N/A`) |

### executed_signal

| 項目 | 型 | 説明 |
| --------------- | -------- | -------------------------------------------------------------------- |
| `fqdn` | 文字列 | 機関のFQDN |
| `status` | 文字列 | `success`:グループ情報のRedisへの登録に成功<br>`failed`:グループ情報の取得またはRedisへの登録に失敗 |
| `retries` | 数値 | その試行までのリトライ回数(初回の試行は 0) |
| `error_type` | 文字列 | 失敗時の例外クラス名(成功時は `None`) |
| `error_message` | 文字列 | 失敗時のエラーメッセージ(成功時は `None`) |
| `updated_at` | 日時 | 成功時はRedisへの登録日時、失敗時はシグナルの送信日時(UTC) |

※ `failed` はリトライのたびに送信される。


## 開発環境構築

Expand Down
9 changes: 9 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ services:
volumes:
- .:/code
- /code/.venv
networks:
- default

redis:
restart: "always"
Expand All @@ -19,3 +21,10 @@ services:
resources:
limits:
memory: 100m
networks:
- default

networks:
default:
external: true
name: weko-group-cache-db_default
6 changes: 3 additions & 3 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# cache_ttl = 86400

# === Map groups API endpoint. ===
map_groups_api_endpoint = "https://sample.gakunin.jp/api/groups/"
map_groups_api_endpoint = "https://sptest.cg.gakunin.jp/api/groups/"

# === Request timeout (in seconds) when connecting to mAP API. ===
# request_timeout = 20
Expand All @@ -42,8 +42,8 @@ map_groups_api_endpoint = "https://sample.gakunin.jp/api/groups/"
# === Maximum time (in seconds) for exponential backoff during request retries. ===
# request_retry_max = 90

# === Redis type to use. `redis` or `sentinel` is allowed. ===
# redis_type = "redis"
# === Redis type to use. `RedisCache` or `RedisSentinelCache` is allowed. ===
# redis_type = "RedisCache"

# === Redis service host name. ===
# redis_host = "localhost"
Expand Down
34 changes: 25 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#:schema https://json.schemastore.org/pyproject.json

[build-system]
requires = ["uv_build>=0.13.5,<0.14"]
build-backend = "uv_build"

[project]
name = "weko-group-cache-db"
version = "1.0.0rc4"
version = "1.0.0rc6"
description = "CLI tool for caching mAP group information on JAIRO Cloud."
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"backoff>=2.2.1",
"blinker>=1.9.0",
"inflect>=7.5.0",
"pydantic-settings>=2.12.0",
"redis>=7.0.1",
"redis>=6.4.0",
"requests>=2.32.5",
"rich-click>=1.9.4",
"werkzeug>=3.1.3",
Expand All @@ -29,6 +36,10 @@ dev = [
"toml>=0.10.2",
]

[tool.uv.build-backend]
module-name = "weko_group_cache_db"
module-root = ""

[tool.taskipy.tasks]
# refer to https://github.com/taskipy/taskipy?tab=readme-ov-file#usage
test = "pytest"
Expand All @@ -46,17 +57,22 @@ addopts = [

[tool.coverage.run]
source = ["weko_group_cache_db"]
omit = ["*/__init__.py", "*/tests/*"]

[tool.coverage.report]
omit = ["__init__.py", "tests/*"]
exclude_also = [
"if t.TYPE_CHECKING:",
]

[tool.ruff.lint]
# refer to https://docs.astral.sh/ruff/settings/#lint
ignore = [
"D203",
"D213",
"TC006",
"COM812",
"ANN201",
"TRY400",
"incorrect-blank-line-before-class",
"multi-line-summary-second-line",
"runtime-cast-value",
"missing-trailing-comma",
"missing-return-type-undocumented-public-function",
"error-instead-of-exception",
]
preview = true
select = ["ALL"]
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def row_config():
"REQUEST_RETRY_BASE": 2,
"REQUEST_RETRY_FACTOR": 15,
"REQUEST_RETRY_MAX": 60,
"REDIS_TYPE": "sentinel",
"REDIS_TYPE": "RedisSentinelCache",
"REDIS_HOST": "redis",
"REDIS_PORT": 26379,
"REDIS_DB_INDEX": 2,
Expand Down
14 changes: 7 additions & 7 deletions tests/ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ target-version = "py314"
[lint]
ignore = [
"D",
"S101",
"assert",
"ANN",
"COM812",
"TC006",
"DTZ005",
"PLC2701",
"SLF001",
"SIM300",
"missing-trailing-comma",
"runtime-cast-value",
"call-datetime-now-without-tzinfo",
"import-private-name",
"private-member-access",
"yoda-conditions",
]
preview = true
select = ["ALL"]
Expand Down
Loading
Loading