Mobile applications have become an integral part of the way we work.
Today, we are going to create an Android mobile app for WordsAPI.
This will be a powerful app that will cover the chosen API and extend it with some additional NLP features.
As the main project instrument, we will use Python.
We also have the opportunity of working with a cross-platform UI framework for this language, called Kivy.
In the final result, our application will process word requests and propose semantic analysis for texts.
Let’s establish how interactions with WordsAPI work. This interface can be used in various ways for “digging” for words. Here are a few example scenarios:
RapidAPI is a powerful API hub, which consists of more than 10,000 accessible APIs. Not only are they available for your personal use but you also have the opportunity of adding new ones, making you a part of the team of 1,000,000+ responsive developer community.
Voila! You now have access to the WordsAPI. You can find your API Key under “X-RapidAPI-Key.”
Our main task is the implementation of such API inside of mobile applications.
We will give a brief explanation of the endpoints structure.
There are two groups of endpoints: words and related words.
The former is about basic word properties. Here you can find the frequency of the word, or even try to get rhymes for it. You can try and test some endpoints for this group, which can be done with the RapidAPI console.
A latter group dedicated to the related words’ features. There is a lot of useful information about the word popularity region, similarity, etc. Take a look at the example:
The result of this request returns all semantic objects, which include the transmitted word. In the displayed case you will see that ‘finger’ is a part of ‘hand’, ‘glove’ and a few more.
Python is a very popular and powerful language. However, there is a stereotype that it is good only for scripting tasks. So today we will try to debunk the false idea and create a fully working visual application.
First of all, let’s install all the important libraries. It is quite obvious that your machine should have Python. But we also need to create a virtual environment. It will separate project data from your PC storage. Then, we need to install three required system modules:
Now let’s talk about the application.
In the world of poem-writing, even the most talented poets have problems with rhymes.
Our application will solve this problem.
It is easy to understand that all ‘dirty’ jobs will be done via WordsAPI, but we won’t just return all suggested rhymes for the word.
The app will be able to send the desired word and return some rhymes for it.
And the final feature is a poem process. As an example of NLP problems, we will take a look at the sentiment analysis.
Sentiment analysis is a way to understand how positive or negative your text is. This is a really important aspect of marketing.
Big companies can analyze all reviews by the ML model for improving it. Usually, it’s a time-wasting process, which includes many stages, but we will use the TextBlob pre-trained model.
TextBlob was trained on movie reviews and can be very helpful in our case.
But let’s start with the design creating. Kivy supports the natural user interface (NUI), which is a portable version for a graphical one.
If you completed all the steps in the installation process, you should be able to run the virtual environment and create your first Python file. Let’s call it main.py.
Here is where we will do all backend processes in the future, but right now, we can start from the standard ‘Hello world!’ application.
Paste the following lines:
import kivy kivy.require('1.0.6') # replace with your current kivy version ! from kivy.app import App from kivy.uix.label import Label class MyApp(App): def build(self): return Label(text='Hello world') if __name__ == '__main__': MyApp().run()
If you are familiar with Python, this code shouldn’t be difficult at all.
Here, we import the App object, which will be a base for a custom application class.
Also, we add a label with a world-famous greeting.
Run this file and you should see next output:
By default, we can add new graphical elements directly from the Python file, but it can be very risky for project structure. That’s why Kivy proposes a custom markup language Kv.
It allows you to distinguish your layouts and visualization for functionality. The principle of this language is very simple as it consists of a nested elements description.
As you can see, there are two buttons:
Further down you’ll find a text input field for poem lyrics.
If you click on the left button, our app will return results for polarity (indicate how positive the text is from -1 to +1) and subjectivity (how much the text represents personal opinion or judgment opposed to factual information).
And when the user highlights an exact word and clicks on the button to the right, it will redirect him/her to the second screen with rhymes.
Each rhyme will be represented in the scrolling text area with some primary explanation.
Here, users can choose one of them and the list of rhymes will drop down from the right side.
If rhymes aren’t good enough, the user can just return back.
Chosen rhymes (if any) will be added to the current text on the main screen.
So once we’ve built a rough markup, we can implement the real one. Create a file main.kv and paste the next snippet:
#:kivy 1.11.1 <MainScreen>: BoxLayout: orientation: 'vertical' padding: 25 spacing: 10 BoxLayout: size_hint: 1, 0.15 orientation: 'horizontal' spacing: 10 Button: text: 'Sentiment analysis' Button: text: 'Get rhymes' ScrollView: id: scrlv size_hint: 1, 0.65 TextInput: id: poem_text text: 'Cellar door' size_hint: 1, None height: max(self.minimum_height, scrlv.height)
This all about the previously demonstrated markup.
Here we will create two segments for the screen.
Now we need to connect this markup with our Python file.
Open main.py and modify it:
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition # Create both screens. Please note the root.manager.current: this is how # you can control the ScreenManager from kv. Each screen has by default a # property manager that gives you the instance of the ScreenManager used. class MainScreen(Screen): pass sm = ScreenManager(transition=SwapTransition()) class MainApp(App): def build(self): sm.add_widget(MainScreen(name='main')) sm.current = 'main' return sm if __name__ == '__main__': MainApp().run()
The most important change – adding ScreenManager.
This object has to control all existing frames. As we will have 2 screens, it will help with navigation and data sending. Also, we will create an empty (for now) MainScreen class, where we will work with events a little later on.
Keep in mind that our app class still has the MainApp title. It is important because Kivy will look for the name-without-App.kv as a markup description. Now run the program..
#:kivy 1.11.1 <MainScreen>: BoxLayout: orientation: 'vertical' padding: 25 spacing: 10 BoxLayout: size_hint: 1, 0.15 orientation: 'horizontal' spacing: 10 Button: text: 'Sentiment analysis' Button: text: 'Get rhymes' on_press: root.manager.current = 'rhymes' ScrollView: id: scrlv size_hint: 1, 0.65 TextInput: id: poem_text text: 'Ginger Pinger' size_hint: 1, None height: max(self.minimum_height, scrlv.height) <RhymesScreen>: BoxLayout: orientation: 'vertical' padding: 25 spacing: 10 ScrollView: id: scrlv size_hint: 1, 0.65 TextInput: id: rhymes_text text: '' size_hint: 1, None height: max(self.minimum_height, scrlv.height) BoxLayout: size_hint: 1, 0.15 orientation: 'horizontal' spacing: 10 Button: text: 'Back' on_release: root.manager.current = 'main' Button: text: 'Choose one'
Here we have two important modifications:
Now we can include our second screen using the main.py file.
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition # Create both screens. Please note the root.manager.current: this is how # you can control the ScreenManager from kv. Each screen has by default a # property manager that gives you the instance of the ScreenManager used. class MainScreen(Screen): pass class RhymesScreen(Screen): pass sm = ScreenManager(transition=SwapTransition()) class MainApp(App): def build(self): sm.add_widget(MainScreen(name='main')) sm.add_widget(RhymesScreen(name='rhymes')) sm.current = 'main' return sm if __name__ == '__main__': MainApp().run()
This looks very similar, but there is one more screen.
Now execute the Python file and try to click on the Get Rhymes button.
The next phase is about creating events. There we will set up all functionality and complete the desktop version of the app.
Now we need to fill our application with actions. This is done with the events and properties of Kivy. The workflow is next:
Now we need to make these words real. First of all, we need to set all properties and define event handlers.
To do this, open the main.kv file and paste next code:
#:kivy 1.11.1 <MainScreen>: input_widget: poem_text BoxLayout: orientation: 'vertical' padding: 25 spacing: 10 BoxLayout: size_hint: 1, 0.15 orientation: 'horizontal' spacing: 10 Button: text: 'Sentiment analysis' on_release: root.get_sentiments() Button: text: 'Get rhymes' on_press: root.manager.current = 'rhymes' ScrollView: id: scrlv size_hint: 1, 0.65 TextInput: id: poem_text text: 'Cellar door' size_hint: 1, None height: max(self.minimum_height, scrlv.height) <RhymesScreen>: on_pre_enter: root.feed_rhymes() input_widget: rhymes_text button_widget: rhymes_button BoxLayout: orientation: 'vertical' padding: 25 spacing: 10 ScrollView: id: scrlv size_hint: 1, 0.65 TextInput: id: rhymes_text text: '' size_hint: 1, None height: max(self.minimum_height, scrlv.height) BoxLayout: size_hint: 1, 0.15 orientation: 'horizontal' spacing: 10 Button: text: 'Back' on_release: root.manager.current = 'main' Button: id: rhymes_button text: 'Choose one'
We created all properties by linking to the basic text field and the rhymes button/text objects.
We also wrote event pointers for all missing buttons and screens.
So the button Sentiment analysis has an on_release action, which is done with the get_sentiments() method. The same structure is used for a second screen.
And the final step is to perform all these handlers. Open Python file and paste the next code version:
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition from kivy.uix.boxlayout import BoxLayout from kivy.uix.popup import Popup from kivy.uix.label import Label from kivy.uix.dropdown import DropDown from kivy.uix.button import Button from kivy.network.urlrequest import UrlRequest from textblob import TextBlob import nltk try: nltk.data.find('corpora/movie_reviews') except LookupError: nltk.download('movie_reviews') try: nltk.data.find('tokenizers/punkt') except LookupError: nltk.download('punkt') headers = { 'x-rapidapi-host': "wordsapiv1.p.rapidapi.com", 'x-rapidapi-key': "<YOUR_RAPID_API_KEY>" } # Create both screens. Please note the root.manager.current: this is how # you can control the ScreenManager from kv. Each screen has by default a # property manager that gives you the instance of the ScreenManager used. class MainScreen(Screen): def get_sentiments(self): sntms = TextBlob(self.input_widget.text).sentiment msg = ''' Polarity: {0}, Subjectivity: {1}. '''.format(sntms.polarity, sntms.subjectivity) popup = Popup(title='Sentiment results', content=Label(text=msg), size_hint=(0.6, 0.6)) popup.open() class RhymesScreen(Screen): def send_rhyme(self, instance, x): poem = sm.get_screen('main').input_widget poem.text = poem.text + " " + x sm.current = 'main' instance.dismiss() self.button_widget.unbind(on_release=instance.open) def get_rhymes_info(self, word): rhymes_endpoint = "https://wordsapiv1.p.rapidapi.com/words/{0}/rhymes".format(word) rhymes = UrlRequest(rhymes_endpoint, method='GET', req_headers=headers) rhymes.wait() rhymes_info = {} for rhyme in rhymes.result['rhymes']['all']: if ' ' not in rhyme: rhyme_info = {} freq_endpoint = "https://wordsapiv1.p.rapidapi.com/words/{0}/frequency".format(rhyme) frequency = UrlRequest(freq_endpoint, method='GET', req_headers=headers) frequency.wait() frequency = frequency.result rhyme_info['frequency'] = frequency['frequency']['zipf'] if 'frequency' in frequency else 0 defin_endpoint = "https://wordsapiv1.p.rapidapi.com/words/{0}/definitions".format(rhyme) definition = UrlRequest(defin_endpoint, method='GET', req_headers=headers) definition.wait() definition = definition.result if ('definitions' in definition): if (len(definition['definitions']) > 0): rhyme_info['definition'] = definition['definitions'][0]['definition'] if 'definition' in definition['definitions'][0] else 'No definition' rhyme_info['partOfSpeech'] = definition['definitions'][0]['partOfSpeech'] if 'partOfSpeech' in definition['definitions'][0] else 'No part of speech' else: rhyme_info['definition'] = 'No definition' rhyme_info['partOfSpeech'] = 'No part of speech' rhymes_info[rhyme] = rhyme_info return rhymes_info def feed_rhymes(self): self.input_widget.text = "" rhymes_info = self.get_rhymes_info(sm.get_screen('main').input_widget.selection_text) dropdown = DropDown() for k, v in rhymes_info.items(): text = '''{0} Frequency: {1} Definition: {2} Part of speech: {3} '''.format(k, v['frequency'], v['definition'], v['partOfSpeech']) self.input_widget.text = self.input_widget.text + "n" + text btn = Button(text=k, size_hint_y=None, height=44) btn.bind(on_release=lambda btn: dropdown.select(btn.text)) dropdown.add_widget(btn) self.button_widget.bind(on_release=dropdown.open) dropdown.bind(on_select=self.send_rhyme) sm = ScreenManager(transition=SwapTransition()) class MainApp(App): def build(self): sm.add_widget(MainScreen(name='main')) sm.add_widget(RhymesScreen(name='rhymes')) sm.current = 'main' return sm if __name__ == '__main__': MainApp().run()
Next stage is the main screen.
There is only one method: get_sentiments().
It takes all text in the input_widget (property of the text field in the display) and does a sentiment analysis.
The result will be shown in the Popup object.
That sums up all events programming.
First of all, we check the nltk module (it was installed with TextBlob) for pre-trained models. If they are absent, we can download them.
The rhymes screen has a more complicated structure. All work is done in the background of the first screen demonstration. We pinned it via the on_pre_enter event.
As it is a big process, we will talk about each method:
Looks like all the jobs were done, so we can test our desktop application.
When the application is ready, we can simply build it for different platforms. As our goal is an Android, let’s do this.
Open the terminal in the project folder and run a virtual environment. We need to set a deploy package. And this is where buildozer comes in, which is exactly why installation (including all its dependencies) is essential.
Now execute this command:
$ buildozer init
If your modules are good, you should get a new file. It is called buildozer.spec. This is a specification file, which allows you to set the deploy package. In our case, it is almost ideal. One important change is adding requirements. Find # (list) Application requirements. Replace the underlying section with the next lines:
# comma separated e.g. requirements = sqlite3,kivy requirements = python3,textblob,openssl,nltk,kivy==master
Here we added all required libraries. Important note: OpenSSL and nltk are optional. Other data in this file is good for our app, so we can start building. Run this command in the terminal:
$ buildozer -v android debug
If it is the first debug, building time can take a while. If there are any problems, you can always try to solve it with guides.
However, you’ll probably be able to find a built APK (format of Android application) file within the bin folder.
If it is there, our mobile program is ready to run. Now you can send it to your smartphone and test it.
Here is a video example of the Poem Generator usage.
As you can see, Python is very handy for mobile development. We have created a cool application with strong services. It can analyze your text and even propose some rhymes to it.
With some refinement, you can probably add some more features (like push notifications or in-app purchases) and list it under word game apps on the Google Play store.
This is it for today, but you can always plunge deeper into the world of APIs. There are so many cool ideas and features that can enhance your own and the lives of those around you.
The RapidAPI team is excited to announce the February 2024 update (version 2024.2) for the…
This January's release brings exciting features and improvements designed to empower you and your developers.…
Rapid API is committed to providing its users with the best possible experience, and the…
In today's fast-paced digital world, APIs (Application Programming Interfaces) have become the backbone of modern…
We're excited to announce the September 2023 Release Notes for the RapidAPI Enterprise Hub! Our…
We hope you enjoyed your summer! We're excited to announce the Rapid API Enterprise Hub…