Skriptens SDK
SDK:n api_managers åtta moduler — datakällor, HTTP, loggar, uppladdade filer, secrets, aviseringar, arbetsflöden och rapporter — med Python-exempel.
Inne i ett skript ligger hela appen inom räckhåll för ett import. SDK:n
heter api_manager och importeras modul för modul:
from api_manager import db, http, log, files, secrets, notify, workflow, reports
De här åtta namnen är hela SDK:ns publika yta — det som inte står här finns inte vid körning:
| Modul | Till vad |
|---|---|
db |
Fråga appens datakällor (Oracle, PostgreSQL, MySQL/MariaDB, SQL Server, …). |
http |
HTTP-anrop till externa tjänster, med automatisk JSON. |
log |
Skriva rader i körningens loggar. |
files |
Läsa filer som skickats via uppladdning i ett API. |
secrets |
Läsa appens hemligheter, dekrypterade på servern. |
notify |
Aviseringar i appen och e-post till appens användare. |
workflow |
Starta arbetsflöden, väcka väntande steg och avgöra mänskliga uppgifter. |
reports |
Skapa appens rapporter som PDF eller Excel. |
Editorn autokompletterar allt detta — namnen, parametrarna och dokumentationen för varje funktion dyker upp medan du skriver.
Dica
Knappen Prompt för LLM i editorns rad öppnar hela SDK-guiden, redo att kopiera med Kopiera allt. Klistra in den i Claude, ChatGPT eller någon annan assistent, tillsammans med vad du vill att skriptet ska göra — assistenten känner då till det exakta kontraktet och hittar inte på funktioner som inte finns.

db — appens datakällor
Datakällorna som konfigurerats i appen refereras med namn. Två funktioner:
from api_manager import db
crm = db("Dados CRM")
linhas = crm.query( # lista med dictar (kolumn -> värde)
"select id, nome from contas where cidade = ?", ["Lisboa"]
)
conta = crm.query_one( # första raden, eller None
"select * from contas where id = ?", [42]
)
params är en positionell lista. Platshållarna är motorns egna i
datakällan:
| Motor | Platshållare | Exempel |
|---|---|---|
| PostgreSQL | $1, $2, … |
where id = $1 |
| MySQL / MariaDB | ? |
where id = ? |
| Oracle | :1, :2, … |
where id = :1 |
Om datakällan inte finns kastar anropet ett fel (och körningen slutar med Fel, om du inte fångar det).
Atenção
Datum i Oracle: undvik att skicka dem som parameter — transporten i JSON
gör typen tvetydig. Föredra en literal i SQL:en:
TO_DATE('2026-06-25','YYYY-MM-DD').
http — anrop till externa tjänster
Fem verb, alla med automatisk JSON — en body som är dict eller lista skickas
som JSON, och ett JSON-svar kommer redan avkodat:
from api_manager import http, log
r = http.get("https://api.exemplo.com/clientes")
# r = {"status": int, "ok": bool, "body": <avkodad json eller text>}
if r["ok"]:
log("mottog", len(r["body"]), "kunder")
r = http.post(
"https://api.exemplo.com/leads",
body={"nome": "Vininha & Filhos", "origem": "keplin"},
headers={"Authorization": "Bearer abc123"},
)
Det finns också http.put(url, body, headers), http.patch(url, body, headers) och http.delete(url, headers). r["ok"] är sant för 2xx-svar —
en 404 eller 500 kastar inget undantag, kontrollera statusen själv.
log — körningens loggar
from api_manager import log
log("bearbetar", 42, {"fase": "inicial"})
Den tar emot flera argument, som print — och varje anrop blir en rad i
körningens loggar, synlig i panelen Körningens resultat och i historiken
Körningar. Klassisk print fångas också upp, men log är SDK:ns
kanoniska form.

files — uppladdade filer
När ett API i appen har ett argument av typen Upload skickar klienten en
fil och skriptet tar emot den i input["args"] som ett handle — byten
ligger på disk, inte i minnet. Modulen files arbetar mot det handtaget:
from api_manager import files
def main(input):
f = input["args"]["ficheiro"] # uppladdningens handtag
texto = files.read_text(f) # str (utf-8)
dados = files.read(f) # bytes
caminho = files.path(f) # absolut sökväg på disk
files.save(f, "ultimo-recebido.csv") # kopierar till skriptets mapp
return {"nome": f["filename"], "tamanho": f["size"]}
Handtaget innehåller filename, mimeType och size — bra för att validera
innan du bearbetar.
secrets — appens hemligheter
Tokens och nycklar sparas på appens sida Secrets (trädet i sidopanelen, gruppen App), krypterade. Skriptet läser dem med nyckeln:
from api_manager import secrets
token = secrets.get("STRIPE_KEY") # -> str | None
if token is None:
raise RuntimeError("Hemligheten STRIPE_KEY är inte konfigurerad i den här appen.")
Värdet dekrypteras på servern, i körningsögonblicket — det syns aldrig i webbläsaren och hamnar aldrig i koden.

Atenção
Gör inte log(token). Loggarna ligger kvar i körningshistoriken — en
hemlighet som skrivits i en logg är inte längre en hemlighet.
notify — aviseringar och e-post
Appen har två fasta kanaler — en i appen och en för e-post — som
aktiveras i appens inställningar för Aviseringar (det är där
SMTP-konfigurationen och avsändaren bor). users är användarnamn för
användare i appen; roles expanderar till alla medlemmar i rollen.
I appen, i realtid:
from api_manager import notify
r = notify.send(
"Rapporten är klar",
subtitle="Månadsrapporter",
body="Månadsrapporten finns tillgänglig.",
users=["joao"],
roles=None,
data={"url": "/relatorios/42"},
)
# r = {"recipients": int, "delivered": int}
delivered räknar dem som levererats i realtid, till dem som är uppkopplade;
de övriga ligger kvar i inkorgen och tar emot dem när de loggar in.
E-post:
r = notify.email(
"Lagervarning",
to=["chefe@empresa.pt"], # fria adresser
users=None,
roles=["admin"], # och/eller appens användare och roller
text="Lagret är under miniminivån.",
html=None,
)
# r = {"accepted": [e-postadresser], "skipped": [användarnamn utan e-post]}
SMTP-utskicket sker asynkront på servern — skriptet väntar inte.
attachments tar emot bilagor med innehållet i base64 (se reports nedan
för det typiska fallet).
workflow — appens arbetsflöden
Ett skript kan starta ett arbetsflöde, väcka den som väntar på en händelse,
och avgöra mänskliga uppgifter. Arbetsflödet refereras med namn (eller med
den stabila identifieraren); key är nyckeln till posten som det körs på:
from api_manager import workflow
r = workflow.start("Aprovação de despesa", 42, data={"valor": 1200})
# r = {"instanceId": int}
r = workflow.signal("visto", key=42)
# r = {"woken": int}
abertas = workflow.tasks("joao")
# öppna uppgifter för den appanvändaren, med de möjliga besluten
r = workflow.complete(task=17, outcome="aprovar", as_user="joao",
data={"nota": "ok"})
# r = {"ok": bool}
Regler som spelar roll:
workflow.startåtervänder så snart motorn når den första väntan — den väntar aldrig på att arbetsflödet ska bli klart.workflow.signalutankeyväcker alla arbetsflöden som stannat på den händelsen;{"woken": 0}är inget fel — det kanske inte finns någon som väntar.- I
workflow.completeäras_userobligatoriskt (den som beslutar hamnar i historiken) och uppgiften måste vara tilldelad den användaren. Värdena föroutcomeär uppgiftsnodens utgångar — samma som personen ser som knappar. Hitta inte på namn.
reports — skapa appens rapporter
Dokumentet skapas på servern, med appens data, utifrån en befintlig rapport:
from api_manager import notify, reports
r = reports.render("Facturas do mês", {"mes": "2026-03"})
# r = {"filename", "pages", "format", "mime", "bytes", "base64"}
notify.email(
"Fakturor för mars",
to=["financeiro@empresa.pt"],
text="Bifogat följer dokumentet.",
attachments=[{"filename": r["filename"], "content": r["base64"]}],
)
Det tredje, valfria argumentet är formatet: "pdf" (standard) eller
"xlsx". Parametrarna är de som rapporten deklarerar. I resultatet kommer
bytes redo att skrivas till disk och base64 redo att bifogas i ett
e-postmeddelande.
Ett komplett exempel
I stil med skriptet atualizar_indicadores i appen Kundhantering — det
läser pipelinen, skriver användbara loggar och varnar när avslut närmar sig:
from datetime import date, timedelta
from api_manager import db, log, notify
def main(input):
crm = db("Dados CRM")
abertas = crm.query_one(
"select count(*) as n, coalesce(sum(valor), 0) as total "
"from oportunidades where fase not in ('fechada_ganha', 'fechada_perdida')"
)
limite = (date.today() + timedelta(days=7)).isoformat()
fechos = crm.query(
"select titulo, data_fecho from oportunidades "
"where fase not in ('fechada_ganha', 'fechada_perdida') "
"and data_fecho <= ? order by data_fecho",
[limite],
)
log("pipeline:", abertas["n"], "affärsmöjligheter /", abertas["total"], "EUR")
if fechos:
notify.send(
"Avslut den här veckan",
body=f"{len(fechos)} affärsmöjligheter med planerat avslut till {limite}.",
roles=["comercial"],
)
return {
"oportunidades_abertas": abertas["n"],
"valor_pipeline": abertas["total"],
"fechos_proximos_7_dias": len(fechos),
}
Gränser och god praxis
- Resultatet från
mainmåste vara serialiserbart som JSON; max 32 MB. - Varje körning respekterar skriptets Tidsgräns (30 sekunder till 10 minuter) — överskrids den avslutas processen och körningen blir Timeout.
- Körningarna är isolerade: förlita dig inte på variabler från en tidigare körning. Spara varaktigt i filer i skriptets mapp eller i en datakälla.
- Gör
log(...)i varje relevant fas — det är det du kommer att läsa när något går fel kl. 07.00 en söndag. - Fånga de fel som går att hantera och registrera dem; låt de fatala stiga — ett ofångat undantag markerar körningen som Fel, och det är det du vill se i historiken när något verkligen är galet.
- Skriv aldrig ut hemligheter, och läs dem alltid från
secrets— lägg dem aldrig i koden.
Vanliga frågor
from api_manager import db misslyckas på min dator.
Det är väntat: modulen api_manager finns bara vid körning på
plattformen — det är där den injiceras. I editorn har du full
autokomplettering för SDK:n; filen api_manager.py som du ser i skriptets
mapp finns bara för det ändamålet.
db("nome") säger att datakällan inte finns.
Namnet måste vara exakt datakällans namn i appen (t.ex.: Dados CRM,
med versaler och mellanslag). Se listan i avsnittet Datakällor i trädet.
notify.email returnerade accepted men e-posten kom aldrig fram.
SMTP-utskicket är asynkront — accepted betyder att e-posten gick vidare
till appens e-postkanal. Kontrollera SMTP-konfigurationen i appens
inställningar för Aviseringar och mottagarens skräppost.
Kan jag använda SDK:n i ett fönsters validering?
Ja — valideringen körs i samma miljö som huvudskriptet, med samma input och
samma SDK. Se Scheman.