Forritaskil (API) á Málstað

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.

Hvernig fæst aðgangur að forritaskilum?

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.

Hvað kosta forritaskilin?

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.

Dæmi um notkun á forritaskilum

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):

python
import httpx

API_KEY = "YOUR_API_KEY"
BASE = "https://api.malstadur.is/v1"
HEADERS = {"X-API-KEY": API_KEY, "Content-Type": "application/json"}

Yfirlestur (Málfríður)

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:

python
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 (Hreimur)

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:

python
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),
  },
)
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 again

Þýðingar (Erlendur)

Fyrir þýðingar er hægt að nota þrenns konar endapunkta til að senda inn verkefni:

  • /translate — fyrir minni textabúta þar sem biðlari bíður eftir svari (samstillt kall, sjá dæmi að neðan).

  • /translate/text — fyrir lengri texta, virkar á svipaðan hátt og talgreining þar sem verkefni er sett af stað og niðurstaða sótt í aðskildu kalli með /translate/text/{id}.

  • /translate/segments — fyrir þýðingu á tímasettum hlutum (t.d. beint frá talgreiningu). Tekur inn sömu hluti og talgreiningin skilar og skilar þýddum hlutum með tímamerkingum. Niðurstaða er sótt með /translate/segments.

Loks birtir /translate/tasks öll þýðingarverkefni (bæði texta og hluta) og styður síun eftir stöðu (status) og gerð (type). Allir endapunktar styðja orðalista og einnig er hægt að sækja orðalista sem tilheyra hópi á Málstað.

Fyrir þýð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/text/{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ð.

Dæmi um einfalda þýðingu á texta:

python
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']}")

Dæmi um þýðingu á talgreiningarúttaki (t.d. fyrir skjátexta):

python

# (segments koma beint úr svari frá /asr/tasks/{id})
resp = httpx.post(
    f"{BASE}/translate/segments",
    headers=HEADERS,
    json={"segments": asr_result["result"], "targetLanguage": "en"},
)
resp.raise_for_status()
task_id = resp.json()["taskId"]

while True:
    status = httpx.get(f"{BASE}/translate/segments/{task_id}", headers=HEADERS).json()
    if status["status"] == "completed":
        for seg in status["result"]["segments"]:
            print(f"  {seg['start']:6.1f}s - {seg['end']:6.1f}s : {seg['text']}")
        break
    elif status["status"] == "failed":
        print(f"Error: {status.get('error')}")
        break
    time.sleep(3)

Næstu skref

Á 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 [email protected] eða [email protected] ef spurningar vakna varðandi forritaskil.

Skráðu þig á póstlistann okkar!

Efnisorð:
Deildu þessari grein: