0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カードリーダーでPASMOを使った勤務表を作ろう!

Last updated at Posted at 2025-11-11

はじめに

今回は uv を使ってみる
image.png

Repository

Pythonの依存管理:uv lock / uv sync と従来の venv + pip の比較

Pythonでプロジェクトを開発する際、依存関係の管理や仮想環境の扱いは悩ましい問題です。最近では pyproject.toml を中心にしたモダンな管理方法が登場しています。その代表例が uv コマンド です。

1. 従来の方法:venv + pip

従来は以下のように管理していました。

python -m venv .venv
# Windows
.venv\Scripts\activate

# macOS / Linux
source .venv/bin/activate
pip install fastapi uvicorn pandas nfcpy
pip freeze > requirements.txt

問題点

  • 手動で requirements.txt を更新する必要がある
  • 間接依存(uvicorn が依存する uvloop など)は自動で固定されない
  • 仮想環境作成・依存インストール・同期を毎回手作業で行う必要がある

2. モダン方式:uv lock / uv sync

uv は pyproject.toml を中心に依存関係と仮想環境を管理するツール です。
pip + venv の操作を簡潔にまとめ、自動化しています。

pyproject.toml の例

[project]
name = "nfc-timecard"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
    "nfcpy>=1.0.4",
    "fastapi>=0.103.0",
    "uvicorn[standard]>=0.22.0",
    "pandas>=1.5.0"
]

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

主要コマンド

コマンド 説明 venv + pip での対応
uv lock pyproject.toml の依存関係を解析し、ロックファイルを生成。間接依存まで固定される pip freeze > requirements.txt に相当(ただし自動化される)
uv sync 仮想環境を作成(なければ自動)し、ロックファイルに従って依存をインストール python -m venv .venv + pip install -r requirements.txt に相当

3. 特徴とメリット

  • 自動ロック
    • 間接依存も含めて完全にバージョン固定
  • 仮想環境自動作成
    • uv sync 一発で .venv ができる
  • pip freeze 不要
    • ロックファイルを自動生成するので管理が楽
  • pyproject.toml に依存を集約
    • 開発者・CI/CD・デプロイ環境で同一依存関係を再現可能

4. まとめ

項目 venv + pip uv
依存追加 pip install X pyproject.toml に追記
依存固定 pip freeze > requirements.txt uv lock
仮想環境作成 python -m venv uv sync が自動作成
依存インストール pip install -r requirements.txt uv sync が一括実行

💡 結論

  • uv lock = 依存関係をロック(requirements.txt 相当)
  • uv sync = ローカル環境に依存をインストール(pip install 相当)
  • pip + venv の作業を 自動化+再現性確保 したものが uv というイメージです

uvインストール方法(Windows)

  • Rust製の高速なPythonパッケージマネージャー
  • pippoetry より圧倒的に高速
  • 重要: pip install uv ではインストールできません
    • Python(pythonコマンド)やpip(pipコマンド)は、Pythonインストール時に自動的にPATHに登録されるため意識する必要がありません
    • しかし、uvはPythonとは独立したスタンドアロンツールなので、別途インストールしてPATHに登録する必要があります
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

インストール後はPowerShell(やPyCharm)を再起動してください。以下で確認できます:

uv --version
  uv 0.9.8 (85c5d3228 2025-11-07)

Get-Command uv
  CommandType     Name                                               Version    Source 
  -----------     ----                                               -------    ------ 
  Application     uv.exe                                             0.0.0.0    C:\Users\XXXX\.local\bin\uv.exe                                                                            

APIサーバを起動

uv run uvicorn app.main:app --reload

補足(OneDrive 環境での注意):

  • プロジェクトが OneDrive 配下にある場合、uv がハードリンクやクリーンアップで失敗することがあります。
    • 一時回避: 同じシェルで UV_LINK_MODE=copy を設定してから実行
      $env:UV_LINK_MODE = 'copy'
      uv run uvicorn app.main:app --reload
      
    • 恒久設定: 環境変数を永続化して常にコピー方式にします(uv の config サブコマンドが無い版でも有効)
      # 現ユーザーに永続(推奨)
      [Environment]::SetEnvironmentVariable('UV_LINK_MODE', 'copy', 'User')
      # または Windows 標準の setx を使用
      setx UV_LINK_MODE copy
      # 反映には新しいターミナルを開く/再ログインが必要です
      
    • それでも .venv の削除に失敗する場合(os error 5 など)は、OneDrive を一時停止してから .venv を作り直してください
      # OneDrive 同期を一時停止 → すべての python/uvicorn を終了
      Remove-Item -Recurse -Force .venv
      $env:UV_LINK_MODE = 'copy'
      uv sync
      uv run uvicorn app.main:app --reload
      
    • より安定させるには、プロジェクトを OneDrive 外(例: C:\dev\nfc-timecard)に移すか、対象フォルダを「このデバイスに常に保持」に設定してください

NFCリーダー(PaSoRi)のセットアップ

Windows用ドライバ(WinUSB)のインストール

Pythonの nfcpy ライブラリでPaSoRiを使うには、WinUSBドライバに変更する必要があります。

Zadigとは?

⚠️ 注意: Zadigでドライバを変更すると、Sony純正ソフト(FeliCa Port Softwareなど)が使えなくなる場合があります。元に戻すにはデバイスマネージャーから元のドライバに戻してください。

手順

  1. Zadig をダウンロード: https://zadig.akeo.ie/
  2. NFCリーダー(PaSoRi)を接続
  3. Zadig を起動 → Options"List All Devices" をON
  4. デバイス一覧から NFCリーダー(Sony RC-S380 など)を選択
  5. Driver欄で "WinUSB" を選び Install Driver をクリック

動作確認

python -m nfc

「読取待ち」状態になればOK。うまくいかない場合はドライバ設定を再確認してください。


マイナンバーカードの制約事項

🚨 重要:マイナンバーカードはUID(固有識別子)がランダム化される

マイナンバーカードをNFCリーダーで読み取った際、個人を特定できる固定IDが取得できません

実験結果

同じマイナンバーカードを3回タップした結果:

[DEBUG] Tag detected: Type4BTag
[DEBUG] Identifier (hex): 84E8FF18 [23:03:47] 84E8FF18 -> clock-in
[DEBUG] Tag detected: Type4BTag
[DEBUG] Identifier (hex): 7B9AFDAF [23:04:19] 7B9AFDAF -> clock-in
[DEBUG] Tag detected: Type4BTag
[DEBUG] Identifier (hex): C76FD9A0 [23:04:28] C76FD9A0 -> clock-in

同じカードなのに、毎回異なるIDが返される ことが確認できました。

技術的背景

  • マイナンバーカードは ISO/IEC 14443 Type B 規格
  • プライバシー保護のため、UID(カード識別子)がランダム化される仕様
  • tag.identifier で取得できる値は毎回変わるため、個人の特定には使えない

取得できた情報

python Tag attributes:
- TYPE: 'Type4Tag'
- identifier: b'\x84\xe8\xff\x18' # ← 毎回変わる!
- is_authenticated: False
- is_present: True
- ndef: None
- product: 'Type4Tag'

代替手段

マイナンバーカードで個人を識別するには:

  1. JPKI(公的個人認証)の証明書を読み取る(PINコード入力が必要、実装が複雑)
  2. カード内のアプリケーション領域にアクセス(APDUコマンドで通信、高度な実装が必要)

結論と推奨

勤怠管理システムでマイナンバーカードを使うのは不向きです。

代替案:

  • 交通系ICカード(Suica、PASMO等): 固定UIDを持ち、簡単に個人識別可能
  • 社員証(Felica/MIFARE等): 企業で発行されるICカード
  • 専用のNFCタグ: 安価で固定ID付きのカードを配布

本プロジェクトでマイナンバーカードを使う場合は、環境変数 ACCEPT_ALL_TAGS=1 を設定し、デモ/検証目的として利用してください。実運用では別のカードの使用を強く推奨します。

検証結果:PASMOでの動作確認 ✅

マイナンバーカードでは識別子がランダム化される問題があったため、PASMO(交通系ICカード) で検証しました。

実行結果

NFC watcher starting... (Ctrl+C to exit) 
[23:16:42] 01010A10XXXXXXXX -> clock-in | in=2025-11-12 23:16:42.995179 out=None hours=None 
[23:16:50] 01010A10XXXXXXXX -> clock-out | in=2025-11-12 23:16:42.995179 out=2025-11-12 23:16:50.359021 hours=0.0

⚠️ セキュリティのため、カードIDの一部をマスキングしています

マイナンバーカードとの比較(デバッグモードでの検証)

PASMO(Type3Tag / FeliCa)

[DEBUG] Tag detected: Type3Tag
[DEBUG] Identifier (hex): 01010A10XXXXXXXX
2回目も同じID
[DEBUG] Identifier (hex): 01010A10XXXXXXXX ✅ 固定

マイナンバーカード(Type4BTag)

[DEBUG] Tag detected: Type4BTag 
[DEBUG] Identifier (hex): 84E8FF18
# 2回目は別のID
[DEBUG] Identifier (hex): 7B9AFDAF ❌ ランダム化
# 3回目もまた別のID
[DEBUG] Identifier (hex): C76FD9A0 ❌ ランダム化

結果

  • PASMO: 同じカードで同じIDが取得できる01010A10XXXXXXXX
  • 出勤→退勤のトグル動作が正常に機能
  • 勤務時間の計算も正確(8秒間 - 休憩1時間 = 0時間)
  • マイナンバーカード: 毎回異なるIDが返される(個人識別不可)

カード種別の比較表

カード種別 タグタイプ 識別子の安定性 勤怠管理での利用
PASMO/Suica Type3Tag (FeliCa) ✅ 固定ID 推奨
マイナンバーカード Type4BTag ❌ 毎回ランダム化 ❌ 不可

技術的背景

マイナンバーカードがランダム化される理由:

  • ISO/IEC 14443 Type B 規格に準拠
  • プライバシー保護のため、UID(Unique Identifier)が意図的にランダム化される
  • カード内の個人情報にアクセスするには、APDUコマンドとPINコードが必要

PASMOが固定IDを持つ理由:

  • FeliCa (Sony) 規格に準拠
  • 交通機関での高速処理のため、固定IDによる即座の識別が必要
  • IDm(製造番号)が固定値として設定されている

結論

交通系ICカード(PASMO、Suica等)は勤怠管理システムに最適です。FeliCaベースのカードは固定IDを持つため、安定した個人識別が可能です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?