<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Having problems with asyncio and 429 errors in Network Platform API</title>
    <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436600#M5843</link>
    <description>&lt;P&gt;&amp;gt;&lt;SPAN&gt;To bad, that it wasn't updated in 2 years&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;There are no issues or pull requests.  Perhaps it is as simple as nothing is broken, and it does exactly all it needs to do.  &lt;SPAN class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;&lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Fri, 19 May 2023 20:49:40 GMT</pubDate>
    <dc:creator>Philip D'Ath</dc:creator>
    <dc:date>2023-05-19T20:49:40Z</dc:date>
    <item>
      <title>Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436595#M5838</link>
      <description>&lt;P&gt;I have been tasked with creating a list of every client in an org that has been whitelisted.  I think there could be between 200,000 and 300,000 clients.&lt;/P&gt;&lt;P&gt;My plan of attack was to iterate through every network, use getNetworkClients to get every client, and iterate through them calling getNetworkClientPolicy on every client to see if they are whitelisted.&lt;/P&gt;&lt;P&gt;If I drop the concurrency to just 1 the below code snippet works fine (but very slow):&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample language-python"&gt;&lt;CODE&gt;async with meraki.aio.AsyncDashboardAPI(
	output_log=False,
	print_console=False,
	maximum_concurrent_requests=1
) as dashboard:
	await searchOrg(dashboard,orgName)
...
clientTasks = [checkPolicy(dashboard,net['id'],client) for client in await dashboard.networks.getNetworkClients(net['id'],total_pages='all',timespan=1*86400)]
for task in asyncio.as_completed(clientTasks):
	await task
...
async def checkPolicy(dashboard,netId,client):
	policies=await dashboard.networks.getNetworkClientPolicy(netId,client['id'])
	if policies['devicePolicy'] == 'Whitelisted':
		print(f"{client['mac']},{client['ip']},{client['description']}")
	elif policies['devicePolicy'] == 'Different policies by SSID':
		print(f"{client['mac']},{client['ip']},{client['description']},{policies['ssids']}")&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;If I change maximum_concurrent_requests from 1 to 2 I start getting a reasonable number of 429 warnings, but it does run.  It I change it to 5 I get a huge number of 429s, and this error gets thrown after a short amount of processing time:&lt;BR /&gt;&lt;BR /&gt;meraki.exceptions.AsyncAPIError: networks, getNetworkClientPolicy - 429 Too Many Requests, Reached retry limit: None&lt;/P&gt;&lt;P&gt;I don't understand with a limit of just 2 why I am hitting any limit and getting 429s.  And then, if the rety limit is "none", why is it throwing an exception.&lt;/P&gt;&lt;P&gt;I really want the concurrency at least at 5.  Any ideas?&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 04:47:39 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436595#M5838</guid>
      <dc:creator>Philip D'Ath</dc:creator>
      <dc:date>2023-05-19T04:47:39Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436596#M5839</link>
      <description>&lt;P&gt;In the async with block, add the parameters to wait on retry and set a high retry count - this is how I do it, seems reliable.&lt;/P&gt;&lt;P&gt;The library will start adding waits before retry and the result is that it'll converge on running at about the natural rate limit.&lt;/P&gt;&lt;PRE class="lia-code-sample language-python"&gt;&lt;CODE&gt;    async with meraki.aio.AsyncDashboardAPI(
        api_key=API_KEY,
        base_url='https://api.meraki.com/api/v1/',
        print_console=False,
        output_log=False,
        suppress_logging=True,
        wait_on_rate_limit=True,
        maximum_retries=100
    ) as aiomeraki:&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 19 May 2023 06:32:58 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436596#M5839</guid>
      <dc:creator>sungod</dc:creator>
      <dc:date>2023-05-19T06:32:58Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436597#M5840</link>
      <description>&lt;P&gt;I have had luck with using a Throttler, but you have to play with the timers sometimes.&lt;/P&gt;&lt;P&gt;It will also depend if you have other scripts running against the API on your ORG, which will impact your rate limit.&lt;/P&gt;&lt;PRE class="lia-code-sample language-markup"&gt;&lt;CODE&gt;from asyncio_throttle import Throttler

# Used to control flow of API calls to the API interface
throttler = Throttler(rate_limit=16, period=1)

# snip of code

async def gather_ports(aiomeraki, serial):

    # had to use throttler or it would overun the API.
    async with throttler:
        try:
            switch_ports = await aiomeraki.switch.getDeviceSwitchPorts(serial)

        except meraki.AsyncAPIError as e:
            print(f"Meraki API error: {e}")
        except Exception as e:
            print(f"some other error: {e}")&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 19 May 2023 11:25:11 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436597#M5840</guid>
      <dc:creator>Andy Mikulas</dc:creator>
      <dc:date>2023-05-19T11:25:11Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436598#M5841</link>
      <description>&lt;P&gt;the asyncio api is just a really dumb semaphore. It is just sending 5 (per default) maximum requests at the same time.&lt;BR /&gt;So if the response of the requests is really quick, then we might hit the rate limit with the script.&lt;/P&gt;&lt;P&gt;you could try to overwrite the builtin semaphore with the throttler (it looks really nice btw. To bad, that it wasn't updated in 2 years &lt;SPAN class="lia-unicode-emoji" title=":face_with_rolling_eyes:"&gt;&lt;span class="lia-unicode-emoji" title=":face_with_rolling_eyes:"&gt;🙄&lt;/span&gt;&lt;/SPAN&gt; )&lt;/P&gt;&lt;PRE class="lia-code-sample language-python"&gt;&lt;CODE&gt;aiomeraki._session._concurrent_requests_semaphore = throttler&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 19 May 2023 19:24:15 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436598#M5841</guid>
      <dc:creator>Greenberet</dc:creator>
      <dc:date>2023-05-19T19:24:15Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436599#M5842</link>
      <description>&lt;P&gt;Thank you for you all your suggestions.  I tried several of these approaches and found this one worked the best for me.&lt;/P&gt;&lt;P&gt;I used this module:&lt;BR /&gt;&lt;A href="https://github.com/uburuntu/throttler" target="_self" rel="nofollow noopener noreferrer"&gt;https://github.com/uburuntu/throttler&lt;/A&gt; &lt;BR /&gt;pip3 install -U throttler&lt;BR /&gt;&lt;BR /&gt;I added this import:&lt;BR /&gt;import throttler&lt;/P&gt;&lt;P&gt;And then I used &lt;A href="https://community.meraki.com/t5/user/viewprofilepage/user-id/33943"&gt;@Greenberet&lt;/A&gt;'s idea to replace the semaphore:&lt;/P&gt;&lt;PRE class="lia-code-sample language-python"&gt;&lt;CODE&gt;async with meraki.aio.AsyncDashboardAPI(
	output_log=False,
	print_console=False
) as dashboard:
	dashboard._session._concurrent_requests_semaphore = throttler.Throttler(rate_limit=5, period=1.0)
	await searchOrg(dashboard,orgName)&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I get zero 429 errors, no retries, nothing.  It just pumps through the requests at 5 per second.&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 20:48:02 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436599#M5842</guid>
      <dc:creator>Philip D'Ath</dc:creator>
      <dc:date>2023-05-19T20:48:02Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436600#M5843</link>
      <description>&lt;P&gt;&amp;gt;&lt;SPAN&gt;To bad, that it wasn't updated in 2 years&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;There are no issues or pull requests.  Perhaps it is as simple as nothing is broken, and it does exactly all it needs to do.  &lt;SPAN class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;&lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 20:49:40 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436600#M5843</guid>
      <dc:creator>Philip D'Ath</dc:creator>
      <dc:date>2023-05-19T20:49:40Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436601#M5844</link>
      <description>&lt;P&gt;As it turns out - not completely solved.  I think I might be running into Python bugs (using 3.11.3).  Maybe 200,000 API calls in I start getting errors like:&lt;/P&gt;&lt;P&gt;[WinError 121] The semaphore timeout period has expired&lt;/P&gt;&lt;P&gt;Then the rate of 429s start going up a lot - but it does still work (I think, hard to tell for sure).  I've had to bumpo the maximum_retries as suggested by &lt;A href="https://community.meraki.com/t5/user/viewprofilepage/user-id/1069"&gt;@jscorb&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Sun, 21 May 2023 20:21:37 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436601#M5844</guid>
      <dc:creator>Philip D'Ath</dc:creator>
      <dc:date>2023-05-21T20:21:37Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436602#M5845</link>
      <description>&lt;P&gt;When there's a 429 return, the library code looks for Retry-After in the response headers and waits for that period.&lt;/P&gt;&lt;P&gt;If that isn't in the headers, it waits for a random time between 1 and nginx_429_retry_wait_time (default is 60, you can specify a different value in the async block.)&lt;/P&gt;&lt;P&gt;So the 429s happen, but they don't matter due to the retry mechanism&lt;/P&gt;&lt;P&gt;If you're issuing a &lt;EM&gt;lot&lt;/EM&gt; of calls at once, they'll get stacked up by the wait/retry, and maybe you'll hit some internal resource limit, might be worth making the the calls in batches of, say, 2,000.&lt;/P&gt;</description>
      <pubDate>Mon, 22 May 2023 07:12:38 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436602#M5845</guid>
      <dc:creator>sungod</dc:creator>
      <dc:date>2023-05-22T07:12:38Z</dc:date>
    </item>
    <item>
      <title>Re: Having problems with asyncio and 429 errors</title>
      <link>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436603#M5846</link>
      <description>&lt;P&gt;Did you solve your issue or are you still having problems ?&lt;/P&gt;</description>
      <pubDate>Tue, 04 Jul 2023 02:55:19 GMT</pubDate>
      <guid>https://community.cisco.com/t5/network-platform-api/having-problems-with-asyncio-and-429-errors/m-p/5436603#M5846</guid>
      <dc:creator>ssinfra</dc:creator>
      <dc:date>2023-07-04T02:55:19Z</dc:date>
    </item>
  </channel>
</rss>

