From 59ff1d0386f05ddeae8d5bc9b707c603b2c2c9da Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Mon, 29 Jan 2024 08:57:57 -0700 Subject: [PATCH 01/12] add the eqn2decapodes workflow --- skema/rest/schema.py | 9 +++++++++ skema/rest/workflows.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/skema/rest/schema.py b/skema/rest/schema.py index cdf9ef197d8..3a07ffb0427 100644 --- a/skema/rest/schema.py +++ b/skema/rest/schema.py @@ -61,6 +61,15 @@ class EquationLatexToAMR(BaseModel): ) +class EquationLatexToDecapodes(BaseModel): + equations: List[str] = Field( + description="Equations in LaTeX", + examples=[[ + r"\frac{\partial x}{\partial t} = {\alpha x} - {\beta x y}", + r"\frac{\partial y}{\partial t} = {\alpha x y} - {\gamma y}", + ]], + ) + class MmlToAMR(BaseModel): equations: List[str] = Field( description="Equations in pMML", diff --git a/skema/rest/workflows.py b/skema/rest/workflows.py index f5cfac96e0a..64cc22a218d 100644 --- a/skema/rest/workflows.py +++ b/skema/rest/workflows.py @@ -204,6 +204,39 @@ async def equations_to_amr(data: schema.MmlToAMR, client: httpx.AsyncClient = De return res.json() +# tex equations -> pmml -> Decapodes +@router.post("/latex/equations-to-decapodes", summary="Equations (LaTeX) → pMML → Decapodes") +async def equations_to_decapodes(data: schema.EquationLatexToDecapodes, client: httpx.AsyncClient = Depends(utils.get_client)): + """ + Converts equations (in LaTeX) to AMR. + + ### Python example + ``` + import requests + + equations = [ + "\\frac{\\delta x}{\\delta t} = {\\alpha x} - {\\beta x y}", + "\\frac{\\delta y}{\\delta t} = {\\alpha x y} - {\\gamma y}" + ] + url = "0.0.0.0" + r = requests.post(f"{url}/workflows/latex/equations-to-amr", json={"equations": equations, "model": "regnet"}) + r.json() + """ + mml: List[str] = [ + utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations + ] + + res = await client.put(f"{SKEMA_RS_ADDESS}/mathml/decapodes", json=mml) + if res.status_code != 200: + return JSONResponse( + status_code=400, + content={ + "error": f"MORAE PUT /mathml/amr failed to process payload with error {res.text}", + "payload": mml, + }, + ) + return res.json() + # code snippets -> fn -> petrinet amr @router.post("/code/snippets-to-pn-amr", summary="Code snippets → PetriNet AMR") async def code_snippets_to_pn_amr(system: code2fn.System, client: httpx.AsyncClient = Depends(utils.get_client)): From fde4d09556fc9c5d4efae58132dbf8359162f52a Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Mon, 29 Jan 2024 09:01:06 -0700 Subject: [PATCH 02/12] update the eqn2decapodes workflow example --- skema/rest/workflows.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/skema/rest/workflows.py b/skema/rest/workflows.py index 64cc22a218d..78bab96bc26 100644 --- a/skema/rest/workflows.py +++ b/skema/rest/workflows.py @@ -208,19 +208,21 @@ async def equations_to_amr(data: schema.MmlToAMR, client: httpx.AsyncClient = De @router.post("/latex/equations-to-decapodes", summary="Equations (LaTeX) → pMML → Decapodes") async def equations_to_decapodes(data: schema.EquationLatexToDecapodes, client: httpx.AsyncClient = Depends(utils.get_client)): """ - Converts equations (in LaTeX) to AMR. + Converts equations (in LaTeX) to Decapodes. ### Python example ``` import requests equations = [ - "\\frac{\\delta x}{\\delta t} = {\\alpha x} - {\\beta x y}", - "\\frac{\\delta y}{\\delta t} = {\\alpha x y} - {\\gamma y}" + "\\frac{\\delta x}{\\delta t} = {\\alpha x} - {\\beta x y}", + "\\frac{\\delta y}{\\delta t} = {\\alpha x y} - {\\gamma y}" ] - url = "0.0.0.0" - r = requests.post(f"{url}/workflows/latex/equations-to-amr", json={"equations": equations, "model": "regnet"}) - r.json() + + url = "http://127.0.0.1:8000" + + r = requests.post(f"{url}/latex/equations-to-decapodes", json={"equations": equations}) + print(r.json()) """ mml: List[str] = [ utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations From 1861a2719ee5e3c18a5eea4de3963cd66fb68467 Mon Sep 17 00:00:00 2001 From: Deepsana Shahi Date: Mon, 29 Jan 2024 11:58:45 -0700 Subject: [PATCH 03/12] Add test for latex to decapodes --- skema/rest/tests/test_latex_to_decapodes.py | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 skema/rest/tests/test_latex_to_decapodes.py diff --git a/skema/rest/tests/test_latex_to_decapodes.py b/skema/rest/tests/test_latex_to_decapodes.py new file mode 100644 index 00000000000..ec644b1799e --- /dev/null +++ b/skema/rest/tests/test_latex_to_decapodes.py @@ -0,0 +1,32 @@ +from httpx import AsyncClient +from skema.rest.workflows import app +import pytest +import json + +@pytest.mark.ci_only +@pytest.mark.asyncio +async def test_post_latex_to_decapodes(): + """ + Test case for /latex/equations-to-decapodes endpoint. + """ + equations = [ + "\\frac{d H}{dt}=\\nabla \\cdot {(\\Gamma*H^{n+2}*\\left|\\nabla{H}\\right|^{n-1}*\\nabla{H})}" + ] + + endpoint = "/latex/equations_to_decapodes" + + async with AsyncClient(app=app, base_url="http://latex-to-decapodes-test") as ac: + response = await ac.put(endpoint, json=equations) + expected = "{\"Var\":[{\"type\":\"infer\",\"name\":\"•1\"},{\"type\":\"infer\",\"name\":\"mult_1\"},{\"type\":\"infer\",\"name\":\"mult_2\"},{\"type\":\"infer\",\"name\":\"mult_3\"},{\"type\":\"infer\",\"name\":\"Γ\"},{\"type\":\"infer\",\"name\":\"•2\"},{\"type\":\"infer\",\"name\":\"H\"},{\"type\":\"infer\",\"name\":\"sum_1\"},{\"type\":\"infer\",\"name\":\"n\"},{\"type\":\"Literal\",\"name\":\"2\"},{\"type\":\"infer\",\"name\":\"•3\"},{\"type\":\"infer\",\"name\":\"•4\"},{\"type\":\"infer\",\"name\":\"•5\"},{\"type\":\"infer\",\"name\":\"•6\"},{\"type\":\"Literal\",\"name\":\"1\"},{\"type\":\"infer\",\"name\":\"•7\"},{\"type\":\"infer\",\"name\":\"•8\"}],\"Op1\":[{\"src\":7,\"tgt\":13,\"op1\":\"Grad\"},{\"src\":13,\"tgt\":12,\"op1\":\"Abs\"},{\"src\":7,\"tgt\":16,\"op1\":\"Grad\"},{\"src\":2,\"tgt\":1,\"op1\":\"Div\"},{\"src\":7,\"tgt\":17,\"op1\":\"D(1,t)\"}],\"Op2\":[{\"proj1\":7,\"proj2\":8,\"res\":6,\"op2\":\"^\"},{\"proj1\":5,\"proj2\":6,\"res\":4,\"op2\":\"*\"},{\"proj1\":9,\"proj2\":15,\"res\":14,\"op2\":\"-\"},{\"proj1\":12,\"proj2\":14,\"res\":11,\"op2\":\"^\"},{\"proj1\":4,\"proj2\":11,\"res\":3,\"op2\":\"*\"},{\"proj1\":3,\"proj2\":16,\"res\":2,\"op2\":\"*\"}],\"Σ\":[{\"sum\":8}],\"Summand\":[{\"summand\":9,\"summation\":1},{\"summand\":10,\"summation\":1}]}" + # check for route's existence + assert ( + any(route.path == endpoint for route in app.routes) == True + ), "{endpoint} does not exist for app" + # check status code + assert ( + response.status_code == 200 + ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" + # check response + assert ( + json.loads(response.text) == expected + ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file From 961074fb9de88d7103961aa68474554c80712aeb Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Mon, 29 Jan 2024 13:09:31 -0700 Subject: [PATCH 04/12] format test_latex_to_decapodes.py --- skema/rest/tests/test_latex_to_decapodes.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/skema/rest/tests/test_latex_to_decapodes.py b/skema/rest/tests/test_latex_to_decapodes.py index ec644b1799e..893842d404e 100644 --- a/skema/rest/tests/test_latex_to_decapodes.py +++ b/skema/rest/tests/test_latex_to_decapodes.py @@ -3,6 +3,7 @@ import pytest import json + @pytest.mark.ci_only @pytest.mark.asyncio async def test_post_latex_to_decapodes(): @@ -17,16 +18,16 @@ async def test_post_latex_to_decapodes(): async with AsyncClient(app=app, base_url="http://latex-to-decapodes-test") as ac: response = await ac.put(endpoint, json=equations) - expected = "{\"Var\":[{\"type\":\"infer\",\"name\":\"•1\"},{\"type\":\"infer\",\"name\":\"mult_1\"},{\"type\":\"infer\",\"name\":\"mult_2\"},{\"type\":\"infer\",\"name\":\"mult_3\"},{\"type\":\"infer\",\"name\":\"Γ\"},{\"type\":\"infer\",\"name\":\"•2\"},{\"type\":\"infer\",\"name\":\"H\"},{\"type\":\"infer\",\"name\":\"sum_1\"},{\"type\":\"infer\",\"name\":\"n\"},{\"type\":\"Literal\",\"name\":\"2\"},{\"type\":\"infer\",\"name\":\"•3\"},{\"type\":\"infer\",\"name\":\"•4\"},{\"type\":\"infer\",\"name\":\"•5\"},{\"type\":\"infer\",\"name\":\"•6\"},{\"type\":\"Literal\",\"name\":\"1\"},{\"type\":\"infer\",\"name\":\"•7\"},{\"type\":\"infer\",\"name\":\"•8\"}],\"Op1\":[{\"src\":7,\"tgt\":13,\"op1\":\"Grad\"},{\"src\":13,\"tgt\":12,\"op1\":\"Abs\"},{\"src\":7,\"tgt\":16,\"op1\":\"Grad\"},{\"src\":2,\"tgt\":1,\"op1\":\"Div\"},{\"src\":7,\"tgt\":17,\"op1\":\"D(1,t)\"}],\"Op2\":[{\"proj1\":7,\"proj2\":8,\"res\":6,\"op2\":\"^\"},{\"proj1\":5,\"proj2\":6,\"res\":4,\"op2\":\"*\"},{\"proj1\":9,\"proj2\":15,\"res\":14,\"op2\":\"-\"},{\"proj1\":12,\"proj2\":14,\"res\":11,\"op2\":\"^\"},{\"proj1\":4,\"proj2\":11,\"res\":3,\"op2\":\"*\"},{\"proj1\":3,\"proj2\":16,\"res\":2,\"op2\":\"*\"}],\"Σ\":[{\"sum\":8}],\"Summand\":[{\"summand\":9,\"summation\":1},{\"summand\":10,\"summation\":1}]}" + expected = '{"Var":[{"type":"infer","name":"•1"},{"type":"infer","name":"mult_1"},{"type":"infer","name":"mult_2"},{"type":"infer","name":"mult_3"},{"type":"infer","name":"Γ"},{"type":"infer","name":"•2"},{"type":"infer","name":"H"},{"type":"infer","name":"sum_1"},{"type":"infer","name":"n"},{"type":"Literal","name":"2"},{"type":"infer","name":"•3"},{"type":"infer","name":"•4"},{"type":"infer","name":"•5"},{"type":"infer","name":"•6"},{"type":"Literal","name":"1"},{"type":"infer","name":"•7"},{"type":"infer","name":"•8"}],"Op1":[{"src":7,"tgt":13,"op1":"Grad"},{"src":13,"tgt":12,"op1":"Abs"},{"src":7,"tgt":16,"op1":"Grad"},{"src":2,"tgt":1,"op1":"Div"},{"src":7,"tgt":17,"op1":"D(1,t)"}],"Op2":[{"proj1":7,"proj2":8,"res":6,"op2":"^"},{"proj1":5,"proj2":6,"res":4,"op2":"*"},{"proj1":9,"proj2":15,"res":14,"op2":"-"},{"proj1":12,"proj2":14,"res":11,"op2":"^"},{"proj1":4,"proj2":11,"res":3,"op2":"*"},{"proj1":3,"proj2":16,"res":2,"op2":"*"}],"Σ":[{"sum":8}],"Summand":[{"summand":9,"summation":1},{"summand":10,"summation":1}]}' # check for route's existence assert ( - any(route.path == endpoint for route in app.routes) == True + any(route.path == endpoint for route in app.routes) == True ), "{endpoint} does not exist for app" # check status code assert ( - response.status_code == 200 + response.status_code == 200 ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" # check response assert ( - json.loads(response.text) == expected + json.loads(response.text) == expected ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file From e21b167e2861b7717d6819a9b5039deead1408f2 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Thu, 1 Feb 2024 14:55:46 -0700 Subject: [PATCH 05/12] add the workflow of eqn2met --- skema/rest/schema.py | 4 +- skema/rest/tests/test_eqns_to_mets.py | 88 +++++++++++++++++++ skema/rest/tests/test_latex_to_decapodes.py | 33 ------- skema/rest/workflows.py | 31 ++++--- skema/skema-rs/skema/src/bin/skema_service.rs | 2 + skema/skema-rs/skema/src/services/mathml.rs | 20 +++++ 6 files changed, 130 insertions(+), 48 deletions(-) create mode 100644 skema/rest/tests/test_eqns_to_mets.py delete mode 100644 skema/rest/tests/test_latex_to_decapodes.py diff --git a/skema/rest/schema.py b/skema/rest/schema.py index 3a07ffb0427..4e47262358a 100644 --- a/skema/rest/schema.py +++ b/skema/rest/schema.py @@ -61,9 +61,9 @@ class EquationLatexToAMR(BaseModel): ) -class EquationLatexToDecapodes(BaseModel): +class EquationToMET(BaseModel): equations: List[str] = Field( - description="Equations in LaTeX", + description="Equations in LaTeX or pMathML", examples=[[ r"\frac{\partial x}{\partial t} = {\alpha x} - {\beta x y}", r"\frac{\partial y}{\partial t} = {\alpha x y} - {\gamma y}", diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py new file mode 100644 index 00000000000..8de352576ff --- /dev/null +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -0,0 +1,88 @@ +from httpx import AsyncClient +from skema.rest.workflows import app +import pytest +import json + + +@pytest.mark.ci_only +@pytest.mark.asyncio +async def test_post_eqns_to_mets_latex(): + """ + Test case for /latex/equations-to-met. + """ + latex_equations = ["E=mc^2", "c=\\frac{a}{b}"] + + endpoint = "/latex/equations-to-met" + + async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: + response = await ac.put(endpoint, json=latex_equations) + expected = """ + [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] + """ + # check for route's existence + assert ( + any(route.path == endpoint for route in app.routes) == True + ), "{endpoint} does not exist for app" + # check status code + assert ( + response.status_code == 200 + ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" + # check response + assert ( + json.loads(response.text) == expected + ), f"Response should be {expected}, but instead received {response.text}" + + +@pytest.mark.ci_only +@pytest.mark.asyncio +async def test_post_eqns_to_mets_mathml(): + """ + Test case for /latex/equations-to-met. + """ + mathml_equations = [ + """ + + E + = + m + + c + 2 + + + """, + """ + + c + = + + + a + + + b + + + + """, + ] + + endpoint = "/latex/equations-to-met" + + async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: + response = await ac.put(endpoint, json=mathml_equations) + expected = """ + [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] + """ + # check for route's existence + assert ( + any(route.path == endpoint for route in app.routes) == True + ), "{endpoint} does not exist for app" + # check status code + assert ( + response.status_code == 200 + ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" + # check response + assert ( + json.loads(response.text) == expected + ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file diff --git a/skema/rest/tests/test_latex_to_decapodes.py b/skema/rest/tests/test_latex_to_decapodes.py deleted file mode 100644 index 893842d404e..00000000000 --- a/skema/rest/tests/test_latex_to_decapodes.py +++ /dev/null @@ -1,33 +0,0 @@ -from httpx import AsyncClient -from skema.rest.workflows import app -import pytest -import json - - -@pytest.mark.ci_only -@pytest.mark.asyncio -async def test_post_latex_to_decapodes(): - """ - Test case for /latex/equations-to-decapodes endpoint. - """ - equations = [ - "\\frac{d H}{dt}=\\nabla \\cdot {(\\Gamma*H^{n+2}*\\left|\\nabla{H}\\right|^{n-1}*\\nabla{H})}" - ] - - endpoint = "/latex/equations_to_decapodes" - - async with AsyncClient(app=app, base_url="http://latex-to-decapodes-test") as ac: - response = await ac.put(endpoint, json=equations) - expected = '{"Var":[{"type":"infer","name":"•1"},{"type":"infer","name":"mult_1"},{"type":"infer","name":"mult_2"},{"type":"infer","name":"mult_3"},{"type":"infer","name":"Γ"},{"type":"infer","name":"•2"},{"type":"infer","name":"H"},{"type":"infer","name":"sum_1"},{"type":"infer","name":"n"},{"type":"Literal","name":"2"},{"type":"infer","name":"•3"},{"type":"infer","name":"•4"},{"type":"infer","name":"•5"},{"type":"infer","name":"•6"},{"type":"Literal","name":"1"},{"type":"infer","name":"•7"},{"type":"infer","name":"•8"}],"Op1":[{"src":7,"tgt":13,"op1":"Grad"},{"src":13,"tgt":12,"op1":"Abs"},{"src":7,"tgt":16,"op1":"Grad"},{"src":2,"tgt":1,"op1":"Div"},{"src":7,"tgt":17,"op1":"D(1,t)"}],"Op2":[{"proj1":7,"proj2":8,"res":6,"op2":"^"},{"proj1":5,"proj2":6,"res":4,"op2":"*"},{"proj1":9,"proj2":15,"res":14,"op2":"-"},{"proj1":12,"proj2":14,"res":11,"op2":"^"},{"proj1":4,"proj2":11,"res":3,"op2":"*"},{"proj1":3,"proj2":16,"res":2,"op2":"*"}],"Σ":[{"sum":8}],"Summand":[{"summand":9,"summation":1},{"summand":10,"summation":1}]}' - # check for route's existence - assert ( - any(route.path == endpoint for route in app.routes) == True - ), "{endpoint} does not exist for app" - # check status code - assert ( - response.status_code == 200 - ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" - # check response - assert ( - json.loads(response.text) == expected - ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file diff --git a/skema/rest/workflows.py b/skema/rest/workflows.py index 78bab96bc26..cc019b2e808 100644 --- a/skema/rest/workflows.py +++ b/skema/rest/workflows.py @@ -204,37 +204,42 @@ async def equations_to_amr(data: schema.MmlToAMR, client: httpx.AsyncClient = De return res.json() -# tex equations -> pmml -> Decapodes -@router.post("/latex/equations-to-decapodes", summary="Equations (LaTeX) → pMML → Decapodes") -async def equations_to_decapodes(data: schema.EquationLatexToDecapodes, client: httpx.AsyncClient = Depends(utils.get_client)): +# equations(pmml or latex) -> MathExpressionTree +@router.post("/latex/equations-to-met", summary="Equations (LaTeX/pMML) → MathExpressionTree") +async def equations_to_met(data: schema.EquationToMET, client: httpx.AsyncClient = Depends(utils.get_client)): """ - Converts equations (in LaTeX) to Decapodes. + Converts equations (in LaTeX or pMathML) to MathExpressionTree (JSON). ### Python example ``` import requests equations = [ - "\\frac{\\delta x}{\\delta t} = {\\alpha x} - {\\beta x y}", - "\\frac{\\delta y}{\\delta t} = {\\alpha x y} - {\\gamma y}" + "E=mc^2", + "c=\\frac{a}{b}" ] url = "http://127.0.0.1:8000" - r = requests.post(f"{url}/latex/equations-to-decapodes", json={"equations": equations}) + r = requests.post(f"{url}/latex/equations-to-met", json={"equations": equations}) print(r.json()) """ - mml: List[str] = [ - utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations - ] + if "" in data.equations[0]: + eqns: List[str] = [ + utils.clean_mml(mml) for mml in data.equations + ] + else: + eqns: List[str] = [ + utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations + ] - res = await client.put(f"{SKEMA_RS_ADDESS}/mathml/decapodes", json=mml) + res = await client.put(f"{SKEMA_RS_ADDESS}/mathml/met", json=eqns) if res.status_code != 200: return JSONResponse( status_code=400, content={ - "error": f"MORAE PUT /mathml/amr failed to process payload with error {res.text}", - "payload": mml, + "error": f"PUT /mathml/met failed to process payload with error {res.text}", + "payload": eqns, }, ) return res.json() diff --git a/skema/skema-rs/skema/src/bin/skema_service.rs b/skema/skema-rs/skema/src/bin/skema_service.rs index 6a218d0575f..c4eb184f16e 100644 --- a/skema/skema-rs/skema/src/bin/skema_service.rs +++ b/skema/skema-rs/skema/src/bin/skema_service.rs @@ -49,6 +49,7 @@ async fn main() -> std::io::Result<()> { skema::services::mathml::get_regnet, skema::services::mathml::get_amr, skema::services::mathml::get_decapodes, + skema::services::mathml::get_met, gromet::get_model_ids, gromet::post_model, gromet::delete_model, @@ -139,6 +140,7 @@ async fn main() -> std::io::Result<()> { .service(skema::services::mathml::get_regnet) .service(skema::services::mathml::get_amr) .service(skema::services::mathml::get_decapodes) + .service(skema::services::mathml::get_met) .service(gromet::get_model_RN) .service(gromet::model2PN) .service(gromet::model2RN) diff --git a/skema/skema-rs/skema/src/services/mathml.rs b/skema/skema-rs/skema/src/services/mathml.rs index c3bf7ff693c..0aba8f3d233 100644 --- a/skema/skema-rs/skema/src/services/mathml.rs +++ b/skema/skema-rs/skema/src/services/mathml.rs @@ -124,6 +124,26 @@ pub async fn get_decapodes(payload: web::Json>) -> HttpResponse { HttpResponse::Ok().json(web::Json(decapodes_collection)) } +/// Return a JSON representation of a METCollection from +/// an array of MathML strings. +#[utoipa::path( +request_body = Vec, +responses( +( +status = 200, +body = Vec +) +) +)] +#[put("/mathml/met")] +pub async fn get_met(payload: web::Json>) -> HttpResponse { + let met_vec: Vec = payload + .iter() + .map(|x| x.parse::().unwrap()) + .collect(); + HttpResponse::Ok().json(web::Json(met_vec)) +} + /// Return a JSON representation of a PetriNet ModelRep constructed from an array of MathML strings. #[utoipa::path( request_body = Vec, From 4ad6f2fb2ed778d05247ca777e0b806c6af21577 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 10:56:07 -0700 Subject: [PATCH 06/12] fix the method error in request --- skema/rest/tests/test_eqns_to_mets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index 8de352576ff..34652d0ec0f 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -15,7 +15,7 @@ async def test_post_eqns_to_mets_latex(): endpoint = "/latex/equations-to-met" async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: - response = await ac.put(endpoint, json=latex_equations) + response = await ac.put(endpoint, json={"equations": latex_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] """ @@ -70,7 +70,7 @@ async def test_post_eqns_to_mets_mathml(): endpoint = "/latex/equations-to-met" async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: - response = await ac.put(endpoint, json=mathml_equations) + response = await ac.put(endpoint, json={"equations": mathml_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] """ From d2baa7942b215d9b897979729d3591200530ac82 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 12:36:20 -0700 Subject: [PATCH 07/12] update test_post_eqns_to_mets --- skema/rest/tests/test_eqns_to_mets.py | 12 ++++++------ skema/rest/workflows.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index 34652d0ec0f..d8e3df6195c 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -8,13 +8,13 @@ @pytest.mark.asyncio async def test_post_eqns_to_mets_latex(): """ - Test case for /latex/equations-to-met. + Test case for /equations-to-met. """ latex_equations = ["E=mc^2", "c=\\frac{a}{b}"] - endpoint = "/latex/equations-to-met" + endpoint = "/equations-to-met" - async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: + async with AsyncClient(app=app, base_url="http://latex-to-mets-test") as ac: response = await ac.put(endpoint, json={"equations": latex_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] @@ -37,7 +37,7 @@ async def test_post_eqns_to_mets_latex(): @pytest.mark.asyncio async def test_post_eqns_to_mets_mathml(): """ - Test case for /latex/equations-to-met. + Test case for /equations-to-met. """ mathml_equations = [ """ @@ -67,9 +67,9 @@ async def test_post_eqns_to_mets_mathml(): """, ] - endpoint = "/latex/equations-to-met" + endpoint = "/equations-to-met" - async with AsyncClient(app=app, base_url="http://eqns-to-mets-test") as ac: + async with AsyncClient(app=app, base_url="http://mathml-to-mets-test") as ac: response = await ac.put(endpoint, json={"equations": mathml_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] diff --git a/skema/rest/workflows.py b/skema/rest/workflows.py index 2f7b21bc925..647106e405d 100644 --- a/skema/rest/workflows.py +++ b/skema/rest/workflows.py @@ -207,7 +207,7 @@ async def equations_to_amr(data: schema.MmlToAMR, client: httpx.AsyncClient = De # equations(pmml or latex) -> MathExpressionTree -@router.post("/latex/equations-to-met", summary="Equations (LaTeX/pMML) → MathExpressionTree") +@router.post("/equations-to-met", summary="Equations (LaTeX/pMML) → MathExpressionTree") async def equations_to_met(data: schema.EquationToMET, client: httpx.AsyncClient = Depends(utils.get_client)): """ Converts equations (in LaTeX or pMathML) to MathExpressionTree (JSON). @@ -223,7 +223,7 @@ async def equations_to_met(data: schema.EquationToMET, client: httpx.AsyncClient url = "http://127.0.0.1:8000" - r = requests.post(f"{url}/latex/equations-to-met", json={"equations": equations}) + r = requests.post(f"{url}/equations-to-met", json={"equations": equations}) print(r.json()) """ if "" in data.equations[0]: From 02fb1af972678251fcc93454c047185e660e1094 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 13:03:32 -0700 Subject: [PATCH 08/12] update test_post_eqns_to_mets --- skema/rest/tests/test_eqns_to_mets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index d8e3df6195c..24eda9d5263 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -15,7 +15,7 @@ async def test_post_eqns_to_mets_latex(): endpoint = "/equations-to-met" async with AsyncClient(app=app, base_url="http://latex-to-mets-test") as ac: - response = await ac.put(endpoint, json={"equations": latex_equations}) + response = await ac.post(endpoint, json={"equations": latex_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] """ @@ -70,7 +70,7 @@ async def test_post_eqns_to_mets_mathml(): endpoint = "/equations-to-met" async with AsyncClient(app=app, base_url="http://mathml-to-mets-test") as ac: - response = await ac.put(endpoint, json={"equations": mathml_equations}) + response = await ac.post(endpoint, json={"equations": mathml_equations}) expected = """ [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] """ From e60a40b3d2d0e44bfe31948fe9ce61918b15f232 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 16:51:22 -0700 Subject: [PATCH 09/12] update test_post_eqns_to_mets --- skema/rest/tests/test_eqns_to_mets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index 24eda9d5263..72d6ad28d07 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -17,7 +17,7 @@ async def test_post_eqns_to_mets_latex(): async with AsyncClient(app=app, base_url="http://latex-to-mets-test") as ac: response = await ac.post(endpoint, json={"equations": latex_equations}) expected = """ - [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] + [{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"E"},"func_of":null}}},{"Cons":["Multiply",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"m"},"func_of":null}}},{"Cons":["Power",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Atom":{"Mn":"2"}}]]}]]}]]},{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Cons":["Divide",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"a"},"func_of":null}}},{"Atom":{"Ci":{"type":null,"content":{"Mi":"b"},"func_of":null}}}]]}]]}] """ # check for route's existence assert ( @@ -72,7 +72,7 @@ async def test_post_eqns_to_mets_mathml(): async with AsyncClient(app=app, base_url="http://mathml-to-mets-test") as ac: response = await ac.post(endpoint, json={"equations": mathml_equations}) expected = """ - [{'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'E'}, 'func_of': None}}}, {'Cons': ['Multiply', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'm'}, 'func_of': None}}}, {'Cons': ['Power', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Atom': {'Mn': '2'}}]]}]]}]]}, {'Cons': ['Equals', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'c'}, 'func_of': None}}}, {'Cons': ['Divide', [{'Atom': {'Ci': {'type': None, 'content': {'Mi': 'a'}, 'func_of': None}}}, {'Atom': {'Ci': {'type': None, 'content': {'Mi': 'b'}, 'func_of': None}}}]]}]]}] + [{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"E"},"func_of":null}}},{"Cons":["Multiply",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"m"},"func_of":null}}},{"Cons":["Power",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Atom":{"Mn":"2"}}]]}]]}]]},{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Cons":["Divide",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"a"},"func_of":null}}},{"Atom":{"Ci":{"type":null,"content":{"Mi":"b"},"func_of":null}}}]]}]]}] """ # check for route's existence assert ( From 9fcf0f8a84d9384958314e75124ce7f6984b5bf8 Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 17:15:45 -0700 Subject: [PATCH 10/12] update test_post_eqns_to_mets --- skema/rest/tests/test_eqns_to_mets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index 72d6ad28d07..fbdec5badc1 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -29,7 +29,7 @@ async def test_post_eqns_to_mets_latex(): ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" # check response assert ( - json.loads(response.text) == expected + response.text == expected ), f"Response should be {expected}, but instead received {response.text}" @@ -84,5 +84,5 @@ async def test_post_eqns_to_mets_mathml(): ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" # check response assert ( - json.loads(response.text) == expected + response.text == expected ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file From ead448b9aeee8e619d93e2e630caadf2fdbc2b7a Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 14 Feb 2024 19:02:19 -0700 Subject: [PATCH 11/12] update test_post_eqns_to_mets --- skema/rest/tests/test_eqns_to_mets.py | 196 ++++++++++++++++++++++++-- 1 file changed, 188 insertions(+), 8 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index fbdec5badc1..66e47e4f8fc 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -16,9 +16,99 @@ async def test_post_eqns_to_mets_latex(): async with AsyncClient(app=app, base_url="http://latex-to-mets-test") as ac: response = await ac.post(endpoint, json={"equations": latex_equations}) - expected = """ - [{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"E"},"func_of":null}}},{"Cons":["Multiply",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"m"},"func_of":null}}},{"Cons":["Power",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Atom":{"Mn":"2"}}]]}]]}]]},{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Cons":["Divide",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"a"},"func_of":null}}},{"Atom":{"Ci":{"type":null,"content":{"Mi":"b"},"func_of":null}}}]]}]]}] - """ + expected = [ + { + "Cons": [ + "Equals", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "E"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Multiply", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "m"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Power", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "c"}, + "func_of": None, + } + } + }, + {"Atom": {"Mn": "2"}}, + ], + ] + }, + ], + ] + }, + ], + ] + }, + { + "Cons": [ + "Equals", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "c"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Divide", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "a"}, + "func_of": None, + } + } + }, + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "b"}, + "func_of": None, + } + } + }, + ], + ] + }, + ], + ] + }, + ] + # check for route's existence assert ( any(route.path == endpoint for route in app.routes) == True @@ -29,7 +119,7 @@ async def test_post_eqns_to_mets_latex(): ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" # check response assert ( - response.text == expected + json.loads(response.text) == expected ), f"Response should be {expected}, but instead received {response.text}" @@ -71,9 +161,99 @@ async def test_post_eqns_to_mets_mathml(): async with AsyncClient(app=app, base_url="http://mathml-to-mets-test") as ac: response = await ac.post(endpoint, json={"equations": mathml_equations}) - expected = """ - [{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"E"},"func_of":null}}},{"Cons":["Multiply",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"m"},"func_of":null}}},{"Cons":["Power",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Atom":{"Mn":"2"}}]]}]]}]]},{"Cons":["Equals",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"c"},"func_of":null}}},{"Cons":["Divide",[{"Atom":{"Ci":{"type":null,"content":{"Mi":"a"},"func_of":null}}},{"Atom":{"Ci":{"type":null,"content":{"Mi":"b"},"func_of":null}}}]]}]]}] - """ + expected = [ + { + "Cons": [ + "Equals", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "E"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Multiply", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "m"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Power", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "c"}, + "func_of": None, + } + } + }, + {"Atom": {"Mn": "2"}}, + ], + ] + }, + ], + ] + }, + ], + ] + }, + { + "Cons": [ + "Equals", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "c"}, + "func_of": None, + } + } + }, + { + "Cons": [ + "Divide", + [ + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "a"}, + "func_of": None, + } + } + }, + { + "Atom": { + "Ci": { + "type": None, + "content": {"Mi": "b"}, + "func_of": None, + } + } + }, + ], + ] + }, + ], + ] + }, + ] + # check for route's existence assert ( any(route.path == endpoint for route in app.routes) == True @@ -84,5 +264,5 @@ async def test_post_eqns_to_mets_mathml(): ), f"Request was unsuccessful (status code was {response.status_code} instead of 200)" # check response assert ( - response.text == expected + json.loads(response.text) == expected ), f"Response should be {expected}, but instead received {response.text}" \ No newline at end of file From 2fc70eecf63031a1f9772184ef0b7ed91b0b98bb Mon Sep 17 00:00:00 2001 From: ualiangzhang Date: Wed, 21 Feb 2024 16:20:49 -0700 Subject: [PATCH 12/12] support the mixed latex and mml input for eqns2met --- skema/rest/tests/test_eqns_to_mets.py | 31 +++++++++++++++------------ skema/rest/workflows.py | 28 +++++++++++------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/skema/rest/tests/test_eqns_to_mets.py b/skema/rest/tests/test_eqns_to_mets.py index 66e47e4f8fc..97cb640edea 100644 --- a/skema/rest/tests/test_eqns_to_mets.py +++ b/skema/rest/tests/test_eqns_to_mets.py @@ -6,11 +6,24 @@ @pytest.mark.ci_only @pytest.mark.asyncio -async def test_post_eqns_to_mets_latex(): +async def test_post_eqns_to_mets_mathml_latex(): """ Test case for /equations-to-met. """ - latex_equations = ["E=mc^2", "c=\\frac{a}{b}"] + latex_equations = [ + """ + + E + = + m + + c + 2 + + + """, + "c=\\frac{a}{b}", + ] endpoint = "/equations-to-met" @@ -125,22 +138,12 @@ async def test_post_eqns_to_mets_latex(): @pytest.mark.ci_only @pytest.mark.asyncio -async def test_post_eqns_to_mets_mathml(): +async def test_post_eqns_to_mets_latex_mathml(): """ Test case for /equations-to-met. """ mathml_equations = [ - """ - - E - = - m - - c - 2 - - - """, + "E=mc^2", """ c diff --git a/skema/rest/workflows.py b/skema/rest/workflows.py index eaba8f47b33..e874a7067da 100644 --- a/skema/rest/workflows.py +++ b/skema/rest/workflows.py @@ -254,14 +254,12 @@ async def equations_to_met(data: schema.EquationToMET, client: httpx.AsyncClient print(r.json()) ``` """ - if "" in data.equations[0]: - eqns: List[str] = [ - utils.clean_mml(mml) for mml in data.equations - ] - else: - eqns: List[str] = [ - utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations - ] + eqns: List[str] = [] + for eqn in data.equations: + if "" in eqn: + eqns.append(utils.clean_mml(eqn)) + else: + eqns.append(utils.clean_mml(eqn2mml.get_mathml_from_latex(eqn))) res = await client.put(f"{SKEMA_RS_ADDESS}/mathml/met", json=eqns) if res.status_code != 200: @@ -296,14 +294,12 @@ async def equations_to_gamr(data: schema.EquationToMET, client: httpx.AsyncClien print(r.json()) ``` """ - if "" in data.equations[0]: - eqns: List[str] = [ - utils.clean_mml(mml) for mml in data.equations - ] - else: - eqns: List[str] = [ - utils.clean_mml(eqn2mml.get_mathml_from_latex(tex)) for tex in data.equations - ] + eqns: List[str] = [] + for eqn in data.equations: + if "" in eqn: + eqns.append(utils.clean_mml(eqn)) + else: + eqns.append(utils.clean_mml(eqn2mml.get_mathml_from_latex(eqn))) res = await client.put(f"{SKEMA_RS_ADDESS}/mathml/g-amr", json=eqns) if res.status_code != 200: