fiftyone-code-style
FiftyOneの公式スタイルに従ったPythonコードを記述し、FiftyOneへの貢献やプラグイン開発、連携コード作成時に、一貫性と品質を保った読みやすいコードを書くことを支援するSkill。
📜 元の英語説明(参考)
Write Python code following FiftyOne's official conventions. Use when contributing to FiftyOne, developing plugins, or writing code that integrates with FiftyOne's codebase.
🇯🇵 日本人クリエイター向け解説
FiftyOneの公式スタイルに従ったPythonコードを記述し、FiftyOneへの貢献やプラグイン開発、連携コード作成時に、一貫性と品質を保った読みやすいコードを書くことを支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o fiftyone-code-style.zip https://jpskill.com/download/17009.zip && unzip -o fiftyone-code-style.zip && rm fiftyone-code-style.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17009.zip -OutFile "$d\fiftyone-code-style.zip"; Expand-Archive "$d\fiftyone-code-style.zip" -DestinationPath $d -Force; ri "$d\fiftyone-code-style.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
fiftyone-code-style.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
fiftyone-code-styleフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
FiftyOne コードスタイル
モジュールテンプレート
"""
モジュールの説明。
| Copyright 2017-2025, Voxel51, Inc.
| `voxel51.com <https://voxel51.com/>`_
|
"""
# 標準ライブラリ
import logging
import os
# サードパーティ
import numpy as np
# eta (Voxel51 ユーティリティ)
import eta.core.utils as etau
# FiftyOne
import fiftyone.core.fields as fof
import fiftyone.core.labels as fol
import fiftyone.core.utils as fou
logger = logging.getLogger(__name__)
def public_function(arg):
"""Public API function."""
return _helper(arg)
def _helper(arg):
"""Private helper (underscore prefix)."""
return arg
インポートの構成
4つのグループに分け、各グループ内でアルファベット順に並べます。
| グループ | 例 |
|---|---|
| 1. 標準ライブラリ | import logging, import os |
| 2. サードパーティ | import numpy as np, from PIL import Image |
| 3. eta パッケージ | import eta.core.utils as etau |
| 4. FiftyOne | import fiftyone.core.labels as fol |
FiftyOne インポートエイリアス
| モジュール | エイリアス |
|---|---|
fiftyone |
fo |
fiftyone.core.labels |
fol |
fiftyone.core.fields |
fof |
fiftyone.core.media |
fom |
fiftyone.core.storage |
fos |
fiftyone.core.utils |
fou |
fiftyone.utils.image |
foui |
fiftyone.utils.video |
fouv |
ドキュメンテーション文字列 (Googleスタイル)
関数ドキュメンテーション文字列
def get_operator(operator_uri, enabled=True):
"""Gets the operator with the given URI.
Args:
operator_uri: the operator URI
enabled (True): whether to include only enabled operators (True) or
only disabled operators (False) or all operators ("all")
Returns:
an :class:`fiftyone.operators.Operator`
Raises:
ValueError: if the operator is not found
"""
クラスドキュメンテーション文字列
class ImageMetadata(Metadata):
"""Class for storing metadata about image samples.
Args:
size_bytes (None): the size of the image on disk, in bytes
mime_type (None): the MIME type of the image
width (None): the width of the image, in pixels
height (None): the height of the image, in pixels
"""
重要なパターン:
- デフォルト値を持つ引数:
param (default): description - 複数行の説明: インデントして継続
- 相互参照:
:class:fiftyone.module.Class``
プライベート関数
# Public API delegates to private helper
def build_for(cls, path_or_url, mime_type=None):
"""Builds a Metadata object for the given file."""
if path_or_url.startswith("http"):
return cls._build_for_url(path_or_url, mime_type=mime_type)
return cls._build_for_local(path_or_url, mime_type=mime_type)
# Private: underscore prefix, focused purpose
def _build_for_local(cls, filepath, mime_type=None):
"""Internal helper for local files."""
size_bytes = os.path.getsize(filepath)
if mime_type is None:
mime_type = etau.guess_mime_type(filepath)
return cls(size_bytes=size_bytes, mime_type=mime_type)
遅延インポート
オプションまたは負荷の高い依存関係には、fou.lazy_import()を使用します。
# Basic lazy import
o3d = fou.lazy_import("open3d", callback=lambda: fou.ensure_package("open3d"))
# With ensure_import for pycocotools
mask_utils = fou.lazy_import(
"pycocotools.mask", callback=lambda: fou.ensure_import("pycocotools")
)
# Internal module lazy import
fop = fou.lazy_import("fiftyone.core.plots.plotly")
使用するタイミング:
- 負荷の高いパッケージ (open3d, tensorflow, torch)
- オプションの依存関係 (pycocotools)
- 循環インポートの防止
ガードパターン
条件付きの動作にはhasattr()を使用します。
# Check for optional attribute
if hasattr(label, "confidence"):
if label.confidence is None or label.confidence < threshold:
label = label.__class__()
# Check for config attribute
if hasattr(eval_info.config, "iscrowd"):
crowd_attr = eval_info.config.iscrowd
else:
crowd_attr = None
# Dynamic state initialization
if not hasattr(pb, "_next_idx"):
pb._next_idx = 0
pb._next_iters = []
エラー処理
致命的でないエラーにはlogger.warning()を使用します。
# Non-fatal: warn and continue
try:
for target in fo.config.logging_debug_targets.split(","):
if logger_name := target.strip():
loggers.append(logging.getLogger(logger_name))
except Exception as e:
logger.warning(
"Failed to parse logging debug targets '%s': %s",
fo.config.logging_debug_targets,
e,
)
# Missing optional import
try:
import resource
except ImportError as e:
if warn_on_failure:
logger.warning(e)
return
# Graceful fallback
try:
mask = etai.render_instance_image(dobj.mask, dobj.bounding_box, frame_size)
except:
width, height = frame_size
mask = np.zeros((height, width), dtype=bool)
冗長な実装を避ける
新しい関数を作成する前に、FiftyOne がすでにその機能を提供しているかどうかを確認してください。
fiftyone.core.utils (fou) の共通ユーティリティ
| 関数 | 目的 |
|---|---|
fou.lazy_import() |
遅延モジュールロード |
fou.ensure_package() |
不足しているパッケージのインストール |
fou.ensure_import() |
インポートが利用可能か確認 |
fou.extract_kwargs_for_class() |
クラスの kwargs の分割 |
fou.load_xml_as_dict() |
XML を dict にパース |
fou.get_default_executor() |
スレッドプールエグゼキュータの取得 |
eta.core.utils (etau) の共通ユーティリティ
| 関数 | 目的 |
|---|---|
etau.guess_mime_type() |
ファイルの MIME タイプの検出 |
etau.is_str() |
文字列かどうかの確認 |
etau.ensure_dir() |
ディレクトリが存在しない場合に作成 |
etau.ensure_basedir() |
親ディレクトリの作成 |
etau.make_temp_dir() |
テンポラリディレクトリの作成 |
新しいコードを書く前に
-
既存のモジュールで同様の機能を検索します。
grep -r "def your_function_name" fiftyone/ grep -r "similar_keyword" fiftyone/core/utils.py -
まずこれらのモジュールを確認してください。
fiftyone.core.utils- 一般的なユーティリティ- `fiftyone.c
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
FiftyOne Code Style
Module Template
"""
Module description.
| Copyright 2017-2025, Voxel51, Inc.
| `voxel51.com <https://voxel51.com/>`_
|
"""
# Standard library
import logging
import os
# Third-party
import numpy as np
# eta (Voxel51 utilities)
import eta.core.utils as etau
# FiftyOne
import fiftyone.core.fields as fof
import fiftyone.core.labels as fol
import fiftyone.core.utils as fou
logger = logging.getLogger(__name__)
def public_function(arg):
"""Public API function."""
return _helper(arg)
def _helper(arg):
"""Private helper (underscore prefix)."""
return arg
Import Organization
Four groups, alphabetized within each:
| Group | Example |
|---|---|
| 1. Standard library | import logging, import os |
| 2. Third-party | import numpy as np, from PIL import Image |
| 3. eta packages | import eta.core.utils as etau |
| 4. FiftyOne | import fiftyone.core.labels as fol |
FiftyOne Import Aliases
| Module | Alias |
|---|---|
fiftyone |
fo |
fiftyone.core.labels |
fol |
fiftyone.core.fields |
fof |
fiftyone.core.media |
fom |
fiftyone.core.storage |
fos |
fiftyone.core.utils |
fou |
fiftyone.utils.image |
foui |
fiftyone.utils.video |
fouv |
Docstrings (Google-Style)
Function Docstring
def get_operator(operator_uri, enabled=True):
"""Gets the operator with the given URI.
Args:
operator_uri: the operator URI
enabled (True): whether to include only enabled operators (True) or
only disabled operators (False) or all operators ("all")
Returns:
an :class:`fiftyone.operators.Operator`
Raises:
ValueError: if the operator is not found
"""
Class Docstring
class ImageMetadata(Metadata):
"""Class for storing metadata about image samples.
Args:
size_bytes (None): the size of the image on disk, in bytes
mime_type (None): the MIME type of the image
width (None): the width of the image, in pixels
height (None): the height of the image, in pixels
"""
Key patterns:
- Args with defaults:
param (default): description - Multi-line descriptions: indent continuation
- Cross-references:
:class:fiftyone.module.Class``
Private Functions
# Public API delegates to private helper
def build_for(cls, path_or_url, mime_type=None):
"""Builds a Metadata object for the given file."""
if path_or_url.startswith("http"):
return cls._build_for_url(path_or_url, mime_type=mime_type)
return cls._build_for_local(path_or_url, mime_type=mime_type)
# Private: underscore prefix, focused purpose
def _build_for_local(cls, filepath, mime_type=None):
"""Internal helper for local files."""
size_bytes = os.path.getsize(filepath)
if mime_type is None:
mime_type = etau.guess_mime_type(filepath)
return cls(size_bytes=size_bytes, mime_type=mime_type)
Lazy Imports
Use fou.lazy_import() for optional/heavy dependencies:
# Basic lazy import
o3d = fou.lazy_import("open3d", callback=lambda: fou.ensure_package("open3d"))
# With ensure_import for pycocotools
mask_utils = fou.lazy_import(
"pycocotools.mask", callback=lambda: fou.ensure_import("pycocotools")
)
# Internal module lazy import
fop = fou.lazy_import("fiftyone.core.plots.plotly")
When to use:
- Heavy packages (open3d, tensorflow, torch)
- Optional dependencies (pycocotools)
- Circular import prevention
Guard Patterns
Use hasattr() for conditional behavior:
# Check for optional attribute
if hasattr(label, "confidence"):
if label.confidence is None or label.confidence < threshold:
label = label.__class__()
# Check for config attribute
if hasattr(eval_info.config, "iscrowd"):
crowd_attr = eval_info.config.iscrowd
else:
crowd_attr = None
# Dynamic state initialization
if not hasattr(pb, "_next_idx"):
pb._next_idx = 0
pb._next_iters = []
Error Handling
Use logger.warning() for non-fatal errors:
# Non-fatal: warn and continue
try:
for target in fo.config.logging_debug_targets.split(","):
if logger_name := target.strip():
loggers.append(logging.getLogger(logger_name))
except Exception as e:
logger.warning(
"Failed to parse logging debug targets '%s': %s",
fo.config.logging_debug_targets,
e,
)
# Missing optional import
try:
import resource
except ImportError as e:
if warn_on_failure:
logger.warning(e)
return
# Graceful fallback
try:
mask = etai.render_instance_image(dobj.mask, dobj.bounding_box, frame_size)
except:
width, height = frame_size
mask = np.zeros((height, width), dtype=bool)
Avoid Redundant Implementations
Before writing new functions, check if FiftyOne already provides the functionality.
Common Utilities in fiftyone.core.utils (fou)
| Function | Purpose |
|---|---|
fou.lazy_import() |
Lazy module loading |
fou.ensure_package() |
Install missing package |
fou.ensure_import() |
Verify import available |
fou.extract_kwargs_for_class() |
Split kwargs for class |
fou.load_xml_as_dict() |
Parse XML to dict |
fou.get_default_executor() |
Get thread pool executor |
Common Utilities in eta.core.utils (etau)
| Function | Purpose |
|---|---|
etau.guess_mime_type() |
Detect file MIME type |
etau.is_str() |
Check if string |
etau.ensure_dir() |
Create directory if missing |
etau.ensure_basedir() |
Create parent directory |
etau.make_temp_dir() |
Create temp directory |
Before Writing New Code
-
Search existing modules for similar functionality:
grep -r "def your_function_name" fiftyone/ grep -r "similar_keyword" fiftyone/core/utils.py -
Check these modules first:
fiftyone.core.utils- General utilitiesfiftyone.core.storage- File/cloud operationsfiftyone.utils.*- Format-specific utilitieseta.core.utils- Low-level helpers
-
Red flags for redundancy:
- File path manipulation → check
os.pathoretau - JSON/dict operations → check
eta.core.serial - Image operations → check
fiftyone.utils.image - Type checking → check
etau.is_str(), etc.
- File path manipulation → check
Code Validation Checklist
Before submitting code, verify:
Style Compliance
- [ ] Module has copyright header docstring
- [ ] Imports in 4 groups (stdlib → third-party → eta → fiftyone)
- [ ] Imports alphabetized within groups
- [ ] FiftyOne imports use standard aliases (fol, fou, etc.)
- [ ] Logger defined as
logger = logging.getLogger(__name__) - [ ] Google-style docstrings with Args/Returns/Raises
- [ ] Private functions prefixed with
_
Code Quality
- [ ] No redundant implementations (checked existing utils)
- [ ] Heavy imports use
fou.lazy_import() - [ ] Optional attributes use
hasattr()guards - [ ] Non-fatal errors use
logger.warning() - [ ] No bare
except:(specify exception type when possible)
Testing
# Run linting
pylint fiftyone/your_module.py
# Check style
black --check fiftyone/your_module.py
# Run tests
pytest tests/unittests/your_test.py -v
Quick Reference
| Pattern | Convention |
|---|---|
| Module structure | Docstring → imports → logger → public → private → classes |
| Private functions | _prefix, module-level, small & focused |
| Docstrings | Google-style with Args/Returns/Raises |
| Error handling | try/except + logger.warning() for non-fatal |
| Lazy imports | fou.lazy_import() for optional deps |
| Guard patterns | hasattr() checks for conditional behavior |
| Import aliases | fol, fof, fom, fos, fou |
| Constants | UPPERCASE, private: _UPPERCASE |
| Class inheritance | Explicit class Foo(object): |
| Redundancy check | Search fou, etau, existing modules first |