Skip to main content

Official Python SDK for the PLCs.ai API — interpret PLC code from your own tools.

Project description

plcsai — Python SDK for the PLCs.ai API

Interpret PLC code from your own tools. Official Python client for the PLCs.ai API. Zero third-party dependencies.

Install

pip install plcsai

Requires Python 3.8+.

Quickstart

from plcsai import Client

client = Client(api_key="plck_live_…")  # or set PLCS_API_KEY

result = client.interpret(
    project_id="prj_…",
    prompt="Why is the filler at line 2 not advancing past Starting?",
)
print(result.answer)
print(result.citations)
print(result.request_id)  # quote this in a support request

Streaming

for event in client.interpret_stream(project_id="prj_…", prompt="…"):
    if event.type == "token":
        print(event.text, end="", flush=True)
    elif event.type == "done":
        print("\nusage:", event.usage)

Conversations, analyses, ingest, embed tokens

conv = client.create_conversation("prj_…", name="Line 2 stoppage")
client.send_message(conv.conversation_id, "And why now?")

job = client.start_analysis("prj_…")
done = client.wait_for_analysis(job.analysis_id)

client.ingest_project(file_path="Conveyor.L5X")

token = client.mint_embed_token("prj_…")  # read-only, for the iframe

Billing consent (enterprise per-project orgs)

If your org is billed per project, creating a new project over the API requires acknowledging the charge. Without it you get a 402 carrying the cost; disclose it, then retry with acknowledge_billing=True:

from plcsai import ApiError

try:
    client.ingest_project(file_path="NewLine.L5X")
except ApiError as e:
    if e.error == "billing_setup_required":
        print("Set up billing in the PLCs desktop app first.")
    elif e.error == "billing_acknowledgement_required":
        cents = e.billing["price_per_project_cents"]
        print(f"This adds a billable project (~${cents/100:.2f}). Confirming…")
        client.ingest_project(file_path="NewLine.L5X", acknowledge_billing=True)
    else:
        raise

This applies only to enterprise per-project orgs creating a new project — other org types and re-uploads/new versions are unaffected.

Projects: list, read source, live values

page = client.list_projects(limit=50)
for p in page.projects:
    print(p.project_id, p.name, p.vendor)

detail = client.get_project("prj_…")          # metadata + analysis_status

src = client.get_source("prj_…", format="scl")  # parsed | scl | ladder (needs code_read)
raw_bytes = client.download_source("prj_…")      # original L5X / ZIP bytes

values = client.get_hmi_values("prj_…")          # needs hmi_view; live=False when no DCA session
history = client.get_hmi_history("prj_…", tag="Motor1.Speed")

Exports (async): PLC file & PDF report

job = client.export_plc("prj_…")                 # or client.export_pdf(...)
done = client.wait_for_export(job.export_id)
artifact = client.download_export(done.export_id)  # L5X / ZIP / PDF bytes
open(done.filename, "wb").write(artifact)

Save a new version (code_write)

res = client.commit_version("prj_…", file_path="Conveyor_edited.L5X")
print(res.resolution, res.version_id)  # add_version, or identical_file (no-op)

Generate code (ai_generate — proposes, never deploys)

proposal = client.generate("prj_…", "Add a 5-second start-up delay timer.")
print(proposal.generated_code)
for block in proposal.code_blocks:
    print(block.language, block.content)
# To persist, commit the edited file via client.commit_version(...) (code_write).

What the client handles for you

  • Auth — sends Authorization: Bearer … on every request.
  • Idempotency — auto-generates a stable Idempotency-Key per write (reused across retries).
  • Retries — backs off and retries only on retryable errors, respecting Retry-After.
  • Streaming — parses SSE into typed StreamEvents.
  • request_id — surfaced on every result.

Errors

Non-2xx responses raise plcsai.ApiError with .status_code, .error, .user_message, .suggested_action, .is_retryable, and .request_id.

Development

pip install -e '.[dev]'
pytest

Releasing (maintainers)

plcsai is published to PyPI. Bump version in pyproject.toml, then:

python -m build
python -m twine upload dist/*

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plcsai-1.2.0.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plcsai-1.2.0-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file plcsai-1.2.0.tar.gz.

File metadata

  • Download URL: plcsai-1.2.0.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for plcsai-1.2.0.tar.gz
Algorithm Hash digest
SHA256 3cefd2d2570e9549844bf28cf63075da37a637ebc6802b861a11aed8e5bfe4ed
MD5 2949c9aed886a0769ee057f9990052db
BLAKE2b-256 c5a86903512f4c99120cc2ea37eb92dca8b4e231e75e86383e4c77f2950cbfb1

See more details on using hashes here.

File details

Details for the file plcsai-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: plcsai-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for plcsai-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ef09b9438d7392e2a28cae75dde4cbec680fa8f12f13dbcf17c12a5b89533a11
MD5 0d774dc707ef42d19eb101eaa29c66b2
BLAKE2b-256 10449d158b128eff76f314020b34535a59fdb39488c49543e484dfc2c62b1f71

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page