DataDog / dd-trace-py

Datadog Python APM Client
https://ddtrace.readthedocs.io/
Other
535 stars 408 forks source link

AttributeError: type object 'Flask' has no attribute 'before_first_request' with Flask > 2.2.4 #5671

Closed sachams closed 1 year ago

sachams commented 1 year ago

Summary of problem

When running ddtrace='1.12.1' and flask='2.3.1', running a migration using flask db upgrade results in the following exception:

AttributeError: type object 'Flask' has no attribute 'before_first_request'. Did you mean: 'got_first_request'?

In the release notes for Flask 2.3.0 these decorators are listed as being removed:

The app.before_first_request and bp.before_app_first_request decorators are removed.

Reverting to flask='2.2.4' (the version before the decorators were removed) is fine - no exception is raised.

Which version of dd-trace-py are you using?

1.12.1

Which version of pip are you using?

22.3.1

Which libraries and their versions are you using?

`pip freeze` alembic==1.10.4 alembic-verify==0.1.4 async-timeout==4.0.2 attrs==23.1.0 autoflake==2.1.1 autopep8==2.0.2 bandit==1.7.5 basis-messaging==3.0.1 basis-sqlalchemy-filters==0.13.1 basis-utils==4.0.2 black==23.3.0 blinker==1.6.2 bytecode==0.14.1 cachelib==0.9.0 cachetools==5.3.0 cattrs==22.2.0 certifi==2022.12.7 cffi==1.15.1 cfgv==3.3.1 charset-normalizer==3.1.0 click==8.1.3 colorama==0.4.6 coverage==7.2.3 cryptography==40.0.2 ddsketch==2.0.4 ddtrace==1.12.1 Deprecated==1.2.13 distlib==0.3.6 docopt==0.6.2 envier==0.4.0 exceptiongroup==1.1.1 fancycompleter==0.9.1 fastdiff==0.3.0 filelock==3.12.0 flake8==6.0.0 Flask==2.3.1 Flask-Caching==2.0.2 flask-marshmallow==0.14.0 Flask-Migrate==3.1.0 Flask-SQLAlchemy==2.5.1 freezegun==1.2.2 GeoAlchemy2==0.13.2 geojson==3.0.1 gitdb==4.0.10 GitPython==3.1.31 google-api-core==2.11.0 google-api-python-client==2.86.0 google-auth==2.17.3 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.3 google-cloud-core==2.3.2 google-cloud-pubsub==2.16.0 google-cloud-runtimeconfig==0.33.2 google-cloud-secret-manager==2.16.1 google-cloud-storage==2.8.0 google-configstore==1.0.1 google-crc32c==1.5.0 google-resumable-media==2.5.0 googleapis-common-protos==1.59.0 greenlet==2.0.2 grpc-google-iam-v1==0.12.6 grpcio==1.54.0 grpcio-status==1.54.0 gunicorn==20.1.0 httplib2==0.22.0 identify==2.5.22 idna==3.4 importlib-metadata==6.0.1 iniconfig==2.0.0 itsdangerous==2.1.2 Jinja2==3.1.2 jsonschema==4.17.3 Mako==1.2.4 markdown-it-py==2.2.0 MarkupSafe==2.1.2 marshmallow==3.19.0 marshmallow-enum==1.5.1 marshmallow-sqlalchemy==0.28.2 mccabe==0.7.0 mdurl==0.1.2 mixpanel==4.10.0 mypy-extensions==1.0.0 nodeenv==1.7.0 numpy==1.24.3 oauthlib==3.2.2 opentelemetry-api==1.17.0 packaging==23.1 pathspec==0.11.1 pbr==5.11.1 pdbpp==0.10.3 platformdirs==3.3.0 pluggy==1.0.0 pre-commit==3.2.2 proto-plus==1.22.2 protobuf==4.22.3 psycopg2==2.9.6 py==1.11.0 pyasn1==0.5.0 pyasn1-modules==0.3.0 pycodestyle==2.10.0 pycparser==2.21 pydash==5.1.2 pyflakes==3.0.1 Pygments==2.15.1 PyJWT==2.6.0 pyparsing==3.0.9 pyrepl==0.9.0 pyrsistent==0.19.3 pytest==7.3.1 pytest-cov==4.0.0 pytest-flask==1.2.0 pytest-html==3.2.0 pytest-metadata==2.0.4 pytest-mock==3.10.0 pytest-report==0.2.1 pytest-testmon==2.0.6 pytest-watch==4.2.0 python-dateutil==2.8.2 python-json-logger==2.0.7 pytz==2023.3 PyYAML==6.0 redis==4.5.4 requests==2.28.2 requests-mock==1.10.0 requests-oauthlib==1.3.1 rich==13.3.4 rsa==4.9 sentry-sdk==1.21.0 setproctitle==1.3.2 shapely==2.0.1 simplejson==3.19.1 six==1.16.0 smmap==5.0.0 snapshottest==0.6.0 SQLAlchemy==1.4.47 sqlalchemy-citext @ git+https://github.com/rouge8/sqlalchemy-citext.git@14e14c5bbd9721e37bd3365186b6827339a723e0 sqlalchemy-diff==0.1.5 SQLAlchemy-Utils==0.38.3 stevedore==5.0.0 tenacity==8.2.2 termcolor==2.3.0 tomli==2.0.1 transitions==0.7.2 typing_extensions==4.5.0 uritemplate==4.1.1 urllib3==1.26.15 virtualenv==20.22.0 wasmer==1.1.0 wasmer-compiler-cranelift==1.1.0 watchdog==3.0.0 Werkzeug==2.3.0 wmctrl==0.4 wrapt==1.15.0 xmltodict==0.13.0 zipp==3.15.0

How can we reproduce your problem?

Configure a Flask webserver and run flask db upgrade

What is the result that you get?

  File "/usr/local/lib/python3.10/site-packages/basis_utils/datadog/tracer.py", line 18, in configure_tracer
    patch_all()
  File "/usr/local/lib/python3.10/site-packages/ddtrace/_monkey.py", line 193, in patch_all
    patch(raise_errors=False, **modules)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/_monkey.py", line 233, in patch
    when_imported(module)(_on_import_factory(contrib, raise_errors=False))
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/importer.py", line 284, in register
    register_post_import_hook(hook, name)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/decorators.py", line 470, in _synchronized
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/importer.py", line 82, in register_post_import_hook
    hook(module)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/_monkey.py", line 158, in on_import
    imported_module.patch()
  File "/usr/local/lib/python3.10/site-packages/ddtrace/contrib/flask/patch.py", line 308, in patch
    _w("flask", "Flask.{}".format(hook), traced_flask_hook)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/wrappers.py", line 882, in wrap_function_wrapper
    return wrap_object(module, name, FunctionWrapper, (wrapper,))
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/wrappers.py", line 822, in wrap_object
    (parent, attribute, original) = resolve_path(module, name)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/wrappers.py", line 812, in resolve_path
    original = lookup_attribute(parent, attribute)
  File "/usr/local/lib/python3.10/site-packages/ddtrace/vendor/wrapt/wrappers.py", line 804, in lookup_attribute
    return getattr(parent, attribute)
AttributeError: type object 'Flask' has no attribute 'before_first_request'. Did you mean: 'got_first_request'?

What is the result that you expected?

No exception raised.

kkaczmarczyk commented 1 year ago

For me this issue happens also on regular flask run.

sachams commented 1 year ago

For me this issue happens also on regular flask run.

Ah yes. Me too, actually.

engineerpassion commented 1 year ago

@gnufede Seeing the same problem with flask==2.3.2.

engineerpassion commented 1 year ago

@gnufede I see these decorators were deprecated and now are removed, are there any alternatives we can use?

gnufede commented 1 year ago

@gnufede I see these decorators were deprecated and now are removed, are there any alternatives we can use?

For these decorators, the Flask documentation states:

Deprecated since version 2.2: Will be removed in Flask 2.3. Run setup code when creating the application instead.

I'm sorry I cannot be more helpful, but this is a Flask deprecation, not a dd-trace-py one

ananddotiyer commented 1 year ago

For me this issue happens also on regular flask run.

Ah yes. Me too, actually.

Has this been solved for you yet @sachams? Please share the solution that worked for you...

sachams commented 1 year ago

For me this issue happens also on regular flask run.

Ah yes. Me too, actually.

Has this been solved for you yet @sachams? Please share the solution that worked for you...

It looks like has been fixed in 1.12.2. I'm using 1.12.6 and I can confirm that it is working as expected.