apm-agent-python icon indicating copy to clipboard operation
apm-agent-python copied to clipboard

Improvement: Export 'async_capture_span' from the top-level 'elasticapm' package for easier imports

Open AlirezaHaghi opened this issue 2 months ago • 3 comments

Describe the bug: "async_capture_span" is not exported from module "elasticapm" Import from "elasticapm.contrib.asyncio.traces" instead

Description Currently, trying to import async_capture_span directly from the top-level elasticapm package fails. This creates friction for developers using static analysis tools (like Pylance/Pyright in VS Code), as it generates import errors.

Steps to Reproduce In a Python file with elastic-apm installed, try to import or use async_capture_span from the top-level package:

--- Pattern 1: Direct import ---
import elasticapm
from elasticapm import async_capture_span
--- Pattern 2: Attribute access ---
@elasticapm.async_capture_span()
async def my_async_task():
    pass
Actual Behavior

Both patterns result in a static analysis error:

"async_capture_span" is not exported from module "elasticapm" Import from "elasticapm.contrib.asyncio.traces" instead

While the code might run (depending on import magic), it is not correctly exposed for static analysis, forcing developers to use # type: ignore comments or scattering deep import paths throughout the codebase.

Expected Behavior

For developer convenience (DX) and consistency with other common functions (like capture_span), async_capture_span should be exposed on the top-level elasticapm module.

This would allow the following to work without any linter/type-checker errors:

from elasticapm import async_capture_span

@async_capture_span()
async def my_async_task():
    pass

Suggested Solution This issue can likely be resolved by importing async_capture_span into the main elasticapm/init.py file and adding it to the all list.

This would make the asyncio helper more discoverable and easier to use.

Thank you!

AlirezaHaghi avatar Oct 18 '25 08:10 AlirezaHaghi

if you want, i can fix it in a simple PR

AlirezaHaghi avatar Oct 18 '25 09:10 AlirezaHaghi

I don't think there's anything specific to async_capture_span as the other imports re-exported from elasticapm, is it because it's imported after __all__ is defined?

xrmx avatar Nov 19 '25 16:11 xrmx

i agree there is nothing specific with that.

AlirezaHaghi avatar Nov 19 '25 16:11 AlirezaHaghi