Skip to content

Commit

Permalink
Add intent server
Browse files Browse the repository at this point in the history
  • Loading branch information
synesthesiam committed Dec 3, 2024
1 parent b834da8 commit 147f8f5
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
74 changes: 74 additions & 0 deletions wyoming/http/conf/intent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
openapi: "3.0.0"
info:
title: 'Wyoming Intent'
version: '1.0.0'
description: 'API for Intent Recognition'
paths:
/api/info:
get:
summary: 'Get service information'
responses:
'200':
description: OK
content:
application/json:
schema:
/api/recognize-intent:
post:
summary: 'Recognize or handle intent'
requestBody:
description: 'Text to process'
required: true
content:
text/plain:
schema:
type: string
parameters:
- in: query
name: language
description: 'Language of text'
schema:
type: string
- in: query
name: uri
description: 'URI of Wyoming intent service'
schema:
type: string
responses:
'200':
description: OK
content:
text/plain:
schema:
type: string
application/json:
schema:
get:
summary: 'Recognize or handle intent'
parameters:
- in: query
name: text
description: 'Text to process'
required: true
schema:
type: string
- in: query
name: language
description: 'Language of text'
schema:
type: string
- in: query
name: uri
description: 'URI of Wyoming intent service'
schema:
type: string
responses:
'200':
description: OK
content:
text/plain:
schema:
type: string
application/json:
schema:
91 changes: 91 additions & 0 deletions wyoming/http/intent_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""HTTP server for intent recognition/handling."""

import io
import logging
import wave
from pathlib import Path
from typing import Any, Dict, Optional

from flask import Response, request

from wyoming.asr import Transcript
from wyoming.client import AsyncClient
from wyoming.error import Error
from wyoming.intent import Intent, NotRecognized
from wyoming.handle import Handled, NotHandled

from .shared import get_app, get_argument_parser

_DIR = Path(__file__).parent
CONF_PATH = _DIR / "conf" / "intent.yaml"


def main():
parser = get_argument_parser()
parser.add_argument("--language", help="Language for text")
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)

app = get_app("intent", CONF_PATH, args)

@app.route("/api/recognize-intent", methods=["POST", "GET"])
async def api_stt() -> Response:
uri = request.args.get("uri", args.uri)
if not uri:
raise ValueError("URI is required")

if request.method == "POST":
text = request.data.decode()
else:
text = request.args.get("text", "")

if not text:
raise ValueError("Text is required")

language = request.args.get("language", args.language)

async with AsyncClient.from_uri(uri) as client:
await client.write_event(Transcript(text=text, language=language).event())

while True:
event = await client.read_event()
if event is None:
raise RuntimeError("Client disconnected")

success = False
type_name = "unknown"
result: Dict[str, Any] = {}

if Intent.is_type(event.type):
success = True
type_name = "intent"
intent = Intent.from_event(event)
result = intent.to_dict()
elif Handled.is_type(event.type):
success = True
type_name = "handled"
handled = Handled.from_event(event)
result = handled.to_dict()
elif NotRecognized.is_type(event.type):
success = False
type_name = "not-recognized"
not_recognized = NotRecognized.from_event(event)
result = not_recognized.to_dict()
elif NotHandled.is_type(event.type):
success = False
type_name = "not-handled"
not_handled = NotHandled.from_event(event)
result = not_handled.to_dict()
elif Error.is_type(event.type):
error = Error.from_event(event)
raise RuntimeError(
f"Unexpected error from client: code={error.code}, text={error.text}"
)

return {"success": success, "type": type_name, "result": result}

app.run(args.host, args.port)


if __name__ == "__main__":
main()

0 comments on commit 147f8f5

Please sign in to comment.