Repository: shazamio/ShazamIO (language: python)

Issue:
First try at configurable country for the endpoints
As we've been discussing in #50, it could be useful to not always hit the shazam "GB" endpoint, but use another country. That discussion shows that the data returned is different depending on which one you use. This patch makes that configurable when you create a shazam instance. Like this:
```
shazam = Shazam(endpoint_country="US")
```
And then you use it like normal. The default for the new parameter is "GB", leaving the old behavior intact.


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index a39919d..db49c8c 100644
--- a/README.md
+++ b/README.md
@@ -143,7 +143,7 @@ from shazamio import Shazam
 async def main():
     shazam = Shazam()
     track_id = 546891609
-    related = await shazam.related_tracks(track_id=track_id, limit=5, start_from=2)
+    related = await shazam.related_tracks(track_id=track_id, limit=5, offset=2)
     # ONLY №3, №4 SONG
     print(related)
 
diff --git a/examples/related_tracks.py b/examples/related_tracks.py
index 53d1c0b..92b2cbe 100644
--- a/examples/related_tracks.py
+++ b/examples/related_tracks.py
@@ -5,7 +5,7 @@
 async def main():
     shazam = Shazam()
     track_id = 546891609
-    related = await shazam.related_tracks(track_id=track_id, limit=5, start_from=2)
+    related = await shazam.related_tracks(track_id=track_id, limit=5, offset=2)
     # ONLY №3, №4 SONG
     print(related)
 
diff --git a/examples/top_artist_tracks.py b/examples/top_artist_tracks.py
index b58d8b8..d24f0b0 100644
--- a/examples/top_artist_tracks.py
+++ b/examples/top_artist_tracks.py
@@ -19,6 +19,7 @@ async def main():
         ),
     )
     serialized = Serialize.artist_v2(about_artist)
+    print(serialized)
     for i in serialized.data[0].views.top_songs.data:
         pprint(i.attributes.name)
 
diff --git a/examples/top_tracks_city.py b/examples/top_tracks_city.py
index b52bbb6..3fcbd93 100644
--- a/examples/top_tracks_city.py
+++ b/examples/top_tracks_city.py
@@ -3,9 +3,11 @@
 
 
 async def main():
-    shazam = Shazam()
+    shazam = Shazam(language="GB")
     top_ten_moscow_tracks = await shazam.top_city_tracks(
-        country_code="RU", city_name="Moscow", limit=10
+        country_code="RU",
+        city_name="Moscow",
+        limit=10,
     )
     print(top_ten_moscow_tracks)
     # ALL TRACKS DICT
diff --git a/shazamio/api.py b/shazamio/api.py
index 27bdc1e..e4b815c 100644
--- a/shazamio/api.py
+++ b/shazamio/api.py
@@ -22,17 +22,18 @@ class Shazam(Converter, Geo, Request):
     """Is asynchronous framework for reverse engineered Shazam API written in Python 3.7 with
     asyncio and aiohttp."""
 
-    def __init__(self, language: str = "ES"):
+    def __init__(self, language: str = "en-US", endpoint_country: str = "GB"):
         super().__init__(language=language)
         self.language = language
+        self.endpoint_country = endpoint_country
 
-    async def top_world_tracks(self, limit: int = 200, start_from: int = 0) -> Dict[str, Any]:
+    async def top_world_tracks(self, limit: int = 200, offset: int = 0) -> Dict[str, Any]:
         """
         Search top world tracks
 
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs.
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                 The default is 0. If you want to skip the first few songs, set this parameter to
                 your own.
             :return: dict tracks
@@ -40,9 +41,10 @@ async def top_world_tracks(self, limit: int = 200, start_from: int = 0) -> Dict[
         return await self.request(
             "GET",
             ShazamUrl.TOP_TRACKS_WORLD.format(
-                limit,
-                start_from,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
             ),
             headers=self.headers(),
         )
@@ -67,7 +69,10 @@ async def artist_about(
 
         return await self.request(
             "GET",
-            ShazamUrl.SEARCH_ARTIST_V2.format(artist_id, language=self.language),
+            ShazamUrl.SEARCH_ARTIST_V2.format(
+                endpoint_country=self.endpoint_country,
+                artist_id=artist_id,
+            ),
             params=params_dict,
             headers=self.headers(),
         )
@@ -83,8 +88,9 @@ async def track_about(self, track_id: int) -> Dict[str, Any]:
         return await self.request(
             "GET",
             ShazamUrl.ABOUT_TRACK.format(
-                track_id,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                track_id=track_id,
             ),
             headers=self.headers(),
         )
@@ -93,7 +99,7 @@ async def top_country_tracks(
         self,
         country_code: Union[CountryCode, str],
         limit: int = 200,
-        start_from: int = 0,
+        offset: int = 0,
     ) -> Dict[str, Any]:
         """
         Get the best tracks by country code
@@ -102,7 +108,7 @@ async def top_country_tracks(
             :param country_code: ISO 3166-3 alpha-2 code. Example: RU,NL,UA
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs.
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                 The default is 0. If you want to skip the first few songs, set this parameter to
                 your own.
             :return: dict songs
@@ -110,10 +116,11 @@ async def top_country_tracks(
         return await self.request(
             "GET",
             ShazamUrl.TOP_TRACKS_COUNTRY.format(
-                country_code,
-                limit,
-                start_from,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                country_code=country_code,
+                limit=limit,
+                offset=offset,
             ),
             headers=self.headers(),
         )
@@ -123,7 +130,7 @@ async def top_city_tracks(
         country_code: Union[CountryCode, str],
         city_name: str,
         limit: int = 200,
-        start_from: int = 0,
+        offset: int = 0,
     ) -> Dict[str, Any]:
         """
         Retrieving information from an artist profile
@@ -134,7 +141,7 @@ async def top_city_tracks(
                 Example: Budapest, Moscow
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs.
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                 The default is 0. If you want to skip the first few songs, set this parameter to
                 your own.
             :return: dict songs
@@ -143,16 +150,20 @@ async def top_city_tracks(
         return await self.request(
             "GET",
             ShazamUrl.TOP_TRACKS_CITY.format(
-                city_id,
-                limit,
-                start_from,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                city_id=city_id,
             ),
             headers=self.headers(),
         )
 
     async def top_world_genre_tracks(
-        self, genre: Union[GenreMusic, int], limit: int = 100, start_from: int = 0
+        self,
+        genre: Union[GenreMusic, int],
+        limit: int = 100,
+        offset: int = 0,
     ) -> Dict[str, Any]:
         """
         Get world tracks by certain genre
@@ -168,14 +179,20 @@ async def top_world_genre_tracks(
 
             :param limit: Determines how many songs the maximum can be in the request.
                     Example: If 5 is specified, the query will return no more than 5 songs.
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                     The default is 0. If you want to skip the first few songs, set this parameter
                     to your own.
             :return: dict songs
         """
         return await self.request(
             "GET",
-            ShazamUrl.GENRE_WORLD.format(genre, limit, start_from, language=self.language),
+            ShazamUrl.GENRE_WORLD.format(
+                language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                genre=genre,
+            ),
             headers=self.headers(),
         )
 
@@ -184,7 +201,7 @@ async def top_country_genre_tracks(
         country_code: str,
         genre: Union[GenreMusic, int],
         limit: int = 200,
-        start_from: int = 0,
+        offset: int = 0,
     ) -> Dict[str, Any]:
         """
         The best tracks by a genre in the country
@@ -199,7 +216,7 @@ async def top_country_genre_tracks(
                 REGIONAL_MEXICANO = 18
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                 The default is 0. If you want to skip the first few songs, set this parameter to
                 your own.
             :return: dict songs
@@ -207,13 +224,21 @@ async def top_country_genre_tracks(
         return await self.request(
             "GET",
             ShazamUrl.GENRE_COUNTRY.format(
-                country_code, genre, limit, start_from, language=self.language
+                language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                country=country_code,
+                genre=genre,
             ),
             headers=self.headers(),
         )
 
     async def related_tracks(
-        self, track_id: int, limit: int = 20, start_from: int = 0
+        self,
+        track_id: int,
+        limit: int = 20,
+        offset: int = 0,
     ) -> Dict[str, Any]:
         """
         Similar songs based song id
@@ -222,49 +247,70 @@ async def related_tracks(
             https://www.shazam.com/track/549952578/
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs
-            :param start_from: A parameter that determines with which song to display the request.
+            :param offset: A parameter that determines with which song to display the request.
                 The default is 0. If you want to skip the first few songs, set this parameter to
                 your own.
             :return: dict tracks
         """
         return await self.request(
             "GET",
-            ShazamUrl.RELATED_SONGS.format(track_id, start_from, limit, language=self.language),
+            ShazamUrl.RELATED_SONGS.format(
+                language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                track_id=track_id,
+            ),
             headers=self.headers(),
         )
 
-    async def search_artist(self, query: str, limit: int = 10) -> Dict[str, Any]:
+    async def search_artist(
+        self,
+        query: str,
+        limit: int = 10,
+        offset: int = 0,
+    ) -> Dict[str, Any]:
         """
         Search all artists by prefix or fullname
             :param query: Artist name or search prefix
             :param limit: Determines how many artists the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 artists.
+            :param offset: A parameter that determines with which song to display the request.
+                The default is 0. If you want to skip the first few songs, set this parameter to
+                your own.
             :return: dict artists
         """
         return await self.request(
             "GET",
             ShazamUrl.SEARCH_ARTIST.format(
-                query,
-                limit,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                query=query,
             ),
             headers=self.headers(),
         )
 
-    async def search_track(self, query: str, limit: int = 10) -> Dict[str, Any]:
+    async def search_track(self, query: str, limit: int = 10, offset: int = 0) -> Dict[str, Any]:
         """
         Search all tracks by prefix
             :param query: Track full title or prefix title
             :param limit: Determines how many songs the maximum can be in the request.
                 Example: If 5 is specified, the query will return no more than 5 songs.
+            :param offset: A parameter that determines with which song to display the request.
+                The default is 0. If you want to skip the first few songs, set this parameter to
+                your own.
             :return: dict songs
         """
         return await self.request(
             "GET",
             ShazamUrl.SEARCH_MUSIC.format(
-                query,
-                limit,
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                limit=limit,
+                offset=offset,
+                query=query,
             ),
             headers=self.headers(),
         )
@@ -322,9 +368,10 @@ async def send_recognize_request(self, sig: DecodedMessage) -> Dict[str, Any]:
         return await self.request(
             "POST",
             ShazamUrl.SEARCH_FROM_FILE.format(
-                str(uuid.uuid4()).upper(),
-                str(uuid.uuid4()).upper(),
                 language=self.language,
+                endpoint_country=self.endpoint_country,
+                uuid_1=str(uuid.uuid4()).upper(),
+                uuid_2=str(uuid.uuid4()).upper(),
             ),
             headers=self.headers(),
             json=data,
diff --git a/shazamio/misc.py b/shazamio/misc.py
index ea506fc..40e8db3 100644
--- a/shazamio/misc.py
+++ b/shazamio/misc.py
@@ -4,52 +4,52 @@
 
 class ShazamUrl:
     SEARCH_FROM_FILE = (
-        "https://amp.shazam.com/discovery/v5/en/GB/iphone/-/tag/{}/{"
-        "}?sync=true&webv3=true&sampling=true "
+        "https://amp.shazam.com/discovery/v5/{language}/{endpoint_country}/iphone/-/tag"
+        "/{uuid_1}/{uuid_2}?sync=true&webv3=true&sampling=true"
         "&connected=&shazamapiversion=v3&sharehub=true&hubv5minorversion=v5.1&hidelb=true&video=v3"
     )
     TOP_TRACKS_WORLD = (
-        "https://www.shazam.com/shazam/v3/en/GB/web/-/tracks/ip-global-chart"
-        "?pageSize={}&startFrom={}"
-    )
-    ARTIST_ABOUT = (
-        "https://www.shazam.com/discovery/v3/en/GB/web/artist/{" "}?shazamapiversion=v3&video=v3 "
+        "https://www.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/ip-global-chart?pageSize={limit}&startFrom={offset}"
     )
     ABOUT_TRACK = (
-        "https://www.shazam.com/discovery/v5/en/GB/web/-/track/{" "}?shazamapiversion=v3&video=v3 "
+        "https://www.shazam.com/discovery/v5/{language}/{endpoint_country}/web/-/track"
+        "/{track_id}?shazamapiversion=v3&video=v3 "
     )
     TOP_TRACKS_COUNTRY = (
-        "https://www.shazam.com/shazam/v3/en/GB/web/-/tracks/ip-country-chart-{}?pageSize={"
-        "}&startFrom={}"
+        "https://www.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/ip-country-chart-{country_code}?pageSize={limit}&startFrom={offset}"
     )
     TOP_TRACKS_CITY = (
-        "https://www.shazam.com/shazam/v3/en/GB/web/-/tracks/ip-city-chart-{}?pageSize={"
-        "}&startFrom={}"
+        "https://www.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/ip-city-chart-{city_id}?pageSize={limit}&startFrom={offset}"
     )
     CITY_IDS = "https://raw.githubusercontent.com/dotX12/dotX12/main/city.json"
     GENRE_WORLD = (
-        "https://www.shazam.com/shazam/v3/en/GB/web/-/tracks/genre-global-chart-{}?pageSize={"
-        "}&startFrom={}"
+        "https://www.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/genre-global-chart-{genre}?pageSize={limit}&startFrom={offset}"
     )
     GENRE_COUNTRY = (
-        "https://www.shazam.com/shazam/v3/en/GB/web/-/tracks/genre-country-chart-{}-{}?pageSize={"
-        "}&startFrom={}"
+        "https://www.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/genre-country-chart-{country}-{genre}?pageSize={limit}&startFrom={offset}"
     )
     RELATED_SONGS = (
-        "https://cdn.shazam.com/shazam/v3/en/GB/web/-/tracks/track-similarities-id-{}"
-        "?startFrom={}&pageSize={}&connected=&channel="
+        "https://cdn.shazam.com/shazam/v3/{language}/{endpoint_country}/web/-/tracks"
+        "/track-similarities-id-{track_id}?startFrom={limit}&pageSize={offset}&connected=&channel="
     )
     SEARCH_ARTIST = (
-        "https://www.shazam.com/services/search/v4/en-US/RU/web/search?term={}"
-        "&offset=0&limit={}&types=artists"
+        "https://www.shazam.com/services/search/v4/{language}/{endpoint_country}/web"
+        "/search?term={query}&limit={limit}&offset={offset}&types=artists"
     )
     SEARCH_MUSIC = (
-        "https://www.shazam.com/services/search/v3/en/GB/web/search?query={}"
-        "&numResults={}&offset=0&types=songs"
+        "https://www.shazam.com/services/search/v3/{language}/{endpoint_country}/web"
+        "/search?query={query}&numResults={limit}&offset={offset}&types=songs"
     )
     LISTENING_COUNTER = "https://www.shazam.com/services/count/v2/web/track/{}"
 
-    SEARCH_ARTIST_V2 = "https://www.shazam.com/services/amapi/v1/catalog/{language}/artists/{}"
+    SEARCH_ARTIST_V2 = (
+        "https://www.shazam.com/services/amapi/v1/catalog/{endpoint_country}/artists/{artist_id}"
+    )
 
 
 class Request:


Test patch:
diff --git a/tests/test_about_artist.py b/tests/test_about_artist.py
index 5ca9054..99c5c4a 100644
--- a/tests/test_about_artist.py
+++ b/tests/test_about_artist.py
@@ -30,4 +30,4 @@ async def test_about_artist():
 
     serialized = Serialize.artist_v2(about_artist)
     assert serialized.data[0].attributes.name == "Markul"
-    assert "Hip-hop/Rap" in serialized.data[0].attributes.genre_names
+    assert "Hip-Hop/Rap" in serialized.data[0].attributes.genre_names