Skip to content

Commit

Permalink
remove incomplete httpx work
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex committed Dec 24, 2024
1 parent 8434258 commit 9495827
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 17 deletions.
54 changes: 52 additions & 2 deletions logfire/_internal/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
import argparse
import functools
import importlib
import importlib.metadata
import importlib.util
import logging
import os
import platform
import re
import sys
import warnings
import webbrowser
from collections import defaultdict
from pathlib import Path
from typing import Any, Iterator, cast
from urllib.parse import urljoin, urlparse
Expand Down Expand Up @@ -195,6 +198,7 @@ def reader() -> Iterator[bytes]:
'urllib3',
}
OTEL_PACKAGE_LINK = {'aiohttp': 'aiohttp-client', 'tortoise_orm': 'tortoiseorm', 'scikit-learn': 'sklearn'}
STANDARD_LIBRARY_PACKAGES = {'urllib', 'sqlite3'}


def parse_inspect(args: argparse.Namespace) -> None:
Expand All @@ -207,11 +211,23 @@ def parse_inspect(args: argparse.Namespace) -> None:
# Ignore warnings from packages that we don't control.
warnings.simplefilter('ignore', category=UserWarning)

packages_to_inspect = OTEL_PACKAGES
if args.ignore_standard_library:
packages_to_inspect -= STANDARD_LIBRARY_PACKAGES

Check warning on line 216 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L216

Added line #L216 was not covered by tests
if args.ignore_package:
packages_to_inspect -= set(args.ignore_package)

Check warning on line 218 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L218

Added line #L218 was not covered by tests

required_by = _build_required_by()

packages: dict[str, str] = {}
for name in OTEL_PACKAGES:
for name in packages_to_inspect:
# Check if the package can be imported (without actually importing it).
if importlib.util.find_spec(name) is None:
continue
else:
# Skip packages that are not required by any other package.
if len([req for req in required_by[name] if not req.startswith('opentelemetry')]) == 0:
continue

otel_package = OTEL_PACKAGE_LINK.get(name, name)
otel_package_import = f'opentelemetry.instrumentation.{otel_package}'
Expand All @@ -220,15 +236,20 @@ def parse_inspect(args: argparse.Namespace) -> None:
packages[name] = otel_package

# Drop packages that are dependencies of other packages.
if packages.get('starlette') and packages.get('fastapi'):
if packages.get('starlette') and len(required_by['starlette'] - {'fastapi'}) == 0:
del packages['starlette']
if packages.get('urllib3') and len(required_by['urllib3'] - {'requests'}) == 0:
del packages['urllib3']

Check warning on line 242 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L242

Added line #L242 was not covered by tests

for name, otel_package in sorted(packages.items()):
package_name = otel_package.replace('.', '-')
import_name = otel_package.replace('-', '_')
link = f'[link={BASE_OTEL_INTEGRATION_URL}/{import_name}/{import_name}.html]opentelemetry-instrumentation-{package_name}[/link]'
table.add_row(name, link)

if not packages:
return

Check warning on line 251 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L251

Added line #L251 was not covered by tests

console.print(
'The following packages from your environment have an OpenTelemetry instrumentation that is not installed:'
)
Expand All @@ -244,6 +265,32 @@ def parse_inspect(args: argparse.Namespace) -> None:
console.print('\n[bold blue]For further information, visit[/bold blue]', end=' ')
console.print(f'[link={INTEGRATIONS_DOCS_URL}]{INTEGRATIONS_DOCS_URL}[/link]')

if args.explain:
console.print('\n[bold]Explanation:[/]')

Check warning on line 269 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L269

Added line #L269 was not covered by tests
for name, otel_package in packages.items():
required_by_name = required_by[name]

Check warning on line 271 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L271

Added line #L271 was not covered by tests
if required_by_name:
console.print(f'\n[bold]{name}[/] is required by:')

Check warning on line 273 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L273

Added line #L273 was not covered by tests
for req in required_by_name:
console.print(f' - {req}')

Check warning on line 275 in logfire/_internal/cli.py

View check run for this annotation

Codecov / codecov/patch

logfire/_internal/cli.py#L275

Added line #L275 was not covered by tests


# Package name should only include digits, letters, underscores, and hyphens.
ONLY_PACKAGE_NAME = re.compile(r'^(?P<name>[a-zA-Z0-9_-]+)')


def _build_required_by() -> dict[str, set[str]]:
"""Build a dictionary of packages and their dependencies."""
required_by: defaultdict[str, set[str]] = defaultdict(set)
for package in importlib.metadata.distributions():
if package.requires is None:
continue
for requirement in package.requires:
match = ONLY_PACKAGE_NAME.match(requirement)
assert match is not None
required_by[match.group('name')].add(package.metadata['Name'])
return required_by


def parse_auth(args: argparse.Namespace) -> None:
"""Authenticate with Logfire.
Expand Down Expand Up @@ -438,6 +485,9 @@ def _main(args: list[str] | None = None) -> None:

cmd_inspect = subparsers.add_parser('inspect', help=parse_inspect.__doc__)
cmd_inspect.set_defaults(func=parse_inspect)
cmd_inspect.add_argument('--ignore-standard-library', action='store_true', help='ignore standard library packages')
cmd_inspect.add_argument('--ignore-package', action='append', help='ignore a package')
cmd_inspect.add_argument('--explain', action='store_true', help='explain the output')

cmd_whoami = subparsers.add_parser('whoami', help=parse_whoami.__doc__)
cmd_whoami.set_defaults(func=parse_whoami)
Expand Down
16 changes: 1 addition & 15 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import logfire._internal.cli
from logfire import VERSION
from logfire._internal.cli import OTEL_PACKAGES, main
from logfire._internal.cli import main
from logfire._internal.config import LogfireCredentials, sanitize_project_name
from logfire.exceptions import LogfireConfigError

Expand Down Expand Up @@ -206,20 +206,6 @@ def test_inspect(
assert capsys.readouterr().err.startswith('The following packages')


def test_inspect_drop_dependant_packages(
tmp_dir_cwd: Path, logfire_credentials: LogfireCredentials, capsys: pytest.CaptureFixture[str]
) -> None:
logfire_credentials.write_creds_file(tmp_dir_cwd / '.logfire')
with ExitStack() as stack:
find_spec = stack.enter_context(patch('importlib.util.find_spec'))
find_spec.side_effect = [True, None] * len(OTEL_PACKAGES)

main(['inspect'])
output = capsys.readouterr().err
assert 'opentelemetry-instrumentation-fastapi' in output
assert 'opentelemetry-instrumentation-starlette' not in output


@pytest.mark.parametrize('webbrowser_error', [False, True])
def test_auth(tmp_path: Path, webbrowser_error: bool) -> None:
auth_file = tmp_path / 'default.toml'
Expand Down

0 comments on commit 9495827

Please sign in to comment.