Skip to content

add utility to get installed libraries #373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

KRRT7
Copy link
Contributor

@KRRT7 KRRT7 commented Jun 24, 2025

User description

this is for future use

I'm not going to integrate it with the full context yet because our current implementation expects objects to be the same when comparing, this is a problem because we can use a library like polars which is faster than pandas in a few contexts and still be "correct" but we will not accept it due to the types of the objects


PR Type

Enhancement


Description

  • Add utility to list installed Python packages

  • Filter out blacklisted development packages

  • Integrate installed_packages into AI POST payloads

  • Add type hints to contextmanager functions


Changes walkthrough 📝

Relevant files
Enhancement
aiservice.py
Add installed packages support to AI client                           

codeflash/api/aiservice.py

  • Imported get_installed_packages into client
  • Stored installed packages on client initialization
  • Added installed_packages to POST payload
  • +4/-0     
    code_utils.py
    Implement installed packages retrieval utility                     

    codeflash/code_utils/code_utils.py

  • Imported importlib.metadata and TYPE_CHECKING
  • Defined blacklist_installed_pkgs set
  • Added get_installed_packages function
  • Annotated contextmanager functions with Generators
  • +34/-2   

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Payload Initialization

    The code assumes payload is a dict when adding installed_packages. If payload is None, this will raise an exception. Consider initializing payload to an empty dict or guarding this assignment.

    url = f"{self.base_url}/ai{endpoint}"
    if method.upper() == "POST":
        if self.installed_packages:
            payload["installed_packages"] = self.installed_packages
        json_payload = json.dumps(payload, indent=None, default=pydantic_encoder)
    Order Determinism

    get_installed_packages returns package names in arbitrary order. You may want to sort the list before returning for deterministic payloads and easier testing.

    def get_installed_packages() -> list[str]:
        pkgs = importlib.metadata.packages_distributions().keys()
        return [
            pkg
            for pkg in pkgs
            if not any(blacklisted in pkg for blacklisted in blacklist_installed_pkgs) and not pkg.startswith("_")
        ]
    Missing Version Info

    The utility only returns package names without versions, which may not be sufficient for reproducibility. Consider including package versions alongside names.

    def get_installed_packages() -> list[str]:
        pkgs = importlib.metadata.packages_distributions().keys()
        return [
            pkg
            for pkg in pkgs
            if not any(blacklisted in pkg for blacklisted in blacklist_installed_pkgs) and not pkg.startswith("_")
        ]

    Copy link

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Initialize payload if missing

    Ensure payload is always a mutable dict before inserting installed packages to avoid
    a TypeError when payload is None. Initialize or default payload to {} at the start
    of the POST branch.

    codeflash/api/aiservice.py [71-72]

    +if payload is None:
    +    payload = {}
     if self.installed_packages:
         payload["installed_packages"] = self.installed_packages
    Suggestion importance[1-10]: 7

    __

    Why: Checking and initializing payload prevents a TypeError when it’s None, ensuring the POST branch never fails at runtime.

    Medium
    Prevent init failure on metadata error

    Wrap the call to get_installed_packages() in a try/except block so that any
    exceptions during metadata retrieval don’t prevent AiServiceClient from
    initializing. On failure, default to an empty list.

    codeflash/api/aiservice.py [31]

    -self.installed_packages = get_installed_packages()
    +try:
    +    self.installed_packages = get_installed_packages()
    +except Exception:
    +    self.installed_packages = []
    Suggestion importance[1-10]: 5

    __

    Why: Wrapping get_installed_packages() guards against metadata retrieval errors, improving resilience without being critical.

    Low
    General
    Add package versions

    Include version information for each package by iterating over
    importlib.metadata.distributions() and formatting entries as "name==version", which
    provides more precise context in the payload.

    codeflash/code_utils/code_utils.py [248-254]

     def get_installed_packages() -> list[str]:
    -    pkgs = importlib.metadata.packages_distributions().keys()
    -    return [
    -        pkg
    -        for pkg in pkgs
    -        if not any(blacklisted in pkg for blacklisted in blacklist_installed_pkgs) and not pkg.startswith("_")
    -    ]
    +    pkgs = []
    +    for dist in importlib.metadata.distributions():
    +        name = dist.metadata["Name"]
    +        version = dist.version
    +        if not any(bl in name for bl in blacklist_installed_pkgs) and not name.startswith("_"):
    +            pkgs.append(f"{name}=={version}")
    +    return pkgs
    Suggestion importance[1-10]: 5

    __

    Why: Including "name==version" entries gives more precise context, but may require downstream adjustments to handle the new format.

    Low
    Limit packages in payload

    Restrict the length of installed_packages added to the payload (e.g., take only the
    first 100 entries) to avoid creating oversized HTTP requests.

    codeflash/api/aiservice.py [71-72]

     if self.installed_packages:
    -    payload["installed_packages"] = self.installed_packages
    +    payload["installed_packages"] = self.installed_packages[:100]
    Suggestion importance[1-10]: 4

    __

    Why: Truncating installed_packages to 100 entries can prevent oversized requests, but it’s a design choice with limited urgency.

    Low

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant