Forum Discussion

nickzxcv's avatar
nickzxcv
Level 2
2 years ago

Pagination for fabric connections search?

I'm writing a script to see how oversubscribed my fabric ports are, by totaling the bandwidth of connections on each port. I'm having trouble with the pagination, no matter what I set for offset and limit in the query parameters, it always seems to come back with offset=0.

https://api.equinix.com/fabric/v4/connections/search
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=20&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=40&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=60&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=80&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=100&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=120&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=140&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=160&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}
https://api.equinix.com/fabric/v4/connections/search?offset=180&limit=20
{'next': '/search?offset=20&limit=20', 'offset': 0, 'total': 193, 'limit': 20}

 

import requests

def get_bearer_token():
    auth_url = 'https://api.equinix.com/oauth2/v1/token'
    credentials = {
        'grant_type': 'client_credentials',
        'client_id': 'XXXXXXXXXXXXXXXXXX',
        'client_secret': 'YYYYYYYYYYYYYYYYY'
    }

    credentials_response = requests.post(auth_url, json=credentials).json()
    return credentials_response['access_token']

token=get_bearer_token()
headers = {'Authorization': 'Bearer {}'.format(token)}

api_v4_url_base = 'https://api.equinix.com/fabric/v4'

ports = dict()
ports_url = api_v4_url_base + '/ports'
ports_response = requests.get(ports_url, headers=headers).json()

for port in ports_response['data']:
    name = port['name']
    bandwidth = port['bandwidth']
    ports[name] = dict()
    ports[name]['bandwidth'] = bandwidth
    ports[name]['connected_bandwidth']=0
    ports[name]['connections'] = dict()

connections = dict()
connections_url = api_v4_url_base + '/connections'
search_base = '/search'
filter_data = {'filter': { 'and':
    [
        {
            'property': '/aSide/accessPoint/port/name',
            'operator': '=',
            'values': list(ports.keys())
        },
        {
            'property': '/operation/equinixStatus',
            'operator': '=',
            'values': [ 'PROVISIONED', 'DEPROVISIONED' ]
        }
    ]
} }

more = True
offset = 0
while more == True:
    connections_url_search = connections_url + search_base
    print(connections_url_search)
    connections_response = requests.post(
        connections_url_search, json=filter_data, headers=headers).json()
    total = connections_response['pagination']['total']
    limit = connections_response['pagination']['limit']
    print(connections_response['pagination'])

    if offset + limit > total:
        more = False
    else:
        offset += limit
        search_base = '/search?offset={}&limit={}'.format(offset, limit)

    #for connection in connections_response['data']:
    #    port = connection['aSide']['accessPoint']['port']['name']
    #    name = connection['name']
    #    bandwidth = connection['bandwidth']
    #    ports[port]['connected_bandwidth'] += bandwidth
    #    ports[port]['connections'][name] = connection
    #    print("{}: {} - {}".format(name, bandwidth, port))
    #print()

 

I tried also just using the "next" page value from the response, but it had this problem too, so I tried calculating the offset myself. It always seems to only return the first page. Setting the limit as 10 for example also seems to have no effect, still returning 20 records. Can anyone reproduce this or tell me what I'm doing wrong? Thanks!

  • Hi nickzxcv ,

    Thank you for reaching to Equinix Fabric Team.

    Please use the limit and offset properties in the request payload. Query Parameter search capability is not enabled for all the search API's.

    Regards,

    Equnix Fabric Engineering Team

     

     

     

  • Here's how I got the pagination to work:

    import requests
    import logging
    
    def get_bearer_token():
        auth_url = 'https://api.equinix.com/oauth2/v1/token'
        credentials = {
            'grant_type': 'client_credentials',
            'client_id': 'XXXXXXXXXXXXXXXXXXXXX',
            'client_secret': 'YYYYYYYYYYYYYYYYYYYYYY'
        }
        
        credentials_response = requests.post(auth_url, json=credentials).json()
        return credentials_response['access_token']
    
    token=get_bearer_token()
    headers = {'Authorization': 'Bearer {}'.format(token)}
    
    api_v4_url_base = 'https://api.equinix.com/fabric/v4'
    
    ports = dict()
    ports_url = api_v4_url_base + '/ports'
    ports_response = requests.get(ports_url, headers=headers).json()
    
    for port in ports_response['data']:
        name = port['name']
        bandwidth = port['bandwidth']
        ports[name] = dict()
        ports[name]['bandwidth'] = bandwidth
        ports[name]['connected_bandwidth']=0
        ports[name]['connections'] = dict()
    
    connections = dict()
    connections_url = api_v4_url_base + '/connections/search'
    post_body = {'filter': { 'and':
        [
            { 
                'property': '/aSide/accessPoint/port/name',
                'operator': '=',
                'values': list(ports.keys())
            },
            {
                'property': '/operation/equinixStatus',
                'operator': '=',
                'values': [ 'PROVISIONED' ]
            }
        ] 
    }, 'pagination': {'offset': 0} }
    
    more = True
    while more == True:
        connections_response = requests.post(
            connections_url, json=post_body, headers=headers).json()
        total = connections_response['pagination']['total']
        limit = connections_response['pagination']['limit']
    
        if post_body['pagination']['offset'] + limit > total:
            more = False
        else:
            post_body['pagination']['offset'] += limit
    
        for connection in connections_response['data']:
            port = connection['aSide']['accessPoint']['port']['name']
            name = connection['name']
            bandwidth = connection['bandwidth']
            ports[port]['connected_bandwidth'] += bandwidth
            ports[port]['connections'][name] = connection
            print("{}: {} - {}".format(name, bandwidth, port))
        print()
    
    
    • Jantzen's avatar
      Jantzen
      Equinix Employee

      Thanks for sharing your working solution! This will help others that come across this thread.

  • aanchala's avatar
    aanchala
    Equinix Employee

    Hi nickzxcv ,

    Thank you for reaching to Equinix Fabric Team.

    Please use the limit and offset properties in the request payload. Query Parameter search capability is not enabled for all the search API's.

    Regards,

    Equnix Fabric Engineering Team

     

     

     

  • Thanks! That's exactly what I needed to know. I was confused by how the "next" part of the pagination response looked like query parameters, but I see in the API document also where it says pagination can be part of the request body.