openapi: 3.0.1 info: title: SearchLy API v1 description: | # Introduction The SearchLy API provides similarity searching based on song lyrics. # Operations The API allows for the `/similarity/by_song` operation, which allows clients to search the similarity for an existing song in the database. Also, the API has an additional `/similarity/by_content` endpoint which allows clients to search similarity given a free String input through a JSON request body. Additional `/song/search` operation is available for searching songs given a query String. # Endpoint The API endpoint for the SearchLy API v1 is as follows: ``` https://searchly.asuarez.dev/api/v1 ``` # Motivation This project was built in order to create an API for searching similarities based on song lyrics. There are a lot of songs in the industry and most of them are talking about the same topic. What I wanted to prove with SearchLy was to estimate how similar are two songs between them based on the meaning of their lyrics. SearchLy is using a database of 100k songs from AZLyrics, using [this scraper](https://github.com/AlbertSuarez/azlyrics-scraper), which is being updated periodically. Then, using word2vec and NMSLIB, it was possible to create an index where you can search similarities using the k-nearest neighbors (KNN) algorithm. > **Note**: I am currently using a micro-instance from DigitalOcean where the API is deployed, so you should expect a bad performance. However, if this API becomes popular I will deploy it in a bigger instance. contact: email: hi@asuarez.dev version: "1.0" externalDocs: description: SearchLy demo url: https://searchly.asuarez.dev/ x-logo: url: 'https://searchly.asuarez.dev/static/img/logo.png' altText: SearchLy servers: - url: https://searchly.asuarez.dev/api/v1 tags: - name: similarity x-displayName: Similarity search - name: song x-displayName: Song search x-tagGroups: - name: Similarity tags: - similarity - name: Song tags: - song paths: /similarity/by_song: get: tags: - similarity summary: API endpoint to search similarity using a song identifier description: | Endpoint for an end-user client to search similarity by song identifier. If you want to run the /similarity/by_song operation, you can do so via an HTTP GET command to the following URL: ``` https://searchly.asuarez.dev/api/v1/similarity/by_song ``` operationId: src.searchly.api.v1.controllers.similarity.by_song parameters: - name: song_id in: query description: Song identifier. required: true example: 234 schema: type: integer responses: 200: description: Standard SearchLy API v1 JSON response. You should check the `error` attribute to determine if there was an error. content: application/json: schema: $ref: '#/components/schemas/APIResponseSimilarity' default: description: Unexpected error. content: application/text: schema: type: string description: Error description. x-code-samples: - lang: 'python' source: | # Make sure you have installed the required packages: # pip install requests import requests url = 'https://searchly.asuarez.dev/api/v1/similarity/by_song' payload = {'song_id': SONG_IDENTIFIER} # Make the classify request response = requests.get(url, params=payload) # The response is formatted in JSON json_response = response.json() - lang: 'Java' source: | try { URL myurl = new URL("https://searchly.asuarez.dev/api/v1/similarity/by_song" + "?song_id=" + "SONG_IDENTIFIER"); con = (HttpURLConnection) myurl.openConnection(); con.setRequestMethod("GET"); StringBuilder content; try (BufferedReader br = new BufferedReader( new InputStreamReader(con.getInputStream(), "utf-8"))) { StringBuilder response = new StringBuilder(); String responseLine = null; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println(response.toString()); } } finally { con.disconnect(); } - lang: 'C#' source: | var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://searchly.asuarez.dev/api/v1/similarity/by_song" + "?song_id=" + "SONG_IDENTIFIER"); httpWebRequest.Method = "GET"; var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) { var result = streamReader.ReadToEnd(); } - lang: 'php' source: | - lang: 'shell' source: | curl "https://searchly.asuarez.dev/api/v1/similarity/by_song?song_id=SONG_IDENTIFIER" /similarity/by_content: post: tags: - similarity summary: API endpoint to search similarity using content description: | Endpoint for an end-user client to search similarity by content. If you want to run the /similarity/by_content operation, you can do so via an HTTP POST command to the following URL: ``` https://searchly.asuarez.dev/api/v1/similarity/by_content ``` operationId: src.searchly.api.v1.controllers.similarity.by_content requestBody: required: true description: Body wrapper for the request. content: application/json: schema: type: object properties: content: type: string description: Content for searching similarity. responses: 200: description: Standard SearchLy API v1 JSON response. You should check the `error` attribute to determine if there was an error. content: application/json: schema: $ref: '#/components/schemas/APIResponseSimilarity' default: description: Unexpected error. content: application/text: schema: type: string description: Error description. x-code-samples: - lang: 'python' source: | # Make sure you have installed the required packages: # pip install requests import requests url = 'https://searchly.asuarez.dev/api/v1/similarity/by_content' request_body = {"content": "CONTENT"} # Make the classify request response = requests.post(url, json=request_body) # The response is formatted in JSON json_response = response.json() - lang: 'Java' source: | try { URL myurl = new URL("https://searchly.asuarez.dev/api/v1/similarity/by_content"); con = (HttpURLConnection) myurl.openConnection(); con.setRequestMethod("POST"); StringBuilder content; String jsonInputString = "{" + "\"content\": \"CONTENT\"" + "}"; try (OutputStream os = con.getOutputStream()) { byte[] input = jsonInputString.getBytes("utf-8"); os.write(input, 0, input.length); } try (BufferedReader br = new BufferedReader( new InputStreamReader(con.getInputStream(), "utf-8"))) { StringBuilder response = new StringBuilder(); String responseLine = null; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println(response.toString()); } } finally { con.disconnect(); } - lang: 'C#' source: | var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://searchly.asuarez.dev/api/v1/similarity/by_content"); httpWebRequest.ContentType = "application/json"; httpWebRequest.Method = "POST"; using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) { string json = "{" + "\"content\": \"CONTENT\"" + "}"; streamWriter.Write(json); } var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) { var result = streamReader.ReadToEnd(); } - lang: 'php' source: | 'CONTENT' ); // Setup cURL $ch = curl_init('https://searchly.asuarez.dev/api/v1/similarity/by_content'); curl_setopt_array($ch, array( CURLOPT_POST => TRUE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPHEADER => array( 'Content-Type: application/json' ), CURLOPT_POSTFIELDS => json_encode($postData) )); // Send the request $response = curl_exec($ch); ?> - lang: 'shell' source: | curl "https://searchly.asuarez.dev/api/v1/similarity/by_content"\ -d content="CONTENT" /song/search: get: tags: - song summary: API endpoint to search songs from the database given a query description: | Endpoint for an end-user client to search songs from the database given a String query. If you want to run the /song/search operation, you can do so via an HTTP GET command to the following URL: ``` https://searchly.asuarez.dev/api/v1/song/search ``` operationId: src.searchly.api.v1.controllers.song.search parameters: - name: query in: query description: Query. required: true example: Miley Cyrus schema: type: string responses: 200: description: Standard SearchLy API v1 JSON response. You should check the `error` attribute to determine if there was an error. content: application/json: schema: $ref: '#/components/schemas/APIResponseSong' default: description: Unexpected error. content: application/text: schema: type: string description: Error description. x-code-samples: - lang: 'python' source: | # Make sure you have installed the required packages: # pip install requests import requests url = 'https://searchly.asuarez.dev/api/v1/song/search' payload = {'query': 'QUERY'} # Make the classify request response = requests.get(url, params=payload) # The response is formatted in JSON json_response = response.json() - lang: 'Java' source: | try { URL myurl = new URL("https://searchly.asuarez.dev/api/v1/song/search" + "?query=" + "QUERY"); con = (HttpURLConnection) myurl.openConnection(); con.setRequestMethod("GET"); StringBuilder content; try (BufferedReader br = new BufferedReader( new InputStreamReader(con.getInputStream(), "utf-8"))) { StringBuilder response = new StringBuilder(); String responseLine = null; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println(response.toString()); } } finally { con.disconnect(); } - lang: 'C#' source: | var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://searchly.asuarez.dev/api/v1/song/search" + "?query=" + "QUERY"); httpWebRequest.Method = "GET"; var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) { var result = streamReader.ReadToEnd(); } - lang: 'php' source: | - lang: 'shell' source: | curl "https://searchly.asuarez.dev/api/v1/song/search?query=QUERY" components: schemas: APIResponseSimilarity: type: object properties: error: type: boolean description: Whether or not the request was successfully processed or not. message: type: string description: Error message if the request was unsuccessful. response: type: object description: Contains the response data if the request was successful. properties: similarity_list: type: array description: Contains all the similarity items representing songs. items: type: object description: Song similarity item. properties: id: type: integer description: Song internal identifier. artist_name: type: string description: Artist's song name. song_name: type: string description: Song name. lyrics: type: string description: Song lyrics. artist_url: type: string description: Artist URL. song_url: type: string description: Song URL. index_id: type: integer description: Index internal identifier. percentage: type: number format: float description: Similarity percentage. APIResponseSong: type: object properties: error: type: boolean description: Whether or not the request was successfully processed or not. message: type: string description: Error message if the request was unsuccessful. response: type: object description: Contains the response data if the request was successful. properties: results: type: array description: Contains all the songs. items: type: object description: Song item. properties: id: type: integer description: Song internal identifier. name: type: string description: Song and Artist name.