import random

songs_data = []
song_list = [
    "Jeff Russo, Noah Hawley - Burning Down the House",
    "Radiohead - Everything in Its Right Place",
    "UNKLE - Lonely Souls",
    "Kendrick Lamar - Sing About Me, I'm Dying of Thirst",
    "The Verve - One Day",
    "Thom Yorke - Analyze",
    "Atoms for Peace - Reverse Running",
    "Portishead - The Rip",
    "Nick Drake - Riverman",
    "The Doors - The End",
    "The Police - Synchronicity II",
    "Incubus - Quicksand",
    'Black Angels - Black Grease'
]

def initSongs():
    item_id = 0
    for item in song_list:
        songs_data.append({"id": item_id, "song": item, "banger": 0, "not banger": 0})
        item_id += 1
    for i in range(200):
        id = getRandomSong()['id']
        addSongBanger(id)
    for i in range(50):
        id = getRandomSong()['id']
        addSongNot(id)
        
def getSongs():
    return(songs_data)

def getSong(id):
    return(songs_data[id])

def getRandomSong():
    return(random.choice(songs_data))

def favoriteSong():
    best = 0
    bestID = -1
    for song in getSongs():
        if song['banger'] > best:
            best = song['banger']
            bestID = song['id']
    return songs_data[bestID]
    
def jeeredSong():
    worst = 0
    worstID = -1
    for song in getSongs():
        if song['not banger'] > worst:
            worst = song['not banger']
            worstID = song['id']
    return songs_data[worstID]

def addSongBanger(id):
    songs_data[id]['banger'] = songs_data[id]['banger'] + 1
    return songs_data[id]['banger']

def addSongNot(id):
    songs_data[id]['not banger'] = songs_data[id]['not banger'] + 1
    return songs_data[id]['not banger']

def printSong(song):
    print(song['id'], song['song'], "\n", "banger:", song['banger'], "\n", "not banger:", song['not banger'], "\n")

def countSongs():
    return len(songs_data)

if __name__ == "__main__": 
    initSongs()
    
    best = favoriteSong()
    print("Most liked", best['banger'])
    printSong(best)
    worst = jeeredSong()
    print("Most jeered", worst['not banger'])
    printSong(worst)
    
    print("Random song")
    printSong(getRandomSong())
    
    print("Songs Count: " + str(countSongs()))
Most liked 24
2 UNKLE - Lonely Souls 
 banger: 24 
 not banger: 2 

Most jeered 6
8 Nick Drake - Riverman 
 banger: 16 
 not banger: 6 

Random song
9 The Doors - The End 
 banger: 11 
 not banger: 3 

Songs Count: 13
from flask import Blueprint, jsonify
from flask_restful import Api, Resource
import requests
import random

app_api = Blueprint('api', __name__,
                   url_prefix='/api/songs')

api = Api(app_api)

class SongsAPI:
    class _Create(Resource):
        def post(self, song):
            pass
            
    class _Read(Resource):
        def get(self):
            return jsonify(getSongs())

    class _ReadID(Resource):
        def get(self, id):
            return jsonify(getSong(id))

    class _ReadRandom(Resource):
        def get(self):
            return jsonify(getRandomSong())
    
    class _ReadCount(Resource):
        def get(self):
            count = countSongs()
            countMsg = {'count': count}
            return jsonify(countMsg)

    class _UpdateLike(Resource):
        def put(self, id):
            addSongBanger(id)
            return jsonify(getSong(id))

    class _UpdateJeer(Resource):
        def put(self, id):
            addSongNot(id)
            return jsonify(getSong(id))

    api.add_resource(_Create, '/create/<string:song>')
    api.add_resource(_Read, '/')
    api.add_resource(_ReadID, '/<int:id>')
    api.add_resource(_ReadRandom, '/random')
    api.add_resource(_ReadCount, '/count')
    api.add_resource(_UpdateLike, '/like/<int:id>/')
    api.add_resource(_UpdateJeer, '/jeer/<int:id>/')
server = 'https://flask.maniflpt.com/'
url = server + "api/songs/"
responses = []

count_response = requests.get(url+"count")
count_json = count_response.json()
count = count_json['count']

num = str(random.randint(0, count-1))
responses.append(
    requests.get(url+num)
    ) 
responses.append(
    requests.put(url+"like/"+num)
    ) 
responses.append(
    requests.put(url+"jeer/"+num)
    ) 

responses.append(
    requests.get(url+"random")
    ) 

for response in responses:
    print(response)
    try:
        print(response.json())
    except:
        print("data error")
---------------------------------------------------------------------------
gaierror                                  Traceback (most recent call last)
File ~/anaconda3/lib/python3.9/site-packages/urllib3/connection.py:174, in HTTPConnection._new_conn(self)
    173 try:
--> 174     conn = connection.create_connection(
    175         (self._dns_host, self.port), self.timeout, **extra_kw
    176     )
    178 except SocketTimeout:

File ~/anaconda3/lib/python3.9/site-packages/urllib3/util/connection.py:72, in create_connection(address, timeout, source_address, socket_options)
     68     return six.raise_from(
     69         LocationParseError(u"'%s', label empty or too long" % host), None
     70     )
---> 72 for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
     73     af, socktype, proto, canonname, sa = res

File ~/anaconda3/lib/python3.9/socket.py:954, in getaddrinfo(host, port, family, type, proto, flags)
    953 addrlist = []
--> 954 for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    955     af, socktype, proto, canonname, sa = res

gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

NewConnectionError                        Traceback (most recent call last)
File ~/anaconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:703, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    702 # Make the request on the httplib connection object.
--> 703 httplib_response = self._make_request(
    704     conn,
    705     method,
    706     url,
    707     timeout=timeout_obj,
    708     body=body,
    709     headers=headers,
    710     chunked=chunked,
    711 )
    713 # If we're going to release the connection in ``finally:``, then
    714 # the response doesn't need to know about the connection. Otherwise
    715 # it will also try to release it and we'll have a double-release
    716 # mess.

File ~/anaconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:386, in HTTPConnectionPool._make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    385 try:
--> 386     self._validate_conn(conn)
    387 except (SocketTimeout, BaseSSLError) as e:
    388     # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.

File ~/anaconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:1040, in HTTPSConnectionPool._validate_conn(self, conn)
   1039 if not getattr(conn, "sock", None):  # AppEngine might not have  `.sock`
-> 1040     conn.connect()
   1042 if not conn.is_verified:

File ~/anaconda3/lib/python3.9/site-packages/urllib3/connection.py:358, in HTTPSConnection.connect(self)
    356 def connect(self):
    357     # Add certificate verification
--> 358     self.sock = conn = self._new_conn()
    359     hostname = self.host

File ~/anaconda3/lib/python3.9/site-packages/urllib3/connection.py:186, in HTTPConnection._new_conn(self)
    185 except SocketError as e:
--> 186     raise NewConnectionError(
    187         self, "Failed to establish a new connection: %s" % e
    188     )
    190 return conn

NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x7f7dbd302cd0>: Failed to establish a new connection: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

MaxRetryError                             Traceback (most recent call last)
File ~/anaconda3/lib/python3.9/site-packages/requests/adapters.py:440, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
    439 if not chunked:
--> 440     resp = conn.urlopen(
    441         method=request.method,
    442         url=url,
    443         body=request.body,
    444         headers=request.headers,
    445         redirect=False,
    446         assert_same_host=False,
    447         preload_content=False,
    448         decode_content=False,
    449         retries=self.max_retries,
    450         timeout=timeout
    451     )
    453 # Send the request.
    454 else:

File ~/anaconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:785, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    783     e = ProtocolError("Connection aborted.", e)
--> 785 retries = retries.increment(
    786     method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
    787 )
    788 retries.sleep()

File ~/anaconda3/lib/python3.9/site-packages/urllib3/util/retry.py:592, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
    591 if new_retry.is_exhausted():
--> 592     raise MaxRetryError(_pool, url, error or ResponseError(cause))
    594 log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)

MaxRetryError: HTTPSConnectionPool(host='flask.maniflpt.com', port=443): Max retries exceeded with url: /api/songs/count (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f7dbd302cd0>: Failed to establish a new connection: [Errno -2] Name or service not known'))

During handling of the above exception, another exception occurred:

ConnectionError                           Traceback (most recent call last)
/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb Cell 4 in <cell line: 5>()
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=1'>2</a> url = server + "api/songs/"
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=2'>3</a> responses = []
----> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=4'>5</a> count_response = requests.get(url+"count")
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=5'>6</a> count_json = count_response.json()
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/tmani/vscode/manimani/_notebooks/2022-10-17-PBL-webapi_tutorial.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=6'>7</a> count = count_json['count']

File ~/anaconda3/lib/python3.9/site-packages/requests/api.py:75, in get(url, params, **kwargs)
     64 def get(url, params=None, **kwargs):
     65     r"""Sends a GET request.
     66 
     67     :param url: URL for the new :class:`Request` object.
   (...)
     72     :rtype: requests.Response
     73     """
---> 75     return request('get', url, params=params, **kwargs)

File ~/anaconda3/lib/python3.9/site-packages/requests/api.py:61, in request(method, url, **kwargs)
     57 # By using the 'with' statement we are sure the session is closed, thus we
     58 # avoid leaving sockets open which can trigger a ResourceWarning in some
     59 # cases, and look like a memory leak in others.
     60 with sessions.Session() as session:
---> 61     return session.request(method=method, url=url, **kwargs)

File ~/anaconda3/lib/python3.9/site-packages/requests/sessions.py:529, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    524 send_kwargs = {
    525     'timeout': timeout,
    526     'allow_redirects': allow_redirects,
    527 }
    528 send_kwargs.update(settings)
--> 529 resp = self.send(prep, **send_kwargs)
    531 return resp

File ~/anaconda3/lib/python3.9/site-packages/requests/sessions.py:645, in Session.send(self, request, **kwargs)
    642 start = preferred_clock()
    644 # Send the request
--> 645 r = adapter.send(request, **kwargs)
    647 # Total elapsed time of the request (approximately)
    648 elapsed = preferred_clock() - start

File ~/anaconda3/lib/python3.9/site-packages/requests/adapters.py:519, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
    515     if isinstance(e.reason, _SSLError):
    516         # This branch is for urllib3 v1.22 and later.
    517         raise SSLError(e, request=request)
--> 519     raise ConnectionError(e, request=request)
    521 except ClosedPoolError as e:
    522     raise ConnectionError(e, request=request)

ConnectionError: HTTPSConnectionPool(host='flask.maniflpt.com', port=443): Max retries exceeded with url: /api/songs/count (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f7dbd302cd0>: Failed to establish a new connection: [Errno -2] Name or service not known'))