{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using LX-Syllabifier to syllabify all words in a text\n", "This is an example notebook that illustrates how you can use the LX-Syllabifier web service to\n", "analyse a text.\n", "\n", "**Before you run this example**, replace `access_key_goes_here` by your webservice access key, below:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "LXSLLABIFIER_WS_API_KEY = 'access_key_goes_here'\n", "LXSLLABIFIER_WS_API_URL = 'https://portulanclarin.net/workbench/lx-syllabifier/api/'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importing required Python modules\n", "The next cell will take care of installing the `requests` package,\n", "if not already installed, and make it available to use in this notebook." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "try:\n", " import requests\n", "except:\n", " !pip3 install requests\n", " import requests\n", "from IPython.display import HTML, display_html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Wrapping the complexities of the JSON-RPC API in a simple, easy to use function\n", "\n", "The `WSException` class defined below, will be used later to identify errors\n", "from the webservice." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class WSException(Exception):\n", " 'Webservice Exception'\n", " def __init__(self, errordata):\n", " \"errordata is a dict returned by the webservice with details about the error\"\n", " super().__init__(self)\n", " assert isinstance(errordata, dict)\n", " self.message = errordata[\"message\"]\n", " # see https://json-rpc.readthedocs.io/en/latest/exceptions.html for more info\n", " # about JSON-RPC error codes\n", " if -32099 <= errordata[\"code\"] <= -32000: # Server Error\n", " if errordata[\"data\"][\"type\"] == \"WebServiceException\":\n", " self.message += f\": {errordata['data']['message']}\"\n", " else:\n", " self.message += f\": {errordata['data']!r}\"\n", " def __str__(self):\n", " return self.message" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next function invoques the LX-Suite webservice through it's public JSON-RPC API." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def syllabify(text):\n", " '''\n", " Arguments\n", " text: a string with a maximum of 10000 characters, Portuguese text, with\n", " the input to be processed\n", "\n", " Returns a string or JSON object with the output according to specification in\n", " https://portulanclarin.net/workbench/lx-syllabifier/\n", " \n", " Raises a WSException if an error occurs.\n", " '''\n", "\n", " request_data = {\n", " 'method': 'syllabify',\n", " 'jsonrpc': '2.0',\n", " 'id': 0,\n", " 'params': {\n", " 'text': text,\n", " 'key': LXSLLABIFIER_WS_API_KEY,\n", " },\n", " }\n", " request = requests.post(LXSLLABIFIER_WS_API_URL, json=request_data)\n", " response_data = request.json()\n", " if \"error\" in response_data:\n", " raise WSException(response_data[\"error\"])\n", " else:\n", " return response_data[\"result\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next function will count the number of syllables in a given string (already processed by LX-Syllabifier):" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def count_syllables(s):\n", " # this is a naive tokenization based on whitespace, but in principle it poses no problem\n", " # because punctuation will be attached to the previous token and that will not change the\n", " # number of syllables\n", " return sum(len(token.split(\"|\")) for token in s.split(\" \"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are a few stanzas from Luís de Camões' work \"Os Lusíadas\" that we will use in our experiment:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "stanzas = [\"\"\"\n", "As armas e os barões assinalados,\n", "Que da ocidental praia Lusitana,\n", "Por mares nunca de antes navegados,\n", "Passaram ainda além da Taprobana,\n", "Em perigos e guerras esforçados,\n", "Mais do que prometia a força humana,\n", "E entre gente remota edificaram\n", "Novo Reino, que tanto sublimaram;\n", "\"\"\",\"\"\"\n", "E também as memórias gloriosas\n", "Daqueles Reis, que foram dilatando\n", "A Fé, o Império, e as terras viciosas\n", "De África e de Ásia andaram devastando;\n", "E aqueles, que por obras valerosas\n", "Se vão da lei da morte libertando;\n", "Cantando espalharei por toda parte,\n", "Se a tanto me ajudar o engenho e arte.\n", "\"\"\",\"\"\"\n", "Cessem do sábio Grego e do Troiano\n", "As navegações grandes que fizeram;\n", "Cale-se de Alexandro e de Trajano\n", "A fama das vitórias que tiveram;\n", "Que eu canto o peito ilustre Lusitano,\n", "A quem Neptuno e Marte obedeceram:\n", "Cesse tudo o que a Musa antígua canta,\n", "Que outro valor mais alto se alevanta.\n", "\"\"\",\"\"\"\n", "E vós, Tágides minhas, pois criado\n", "Tendes em mim um novo engenho ardente,\n", "Se sempre em verso humilde celebrado\n", "Foi de mim vosso rio alegremente,\n", "Dai-me agora um som alto e sublimado,\n", "Um estilo grandíloquo e corrente,\n", "Porque de vossas águas, Febo ordene\n", "Que não tenham inveja às de Hipoerene.\n", "\"\"\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we will use the functions we defined above for syllabifying an excerpt from Luís de Camões' work \"Os Lusíadas\", and to count the number of syllables in each line:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
12
As ar·mas e os ba·rões as·si·na·la·dos,
12
Que da o·ci·den·tal prai·a Lu·si·ta·na,
12
Por ma·res nun·ca de an·tes na·ve·ga·dos,
13
Pas·sa·ram a·in·da a·lém da Ta·pro·ba·na,
11
Em pe·ri·gos e guer·ras es·for·ça·dos,
13
Mais do que pro·me·ti·a a for·ça hu·ma·na,
13
E en·tre gen·te re·mo·ta e·di·fi·ca·ram
11
No·vo Rei·no, que tan·to su·bli·ma·ram;
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
12
E tam·bém as me·mó·ri·as glo·ri·o·sas
11
Da·que·les Reis, que fo·ram di·la·tan·do
15
A Fé, o Im·pé·ri·o, e as ter·ras vi·ci·o·sas
16
De Á·fri·ca e de Á·si·a an·da·ram de·vas·tan·do;
12
E a·que·les, que por o·bras va·le·ro·sas
11
Se vão da lei da mor·te li·ber·tan·do;
12
Can·tan·do es·pa·lha·rei por to·da par·te,
15
Se a tan·to me a·ju·dar o en·ge·nho e ar·te.
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
13
Ces·sem do sá·bi·o Gre·go e do Troi·a·no
11
As na·ve·ga·ções gran·des que fi·ze·ram;
13
Ca·le-·se de A·le·xan·dro e de Tra·ja·no
12
A fa·ma das vi·tó·ri·as que ti·ve·ram;
14
Que eu can·to o pei·to i·lus·tre Lu·si·ta·no,
13
A quem Nep·tu·no e Mar·te o·be·de·ce·ram:
15
Ces·se tu·do o que a Mu·sa an·tí·gu·a can·ta,
13
Que ou·tro va·lor mais al·to se a·le·van·ta.
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
11
E vós, Tá·gi·des mi·nhas, pois cri·a·do
13
Ten·des em mim um no·vo en·ge·nho ar·den·te,
13
Se sem·pre em ver·so hu·mil·de ce·le·bra·do
12
Foi de mim vos·so ri·o a·le·gre·men·te,
14
Dai-·me a·go·ra um som al·to e su·bli·ma·do,
12
Um es·ti·lo gran·dí·lo·quo e cor·ren·te,
12
Por·que de vos·sas á·guas, Fe·bo or·de·ne
14
Que não te·nham in·ve·ja às de Hi·po·e·re·ne.
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for stanza in stanzas:\n", " html = ['
']\n", " syllabified = syllabify(stanza)\n", " html.extend([\n", " f'
{count_syllables(verse)}
{verse.replace(\"|\", \"·\")}
'\n", " for verse in syllabified.strip().splitlines()\n", " ])\n", " html.append('
')\n", " display_html(HTML(\"\".join(html)))\n", "display_html(HTML(\"\"\"\"\"\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting the status of a webservice access key" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def get_key_status():\n", " '''Returns a string with the detailed status of the webservice access key'''\n", " \n", " request_data = {\n", " 'method': 'key_status',\n", " 'jsonrpc': '2.0',\n", " 'id': 0,\n", " 'params': {\n", " 'key': LXSLLABIFIER_WS_API_KEY,\n", " },\n", " }\n", " request = requests.post(LXSLLABIFIER_WS_API_URL, json=request_data)\n", " response_data = request.json()\n", " if \"error\" in response_data:\n", " raise WSException(response_data[\"error\"])\n", " else:\n", " return response_data[\"result\"]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'requests_remaining': 99999894,\n", " 'chars_remaining': 999946533,\n", " 'expiry': '2030-01-10T00:00+00:00'}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "get_key_status()" ] } ], "metadata": { "interpreter": { "hash": "006d5deb8e6cdcd4312641bdf15f3bc20f0769a7305d81173599a7b40f33b4a2" }, "kernelspec": { "display_name": "Python 3.7.7 64-bit", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7" } }, "nbformat": 4, "nbformat_minor": 2 }