Recursion Error when using Third Party APIs

Hello everyone,

I’m currently experiencing a persistent issue related to the utilization of specific third-party Python packages, namely ‘requests’, ‘openai’, and ‘geopy’. The problem surfaced a few months ago and has been persisting since then.

Whenever I try to use any of these packages, a RecursionError gets raised, specifying that the maximum recursion depth has been exceeded. The traceback points to the ssl.py module in Python 3.10, which seems to suggest that the issue arises when these libraries attempt to make calls outside of the server.

Here is the error message that I’m receiving:

RecursionError: maximum recursion depth exceeded
at /usr/local/lib/python3.10/ssl.py:620

For context, I am currently subscribed to the Professional plan.

I’m reaching out in hopes of obtaining some insights into this matter. Could this be a bug or is it related to my server configuration? Any advice or suggestions would be greatly appreciated.

Thank you in advance for your assistance.

I remember the last time you had a problem like this using 3.7 most of the answers from the wider internet said it had something to do with gevent, but nothing about that worked.

What if you tried installing the packages in Anvil in this order? maybe the having the latest one installed before the rest of the packages might help?

I tried that too. It doesn’t seem to be related to a specific library. My gut is telling me it has something to do with not having a persistent server running?

That was also my guess, but it was just a guess so I didn’t say anything :see_no_evil:

1 Like

If that is the case, I hope the Anvil team will fix the issue. Since my function is still running, the session “should” still be live? One would think… Sometimes that just gets us in trouble :crazy_face:

Hi @chad63e, could you post the full traceback of your code (not just the top line)? That way we can see what the recursion loop is

This is with Open AI
RecursionError: maximum recursion depth exceeded

  • at /usr/local/lib/python3.10/ssl.py:620
  • called from /usr/local/lib/python3.10/ssl.py:620
  • called from /usr/local/lib/python3.10/ssl.py:620
  • called from /home/anvil/.env/lib/python3.10/site-packages/urllib3/util/ssl_.py:312
  • called from /home/anvil/.env/lib/python3.10/site-packages/urllib3/connection.py:400
  • called from /home/anvil/.env/lib/python3.10/site-packages/urllib3/connectionpool.py:1042
  • called from /home/anvil/.env/lib/python3.10/site-packages/urllib3/connectionpool.py:386
  • called from /home/anvil/.env/lib/python3.10/site-packages/urllib3/connectionpool.py:703
  • called from /home/anvil/.env/lib/python3.10/site-packages/requests/adapters.py:489
  • called from /home/anvil/.env/lib/python3.10/site-packages/requests/sessions.py:701
  • called from /home/anvil/.env/lib/python3.10/site-packages/requests/sessions.py:587
  • called from /home/anvil/.env/lib/python3.10/site-packages/openai/api_requestor.py:516
  • called from /home/anvil/.env/lib/python3.10/site-packages/openai/api_requestor.py:216
  • called from /home/anvil/.env/lib/python3.10/site-packages/openai/api_resources/abstract/engine_api_resource.py:153
  • called from /home/anvil/.env/lib/python3.10/site-packages/openai/api_resources/completion.py:25
  • called from ServerTools.errors, line 119
  • called from ServerTools.errors, line 22
  • called from ColorPaletteCreater, line 20

This is with GeoPy
GeocoderServiceError: maximum recursion depth exceeded while calling a Python object

  • at /home/anvil/.env/lib/python3.10/site-packages/geopy/adapters.py:472
  • called from /home/anvil/.env/lib/python3.10/site-packages/geopy/adapters.py:447
  • called from /home/anvil/.env/lib/python3.10/site-packages/geopy/geocoders/base.py:368
  • called from /home/anvil/.env/lib/python3.10/site-packages/geopy/geocoders/nominatim.py:297
  • called from ServerTools.geo_tools, line 115
  • called from ServerTools.geo_tools, line 141
  • called from ColorPaletteCreater, line 21

I don’t currently have any code written using the Request library.

For reference, I looked into this the other day, and the line is calling super() on the SSLContext class while creating a setter for the options property, but the options property aliases to an Options class that is written in C.

If I had to guess something with this class violating thread safety is why it keeps trying to create this setter property recursively, but “only in Anvil”.

image

https://github.com/python/cpython/blob/3.10/Lib/ssl.py

Hello Ian,

I hope all is well with you. I appreciate you spending the time to investigate the recursion error I’ve been getting when using third-party APIs in Anvil.

Your analysis suggests that the SSLContext class’s creation of a setter for the options property, which might be causing a recursion loop due to potential thread safety violations, may be the source of the issue.

I was hoping you might have a possible solution in mind or could point me in the direction of an alternative strategy to solve this problem to help me move forward. Can you recommend any changes to the code or point me in the right direction for pertinent information or resources to solve this issue?

I know this problem “only exists in Anvil,” so I would greatly appreciate any advice you could provide.

Looking forward to your response soon.

Thanks,

Chad

I really only know enough to say “this sounds wrong but I don’t know why”, and the only thing I could really end up doing is monkey-patching SSL code. (aka sub-optimal security)

I think the only legitimate fix could come from Anvil, it might even have something to do with the way Cpython uses system packages, and I definitely can’t fix any of those settings.
Or it could be…
threading,
multiprocessing,
coroutines,
concurrency issues,
[insert your own black magic python module here]
etc…

Skill Issue I guess. :thinking:

A quick Google search suggests that others not using Anvil have had similar errors when installing and configuring a Python environment that includes some of these packages. I would suggest starting from a minimal app and one-by-one, adding the libraries and function calls you need to see when the error starts occurring. Alternatively, you can start from your broken app and strip things out one-by-one until the error doesn’t occur.

After an extended journey into the troubleshooting abyss, I finally narrowed the issue down to these two lines of code!

import gevent.monkey
gevent.monkey.patch_all(thread=False)

All that trouble for a function I don’t think I’m even planning on using any longer :face_with_spiral_eyes:

@brooke
Thank you for encouraging me to delve deeper into this issue. Initially, I was convinced that the problem wasn’t originating from my side. However, after further investigation, I’ve come to realize that there were aspects of my code I hadn’t thoroughly examined. The root cause, it seems, was hidden within a dependency that I hadn’t noticed was part of the two applications where I was implementing third-party libraries, specifically LangChain and Gspread. The coincidence of encountering similar issues with both libraries led me to prematurely conclude that the fault lay elsewhere. I appreciate the nudge to reassess my assumptions.

@ianb
Thanks for your efforts in trying to help me resolve my issue.

5 Likes