Compare commits

..

13 Commits

Author SHA1 Message Date
Logan Markewich 92380987b6 fix index tests 2025-12-03 15:55:45 -06:00
Logan Markewich 44bf80346c fix some tests 2025-12-03 15:52:58 -06:00
Logan Markewich 4273e27c48 fix finally 2025-12-03 15:15:02 -06:00
Logan Markewich 3b9d63e019 clean up tests 2025-11-27 18:20:47 -06:00
Logan Markewich 51b4c80515 inject project_id and organization_id 2025-11-27 18:20:26 -06:00
George He 6f96fab48e Fix sheets API 2025-11-27 14:59:41 -08:00
George He 87dec5433d Add timeouts to E2E GHA (#1031)
* Add timeouts

* Session timeouts too
2025-11-27 14:57:59 -08:00
Pierre-Loic Doulcet 99f4eba8d0 Pierre/more parse parameters (#1027)
* up python sdk

* bupmVErsion

* Update py/llama_cloud_services/parse/base.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update py/llama_cloud_services/parse/base.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-25 14:43:27 +01:00
github-actions[bot] 54561e2dd2 chore: version packages (#1025) 2025-11-24 16:41:22 -06:00
Logan Markewich bfaec79a8f changeset 2025-11-24 16:37:58 -06:00
Logan Markewich 3e0e522a6b update ts 2025-11-24 16:36:31 -06:00
Logan Markewich f70b6d87ec update py 2025-11-24 16:31:15 -06:00
Logan Markewich 693b5b83b1 improve llama-sheets example 2025-11-24 09:44:11 -06:00
26 changed files with 222 additions and 85 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
os: [ubuntu-latest, windows-latest]
python-version: ["3.9"]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- name: Install uv
uses: astral-sh/setup-uv@v7
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Checkout Repo
uses: actions/checkout@v6
uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
+1 -1
View File
@@ -60,7 +60,7 @@ jobs:
- name: Checkout repository
if: steps.check-access.outputs.authorized == 'true'
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
fetch-depth: 1
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
matrix:
python-version: ["3.9"]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }}
- name: Install uv
+2 -1
View File
@@ -12,13 +12,14 @@ env:
jobs:
test_e2e:
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
# You can use PyPy versions in python-version.
# For example, pypy-2.7 and pypy-3.8
matrix:
python-version: ["3.12"]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install uv
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install uv
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
name: Test - TypeScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v5
@@ -15,7 +15,7 @@ jobs:
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout Repo
uses: actions/checkout@v6
uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
@@ -24,8 +24,8 @@ from workflows import Context
dotenv.load_dotenv()
# Global context for loaded dataframes
_dataframe_context: Dict[str, Any] = {}
# Global context for executed code
_code_context: Dict[str, Any] = {}
# Helper function for initial agent context
@@ -79,36 +79,30 @@ def list_extracted_data(data_dir: str = "data") -> str:
# Agent tool for code execution against dataframes
def execute_dataframe_code(
code: str, load_files: Optional[Dict[str, str]] = None
) -> str:
def execute_code(code: str) -> str:
"""
Execute Python pandas code against LlamaSheets extracted data.
Execute Python pandas code against LlamaSheets extracted data.
This tool allows flexible data analysis by executing arbitrary pandas code.
You can load parquet files, manipulate dataframes, and return results.
This tool allows flexible data analysis by executing arbitrary pandas code.
You can load parquet files, manipulate dataframes, and return results.
The code executes in a context where:
- pandas is available as 'pd'
- json is available for formatting output
- Previously loaded dataframes are accessible by their variable names
The code executes in a context where:
- pandas is available as 'pd'
- json is available for formatting output
Args:
code: Python code to execute. Any print() statements or stdout/stderr
will be captured and returned. Optionally set a 'result' variable
for structured output.
load_files: Optional dict mapping variable names to file paths to load
Example: {"df": "data/sales_region_1.parquet",
"meta": "data/sales_metadata_1.parquet"}
Args:
code: Python code to execute. Any print() statements or stdout/stderr
will be captured and returned. Optionally set a 'result' variable
for structured output.
Returns:
String containing:
- Any stdout/stderr output from the code execution
- The 'result' variable if it was set (formatted appropriately)
- Error message if execution failed
Returns:
String containing:
- Any stdout/stderr output from the code execution
- The 'result' variable if it was set (formatted appropriately)
- Error message if execution failed
Example usage:
code = '''
Example usage:
code = '''
# Load and inspect data
df = pd.read_parquet("data/sales_region_1.parquet")
print(f"Loaded {len(df)} rows")
@@ -118,9 +112,9 @@ def execute_dataframe_code(
"columns": list(df.columns),
"sample": df.head(3).to_dict(orient="records")
}
'''
'''
"""
global _dataframe_context
global _code_context
# Capture stdout and stderr
stdout_capture = io.StringIO()
@@ -138,24 +132,17 @@ def execute_dataframe_code(
"pd": pd,
"json": json,
"Path": Path,
**_dataframe_context, # Include previously loaded dataframes
**_code_context, # Include previously loaded dataframes
}
# Load any requested files into context
if load_files:
for var_name, file_path in load_files.items():
if file_path.endswith(".parquet"):
exec_context[var_name] = pd.read_parquet(file_path)
# Also save to global context for future calls
_dataframe_context[var_name] = exec_context[var_name]
elif file_path.endswith(".json"):
with open(file_path, "r") as f:
exec_context[var_name] = json.load(f)
_dataframe_context[var_name] = exec_context[var_name]
# Execute the code
exec(code, exec_context)
# Update global context with any new variables (excluding built-ins and modules)
for key, value in exec_context.items():
if not key.startswith("_") and key not in ["pd", "json", "Path"]:
_code_context[key] = value
# Restore stdout/stderr
sys.stdout = old_stdout
sys.stderr = old_stderr
@@ -223,8 +210,8 @@ def create_llamasheets_agent(
# Initialize LLM
llm = OpenAI(model=llm_model, api_key=api_key)
# Create tools - just 4 simple but powerful tools
tools = [execute_dataframe_code]
# Create tools list
tools = [execute_code]
# System prompt to guide the agent
available_regions = list_extracted_data()
@@ -238,11 +225,8 @@ LlamaSheets extracts messy spreadsheets into clean parquet files with two types
- Type detection: data_type, is_date_like, is_percentage, is_currency
- Layout: is_in_first_row, is_merged_cell, horizontal_alignment
Your approach:
1. Use list_extracted_data() to discover available files
2. Use execute_dataframe_code() to load and analyze data with pandas
3. Use metadata to understand structure (bold = headers, colors = groups)
4. Use save_dataframe() to export results
You have access to tools that allow you to execute Python pandas code against these files.
Use these tools to load the parquet files, analyze the data, and return results.
Key tips:
- Bold cells in metadata often indicate headers
@@ -299,7 +283,7 @@ async def main():
print(ev.delta, end="", flush=True)
_ = await handler
print("=== End Query ===\n")
print("\n=== End Query ===\n")
if __name__ == "__main__":
+6
View File
@@ -1,5 +1,11 @@
# llama-cloud-services-py
## 0.6.82
### Patch Changes
- bfaec79: Update for new page number params
## 0.6.81
### Patch Changes
+1 -1
View File
@@ -15,4 +15,4 @@ test: ## Run unit tests via pytest
.PHONY: e2e
e2e: ## Run all tests. Run with high parallelism using xdist since tests are bottlenecked bound by the slow backend parsing
uv run pytest -v -n 32 tests/
uv run pytest -v -n 32 --timeout=300 --session-timeout=1740 tests/
+35 -3
View File
@@ -2,7 +2,7 @@ import asyncio
import io
import os
import time
from typing import TYPE_CHECKING
from typing import Any, Dict, TYPE_CHECKING
import httpx
from llama_cloud.client import AsyncLlamaCloud
@@ -68,6 +68,8 @@ class LlamaSheets:
max_timeout: int = 300,
poll_interval: int = 5,
max_retries: int = 3,
project_id: str | None = None,
organization_id: str | None = None,
async_httpx_client: httpx.AsyncClient | None = None,
) -> None:
"""Initialize the LlamaSheets client.
@@ -78,6 +80,8 @@ class LlamaSheets:
max_timeout: Maximum time to wait for job completion in seconds
poll_interval: Interval between status checks in seconds
max_retries: Maximum number of retries for failed requests
project_id: Project ID for file operations. If not provided, will use LLAMA_CLOUD_PROJECT_ID env var
organization_id: Organization ID for file operations. If not provided, will use LLAMA_CLOUD_ORGANIZATION_ID env var
async_httpx_client: Optional custom async httpx client
"""
self.api_key = api_key or os.environ.get("LLAMA_CLOUD_API_KEY")
@@ -93,15 +97,32 @@ class LlamaSheets:
self.poll_interval = poll_interval
self.max_retries = max_retries
self.project_id = project_id or os.environ.get("LLAMA_CLOUD_PROJECT_ID")
self.organization_id = organization_id or os.environ.get(
"LLAMA_CLOUD_ORGANIZATION_ID"
)
self._async_client: httpx.AsyncClient | None = async_httpx_client
self._files_client = FileClient(
AsyncLlamaCloud(
token=self.api_key,
base_url=self.base_url,
httpx_client=async_httpx_client,
)
),
project_id=self.project_id,
organization_id=self.organization_id,
)
def _get_default_params(self) -> dict[str, str]:
"""Get default query parameters for API requests"""
params = {}
if self.project_id is not None:
params["project_id"] = self.project_id
if self.organization_id is not None:
params["organization_id"] = self.organization_id
return params
def _get_async_client(self) -> httpx.AsyncClient:
"""Get or create the async httpx client"""
if self._async_client is None:
@@ -306,6 +327,8 @@ class LlamaSheets:
"config": config.model_dump(mode="json", exclude_none=True),
}
params = self._get_default_params()
try:
async for attempt in AsyncRetrying(
stop=stop_after_attempt(self.max_retries),
@@ -318,6 +341,7 @@ class LlamaSheets:
response = await client.post(
f"{self.base_url}/api/v1/beta/sheets/jobs",
headers=self._get_headers(),
params=params,
json=payload,
)
response.raise_for_status()
@@ -347,12 +371,17 @@ class LlamaSheets:
):
with attempt:
client = self._get_async_client()
params: Dict[str, Any] = {
"include_results": include_results_metadata,
**self._get_default_params(),
}
response = await client.get(
f"{self.base_url}/api/v1/beta/sheets/jobs/{job_id}",
headers=self._get_headers(),
params={"include_results": include_results_metadata},
params=params,
)
response.raise_for_status()
return SpreadsheetJobResult.model_validate(response.json())
except Exception as e:
raise SpreadsheetAPIError(f"Failed to get job status: {e}") from e
@@ -415,6 +444,8 @@ class LlamaSheets:
# Get presigned URL
presigned_response = None
result_type_str = str(result_type)
params = self._get_default_params()
try:
async for attempt in AsyncRetrying(
stop=stop_after_attempt(self.max_retries),
@@ -427,6 +458,7 @@ class LlamaSheets:
response = await client.get(
f"{self.base_url}/api/v1/beta/sheets/jobs/{job_id}/regions/{region_id}/result/{result_type_str}",
headers=self._get_headers(),
params=params,
)
response.raise_for_status()
presigned_response = PresignedUrlResponse.model_validate(
+22
View File
@@ -654,6 +654,9 @@ class LlamaCloudIndex(BaseManagedIndex):
],
)
# Trigger a sync
client.pipelines.sync_pipeline(pipeline_id=index.pipeline.id)
doc_ids = [doc.id for doc in upserted_documents]
index.wait_for_completion(
doc_ids=doc_ids, verbose=verbose, raise_on_error=raise_on_error
@@ -738,6 +741,10 @@ class LlamaCloudIndex(BaseManagedIndex):
)
],
)
# Trigger a sync
self._client.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
upserted_document = upserted_documents[0]
self.wait_for_completion(
doc_ids=[upserted_document.id], verbose=verbose, raise_on_error=True
@@ -760,6 +767,9 @@ class LlamaCloudIndex(BaseManagedIndex):
)
],
)
# Trigger a sync
await self._aclient.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
upserted_document = upserted_documents[0]
await self.await_for_completion(
doc_ids=[upserted_document.id], verbose=verbose, raise_on_error=True
@@ -782,6 +792,9 @@ class LlamaCloudIndex(BaseManagedIndex):
)
],
)
# Trigger a sync
self._client.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
upserted_document = upserted_documents[0]
self.wait_for_completion(
doc_ids=[upserted_document.id], verbose=verbose, raise_on_error=True
@@ -804,6 +817,9 @@ class LlamaCloudIndex(BaseManagedIndex):
)
],
)
# Trigger a sync
await self._aclient.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
upserted_document = upserted_documents[0]
await self.await_for_completion(
doc_ids=[upserted_document.id], verbose=verbose, raise_on_error=True
@@ -827,6 +843,9 @@ class LlamaCloudIndex(BaseManagedIndex):
for doc in documents
],
)
# Trigger a sync
self._client.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
doc_ids = [doc.id for doc in upserted_documents]
self.wait_for_completion(doc_ids=doc_ids, verbose=True, raise_on_error=True)
return [True] * len(doc_ids)
@@ -849,6 +868,9 @@ class LlamaCloudIndex(BaseManagedIndex):
for doc in documents
],
)
# Trigger a sync
await self._aclient.pipelines.sync_pipeline(pipeline_id=self.pipeline.id)
doc_ids = [doc.id for doc in upserted_documents]
await self.await_for_completion(
doc_ids=doc_ids, verbose=True, raise_on_error=True
+72 -3
View File
@@ -285,7 +285,7 @@ class LlamaParse(BasePydanticReader):
description="Note: Non compatible with gpt-4o. If set to true, the parser will use a faster mode to extract text from documents. This mode will skip OCR of images, and table/heading reconstruction.",
)
guess_xlsx_sheet_names: Optional[bool] = Field(
guess_xlsx_sheet_name: Optional[bool] = Field(
default=False,
description="Whether to guess the sheet names of the xlsx file.",
)
@@ -313,6 +313,10 @@ class LlamaParse(BasePydanticReader):
default=False,
description="If set to true, the parser will ignore document elements for layout detection and only rely on a vision model.",
)
inline_images_in_markdown: Optional[bool] = Field(
default=False,
description="If set to true, the parser will inline images in the markdown output.",
)
input_s3_region: Optional[str] = Field(
default=None,
description="The region of the input S3 bucket if input_s3_path is specified.",
@@ -329,6 +333,10 @@ class LlamaParse(BasePydanticReader):
default=None,
description="The maximum timeout in seconds to wait for the parsing to finish. Override default timeout of 30 minutes. Minimum is 120 seconds.",
)
keep_page_separator_when_merging_tables: Optional[bool] = Field(
default=False,
description="If set to true, the parser will keep the page separator when merging tables across pages.",
)
language: Optional[str] = Field(
default="en", description="The language of the text to parse."
)
@@ -400,6 +408,10 @@ class LlamaParse(BasePydanticReader):
default=False,
description="If set, the parser will try to preserve very small text lines. This can be useful for documents containing vector graphics with very small text lines that may not be recognized by OCR or a vision model (such as in CAD drawings).",
)
presentation_out_of_bounds_content: Optional[bool] = Field(
default=False,
description="If set to true, the parser will include out-of-bounds content in presentation files.",
)
precise_bounding_box: Optional[bool] = Field(
default=False,
description="If set to true, the parser will use a more precise bounding box to extract text from documents. This will increase the accuracy of the parsing job, but reduce the speed.",
@@ -416,6 +428,14 @@ class LlamaParse(BasePydanticReader):
default=None,
description="A suffix to add after error message in failed pages. If not set, no suffix will be used.",
)
remove_hidden_text: Optional[bool] = Field(
default=False,
description="If set to true, the parser will remove hidden text from the document.",
)
save_images: Optional[bool] = Field(
default=True,
description="If set to true, the parser will save images extracted from the document.",
)
skip_diagonal_text: Optional[bool] = Field(
default=False,
description="If set to true, the parser will ignore diagonal text (when the text rotation in degrees modulo 90 is not 0).",
@@ -440,6 +460,10 @@ class LlamaParse(BasePydanticReader):
default=False,
description="If set to true, the parser will use a specialized one-shot chart parsing model to extract data from charts. This model is able to understand the chart type and extract the data accordingly. It is more accurate than the efficient model, but also more expensive.",
)
specialized_image_parsing: Optional[bool] = Field(
default=False,
description="If set to true, the parser will use a specialized image parsing model to extract data from images.",
)
strict_mode_buggy_font: Optional[bool] = Field(
default=False,
description="If set to true, the parser will fail if it can't extract text from a document because of a buggy font.",
@@ -536,6 +560,10 @@ class LlamaParse(BasePydanticReader):
default=None,
description="A prefix to add to the page footer in the output markdown.",
)
extract_printed_page_number: Optional[bool] = Field(
default=None,
description="Whether to extract the printed page numbers from pages in the document.",
)
# Deprecated
bounding_box: Optional[str] = Field(
@@ -580,6 +608,23 @@ class LlamaParse(BasePydanticReader):
description="Automatically check for Python SDK updates.",
)
@model_validator(mode="before")
@classmethod
def handle_deprecated_params(cls, data: Dict[str, Any]) -> Dict[str, Any]:
# Handle deprecated guess_xlsx_sheet_names -> guess_xlsx_sheet_name
if "guess_xlsx_sheet_names" in data:
warnings.warn(
"The parameter 'guess_xlsx_sheet_names' is deprecated and will be removed in a future release. "
"Use 'guess_xlsx_sheet_name' instead.",
DeprecationWarning,
stacklevel=2,
)
# Only set the new parameter if it's not already explicitly set
if "guess_xlsx_sheet_name" not in data:
data["guess_xlsx_sheet_name"] = data["guess_xlsx_sheet_names"]
del data["guess_xlsx_sheet_names"]
return data
@model_validator(mode="before")
@classmethod
def warn_extra_params(cls, data: Dict[str, Any]) -> Dict[str, Any]:
@@ -820,8 +865,8 @@ class LlamaParse(BasePydanticReader):
)
data["formatting_instruction"] = self.formatting_instruction
if self.guess_xlsx_sheet_names:
data["guess_xlsx_sheet_names"] = self.guess_xlsx_sheet_names
if self.guess_xlsx_sheet_name:
data["guess_xlsx_sheet_name"] = self.guess_xlsx_sheet_name
if self.html_make_all_elements_visible:
data["html_make_all_elements_visible"] = self.html_make_all_elements_visible
@@ -845,6 +890,9 @@ class LlamaParse(BasePydanticReader):
"ignore_document_elements_for_layout_detection"
] = self.ignore_document_elements_for_layout_detection
if self.inline_images_in_markdown:
data["inline_images_in_markdown"] = self.inline_images_in_markdown
if input_url is not None:
files = None
data["input_url"] = str(input_url)
@@ -873,6 +921,11 @@ class LlamaParse(BasePydanticReader):
if self.job_timeout_in_seconds is not None:
data["job_timeout_in_seconds"] = self.job_timeout_in_seconds
if self.keep_page_separator_when_merging_tables:
data[
"keep_page_separator_when_merging_tables"
] = self.keep_page_separator_when_merging_tables
if self.language:
data["language"] = self.language
@@ -951,6 +1004,11 @@ class LlamaParse(BasePydanticReader):
if self.preserve_very_small_text:
data["preserve_very_small_text"] = self.preserve_very_small_text
if self.presentation_out_of_bounds_content:
data[
"presentation_out_of_bounds_content"
] = self.presentation_out_of_bounds_content
if self.preset is not None:
data["preset"] = self.preset
@@ -970,6 +1028,11 @@ class LlamaParse(BasePydanticReader):
"replace_failed_page_with_error_message_suffix"
] = self.replace_failed_page_with_error_message_suffix
if self.remove_hidden_text:
data["remove_hidden_text"] = self.remove_hidden_text
data["save_images"] = self.save_images
if self.skip_diagonal_text:
data["skip_diagonal_text"] = self.skip_diagonal_text
@@ -994,6 +1057,9 @@ class LlamaParse(BasePydanticReader):
if self.specialized_chart_parsing_plus:
data["specialized_chart_parsing_plus"] = self.specialized_chart_parsing_plus
if self.specialized_image_parsing:
data["specialized_image_parsing"] = self.specialized_image_parsing
if self.strict_mode_buggy_font:
data["strict_mode_buggy_font"] = self.strict_mode_buggy_font
@@ -1049,6 +1115,9 @@ class LlamaParse(BasePydanticReader):
"markdown_table_multiline_header_separator"
] = self.markdown_table_multiline_header_separator
if self.extract_printed_page_number is not None:
data["extract_printed_page_number"] = self.extract_printed_page_number
# Deprecated
if self.bounding_box is not None:
data["bounding_box"] = self.bounding_box
+13
View File
@@ -250,6 +250,19 @@ class Page(SafeBaseModel):
slideSpeakerNotes: Optional[str] = Field(
default=None, description="The speaker notes for the slide."
)
confidence: Optional[float] = Field(
default=None, description="The confidence of the page parsing."
)
printedPageNumber: Optional[str] = Field(
default=None,
description="The printed page number on the page, if found and extractPrintedPageNumber is set to true.",
)
pageHeaderMarkdown: Optional[str] = Field(
default=None, description="The page header in markdown format."
)
pageFooterMarkdown: Optional[str] = Field(
default=None, description="The page footer in markdown format."
)
class JobResult(SafeBaseModel):
+7
View File
@@ -1,5 +1,12 @@
# llama_parse
## 0.6.82
### Patch Changes
- Updated dependencies [bfaec79]
- llama-cloud-services-py@0.6.82
## 0.6.81
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llama_parse",
"version": "0.6.81",
"version": "0.6.82",
"description": "",
"main": "index.js",
"private": false,
+2 -2
View File
@@ -11,13 +11,13 @@ dev = [
[project]
name = "llama-parse"
version = "0.6.81"
version = "0.6.83"
description = "Parse files into RAG-Optimized formats."
authors = [{name = "Logan Markewich", email = "logan@llamaindex.ai"}]
requires-python = ">=3.9,<4.0"
readme = "README.md"
license = "MIT"
dependencies = ["llama-cloud-services>=0.6.81"]
dependencies = ["llama-cloud-services>=0.6.82"]
[project.scripts]
llama-parse = "llama_parse.cli.main:parse"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llama-cloud-services-py",
"version": "0.6.81",
"version": "0.6.82",
"private": false,
"license": "MIT",
"scripts": {},
+2 -1
View File
@@ -7,6 +7,7 @@ dev = [
"pytest>=8.0.0,<9",
"pytest-xdist>=3.6.1,<4",
"pytest-asyncio",
"pytest-timeout>=2.3.1",
"ipykernel>=6.29.0,<7",
"pre-commit==3.2.0",
"autoevals>=0.0.114,<0.0.115",
@@ -22,7 +23,7 @@ dev = [
[project]
name = "llama-cloud-services"
version = "0.6.81"
version = "0.6.83"
description = "Tailored SDK clients for LlamaCloud services."
authors = [{name = "Logan Markewich", email = "logan@runllama.ai"}]
requires-python = ">=3.9,<4.0"
+6 -12
View File
@@ -10,16 +10,16 @@ from llama_cloud_services.beta.sheets.types import SpreadsheetParsingConfig
@pytest.fixture
def sheets_client():
"""Create a LlamaSheets client for testing."""
api_key = os.getenv(
"LLAMA_CLOUD_API_KEY", "llx-3AEorIw5v0lnJPzEOI9xSl0N8yFx3fguw0Zn8QJHzGWmwg5r"
)
base_url = os.getenv("LLAMA_CLOUD_BASE_URL", "https://api.staging.llamaindex.ai")
api_key = os.getenv("LLAMA_CLOUD_API_KEY")
base_url = os.getenv("LLAMA_CLOUD_BASE_URL", "https://api.cloud.llamaindex.ai")
project_id = os.getenv("LLAMA_CLOUD_PROJECT_ID")
client = LlamaSheets(
api_key=api_key,
base_url=base_url,
max_timeout=300,
poll_interval=2,
project_id=project_id,
)
return client
@@ -51,10 +51,7 @@ def sample_excel_file():
@pytest.mark.skipif(
os.environ.get(
"LLAMA_CLOUD_API_KEY", "llx-3AEorIw5v0lnJPzEOI9xSl0N8yFx3fguw0Zn8QJHzGWmwg5r"
)
== "",
os.environ.get("LLAMA_CLOUD_API_KEY", "") == "",
reason="LLAMA_CLOUD_API_KEY not set",
)
@pytest.mark.asyncio
@@ -134,10 +131,7 @@ async def test_spreadsheet_extraction_e2e(
@pytest.mark.skipif(
os.environ.get(
"LLAMA_CLOUD_API_KEY", "llx-3AEorIw5v0lnJPzEOI9xSl0N8yFx3fguw0Zn8QJHzGWmwg5r"
)
== "",
os.environ.get("LLAMA_CLOUD_API_KEY", "") == "",
reason="LLAMA_CLOUD_API_KEY not set",
)
@pytest.mark.asyncio
+2 -2
View File
@@ -78,7 +78,7 @@ async def test_upload_bytes(
uploaded_file = await file_client.upload_bytes(file_bytes, external_file_id)
assert isinstance(uploaded_file, File)
expected_name = external_file_id if use_presigned_url else "upload"
expected_name = external_file_id
assert uploaded_file.name == expected_name
assert uploaded_file.external_file_id == external_file_id
@@ -100,7 +100,7 @@ async def test_upload_buffer(
uploaded_file = await file_client.upload_buffer(buffer, external_file_id, file_size)
assert isinstance(uploaded_file, File)
expected_name = external_file_id if use_presigned_url else "upload"
expected_name = external_file_id
assert uploaded_file.name == expected_name
assert uploaded_file.external_file_id == external_file_id
+6
View File
@@ -1,5 +1,11 @@
# llama-cloud-services
## 0.4.2
### Patch Changes
- bfaec79: Update for new page number params
## 0.4.1
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llama-cloud-services",
"version": "0.4.1",
"version": "0.4.2",
"type": "module",
"license": "MIT",
"scripts": {
+2
View File
@@ -185,6 +185,7 @@ export class LlamaParseReader extends FileReader {
page_footer_prefix?: string | undefined;
page_footer_suffix?: string | undefined;
merge_tables_across_pages_in_markdown?: boolean | undefined;
extract_printed_page_number?: boolean | undefined;
constructor(
params: Partial<Omit<LlamaParseReader, "language" | "apiKey">> & {
@@ -381,6 +382,7 @@ export class LlamaParseReader extends FileReader {
page_footer_suffix: this.page_footer_suffix,
merge_tables_across_pages_in_markdown:
this.merge_tables_across_pages_in_markdown,
extract_printed_page_number: this.extract_printed_page_number,
} satisfies {
[Key in keyof BodyUploadFileApiParsingUploadPost]-?:
| BodyUploadFileApiParsingUploadPost[Key]