-
Notifications
You must be signed in to change notification settings - Fork 1
Services API
The service API package defines and handles the interaction between the app and external RESTful APIs over HTTP(S). It also performs its own error handling and output parsing. It is a completely removable component and can exist on its own and inserted anywhere.
For use as a RESTful API (instead of native Java code, detailed below), more information can be found in the section [below](#RESTful-Service API-Interaction).
The makeRequest
method takes the service name and required data as parameters and performs the API request, the output is a sentence for the speech synthesiser to speak aloud to the user (with the relevant data included).
- This output is put onto an API response queue, maintained by the main controller of the app.
void makeRequest(String serviceName, HashMap <String, String> payload)
The recognised service names are:
- "air quality"
- "book"
- "charity search"
- "charity by city"
- "current weather"
- "dictionary"
- "ingredient"
- "joke"
- "nearest transport"
- "news"
- "random recipe"
- "recipe"
- "recipe instructions"
- "stocks"
- "transport search"
- "weather forecast"
The API response queue should have the type:
BlockingQueue<ApiResponse> appQueue;
Periodically polling this queue returns an ApiResponse
object returning the service's response after a call is made.
The string response, used in speech synthesis, can be retrieved using the getResponse()
method of the object.
The name of the service that was called can be retrieved using the getName()
method of the object.
A service may return (required) data that is not suitable for speech synthesis e.g. an image to display.
This type of data is referred to as 'metadata', stored in a HashMap<String, Object
named metadata
.
It is retrieved by calling the metadata()
method of an ApiResponse
object.
- Note that there is no standard for the representation of data inside the hashmap - this is entirely dependent on the service, and its corresponding
parseOutput
method. - Expected metadata (for successful API calls) for relevant services is detailed below, for that specific service only.
The getName()
method should be used to check what service was returned to determine how to read its metadata, if required.
An example implementation showing how to retrieve responses can be found in test package.
The following section defines the required parameters needed by each service. See the "Adding Services" wiki article for more information on how to integrate new services.
The following set of tables define the required data needed by each service. The internal structure of a REST
ful
service API request is a HashMap<String, String>
object where the Attribute columns below represent the exact field names in
the hash map for a service.
A service allowing the user to retrieve information about the current weather in their (or explicitly specified) city.
Attribute | Type | Default | Description |
---|---|---|---|
CITY_NAME |
String | "London" |
The name of the city the user's device is located in. |
COUNTRY_CODE |
String | "uk" |
The two-character ISO country code of the city. The full list of possible country codes can be found here. |
LANGUAGE |
String | "en" |
The two-character (or three) ISO code of the language to return the weather in. The full list of possible language codes can be found here. |
A service returning the predicted weather for the user's exact location.
Attribute | Type | Default | Description |
---|---|---|---|
LAT |
Double | 51.534121 |
The latitude of the user's current (or most recent) location. |
LON |
Double | -0.006 |
The longitude of the user's current (or most recent location. |
LANGUAGE |
String | "en" |
The two-character (or three) ISO code of the language to return the weather in. The full list of possible language codes can be found here. |
DAYS |
Integer | 1 |
The number of days to forecast for. The minimum is 7 and the maximum is 7. |
A service returning the air quality index for a given city.
Attribute | Type | Default | Description |
---|---|---|---|
CITY_NAME |
String | "London" |
The name of the city the user's device is located in. |
A service allowing the user to retrieve stock information on an equity of their choice.
Attribute | Type | Default | Description |
---|---|---|---|
FUNCTION |
String | "TIME_SERIES_INTRADAY" |
The time series of your choice. |
SYMBOL |
String | "IBM" |
The name of the equity. |
INTERVAL |
Integer | 1 |
Time interval between two consecutive data points in the time series. The following values are supported: 1 , 5 , 15 , 30 , 60 . |
A service retrieving a random or specific joke.
Attribute | Type | Default | Description |
---|---|---|---|
TERM |
String | "" |
The search term to search for a joke. |
A service retrieving the definition, examples and synonyms for a given word.
Attribute | Type | Default | Description |
---|---|---|---|
WORD |
String | "hello" |
The word to retrieve the definition of. |
LANGUAGE |
String | "en" |
The two-character (or three) ISO code of the language to return the definition in. The full list of possible language codes can be found here. |
INCLUDE_SYNONYMS |
Boolean | "false" |
Indicates whether to retrieve the synonyms of the word as well. |
SYNONYMS_ONLY |
Boolean | "false" |
Allows for thesaurus usage, retrieving only the synonyms of the word and not its definition and example sentence usage. If this is set to true , INCLUDE_SYNONYMS is also set to true by default. |
This service returns either the nearest train stations or bus stops for a given location range.
Attribute | Type | Default | Description |
---|---|---|---|
MIN-LAT |
Double | 51.530121 |
The minimum latitude, representing one corner of the bounding box - must be less than MAX-LAT . |
MAX-LAT |
Double | 51.538121 |
The maximum latitude, representing one corner of the bounding box - must be more than MIN-LAT . |
MIN-LON |
Double | -0.009 |
The minimum longitude, representing one corner of the bounding box - must be less than MAX-LON . |
MAX-LON |
Double | -0.001 |
The maximum longitude, representing one corner of the bounding box - must be more than MIN-LON . |
TRANSPORT |
String | "train_station" |
Indicates whether to search for a train station (train_station ) or a bus stop (bus_stop ). |
Note that this service does not return any spoken ouput, just the coordinates of the nearest transport points defined below.
The metadata returned by this service contains just one top-level field - locations
which is an array of latitude, longitude pairs for each returned transport point. Each element in the locations
array is a Double[]
array, with the following elements:
Attribute | Type | Description |
---|---|---|
latitude |
Double |
The latitude of the transport point. |
longitude |
Double |
The longitude of the transport point. |
Note that the ordering here is important - the first element in the array is the latitude
, the second the longitude
.
This service returns information on a bus stop or train station by its name.
Attribute | Type | Default | Description |
---|---|---|---|
QUERY |
String | "euston" |
The name of the train station or bus stop to search for. |
TRANSPORT |
String | "train_station" |
Indicates whether to search for a train station (train_station ) or a bus stop (bus_stop ). |
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
latitude |
Double |
The latitude of the transport point. |
longitude |
Double |
The longitude of the transport point. |
This service returns a random recipe.
This service requires no parameters - supplying them has no effect.
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
recipe-id |
String |
The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API. |
image |
String |
A URL to the cover image of the recipe. |
This service returns a set of recipes by searching via natural language.
Attribute | Type | Default | Description |
---|---|---|---|
QUERY |
String | "" |
The search term. |
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
recipe-id |
String |
The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API. |
image |
String |
A URL to the cover image of the recipe. |
This service returns a set of recipes with certain ingredients, specified by the user.
Attribute | Type | Default | Description |
---|---|---|---|
INGREDIENTS |
String | "" |
A comma separated string of ingredients to search for. |
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
recipe-id |
String |
The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API. |
image |
String |
A URL to the cover image of the recipe. |
This service returns the instructions for the recipes returned by the services above.
Attribute | Type | Default | Description |
---|---|---|---|
ID |
String | "" |
The ID of the recipe. |
DETAILED |
Boolean | true |
Whether to split instructions into steps (true ) or return a plain description (false ). |
Note that this service is intended to be used internally - each recipe service above returns the ID
of the recipe in the metadata
of the response object; the recipe instructions service should then be used to retrieve the instructions of that recipe.
This service also returns no spoken output. The metadata
, defined below, can be used to programmatically decide what steps to read (instead of reading it all at once).
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
steps |
ArrayList<String> |
An array of instructions for the recipe - each element is one instruction step. |
This service returns a news article based on the user's search.
Attribute | Type | Default | Description |
---|---|---|---|
QUERY |
String | "" |
The search term, in natural language. |
LANGUAGE |
String | "en" |
The language to return the result in. Uses the two-character IS0-639-1 code scheme. The full list of possible language codes can be found here. |
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
url |
String |
A URL to the full news article. |
image |
String |
A URL to the cover image of the article. |
This service returns information on a specified number of charities, based on the user's search in natural language.
Attribute | Type | Default | Description |
---|---|---|---|
QUERY |
String | "" |
The search term, in natural language. |
VALUES |
String | 1 |
The (maximum) number of charities to return information on. |
The metadata returned by this service contains just one top-level field: charities
which is an array of maps (each one representing a charity) where each map contains the following information:
Attribute | Type | Description |
---|---|---|
name |
String |
The name of the charity. |
URL |
String |
A URL to the charity's registered page. |
donationURL |
String |
A URL to donate to the charity. |
latitude |
Double |
The latitude of the charity. |
longitude |
Double |
The longitude of the charity. |
This service returns information on a specified number of charities in a given city.
Attribute | Type | Default | Description |
---|---|---|---|
CITY |
String | "london" |
The search term, in natural language. |
VALUES |
Integer | 1 |
The (maximum) number of charities to return information on. |
The metadata returned by this service contains just one top-level field: charities
which is an array of maps (each one representing a charity) where each map contains the following information:
Attribute | Type | Description |
---|---|---|
name |
String |
The name of the charity. |
URL |
String |
A URL to the charity's registered page. |
donationURL |
String |
A URL to donate to the charity. |
latitude |
Double |
The latitude of the charity. |
longitude |
Double |
The longitude of the charity. |
This service returns information on a book based on the user's search.
Attribute | Type | Default | Description |
---|---|---|---|
QUERY |
String | "" |
The search term, in natural language. Entirely optional. |
TOPIC |
String | "" |
A certain topic to look for. Entirely optional. |
LANGUAGES |
String | "en" |
A comma separated string containing the list of languages to search for. Uses the two-character IS0-639-1 code scheme. The full list of possible language codes can be found here. |
Note that both the QUERY
and TOPIC
attributes are optional, but at least one must be supplied.
The metadata returned by this service is:
Attribute | Type | Description |
---|---|---|
id |
Integer |
The ID of the book, useful for making further API calls. |
image/jpeg |
String |
A URL to the image of the book cover. |
text/html |
String |
A URL to an online version of the book, formatted with HTML. |
text/plaintext |
String |
A URL to an online verison of the book, in plain text with no formatting. |
application/x-mobipocket-ebook |
String |
A URL to an ebook download of the book. |
application/epub+zip |
String |
A URL to an ebook download of the book in a different format than above. |
This Java package allows the service API interaction to be accessed via a restful API on localhost
.
The following endpoints are available:
- "air-quality"
- "book"
- "current-weather"
- "charity-search"
- "charity-by-city"
- "dictionary"
- "ingredient"
- "joke"
- "nearest-transport"
- "news"
- "random-recipe"
- "recipe"
- "recipe-instructions"
- "stocks"
- "transport-search"
- "weather-forecast"
As per the service APIs included except any spaces in the service names are replaced with hyphens.
Parameters are to be supplied in the URL in lowercase form.
- e.g., the dictionary service endpoint requires a
WORD
parameter (as per the outer README) and is supplied (in lowercase) as:
/dictionary?word=word_here
- Services that require multiple parameters are supplied by an ampersand (&) separated list.
Note that there are no POST
requests available (only GET
), setting the request method to POST
in the request
header will result in an error.
All responses are of the form:
{ "service": "", "message": "", "metadata": {}, "code": code }
Where
-
service - the name of the service; this is either the endpoint, for a recognised service or
error
if a client HTTP error occurs. - message - a natural language string representing the service response - useful for voice assistants.
- metadata - extra data that may be useful, but unsuitable for natural language e.g., image/web links.
- code - the HTTP status code using this standard.
To start the application in a Docker container, you must first build the image with:
docker build --tag services .
And then to start the application on port 8080
:
docker run --rm services services/services
Note that you must be running these docker commands from one level up, just outside this folder. You should navigate to the containing folder before building or running the image:
cd ..
To start the application, ensuring no service is currently using port 8080
, run the following command in a terminal in
the "services" directory (where the pom.xml
is located):
mvn clean; mvn org.springframework.boot:spring-boot-maven-plugin:run
An executable jar
file can be used instead, built and executed manually using:
mvn clean package
You can also start the application using a Python script with the following command:
python3 tools/run.py
For simplicity, a shell script is included to run the service interaction as a RESTful API:
./services
Depending on your system configuration, you may need to give the script execution permissions which can only be done with administrator privileges (sudo
):
chmod +x services
And then perform your HTTP requests. For example, after the application is running, open a terminal and enter:
curl "localhost:8080/current-weather?city=london"
This will return something similar to:
{ "service":"current weather", "message":"The weather in London today is broken clouds with the temperature being 7 degrees celsius but will probably feel like 4 degrees celsius. The high will be 7 degrees celsius and the low, 6 degrees celsius. Don't forget to dress warm today!", "metadata":{}, "code":200 }
Note that the URL must be quoted to escape the question marks and ampersands if performing HTTP requests from the command line.
There are different execution options for the API, summarised below.
Note that these can only be enabled by passing them as command line arguments to the Python run
script or running the
application as a jar
. Command line arguments are unavailable with Java if not executing using a jar
file (using
the java -jar ...
command).
The following arguments are all optional.
- A desired port can be specified using
-port=PORT
(or one of--port
,-p
and--p
). Note that this must be an integer and is set to8080
by default. - Logging information to the console can be enabled with the
-l
(or--l
) flag - logging is disabled by default. - The application can be built into a single jar and executing using the
-jar
(or--jar
) flag.- This option is only available using the Python
run
script.
- This option is only available using the Python
When using the jar
file (with java -jar ...
):
- The
-l
flag is supplied without the leading-
character(s) - i.e. asl
. - The
-port
flag is always supplied with a single-
and the same goes for-p
.
Running python3 tools/run.py -h
gives you a similar breakdown of possible command line arguments and their aliases.
- The
-h
flag is not available outside of the Python script.
To execute unit tests(served at: http://localhost:8000/surefire-report.html):
docker run -p 80:8000 -ti --rm services /services/tools/test
To execute PMD analysis(served at: http://localhost:8000/pmd.html):
docker run -p 80:8000 -ti --rm services /services/tools/analysis
To execute test coverage (served at: http://localhost:8000/jacoco):
docker run -p 80:8000 -ti --rm services /services/tools/coverage