Skip to content

Commit dc553e6

Browse files
committed
WIP AF
1 parent bdfa33c commit dc553e6

File tree

8 files changed

+343
-31
lines changed

8 files changed

+343
-31
lines changed

client_db.pkl

9.4 KB
Binary file not shown.

src/axiomatic/axtract/interactive_table.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from IPython.display import display # type: ignore
33
import json # type: ignore
44
import os # type: ignore
5-
from .. import EquationExtractionResponse, VariableRequirement
5+
from .. import EquationProcessingResponse, VariableRequirement
66

77

88
def _find_symbol(name, variable_dict):
@@ -33,15 +33,15 @@ def _requirements_from_table(results, variable_dict):
3333
return requirements
3434

3535

36-
def interactive_table(loaded_equations, file_path="./custom_presets.json"):
36+
def interactive_table(loaded_equations: EquationProcessingResponse, file_path: str = "./custom_presets.json"):
3737
"""
3838
Creates an interactive table for IMAGING_TELESCOPE,
3939
PAYLOAD, and user-defined custom templates.
4040
Adds or deletes rows, and can save custom templates persistently in JSON.
4141
4242
Parameters
4343
----------
44-
loaded_equations : EquationExtractionResponse
44+
loaded_equations : EquationProcessingResponse
4545
The extracted equations containing variable information
4646
file_path : str, optional
4747
JSON file path where we load and save user-created custom templates.
@@ -382,14 +382,14 @@ def save_requirements(_):
382382
return requirements_result
383383

384384

385-
def _create_variable_dict(equation_response: EquationExtractionResponse) -> dict:
385+
def _create_variable_dict(equation_response: EquationProcessingResponse) -> dict:
386386
"""
387-
Creates a variable dictionary from an EquationExtractionResponse object
387+
Creates a variable dictionary from an EquationProcessingResponse object
388388
for use with the interactive_table function.
389389
390390
Parameters
391391
----------
392-
equation_response : EquationExtractionResponse
392+
equation_response : EquationProcessingResponse
393393
The equation extraction response containing equations and their symbols
394394
395395
Returns

src/axiomatic/client.py

Lines changed: 104 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
from typing import Dict, List, Optional, Union
99

1010
from .base_client import BaseClient, AsyncBaseClient
11-
from . import ParseResponse, EquationExtractionResponse, EquationProcessingResponse
11+
from . import ParseResponse, EquationProcessingResponse
1212
from .axtract.axtract_report import create_report
1313
from .axtract.validation_results import display_full_results
14-
from .axtract.interactive_table import _create_variable_dict
15-
from .types.variable_requirement import VariableRequirement as ApiVariableRequirement
14+
from .axtract.interactive_table import _create_variable_dict, VariableRequirement
15+
from .types.variable_requirement import VariableRequirement
16+
from .types.validate_equations_body import ValidateEquationsBody
1617

1718

1819
class Axiomatic(BaseClient):
@@ -27,36 +28,83 @@ def __init__(self, *args, **kwargs):
2728

2829

2930
class AxtractHelper:
30-
from .axtract.interactive_table import VariableRequirement
31-
3231
_ax_client: Axiomatic
3332

3433
def __init__(self, ax_client: Axiomatic):
34+
"""Initialize the AxtractHelper with an Axiomatic client.
35+
36+
Args:
37+
ax_client (Axiomatic): The Axiomatic client instance to use for API calls
38+
"""
3539
self._ax_client = ax_client
3640

37-
def create_report(self, response: EquationExtractionResponse, path: str):
41+
def create_report(self, response: EquationProcessingResponse, path: str):
42+
"""Create a report from equation extraction results.
43+
44+
Args:
45+
response (EquationExtractionResponse): The extracted equations and their metadata
46+
path (str): Directory path where the report should be saved
47+
"""
3848
create_report(response, path)
3949

4050
def analyze_equations(
4151
self,
4252
file_path: Optional[str] = None,
4353
url_path: Optional[str] = None,
4454
parsed_paper: Optional[ParseResponse] = None,
45-
) -> Optional[EquationExtractionResponse]:
55+
) -> Optional[EquationProcessingResponse]:
56+
"""Analyze and extract equations from a scientific document.
57+
58+
This method supports three input methods:
59+
1. Local PDF file path
60+
2. URL to a PDF (with special handling for arXiv URLs)
61+
3. Pre-parsed paper data
62+
63+
Args:
64+
file_path (Optional[str]): Path to a local PDF file
65+
url_path (Optional[str]): URL to a PDF file (supports arXiv links)
66+
parsed_paper (Optional[ParseResponse]): Pre-parsed paper data
67+
68+
Returns:
69+
Optional[EquationExtractionResponse]: Extracted equations and their metadata.
70+
Returns None if no valid input is provided.
71+
72+
Examples:
73+
# From local file
74+
client.analyze_equations(file_path="path/to/paper.pdf")
75+
76+
# From URL
77+
client.analyze_equations(url_path="https://arxiv.org/pdf/2203.00001.pdf")
78+
79+
# From parsed paper
80+
client.analyze_equations(parsed_paper=parsed_data)
81+
"""
4682
if file_path:
4783
with open(file_path, "rb") as pdf_file:
48-
response = self._ax_client.document.equation.from_pdf(document=pdf_file)
84+
parsed_document = self._ax_client.document.parse(file=pdf_file)
85+
print("We are almost there")
86+
response = self._ax_client.document.equation.process(
87+
markdown=parsed_document.markdown,
88+
interline_equations=parsed_document.interline_equations,
89+
inline_equations=parsed_document.inline_equations
90+
)
4991

5092
elif url_path:
5193
if "arxiv" in url_path and "abs" in url_path:
5294
url_path = url_path.replace("abs", "pdf")
5395
url_file = requests.get(url_path)
5496
from io import BytesIO
5597
pdf_stream = BytesIO(url_file.content)
56-
response = self._ax_client.document.equation.from_pdf(document=pdf_stream)
98+
parsed_document = self._ax_client.document.parse(file=url_file.content)
99+
print("We are almost there")
100+
response = self._ax_client.document.equation.process(
101+
markdown=parsed_document.markdown,
102+
interline_equations=parsed_document.interline_equations,
103+
inline_equations=parsed_document.inline_equations
104+
)
57105

58106
elif parsed_paper:
59-
response = EquationExtractionResponse.model_validate(
107+
response = EquationProcessingResponse.model_validate(
60108
self._ax_client.document.equation.process(**parsed_paper.model_dump()).model_dump()
61109
)
62110

@@ -68,22 +116,55 @@ def analyze_equations(
68116

69117
def validate_equations(
70118
self,
71-
requirements: List[VariableRequirement],
72-
loaded_equations: EquationExtractionResponse,
119+
requirements: list[VariableRequirement],
120+
loaded_equations: EquationProcessingResponse,
73121
show_hypergraph: bool = True,
122+
include_internal_model: bool = False,
74123
):
75-
api_requirements = [
76-
ApiVariableRequirement(
77-
symbol=req.symbol, name=req.name, value=req.value, units=req.units, tolerance=req.tolerance
78-
)
79-
for req in requirements
80-
]
124+
"""Validate equations against a set of variable requirements.
125+
126+
Args:
127+
requirements: List of variable requirements to validate
128+
loaded_equations: Previously processed equations to validate
129+
show_hypergraph: Whether to display the validation results graph (default: True)
130+
include_internal_model: Whether to include internal model equations in validation (default: False)
131+
132+
Returns:
133+
EquationValidationResult containing the validation results
134+
"""
135+
# Convert loaded_equations to dict first to ensure proper serialization
136+
equations_dict = loaded_equations.model_dump() if hasattr(loaded_equations, 'model_dump') else loaded_equations.dict()
137+
138+
request_body = ValidateEquationsBody(
139+
variables=requirements,
140+
paper_equations=equations_dict,
141+
include_internal_model=include_internal_model
142+
)
143+
144+
print(request_body.model_dump_json())
145+
146+
api_response = self._ax_client.document.equation.validate(request_body.model_dump_json())
147+
148+
if show_hypergraph:
149+
pass
150+
151+
return api_response
152+
153+
154+
155+
156+
def set_numerical_requirements(self, extracted_equations: EquationProcessingResponse):
157+
"""Launch an interactive interface for setting numerical requirements for equations.
81158
82-
variable_dict = _create_variable_dict(loaded_equations)
83-
api_response = self._ax_client.document.equation.validate(request=api_requirements)
84-
display_full_results(api_response.model_dump(), variable_dict, show_hypergraph=show_hypergraph)
159+
This method opens an interactive table interface where users can specify
160+
requirements for variables found in the extracted equations.
85161
86-
def set_numerical_requirements(self, extracted_equations):
162+
Args:
163+
extracted_equations: The equations to set requirements for
164+
165+
Returns:
166+
The requirements set through the interactive interface
167+
"""
87168
from .axtract.interactive_table import interactive_table
88169

89170
result = interactive_table(extracted_equations)
@@ -255,4 +336,4 @@ def _load_objects_from_base64(self, encoded_dict):
255336
return loaded_objects
256337

257338

258-
class AsyncAxiomatic(AsyncBaseClient): ...
339+
class AsyncAxiomatic(AsyncBaseClient): ...
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from pydantic import BaseModel, Field
2+
from typing import List, Dict, Optional
3+
4+
class DictItem(BaseModel):
5+
key: str
6+
value: str
7+
8+
class ResponseEquation(BaseModel):
9+
"""
10+
Pydantic model representing a scientific or mathematical equation.
11+
"""
12+
13+
name: str = Field(
14+
...,
15+
description="Human-readable name of the equation (e.g., 'Newton's Law')",
16+
)
17+
description: str = Field(..., description="Text describing the equation")
18+
original_format: str = Field(..., description="Original form of the equation (e.g., LaTeX)")
19+
wolfram_expressions: str = Field(
20+
..., description="Equation in Wolfram Language (or other symbolic form)"
21+
)
22+
latex_symbols: list[DictItem] = Field(
23+
..., description="Detailed metadata for each latex variable in original format"
24+
)
25+
wolfram_symbols: list[str] = Field(
26+
..., description="List of symbols used in the wolfram expression"
27+
)
28+
narrative_assumptions: list[str] = Field(
29+
..., description="Narrative text describing assumptions/approximations"
30+
)
31+
type: list[str] = Field(
32+
...,
33+
description="List of equation classifications (e.g., ['scalar','tensor'])",
34+
)
35+
field_tags: list[str] = Field(
36+
...,
37+
description="Classification tags (e.g., ['quantum mechanics','gravitation'])",
38+
)

src/axiomatic/types/equation_processing_response.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from ..core.pydantic_utilities import UniversalBaseModel
44
import typing
5-
from .equation_extraction import EquationExtraction
5+
from .equation_processing import ResponseEquation
66
from ..core.pydantic_utilities import IS_PYDANTIC_V2
77
import pydantic
88

99

1010
class EquationProcessingResponse(UniversalBaseModel):
11-
equations: typing.List[EquationExtraction]
11+
equations: typing.List[ResponseEquation]
1212

1313
if IS_PYDANTIC_V2:
1414
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from .variable_requirement import VariableRequirement
2+
from .equation_processing_response import EquationProcessingResponse
3+
from pydantic import BaseModel
4+
5+
class ValidateEquationsBody(BaseModel):
6+
variables: list[VariableRequirement]
7+
paper_equations: EquationProcessingResponse
8+
include_internal_model: bool = False

test_axai.pdf

125 KB
Binary file not shown.

0 commit comments

Comments
 (0)