Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
math_tutor_dev
public_math_tutor
Commits
925d5684
Commit
925d5684
authored
Jan 26, 2026
by
Kantz
Browse files
Mahtpix error und type handling.
parent
d9a5740d
Changes
4
Show whitespace changes
Inline
Side-by-side
math-tutor/backend/app/api/canvas.py
View file @
925d5684
...
@@ -5,6 +5,8 @@ import time
...
@@ -5,6 +5,8 @@ import time
from
pathlib
import
Path
from
pathlib
import
Path
from
typing
import
Optional
from
typing
import
Optional
import
logging
from
app
import
config
from
app
import
config
from
fastapi
import
APIRouter
,
HTTPException
from
fastapi
import
APIRouter
,
HTTPException
from
pydantic
import
BaseModel
,
Field
from
pydantic
import
BaseModel
,
Field
...
@@ -12,6 +14,8 @@ from mpxpy.mathpix_client import MathpixClient
...
@@ -12,6 +14,8 @@ from mpxpy.mathpix_client import MathpixClient
router
=
APIRouter
()
router
=
APIRouter
()
logger
=
logging
.
getLogger
(
__name__
)
settings
=
config
.
get_mathpix_settings
()
settings
=
config
.
get_mathpix_settings
()
mathpix_client
=
None
mathpix_client
=
None
...
@@ -60,7 +64,16 @@ def save_canvas(request: CanvasSaveRequest) -> CanvasSaveResponse:
...
@@ -60,7 +64,16 @@ def save_canvas(request: CanvasSaveRequest) -> CanvasSaveResponse:
handle
.
write
(
raw
)
handle
.
write
(
raw
)
try
:
try
:
image
=
mathpix_client
.
image_new
(
str
(
file_path
))
image
=
mathpix_client
.
image_new
(
file_path
=
str
(
file_path
),
include_line_data
=
True
)
lines
=
image
.
lines_json
()
logger
.
info
(
"Mathpix lines: %s"
,
lines
)
line_type
=
lines
[
0
][
"type"
]
if
lines
else
None
if
line_type
!=
"math"
:
return
CanvasSaveResponse
(
status
=
"error"
,
latex
=
f
"Please provide a math-formula, you provided a
{
line_type
}
."
,
saved_as
=
str
(
file_path
),
)
mmd
=
image
.
mmd
()
mmd
=
image
.
mmd
()
conversion
=
mathpix_client
.
conversion_new
(
conversion
=
mathpix_client
.
conversion_new
(
mmd
=
mmd
,
mmd
=
mmd
,
...
...
math-tutor/frontend/src/components/Canvas/CanvasDrawer.tsx
View file @
925d5684
...
@@ -6,6 +6,8 @@ type CanvasDrawerProps = {
...
@@ -6,6 +6,8 @@ type CanvasDrawerProps = {
onToggle
:
()
=>
void
;
onToggle
:
()
=>
void
;
onClear
?:
()
=>
void
;
onClear
?:
()
=>
void
;
onSave
?:
(
dataUrl
:
string
)
=>
void
|
Promise
<
void
>
;
onSave
?:
(
dataUrl
:
string
)
=>
void
|
Promise
<
void
>
;
statusMessage
?:
string
;
statusKind
?:
"
info
"
|
"
error
"
|
"
ok
"
;
};
};
export
default
function
CanvasDrawer
({
export
default
function
CanvasDrawer
({
...
@@ -13,6 +15,8 @@ export default function CanvasDrawer({
...
@@ -13,6 +15,8 @@ export default function CanvasDrawer({
onToggle
,
onToggle
,
onClear
,
onClear
,
onSave
,
onSave
,
statusMessage
,
statusKind
,
}:
CanvasDrawerProps
)
{
}:
CanvasDrawerProps
)
{
const
canvasRef
=
useRef
<
HTMLCanvasElement
|
null
>
(
null
);
const
canvasRef
=
useRef
<
HTMLCanvasElement
|
null
>
(
null
);
const
[
isDrawing
,
setIsDrawing
]
=
useState
(
false
);
const
[
isDrawing
,
setIsDrawing
]
=
useState
(
false
);
...
@@ -135,6 +139,13 @@ export default function CanvasDrawer({
...
@@ -135,6 +139,13 @@ export default function CanvasDrawer({
</
div
>
</
div
>
{
isVisible
?
(
{
isVisible
?
(
<
div
className
=
"canvas-body"
>
<
div
className
=
"canvas-body"
>
{
statusMessage
?
(
<
div
className
=
{
`canvas-status
${
statusKind
?
statusKind
:
"
info
"
}
`
}
>
{
statusMessage
}
</
div
>
)
:
null
}
<
div
className
=
"canvas-surface"
>
<
div
className
=
"canvas-surface"
>
<
canvas
<
canvas
ref
=
{
canvasRef
}
ref
=
{
canvasRef
}
...
...
math-tutor/frontend/src/pages/App.tsx
View file @
925d5684
...
@@ -18,6 +18,10 @@ export default function App() {
...
@@ -18,6 +18,10 @@ export default function App() {
const
[
sections
,
setSections
]
=
useState
<
RetrievedDoc
[]
>
([]);
const
[
sections
,
setSections
]
=
useState
<
RetrievedDoc
[]
>
([]);
const
[
retrievalLoading
,
setRetrievalLoading
]
=
useState
(
false
);
const
[
retrievalLoading
,
setRetrievalLoading
]
=
useState
(
false
);
const
[
retrievalError
,
setRetrievalError
]
=
useState
<
string
|
null
>
(
null
);
const
[
retrievalError
,
setRetrievalError
]
=
useState
<
string
|
null
>
(
null
);
const
[
canvasStatus
,
setCanvasStatus
]
=
useState
<
{
kind
:
"
info
"
|
"
error
"
|
"
ok
"
;
message
:
string
;
}
|
null
>
(
null
);
const
handleSend
=
async
()
=>
{
const
handleSend
=
async
()
=>
{
const
trimmed
=
draft
.
trim
();
const
trimmed
=
draft
.
trim
();
...
@@ -106,15 +110,10 @@ export default function App() {
...
@@ -106,15 +110,10 @@ export default function App() {
};
};
const
handleCanvasSave
=
async
(
dataUrl
:
string
)
=>
{
const
handleCanvasSave
=
async
(
dataUrl
:
string
)
=>
{
setMessages
((
prev
)
=>
[
setCanvasStatus
({
...
prev
,
kind
:
"
info
"
,
{
message
:
"
Saving drawing and converting to LaTeX...
"
,
id
:
`m-
${
Date
.
now
()}
-assistant`
,
});
role
:
"
assistant
"
,
text
:
"
Saving drawing and converting to LaTeX...
"
,
},
]);
setIsCanvasVisible
(
false
);
try
{
try
{
const
response
=
await
fetch
(
"
http://localhost:8000/api/canvas/save
"
,
{
const
response
=
await
fetch
(
"
http://localhost:8000/api/canvas/save
"
,
{
...
@@ -124,24 +123,39 @@ export default function App() {
...
@@ -124,24 +123,39 @@ export default function App() {
});
});
if
(
!
response
.
ok
)
{
if
(
!
response
.
ok
)
{
throw
new
Error
(
`Save failed:
${
response
.
status
}
`
);
let
message
=
`Save failed:
${
response
.
status
}
`
;
try
{
const
errorPayload
:
{
detail
?:
string
}
=
await
response
.
json
();
if
(
errorPayload
.
detail
)
{
message
=
errorPayload
.
detail
;
}
}
catch
(
error
)
{
void
error
;
}
setCanvasStatus
({
kind
:
"
error
"
,
message
});
return
;
}
}
const
payload
:
{
latex
?:
string
}
=
await
response
.
json
();
const
payload
:
{
status
?:
string
;
latex
?:
string
}
=
await
response
.
json
();
if
(
payload
.
status
&&
payload
.
status
!==
"
ok
"
)
{
setCanvasStatus
({
kind
:
"
error
"
,
message
:
payload
.
latex
||
"
Canvas save failed.
"
,
});
return
;
}
if
(
payload
.
latex
)
{
if
(
payload
.
latex
)
{
setDraft
((
prev
)
=>
setDraft
((
prev
)
=>
prev
?
`
${
prev
}
${
payload
.
latex
}
`
:
payload
.
latex
prev
?
`
${
prev
}
${
payload
.
latex
}
`
:
payload
.
latex
);
);
setCanvasStatus
({
kind
:
"
ok
"
,
message
:
"
Canvas saved.
"
});
setIsCanvasVisible
(
false
);
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
setMessages
((
prev
)
=>
[
setCanvasStatus
({
...
prev
,
kind
:
"
error
"
,
{
message
:
"
Canvas save failed. Check the API logs.
"
,
id
:
`m-
${
Date
.
now
()}
-assistant`
,
});
role
:
"
assistant
"
,
text
:
"
Canvas save failed. Check the API logs.
"
,
},
]);
void
error
;
void
error
;
}
}
};
};
...
@@ -242,6 +256,8 @@ export default function App() {
...
@@ -242,6 +256,8 @@ export default function App() {
isVisible
=
{
isCanvasVisible
}
isVisible
=
{
isCanvasVisible
}
onToggle
=
{
handleToggleCanvas
}
onToggle
=
{
handleToggleCanvas
}
onSave
=
{
handleCanvasSave
}
onSave
=
{
handleCanvasSave
}
statusMessage
=
{
canvasStatus
?.
message
}
statusKind
=
{
canvasStatus
?.
kind
}
/>
/>
)
:
null
}
)
:
null
}
</
section
>
</
section
>
...
...
math-tutor/frontend/src/styles/theme.css
View file @
925d5684
...
@@ -204,6 +204,27 @@ body {
...
@@ -204,6 +204,27 @@ body {
gap
:
12px
;
gap
:
12px
;
}
}
.canvas-status
{
padding
:
8px
10px
;
border-radius
:
10px
;
background
:
#f6f0e4
;
color
:
#6f675d
;
font-size
:
12px
;
border
:
1px
solid
#d8d1c4
;
}
.canvas-status.error
{
background
:
#f3d9d6
;
color
:
#8a3b2f
;
border-color
:
#e2b4ae
;
}
.canvas-status.ok
{
background
:
#dfe9d6
;
color
:
#2d5c2c
;
border-color
:
#b7c9ab
;
}
.canvas-surface
{
.canvas-surface
{
border
:
1px
dashed
#b9b2a4
;
border
:
1px
dashed
#b9b2a4
;
border-radius
:
12px
;
border-radius
:
12px
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment