45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
import asyncio
|
|
|
|
try:
|
|
import httpx
|
|
except ImportError:
|
|
raise ImportError("Please install httpx with 'pip install httpx' ")
|
|
|
|
from rich.json import JSON
|
|
|
|
from textual.app import App, ComposeResult
|
|
from textual.containers import VerticalScroll
|
|
from textual.widgets import Input, Static
|
|
|
|
|
|
class DictionaryApp(App):
|
|
"""Searches a dictionary API as-you-type."""
|
|
|
|
CSS_PATH = "dictionary.css"
|
|
|
|
def compose(self) -> ComposeResult:
|
|
yield Input(placeholder="Search for a word")
|
|
yield VerticalScroll(Static(id="results"), id="results-container")
|
|
|
|
async def on_input_changed(self, message: Input.Changed) -> None:
|
|
"""A coroutine to handle a text changed message."""
|
|
if message.value:
|
|
# Look up the word in the background
|
|
asyncio.create_task(self.lookup_word(message.value))
|
|
else:
|
|
# Clear the results
|
|
self.query_one("#results", Static).update()
|
|
|
|
async def lookup_word(self, word: str) -> None:
|
|
"""Looks up a word."""
|
|
url = f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}"
|
|
async with httpx.AsyncClient() as client:
|
|
results = (await client.get(url)).text
|
|
|
|
if word == self.query_one(Input).value:
|
|
self.query_one("#results", Static).update(JSON(results))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app = DictionaryApp()
|
|
app.run()
|