Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion infra/scripts/validate_bicep_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ def parse_parameters_env_vars(json_path: Path) -> dict[str, list[str]]:
data = json.loads(sanitized)
params = data.get("parameters", {})
except json.JSONDecodeError:
pass
# Keep validation resilient for partially templated/malformed files:
# if JSON parsing fails, treat as having no parsable parameters.
params = {}

# Walk each top-level parameter and scan its entire serialized value
# for ${VAR} references from the original text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def create_client(
env_file_encoding: str | None = None,
instruction_role: str | None = None,
) -> "AzureOpenAIChatClient":
...
pass

@overload
@staticmethod
Expand All @@ -166,7 +166,7 @@ def create_client(
instruction_role: str | None = None,
retry_config: RateLimitRetryConfig | None = None,
) -> AzureOpenAIChatClientWithRetry:
...
pass

@overload
@staticmethod
Expand All @@ -190,7 +190,7 @@ def create_client(
env_file_path: str | None = None,
env_file_encoding: str | None = None,
) -> "AzureOpenAIAssistantsClient":
...
pass

@overload
@staticmethod
Expand All @@ -212,7 +212,7 @@ def create_client(
env_file_encoding: str | None = None,
instruction_role: str | None = None,
) -> "AzureOpenAIResponsesClient":
...
pass

@overload
@staticmethod
Expand All @@ -235,7 +235,7 @@ def create_client(
instruction_role: str | None = None,
retry_config: RateLimitRetryConfig | None = None,
) -> AzureOpenAIResponseClientWithRetry:
...
pass

@overload
@staticmethod
Expand All @@ -252,7 +252,7 @@ def create_client(
env_file_path: str | None = None,
env_file_encoding: str | None = None,
) -> "AzureAIAgentClient":
...
pass

@staticmethod
def create_client(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,15 @@ async def _tail():
if callable(close):
try:
await close()
except Exception:
pass
except Exception as close_exc:
# Best-effort stream cleanup: ignore close failures so we preserve
# the original exception/retry path.
logger.debug(
"[AOAI_RETRY_STREAM] ignoring stream close failure during retry handling: %s",
_format_exc_brief(close_exc)
if isinstance(close_exc, BaseException)
else str(close_exc),
)

# One-shot retry for context-length failures.
if (
Expand Down Expand Up @@ -802,8 +809,13 @@ async def _tail():
if callable(close):
try:
await close()
except Exception:
pass
except Exception as close_error:
# Intentionally suppress close-time failures so we do not
# mask the original streaming exception that triggered retry handling.
logger.debug(
"[AOAI_RETRY_STREAM] ignoring stream close failure during error handling",
exc_info=close_error,
)

# One-shot retry for context-length failures.
if (
Expand Down
1 change: 1 addition & 0 deletions src/ContentProcessorAPI/app/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class Application(Application_Base):

def __init__(self):
super().__init__(env_file_path=os.path.join(os.path.dirname(__file__), ".env"))
self.bootstrap()

def initialize(self):
"""Build the FastAPI app, attach middleware, routers, and dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
retrieve them during downstream pipeline stages.
"""

from azure.core.exceptions import ResourceNotFoundError
from azure.storage.blob import BlobServiceClient

from app.utils.azure_credential_utils import get_azure_credential
Expand Down Expand Up @@ -124,7 +125,8 @@ def delete_blob_and_cleanup(self, blob_name, container_name=None):
container_client = self._get_container_client(container_name)
try:
container_client.delete_blob(blob_name)
except Exception:
except ResourceNotFoundError:
# Blob already absent; continue with folder cleanup checks.
pass

blobs = container_client.list_blobs()
Expand Down
11 changes: 7 additions & 4 deletions src/ContentProcessorAPI/app/libs/base/application_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"""Abstract base for the application bootstrap sequence.

Orchestrates the startup order: load .env → read Azure App Configuration →
populate AppContext with configuration and credentials → configure logging →
call the concrete ``initialize()`` implemented by the subclass.
populate AppContext with configuration and credentials → configure logging.
The concrete ``initialize()`` hook is invoked
explicitly via ``bootstrap()``
after construction is complete.
"""

import inspect
Expand Down Expand Up @@ -53,14 +55,13 @@ def initialize(self):
)

def __init__(self, env_file_path: str | None = None, **data):
"""Execute the full bootstrap sequence.
"""Execute base bootstrap setup.

Steps:
1. Load ``.env`` from *env_file_path* (or derive from subclass location).
2. Read Azure App Configuration and inject values into ``os.environ``.
3. Populate ``application_context`` with config and Azure credentials.
4. Configure Python logging if enabled in config.
5. Call ``self.initialize()``.

Args:
env_file_path: Explicit path to a ``.env`` file (optional).
Expand Down Expand Up @@ -103,6 +104,8 @@ def __init__(self, env_file_path: str | None = None, **data):
):
logging.getLogger(logger_name).setLevel(azure_level)

def bootstrap(self):
"""Run subclass initialization after construction has completed."""
self.initialize()

def _load_env(self, env_file_path: str | None = None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class FastAPIWithContext(Protocol):
app_context: AppContext

def include_router(self, *args, **kwargs) -> None:
...
pass


def add_app_context_to_fastapi(
Expand Down
6 changes: 4 additions & 2 deletions src/ContentProcessorAPI/app/routers/claimprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,10 @@ async def delete_claim_container(claim_id: str, request: Request = None):
)
try:
claim_processor.delete_claim_container(claim_id=claim_id)
except Exception:
pass
except Exception as ex:
# Best-effort cleanup: continue deleting the claim-process record even if
# the backing claim container is already missing or cannot be deleted.
print(f"Failed to delete claim container for '{claim_id}': {ex}")

batch_process_repository: ClaimBatchProcessRepository = app.app_context.get_service(
ClaimBatchProcessRepository
Expand Down
2 changes: 1 addition & 1 deletion src/ContentProcessorWeb/src/Components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import React from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { useHeaderHooks, Header } from "../../Hooks/useHeaderHooks";
import { Header } from "../../Hooks/useHeaderHooks";
import {
TabList,
Tab,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ const UploadFilesModal: React.FC<UploadFilesModalProps> = ({ open, onClose }) =>
setFileErrors({})
setUploadCompleted(false);
setFileSchemas({});
}
};
const onCloseHandler = () => {
resetState();
onClose();
Expand Down
2 changes: 1 addition & 1 deletion src/ContentProcessorWeb/src/Hooks/useFileType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @file Tests for useFileType — MIME type resolution based on file extension.
*/

import { renderHook, act } from '@testing-library/react';
import { renderHook } from '@testing-library/react';
import useFileType from './useFileType';
import type { FileWithExtension } from './useFileType';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import {
import { Tooltip, Button } from "@fluentui/react-components";
import {
TableBody, TableCell, TableRow, Table,
TableHeader, TableHeaderCell, TableCellLayout, createTableColumn, useTableFeatures,
useTableSelection, useTableSort, TableColumnId,
TableRowId
TableHeader, TableHeaderCell, TableCellLayout
} from "@fluentui/react-components";

import { useDispatch, useSelector, shallowEqual } from "react-redux";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
saveClaimComment,
fetchContentJsonData,
setActiveProcessId,
setModifiedResult,
} from '../../store/slices/centerPanelSlice';
import { startLoader, stopLoader } from "../../store/slices/loaderSlice";
import { setRefreshGrid } from "../../store/slices/leftPanelSlice";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { bundleIcon, ChevronDoubleLeft20Filled, ChevronDoubleLeft20Regular } fro
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { AppDispatch, RootState } from '../../store';
import { fetchContentFileData } from '../../store/slices/rightPanelSlice';
import { updatePanelCollapse } from "../../store/slices/defaultPageSlice";

import PanelToolbar from "../../Hooks/usePanelHooks";
import DocumentViewer from '../../Components/DocumentViewer/DocumentViewer';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ describe('centerPanelSlice', () => {
});

it('should set cError and clear contentData on rejected', () => {
const error = new Error('Server error');
const action = {
type: fetchContentJsonData.rejected.type,
error: { message: 'Server error' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def create_client( # noqa: E704
env_file_path: str | None = None,
env_file_encoding: str | None = None,
instruction_role: str | None = None,
) -> "AzureOpenAIChatClient": ...
) -> "AzureOpenAIChatClient":
pass

@overload
@staticmethod
Expand All @@ -164,7 +165,8 @@ def create_client( # noqa: E704
env_file_encoding: str | None = None,
instruction_role: str | None = None,
retry_config: RateLimitRetryConfig | None = None,
) -> AzureOpenAIChatClientWithRetry: ...
) -> AzureOpenAIChatClientWithRetry:
pass

@overload
@staticmethod
Expand All @@ -187,7 +189,8 @@ def create_client( # noqa: E704
async_client: object | None = None,
env_file_path: str | None = None,
env_file_encoding: str | None = None,
) -> "AzureOpenAIAssistantsClient": ...
) -> "AzureOpenAIAssistantsClient":
raise NotImplementedError

@overload
@staticmethod
Expand All @@ -208,7 +211,8 @@ def create_client( # noqa: E704
env_file_path: str | None = None,
env_file_encoding: str | None = None,
instruction_role: str | None = None,
) -> "AzureOpenAIResponsesClient": ...
) -> "AzureOpenAIResponsesClient":
pass

@overload
@staticmethod
Expand All @@ -230,7 +234,8 @@ def create_client( # noqa: E704
env_file_encoding: str | None = None,
instruction_role: str | None = None,
retry_config: RateLimitRetryConfig | None = None,
) -> AzureOpenAIResponseClientWithRetry: ...
) -> AzureOpenAIResponseClientWithRetry:
raise NotImplementedError

@overload
@staticmethod
Expand All @@ -246,7 +251,8 @@ def create_client( # noqa: E704
async_credential: object | None = None,
env_file_path: str | None = None,
env_file_encoding: str | None = None,
) -> "AzureAIAgentClient": ...
) -> "AzureAIAgentClient":
pass

@staticmethod
def create_client(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,8 +679,15 @@ async def _tail():
if callable(close):
try:
await close()
except Exception:
pass
except Exception as close_error:
# Best-effort cleanup: ignore close failures so we preserve
# retry/original-error handling behavior.
logger.debug(
"[AOAI_RETRY_STREAM] ignored stream close error during cleanup: %s",
_format_exc_brief(close_error)
if isinstance(close_error, BaseException)
else str(close_error),
)

# One-shot retry for context-length failures.
if (
Expand Down Expand Up @@ -865,8 +872,13 @@ async def _tail():
if callable(close):
try:
await close()
except Exception:
pass
except Exception as close_err:
logger.debug(
"[AOAI_RETRY_STREAM] ignoring stream close error during cleanup: %s",
_format_exc_brief(close_err)
if isinstance(close_err, BaseException)
else str(close_err),
)

# One-shot retry for context-length failures.
if (
Expand Down
7 changes: 5 additions & 2 deletions src/ContentProcessorWorkflow/src/main_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,11 @@ async def run_queue_service(
try:
if app.queue_service:
await app.queue_service.stop_service()
except Exception:
pass
except Exception as cleanup_error:
logger.debug(
"Ignoring cleanup error while re-raising original failure: %s",
cleanup_error,
)
raise


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import asyncio
import inspect
import json
import logging
import uuid
Expand Down Expand Up @@ -295,7 +296,7 @@ async def poll_status(

if on_poll is not None:
poll_handler = on_poll(result)
if asyncio.iscoroutine(poll_handler):
if inspect.isawaitable(poll_handler):
await poll_handler

status = result.get("status", "processing")
Expand Down
Loading
Loading