I am using rest_framework_simple_api_key in my production application on python version 3.9 . On running command
python generate_fernet_keymanage.py as given in doc(djangorestframework-simple-apikey) i am getting
File "C:\Users\DELL\anaconda3\lib\site-packages\rest_framework_simple_api_key\models.py", line 15, in <module>
class AbstractAPIKeyManager(models.Manager):
File "C:\Users\DELL\anaconda3\lib\site-packages\rest_framework_simple_api_key\models.py", line 16, in AbstractAPIKeyManager
def get_api_key(self, pk: int | str):
TypeError: unsupported operand type(s) for |: 'type' and 'type'
On Searching I got reason is i am getting error is The error TypeError: unsupported operand type(s) for |: 'type' and 'type' is caused by the use of the int | str syntax for type hinting, which is only supported in Python 3.10 and later versions. I can't change my python version as it is in production so I came across solution monkey patching then i got this article https://medium.com/lemon-code/monkey-patch-f1de778d61d3 my monkey_patch.py file:
def patch_get_api_key():
print("*********************************EXE****************************************")
"""
Monkey patch for AbstractAPIKeyManager.get_api_key method to replace the type hint.
"""
from typing import Union
def patched_get_api_key(self, pk: Union[int, str]):
try:
print("Patched get_api_key method")
return self.get(pk=pk)
except self.model.DoesNotExist:
return None
print("Before import")
import rest_framework_simple_api_key.models as models
print("After import")
models.AbstractAPIKeyManager.get_api_key = patched_get_api_key
I added code in my apps.py file:
# myapp/apps.py
from django.apps import AppConfig
class MyCustomAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'roomroot'
def ready(self):
""" Load monkey patching. """
try:
from .monkey_patch import patch_get_api_key
patch_get_api_key()
except ImportError:
pass
and called it in manage.py file:
def main():
"""Run administrative tasks."""
settings_module = "roomroot.deployment" if "WEBSITEHOSTNAME" in os.environ else "roomroot.settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module)
from roomroot.monkey_patch import patch_get_api_key
patch_get_api_key()
by running command for generating generate_fernet_key i am getting error:
python manage.py generate_fernet_key
*********************************EXE****************************************
Before import
Traceback (most recent call last):
File "F:\Abha\Room_Reveal\Backend\roomroot\manage.py", line 27, in <module>
main()
File "F:\Abha\Room_Reveal\Backend\roomroot\manage.py", line 14, in main
patch_get_api_key()
File "F:\Abha\Room_Reveal\Backend\roomroot\roomroot\monkey_patch.py", line 18, in patch_get_api_key
from rest_framework_simple_api_key.models import AbstractAPIKeyManager
File "C:\Users\DELL\anaconda3\lib\site-packages\rest_framework_simple_api_key\models.py", line 15, in <module>
class AbstractAPIKeyManager(models.Manager):
File "C:\Users\DELL\anaconda3\lib\site-packages\rest_framework_simple_api_key\models.py", line 16, in AbstractAPIKeyManager
def get_api_key(self, pk: int | str):
TypeError: unsupported operand type(s) for |: 'type' and 'type'
My question is using patch to do resolve this error is good idea? Also I tried calling my patch_get_api_key() in setting.py file still getting type error.
No amount of monkey patching is going to help you solve that issue. To monkey patch the method you need to import the module, when the module is being imported / loaded the class definition and hence the method definition would occur causing the TypeError
before you ever have the chance to patch it.
You have two sensible solutions: