Android

How to Build an Android App with Python (and the WordsAPI)

Introduction

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.

Related: How to build an Android App using JavaScript

WordsAPI explanation

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:

  • word definitions
  • antonyms/synonyms
  • pronunciations
  • word-usage among regions

Connect to the WordsAPI

How to Get a WordsAPI API Key

1. Sign Up for a RapidAPI Key

The first thing to do is to sign up for a RapidAPI account. Why not, it’s free.

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.

2. Navigate to the WordsAPI Page

Search for the WordsAPI or click here to navigate to the WordsAPI.

3. Subscribe to the API

Next, click on the pricing tab, and subscribe to one of the pricing plans. Hint: There’s a Basic Plan that allows up to 2500 free requests/day

4. Test the Endpoints

Return to the endpoints page, select any of the endpoints and click “test endpoint”.

Voila! You now have access to the WordsAPI. You can find your API Key under “X-RapidAPI-Key.”

Connect to the WordsAPI
We won’t go into all the details of WordsAPI. You can look at an example of a Python application on this page. There is a deep tutorial through the synonyms game creation.

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.

Let’s take a look at the Syllables endpoint. The result of a request is printed on the right side of the screen. Each syllable of the word ‘incredible’ is represented as a separate element on the list.

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.

Connect to the WordsAPI

How to build a Word Application for Android

Requirements

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:

  • kivy – a multi-platformed framework for creating the graphical user interface (GUI). It supports all the beauty and simplicity of Python. Users can create adaptive programs with ease for various operating systems. The main advantage – you don’t need to do anything after you’ve created the desktop version. If the program is ready on one platform, you can easily convert it to any other. For example, from Android to iOS.
  • buildozer – a special utility that assists with building packages. Actually, basic Kivy doesn’t create a final application. This part of the job lays on the proverbial shoulders of buildozer. It’s important to keep in mind that sometimes, it can be difficult to install this module correctly. So it is highly recommended to work with virtual environments.
  • textblob – a library, which has many pre-trained models for text analysis. It will be very useful for natural language processing (NLP). You’ll need NLP because the application doesn’t make any sense without advanced features. We aren’t interested in copying blind API requests. The app should be reasonably practical.

Python + Kivy NUI

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:

Now, we need to prepare our screens for all planned tasks.

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.

Here is a template of our main screen.

As you can see, there are two buttons:

  1. ‘Sentiment analysis’
  2. and ‘Get rhymes’.

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.

Above you can see the template of the rhymes screen.

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.

  1. The first is for buttons using the BoxLayout container.
  2. Second is a scrolling text input with a custom option (id: scrlv), which helps to control TextInput size.

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..

Right now buttons aren’t responsive yet, but it’s because we didn’t create any events. A more important fact is that we need to create a second screen. So open the main.kv and modify it one more time:
#: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:

  1. We created the markup for a Rhymes Screen – very similar to the Main, but with replaced buttons and text input.
  2. And the second improvement touches the navigation. We pointed out actions for transferring buttons. It was done by an on_release option for them.

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.

Now our buttons are responsive (not all, but for the most part), so we can submit our design stage.

The next phase is about creating events. There we will set up all functionality and complete the desktop version of the app.

Connect to the WordsAPI

Creating Events

Now we need to fill our application with actions. This is done with the events and properties of Kivy. The workflow is next:

  • A developer pins the property value for a single visual object;
  • The entire screen gets the ID of that property. This is a unique way to work with the object within a custom screen class in Python.
  • Each call-able object in the markup takes a pointer on action and method for it. For example, if the button was pressed, then do the method button_press().
  • Events handler is a general Python function inside of the screen class, that works and changes needed data.

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.

Connect to the WordsAPI
Each screen class was expanded with methods that are important for application functionality.

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:

  • get_rhymes_info – the most difficult method for computation. Here we make all API requests. Keep in mind that it is done by a URLRequest object. It is a part of Kivy original modules, and that’s why there won’t be any problems. Here we request all rhymes for words. Finally, we get the dictionary for each element. One particular key is a unique rhyme, while the value is a dict with all details.
  • send_rhyme – when the rhyme is chosen, this method sends it to the main screen.
  • feed_rhymes – entry point of all procedures. It is the main method that connects all previous ones. Here we use get_rhymes_info and receive all data. Next, we print it in the text area and create a Dropdown option for Choose One button. So when the user ticks descriptions and makes a choice, data will be sent to the send_rhyme.

Looks like all the jobs were done, so we can test our desktop application.

Here is the sentiment analysis of My Mistress’ eyes by William Shakespeare. It says that the poem is more positive and definitely subjective.

Here are all proposed rhymes for ‘Ginger’. Users can read the definition, frequency, and part of speech for each option. There is a drop-down list that gives you the option to choose one of them.

Android deploy

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.

Connect to the WordsAPI

Conclusion

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.

 

5/5 - (2 votes)
Share
Published by

Recent Posts

Rapid Enterprise API Hub Levels Up Custom Branding, Monetization, and Management in February Release

The RapidAPI team is excited to announce the February 2024 update (version 2024.2) for the…

1 day ago

Supercharge Your Enterprise Hub with January’s Release: Search Insights, Login Flexibility, and More!

This January's release brings exciting features and improvements designed to empower you and your developers.…

2 months ago

Enhanced Functionality and Improved User Experience with the Rapid API Enterprise Hub November 2023 Release

Rapid API is committed to providing its users with the best possible experience, and the…

4 months ago

The Power of Supporting Multiple API Gateways in an API Marketplace Platform

In today's fast-paced digital world, APIs (Application Programming Interfaces) have become the backbone of modern…

5 months ago

Rapid API Enterprise Hub – September 2023 Release Notes

We're excited to announce the September 2023 Release Notes for the RapidAPI Enterprise Hub! Our…

6 months ago

Rapid API Enterprise Hub – August 2023 Release Notes

We hope you enjoyed your summer!  We're excited to announce the Rapid API Enterprise Hub…

7 months ago