Skip to content

Break circular Python imports and replace import-order workarounds #1461

Description

@paullizer

Summary

Remove circular Python dependencies and the import-order workarounds they require through small, behavior-preserving refactoring steps. Keep legitimate optional/performance-driven lazy imports rather than mechanically moving every import to module scope.

Scope

  • Establish a reproducible import-dependency inventory and regression guard, distinguishing module-scope, function-local, conditional, and dynamic imports.
  • Break the settings/document-analysis cycle by separating pure defaults, constants, and input normalization from service implementations.
  • Untangle settings/authentication and cache/logging/Key Vault dependencies without changing authorization, settings refresh, Redis fallback, or secret handling.
  • Separate configuration from Cosmos/client/media initialization; make initialization explicit at the web and scheduler entrypoints while preserving their existing invocation contracts.
  • Move shared business logic out of route modules so chat/orchestration/workflow and Control Center services do not import HTTP route implementations. Address the related visual-export and MCP factory/runtime cycles in separate slices.
  • Replace wildcard imports and dual-path import fallbacks in migrated boundaries with explicit dependencies; avoid an unrelated repository-wide formatting or package-layout rewrite.
  • Add isolated regression coverage, document the dependency rules, and update the application version when implementation lands.

Acceptance Criteria

  • The current module-scope cycle is removed and the application-module import graph remains free of module-scope cycles.
  • Existing deferred cycles are reduced by moving shared responsibilities to lower-level modules, not merely hidden behind additional local imports or importlib calls; any retained cycle has an explicit justification and tracked follow-up.
  • Migrated service modules do not import route modules, and foundational configuration/contract imports do not create Azure resources or start background work.
  • Cold imports in supported orders and explicit initialization are covered without live Azure calls; repeated initialization does not duplicate clients, handlers, or background loops.
  • Existing web/scheduler entrypoints, settings behavior, route/Blueprint security policies, document permissions, optional features, and shared-cache behavior are preserved.
  • Dependency checks detect new or reintroduced edges, including cycle regressions inside an existing connected component; scoped exceptions cannot grow silently.
  • Functional-test headers and fix documentation reference the implementation version from application/single_app/config.py.

Notes

Initial read-only inventory at application version 0.261.101 covered 298 named Python modules under application/single_app. The explicit-import graph has one module-scope cyclic component containing nine modules. One representative path is:

functions_settings -> functions_document_actions -> functions_document_analysis -> functions_search -> functions_content -> functions_settings

Including function-local imports exposes three cyclic components involving 117 modules, including one 111-module component. There are 217 wildcard import statements across 60 modules; 56 modules use from config import *. These are static dependency findings, not a claim that every cycle currently causes a startup failure. Dynamic imports and implicit package initialization need to be included in the implementation baseline.

Existing guardrails include functional_tests/test_codeql_import_cycle_lazy_imports.py and functional_tests/route_tests/. The plan must preserve those regression contracts while replacing source-shape workarounds with behavior and dependency-boundary coverage.

Requested triage: P2, L, assigned to paullizer. Planning only at issue creation; application code has not been changed.

Activity

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

Metadata

Metadata

Labels

P2Priority 2: important, scheduled after P0/P1enhancementNew feature or request

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions