mcpField
F
fcode-python

fcode-python

github.com/factorialco開発1399 回インストール今日更新
リポジトリ

fcode-python について

fcode-pythonは、Factorial Code上でPython 3.13のプロセスを書くためのガイドです。プラットフォームのAPIや実行時の注意点を、開発者向けにまとめています。

主な機能

  1. 01Python 3.13のプロセス規約
  2. 02Factorial CodeのコンテキストとモジュールAPI
  3. 03データストアと秘密情報の扱い
  4. 04ログとエラー処理の実践
  5. 05パッケージ、メール、戻り値

活用シーン

  1. 01Factorial CodeのPythonプロセスの作成
  2. 02構造化データや認証情報の保存
  3. 03共有ログを使った障害調査
  4. 04プロセスからのメール送信

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/factorialco/factorial-code-skills --skill fcode-python

インストール後、Claude Code で/fcode-pythonを入力して読み込まれたか確認します。

詳細

Factorial Code — Python

Factorial Code で実行される Python の記述ガイドラインです。ランタイムは Python 3.13 です。プラットフォームのモデル(プロセス、モジュール、データストア)については、 fcode-core-concepts を参照してください。

項目ガイドライン
ランタイムPython 3.13
プロセスのエントリーファイルmain.py
エントリーポイントdef main()
パラメーターfcode.context.parameters
変数os.getenv("X") または fcode.env.X
モジュールのインポートfcode.import_module("module-slug")

注意点

  • エントリーポイントとして main() を定義します。ただし、自分で呼び出してはいけません — Factorial Code が呼び出します。
  • fcode.import_module() の名前はハードコードされた文字列リテラルでなければなりません。変数は使えません。fcode.import_module("shopify-client") ✅、 fcode.import_module(name) ❌。
  • fcode.i18n に別名を付けてはいけません — そのまま呼び出してください(fcode.i18n("key") ✅、 t = fcode.i18n ❌)。別名を付けた呼び出しは実行時に「i18n is disabled」をスローします。 fcode-i18n を参照してください。
  • データストアに保存できるのは文字列と数値のみです — set の前にオブジェクトを json.dumps で変換し、get の後に json.loads で復元してください。
  • データストアに保存するシークレットは暗号化してください — set の第3引数に True を渡します(fcode.datastore.set(key, token, True))。get では透過的に復号されます。 通常の set では値が平文で保存されます。
  • camelCase ではなく snake_case を使用し、PEP 8 に従ってください。役立つ場合は型ヒントを追加してください。
  • メインの処理フローを try/except で囲み、捕捉したエラーを fcode-logs を通じてコンテキストとともにログに記録し(「ログ」を参照)、対処可能なエラーを発生させてください。状態の保持にグローバル変数を使わず、パラメーターまたは戻り値で受け渡してください。
  • シークレットをハードコードしたり、ログに記録したりしてはいけません — os.getenv から読み取ってください。

プロセステンプレート

def main():
    parameters = fcode.context.parameters

    # Your code here

    return { "message": "Success!" }

ヘルパー

import os

# Execution / process / schedule metadata
execution_id = fcode.execution.id
process_id = fcode.execution.process.id
schedule_id = fcode.execution.schedule.id   # when run from a schedule
timezone = fcode.execution.timezone

# Workspace (team) metadata
team_slug = fcode.team.slug

# Environment variables (secrets/config)
api_key = os.getenv("API_KEY")  # or fcode.env.API_KEY

# Import a Factorial Code module (hardcoded name only)
client = fcode.import_module("module-name")
client_v1 = fcode.import_module("module-name", "v1.0.0")  # pinned version tag or alias

# Run another process
fcode.processes.run("process-identifier", options)

# Translations (workspace locales — see fcode-i18n)
greeting = fcode.i18n("greetings.hello", {"name": "Ada"})  # %{name} filled in
fcode.i18n("greetings.hello", {"name": "Ada"}, {"locale": "es"})  # another locale, this lookup only (value may be dynamic)
locale = fcode.i18n.locale  # the execution's locale

ログ

共有 fcode-logs モジュールを通じてログを記録してください — レベルに応じて制御されるログ機能は、すべてのワークスペースに継承されます。チーム変数 LOG_LEVEL (debug | info | warn | error、デフォルトは info)を読み取り、print に転送します(debug/info は stdout、 warn/error は stderr)。そのため、呼び出し箇所は通常の print のように記述できます。

log = fcode.import_module("fcode-logs")  # import once; reuse `log` everywhere, including `except`

log.info("sync started", process_slug)  # stdout when LOG_LEVEL ≤ info
log.debug(request_payload)               # stdout only when LOG_LEVEL=debug
log.warn("token missing — skipping")      # stderr when LOG_LEVEL ≤ warn
log.error("sync failed", str(err))         # stderr — always emitted

詳細にログを記録してください — ログのポリシー(開始/終了、外部呼び出しと判断を info で、ペイロードを debug で記録すること、再送出前にコンテキストとともに except 内で必ずログを記録すること)は、 fcode-core-concepts の §General rules に記載されています。ローカルまたは開発用ワークスペースで LOG_LEVEL=debug を設定すると、実行全体を追跡できます。本番環境では info のままにしてください。 シークレットをログに記録してはいけません。各実行で保持されるログは最大 500 行/500 KB で、それ以降のエントリーは破棄されます(fcode-core-concepts › Plans & limits)。

依存関係

外部 pip パッケージは自動的にインストールされます — import するだけで使えます。 パッケージ名とインポート名が異なる場合は、@add-package で宣言してください。

# @add-package requests
import requests

親ワークスペースが提供するパッケージは、ここでもすでにインストールされています — 再宣言しないでください(fcode-core-concepts を参照)。

データストアとストレージ

import json, os

# Datastore (strings/numbers only)
fcode.datastore.set("key", "value")
fcode.datastore.set("key", json.dumps({ "name": "John", "age": 30 }))
value = fcode.datastore.get("key")
fcode.datastore.delete("key")
# Encrypted at rest with a key owned by the workspace — for tokens, credentials,
# personal data. The third argument must be a bool; get() is transparent.
# Keys (entry names) are never encrypted.
fcode.datastore.set("oauth.token", access_token, True)
token = fcode.datastore.get("oauth.token")

# Storage (files)
local_path = os.path.join(os.environ.get("TMP_DATA_DIR"), "localfile.txt")

with open(local_path, "rb") as f:
    obj = fcode.storage.upload("path/myfile.txt", f)

objects = fcode.storage.list()

content = fcode.storage.download("path/myfile.txt")
with open(local_path, "wb") as f:
    f.write(content)

# Form file params arrive as "fcode.storage://…" references — strip the
# prefix before download; see fcode-forms.

# Signed download URL — { "url", "expiresAt" }. A real HTTPS link in the
# cloud, a file:// URL locally (same shape, no special-casing).
signed = fcode.storage.create_signed_url("path/myfile.txt")

fcode.storage.delete("path/myfile.txt")

ローカルディスク: 一時ファイルは os.environ.get("TMP_DATA_DIR") の下に書き込んでください。

変数、スケジュール、OAuth

チーム変数の読み書きやプロセスのスケジュール管理は実行時に行えます — 自分のチームに限定され、API トークンは不要です(データストア/ストレージと同様)。

# Team variables (config/secrets)
# Default is SENSITIVE: fcode.variables.set(key, value) creates a sensitive
# (masked, immutable-sensitivity) variable. Pass sensitive=False for plain
# config values.
fcode.variables.set("API_KEY", "secret")  # sensitive by default
fcode.variables.set("BASE_URL", "https://api.acme.com", sensitive=False)  # required for non-secret config
v = fcode.variables.get("API_KEY")  # TeamVariable (has resolving_team_slug) or None
all_vars = fcode.variables.list()   # includes variables inherited from parents
fcode.variables.delete("API_KEY")   # no-op on an inherited variable

# Schedules (cron or one-off date_time) for a process
schedule = fcode.schedule.create(
    "my-process",
    cron="0 0 6 * * SUN",  # or: date_time="2026-04-24T12:30:00.000"
    parameters={"foo": "bar"},
    allow_concurrent_executions=False,  # optional
)
schedules = fcode.schedule.list(process_id=fcode.execution.process.id)
current = fcode.schedule.get(schedule["id"])
fcode.schedule.update(schedule["id"], cron="0 0 7 * * SUN")
fcode.schedule.pause(schedule["id"])
fcode.schedule.resume(schedule["id"])
fcode.schedule.delete(schedule["id"])
# delete every schedule for a process (pass the process UUID)
fcode.schedule.delete_for_process(fcode.execution.process.id)

# Start a third-party OAuth authorization. The platform holds the state, the PKCE
# verifier and the one redirect_uri registered with the provider, and invokes
# `on_complete` when the provider redirects back -- so never build an authorization
# URL or a state by hand, and never expose a callback webhook.
flow = fcode.oauth.start(
    authorize_url="https://login.example.com/authorize",
    client_id=fcode.env.PROVIDER_CLIENT_ID,
    scope=["openid", "offline_access"],
    on_complete="oauth-callback",      # the process that receives the code
    data={"companyId": company_id},    # carried back untouched; never a secret
    extra_params={"nonce": nonce},     # optional, provider-specific
    pkce=True,                         # default
)
flow.authorization_url  # hand this to the form's oauth widget

on_complete は、fcode.context.parameters 内の code、codeVerifier、redirectUri、data、state とともに呼び出されます(プロバイダーが拒否した場合は error/errorDescription が渡されます)。 トークン交換時には redirectUri をそのまま使用してください — プロバイダーはバイト単位で比較します。fcode-examples の references/oauth-connect.md を参照してください。

fcode.variables.set/delete の変更はサーバー側にのみ保存されます。同じ実行中の fcode.env には反映されません(fcode.env は実行開始時に取得されたスナップショットです)。

継承された変数

list()/get()には、親ワークスペースから継承された変数も含まれます(モデルについては fcode-core-conceptsを参照)。継承された変数には、所有者を示す resolving_team_slugが付与されています。継承されたキーに対するset()は、この ワークスペースに上書き値を作成します。ここから値を変更する唯一の方法です。一方、 そのキーに対するdelete()は何もせずに終了するため、アンインストール処理で親の 認証情報が削除されることはありません(実際に何を削除したかを報告する必要がある場合は、 resolving_team_slugを確認してください)。fcode.env.set_env_var/del_env_varも 同じように動作します。

メールの送信

組み込みのfcode.send_mailを使ってメールを送信できます。SMTPの設定は不要です(モデルについては fcode-core-conceptsを参照)。

info = fcode.send_mail(
    to="[email protected]",   # string or list[str]
    subject="Report ready",
    text="Plain-text body",  # provide text, html, or both
    html="<b>HTML body</b>",
)
# info => { "messageId", "accepted", "rejected" }
  • Fromアドレスはプラットフォームによって固定されています。指定したfromは無視されます。
  • 各実行で送信できるメールは、デフォルトで最大3通です。上限に達すると、それ以降の呼び出しはエラーになります。
  • ローカルで実行する場合(fcode run)、マネージャーがないため、メールは送信されずログに記録されます。
  • 許容される用途(受信者にできる人、本文に含められる内容など)はプラットフォームのルールで定められており、違反するとリリースがブロックされます。fcode-core-conceptsの「メールの送信」を参照してください。

戻り値

# Standard
return { "message": "Success!" }

# Custom HTTP status (webhooks)
return { "status": 404, "body": { "message": "Not found" }, "headers": { "Content-Type": "application/json" } }

# Transient (not persisted in execution results)
return { "transient": True, "data": sensitive_data }

# Synchronous UI trigger button inside Factorial (see fcode-ui-triggers).
# Returned unchanged to the page; signal a failure with an error, not in the body.
return { "synced": 42 }

戻り値の上限は500 KBです。これを超える結果では実行が失敗します。データはストレージに保存し、 参照を返してください(fcode-core-concepts › プランと制限)。

コメント