Vöruvirkni Málstaðar er núna aðgengileg í gegnum forritaskil (API) á https://api.malstadur.is. Þar er m.a. hægt að nálgast yfirlestur, talgreiningu og þýðingar en síðar mun einnig bætast við aukin virkni líkt og einfalt mál, samantekt og fleira.
Til að fá aðgang að forritaskilum þarf fyrst að stofna til frjálsrar áskriftar. Þá geta eigendur og stjórnendur áskriftar nálgast síðu um forritaskil í notendavalmyndinni niðri til vinstri:
Þar er hægt að búa til API lykla með tilgreindum réttindum og gildistíma, ásamt því að fylgjast með notkun og kostnaði. Þær þjónustur sem lyklar tengjast við eru:
Yfirlestur (/v1/grammar): Sami yfirlestur og er í boði í Málfríði.
Talgreining (/v1/asr): Sama talgreining og er í boði í Hreimi.
Þýðingar (/v1/translate): Sama þýðingarvirkni og er í boði í Erlendi.
Textavinnsla: Í augnablikinu eru engir endapunktar fyrir textavinnslu virkir en hér munu m.a. bætast við endapunktar fyrir samantekt og einfalt mál.
Almennur aðgangur að forritaskilum kostar ekkert umfram almennt gjald að frjálsri áskrift, en notkun fylgir eftirfarandi gjöldum:
1 kr. / 100 stafabil fyrir yfirlestur, þýðingar og textavinnslu.
2.000 kr. / klst. fyrir talgreiningu.
Inneign sem fylgir frjálsri áskrift nýtist einungis í notkun á vefnum en ekki á forritaskilum.
Ef þörf er á greiðari aðgangi að forritaskilum, t.d. fyrir formlegan rekstur á vöru með minni takmörkun á fjölda beiðna hverju sinni (rate limit), þá er hægt að útvega það með sértækum þjónustusamningi.
Hér að neðan eru einföld dæmi um notkun á helstu endapunktum í Python, en þau fylgja öll eftir eftirfarandi uppsetningu (með þeirri forsendu að httpx sé uppsett í umhverfi):
import httpx
API_KEY = "YOUR_API_KEY"
BASE = "https://api.malstadur.is/v1"
HEADERS = {"X-API-KEY": API_KEY, "Content-Type": "application/json"}Hægt er að senda inn marga texta í einu, t.d. mismunandi málsgreinar, og fá leiðrétta útgáfu af hverjum og einum ásamt merkingum á þeim breytingum sem gerðar eru:
texts = [
"Ég fór í búðina og keypti mér eina mjólk.",
"Hún sagðist vera komin heim alla dagana."
]
resp = httpx.post(f"{BASE}/grammar", headers=HEADERS, json={"texts": texts})
resp.raise_for_status()
data = resp.json()
for i, result in enumerate(data["results"]):
print(f"Original text: {result['originalText']}")
print(f"Corrected text: {result['changedText']}")
if result["diffAnnotations"]:
for ann in result["diffAnnotations"]:
print(f"[{ann['changeType']}] \"{ann['origString']}\" -> \"{ann['changedString']}\"")
else:
print("No corrections")Talgreining tekur inn vefslóð (URL) sem vísar á upptöku til að talgreina. Ef unnið er með upptöku sem hefur enga vefslóð þarf fyrst að hlaða henni upp á tímabundið geymslusvæði þaðan sem henni verður sjálfvirkt eytt eftir sólarhring:
from pathlib import Path
import time
# 1. Get path and content type of media file
path = Path("YOUR_MEDIA_FILE_PATH")
ext_to_mime = {
".mp3": "audio/mpeg",
".wav": "audio/wav",
".m4a": "audio/mp4",
".ogg": "audio/ogg",
".flac": "audio/flac",
".mp4": "video/mp4",
".webm": "video/webm",
}
content_type = ext_to_mime.get(path.suffix.lower(), "audio/mpeg")
file_size = path.stat().st_size
# 2. Get presigned upload URL
presign = httpx.post(
f"{BASE}/uploads/presign",
headers=HEADERS,
json={"content_type": content_type, "file_size": file_size}
)
presign.raise_for_status()
presign_data = presign.json()
# 3: Upload file directly to storage
upload = httpx.put(
presign_data["uploadUrl"],
data=path.read_bytes(),
headers={
"Content-Type": content_type,
"Content-Length": str(file_size),
"x-amz-acl": "public-read",
},
)
upload.raise_for_status()
# 4: Create transcription task
task = httpx.post(
f"{BASE}/asr/tasks",
headers=HEADERS,
json={"url": presign_data["objectUrl"], "input_language": "is"},
)
task.raise_for_status()
task_data = task.json()
task_id = task_data["taskId"]
# 5: Poll until completion
while True:
status_resp = httpx.get(f"{BASE}/asr/tasks/{task_id}", headers=HEADERS)
status_resp.raise_for_status()
status = status_resp.json()
if status["status"] == "completed":
for seg in status["result"]:
print(f" {seg['start']:6.1f}s - {seg['end']:6.1f}s : {seg['text']}")
break
elif status["status"] == "failed":
print(f"\nError: task failed: {status.get('error', 'unknown')}")
break
else:
print(f"Task status: {status['status']} (progress: {status['progress']*100:.1f}%)")
time.sleep(5) # Wait 5 seconds before polling againFyrir þýðingar er hægt að nota tvenns konar endapunkta, annars vegar /translate sem er ætlaður fyrir minni textabúta þar sem biðlari einfaldlega bíður eftir svari (sjá dæmi að neðan), og hins vegar /translate/tasks/{id} sem virkar á svipaðan hátt og talgreining þar sem eitt eða fleiri verkefni eru sett af stað og niðurstaða svo sótt í aðskildu kalli. Báðir endapunktar styðja einnig að taka inn orðalista en einnig er hægt að sækja orðalista sem tilheyra hóp á Málstað.
text = "The weather in Reykjavik is beautiful today, although a bit cold."
resp = httpx.post(f"{BASE}/translate", headers=HEADERS, json={"text": text, "targetLanguage": "is"})
resp.raise_for_status()
data = resp.json()
print(f"Translation: {data['text']}")Á næstunni munum við svo bæta við forritaskilum fyrir m.a. samantekt og einfaldað mál. Einnig erum við að vinna að nýrri virkni sem snýr að ljóslestri og læsileikamati sem mun líta dagsins ljós á næstu mánuðum á bæði vef og í forritaskilum.
Endilega hafið samband í gegnum api@mideind.is eða malstadur@mideind.is ef spurningar vakna varðandi forritaskil.