Skip to content
Open
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
12 changes: 12 additions & 0 deletions marker/services/azure_openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ def __call__(
f"Rate limit error: {e}. Retrying in {wait_time} seconds... (Attempt {tries}/{total_tries})"
)
time.sleep(wait_time)
except json.JSONDecodeError as e:
# The response was not valid JSON
if tries == total_tries:
# Last attempt failed. Give up
logger.error(
f"JSONDecodeError: {e}. Max retries reached. Giving up. (Attempt {tries}/{total_tries})",
)
break
else:
logger.warning(
f"JSONDecodeError: {e}. (Attempt {tries}/{total_tries})",
)
except Exception as e:
logger.error(f"Azure OpenAI inference failed: {e}")
break
Expand Down
34 changes: 22 additions & 12 deletions marker/services/claude.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import anthropic
from anthropic import RateLimitError, APITimeoutError
from marker.logger import get_logger
from pydantic import BaseModel
from pydantic import BaseModel, ValidationError

from marker.schema.blocks import Block
from marker.services import BaseService
Expand All @@ -17,7 +17,7 @@

class ClaudeService(BaseService):
claude_model_name: Annotated[
str, "The name of the Google model to use for the service."
str, "The name of the Claude model to use for the service."
] = "claude-3-7-sonnet-20250219"
claude_api_key: Annotated[str, "The Claude API key to use for the service."] = None
max_claude_tokens: Annotated[
Expand Down Expand Up @@ -47,16 +47,14 @@ def validate_response(self, response_text: str, schema: type[T]) -> T:
try:
# Try to parse as JSON first
out_schema = schema.model_validate_json(response_text)
out_json = out_schema.model_dump()
return out_json
except Exception:
try:
# Re-parse with fixed escapes
escaped_str = response_text.replace("\\", "\\\\")
out_schema = schema.model_validate_json(escaped_str)
return out_schema.model_dump()
except Exception:
return
except ValidationError:
# Re-parse with fixed escapes
escaped_str = response_text.replace("\\", "\\\\")
# If we fail again, let the ValidationError be handled by the caller
out_schema = schema.model_validate_json(escaped_str)

out_json = out_schema.model_dump()
return out_json

def get_client(self):
return anthropic.Anthropic(
Expand Down Expand Up @@ -127,6 +125,18 @@ def __call__(
f"Rate limit error: {e}. Retrying in {wait_time} seconds... (Attempt {tries}/{total_tries})",
)
time.sleep(wait_time)
except ValidationError as e:
# The response was not valid JSON
if tries == total_tries:
# Last attempt failed. Give up
logger.error(
f"ValidationError: {e}. Max retries reached. Giving up. (Attempt {tries}/{total_tries})",
)
break
else:
logger.warning(
f"ValidationError: {e}. (Attempt {tries}/{total_tries})",
)
except Exception as e:
logger.error(f"Error during Claude API call: {e}")
break
Expand Down
12 changes: 12 additions & 0 deletions marker/services/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ def __call__(
f"Rate limit error: {e}. Retrying in {wait_time} seconds... (Attempt {tries}/{total_tries})",
)
time.sleep(wait_time)
except json.JSONDecodeError as e:
# The response was not valid JSON
if tries == total_tries:
# Last attempt failed. Give up
logger.error(
f"JSONDecodeError: {e}. Max retries reached. Giving up. (Attempt {tries}/{total_tries})",
)
break
else:
logger.warning(
f"JSONDecodeError: {e}. (Attempt {tries}/{total_tries})",
)
except Exception as e:
logger.error(f"OpenAI inference failed: {e}")
break
Expand Down