Skip to content

Rely on infogami-style setup to avoid duplicate setup calls#12046

Merged
RayBB merged 1 commit intointernetarchive:masterfrom
cdrini:hotfix/double-setup-calls
Mar 11, 2026
Merged

Rely on infogami-style setup to avoid duplicate setup calls#12046
RayBB merged 1 commit intointernetarchive:masterfrom
cdrini:hotfix/double-setup-calls

Conversation

@cdrini
Copy link
Copy Markdown
Collaborator

@cdrini cdrini commented Mar 8, 2026

Closes #12034

This isn't ideal, but this setup pattern is used profusely and recursively throughout the codebase; including in infogami. To close the P0 and remove the risk of double-running sensitive internals, this seems like the quickest, simplest approach.

Technical

In infogami we often use a pattern like this to define an endpoint:

class scan(delegate.page):
    path = "/barcodescanner"

    def GET(self):
        return render.barcodescanner()

Sub-classing delegate.page is enough to register the endpoint. But if the file is never imported, that sub-classing never happens! So the pattern that infogami/webpy use is to have a setup method in the bottom of every file that contains endpoints, like this:

class scan(delegate.page):
    ...

def setup():
    # Importing calls _others'_ setup methods
    from openlibrary.plugins.worksearch import autocomplete

setup()

This is a problematic pattern, because it makes it incredibly easy to:

  1. Forget to create this magic setup method, which would cause nothing to happen
  2. Accidentally register another file's endpoints just by importing, and not include it in the setup method
  3. Makes it impossible to import any methods/helpers without also registering endpoints

A better approach is to make it explicit, as #11762 does:

class scan(delegate.page):
    ...

def setup():
    from openlibrary.plugins.worksearch import autocomplete import setup as autocomplete_setup

    autocomplete_setup()

This decouples the setup from the import, but again still has the magic endpoint definition. And the new issue introduced is that we can now call these setup methods twice, resulting in undefined behaviour.

This is possibly also complicated by the @public decorator, which also requires being called at the correct point in the infogami import life-cycle.

Testing

No duplicate headers on testing or prod.

Screenshot

Stakeholders

@cdrini cdrini added Patch Deployed This PR has been deployed to production independently, outside of the regular deploy cycle. Priority: 1 Do this week, receiving emails, time sensitive, . [managed] labels Mar 8, 2026
@cdrini cdrini marked this pull request as ready for review March 9, 2026 17:56
Copilot AI review requested due to automatic review settings March 9, 2026 17:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Open Library’s Infogami app initialization to avoid duplicate setup() execution by relying on module-import side effects (endpoint registration) instead of explicitly importing and calling plugin setup() functions.

Changes:

  • Removes explicit setup imports for several plugins from openlibrary/code.py.
  • Registers plugin endpoints by importing each plugin’s code module inside setup().

Comment on lines +25 to +30
import openlibrary.plugins.openlibrary.code # noqa: I001 registers endpoints
import openlibrary.plugins.worksearch.code
import openlibrary.plugins.inside.code
import openlibrary.plugins.books.code
import openlibrary.plugins.admin.code
import openlibrary.plugins.upstream.code
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These imports are only for side effects, but as written they will trigger Ruff F401 (unused import) for each line (only the last one is suppressed). Consider switching to importlib.import_module(...) calls (keeps explicit ordering without isort interference and avoids F401), or add # noqa: F401 to each import (and optionally combine with the existing I001 suppression if you’re intentionally keeping a non-isort order).

Suggested change
import openlibrary.plugins.openlibrary.code # noqa: I001 registers endpoints
import openlibrary.plugins.worksearch.code
import openlibrary.plugins.inside.code
import openlibrary.plugins.books.code
import openlibrary.plugins.admin.code
import openlibrary.plugins.upstream.code
import openlibrary.plugins.openlibrary.code # noqa: I001, F401 registers endpoints
import openlibrary.plugins.worksearch.code # noqa: F401 registers endpoints
import openlibrary.plugins.inside.code # noqa: F401 registers endpoints
import openlibrary.plugins.books.code # noqa: F401 registers endpoints
import openlibrary.plugins.admin.code # noqa: F401 registers endpoints
import openlibrary.plugins.upstream.code # noqa: F401 registers endpoints

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@cdrini cdrini Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it won't let me do that. Not sure why. It gets reverted by (I think) ruff.

@github-project-automation github-project-automation bot moved this to Waiting Review/Merge from Staff in Ray's Project Mar 11, 2026
Copy link
Copy Markdown
Collaborator

@RayBB RayBB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.
It's not ideal but needed for short term fixes.
Long term we'll naturally move away from these as we move towards fastapi.

@RayBB RayBB merged commit 5fd063e into internetarchive:master Mar 11, 2026
8 checks passed
@github-project-automation github-project-automation bot moved this from Waiting Review/Merge from Staff to Done in Ray's Project Mar 11, 2026
@cdrini cdrini mentioned this pull request Mar 12, 2026
@RayBB RayBB removed the On Testing label Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Patch Deployed This PR has been deployed to production independently, outside of the regular deploy cycle. Priority: 1 Do this week, receiving emails, time sensitive, . [managed]

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

P0: Choose some intervention/remediation to prevent setup() from being loaded multiple times; @cdrini

3 participants