Yield with uploads (#1339)
This commit is contained in:
parent
3f151f054d
commit
ca11b82432
@ -323,21 +323,26 @@ export const uploadFiles = async (state, setResult, handler) => {
|
||||
}
|
||||
|
||||
// Send the file to the server.
|
||||
await axios.post(UPLOADURL, formdata, headers).then((response) => {
|
||||
// Apply the delta and set the result.
|
||||
const update = response.data;
|
||||
applyDelta(state, update.delta);
|
||||
|
||||
// Set processing to false and return.
|
||||
setResult({
|
||||
state: state,
|
||||
events: update.events,
|
||||
final: true,
|
||||
processing: false,
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
await axios.post(UPLOADURL, formdata, headers)
|
||||
.then(() => { return true; })
|
||||
.catch(
|
||||
error => {
|
||||
if (error.response) {
|
||||
// The request was made and the server responded with a status code
|
||||
// that falls out of the range of 2xx
|
||||
console.log(error.response.data);
|
||||
} else if (error.request) {
|
||||
// The request was made but no response was received
|
||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
||||
// http.ClientRequest in node.js
|
||||
console.log(error.request);
|
||||
} else {
|
||||
// Something happened in setting up the request that triggered an Error
|
||||
console.log(error.message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,9 @@ class App(Base):
|
||||
# The component to render if there is a connection error to the server.
|
||||
connect_error_component: Optional[Component] = None
|
||||
|
||||
# The async server name space
|
||||
event_namespace: Optional[AsyncNamespace] = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the app.
|
||||
|
||||
@ -127,11 +130,10 @@ class App(Base):
|
||||
self.socket_app = ASGIApp(self.sio, socketio_path="")
|
||||
|
||||
# Create the event namespace and attach the main app. Not related to any paths.
|
||||
event_namespace = EventNamespace("/event", self)
|
||||
self.event_namespace = EventNamespace("/event", self)
|
||||
|
||||
# Register the event namespace with the socket.
|
||||
self.sio.register_namespace(event_namespace)
|
||||
|
||||
self.sio.register_namespace(self.event_namespace)
|
||||
# Mount the socket app with the API.
|
||||
self.api.mount(str(constants.Endpoint.EVENT), self.socket_app)
|
||||
|
||||
@ -592,9 +594,6 @@ def upload(app: App):
|
||||
Args:
|
||||
files: The file(s) to upload.
|
||||
|
||||
Returns:
|
||||
The state update after processing the event.
|
||||
|
||||
Raises:
|
||||
ValueError: if there are no args with supported annotation.
|
||||
"""
|
||||
@ -603,10 +602,10 @@ def upload(app: App):
|
||||
for file in files:
|
||||
assert file.filename is not None
|
||||
file.filename = file.filename.split(":")[-1]
|
||||
|
||||
# Get the state for the session.
|
||||
state = app.state_manager.get_state(token)
|
||||
|
||||
# get the current session ID
|
||||
sid = state.get_sid()
|
||||
# get the current state(parent state/substate)
|
||||
path = handler.split(".")[:-1]
|
||||
current_state = state.get_substate(path)
|
||||
@ -636,12 +635,17 @@ def upload(app: App):
|
||||
name=handler,
|
||||
payload={handler_upload_param[0]: files},
|
||||
)
|
||||
# TODO: refactor this to handle yields.
|
||||
update = await state._process(event).__anext__()
|
||||
|
||||
async for update in state._process(event):
|
||||
# Postprocess the event.
|
||||
update = await app.postprocess(state, event, update)
|
||||
# Send update to client
|
||||
await asyncio.create_task(
|
||||
app.event_namespace.emit( # type: ignore
|
||||
str(constants.SocketEvent.EVENT), update.json(), to=sid
|
||||
)
|
||||
)
|
||||
# Set the state for the session.
|
||||
app.state_manager.set_state(event.token, state)
|
||||
return update
|
||||
|
||||
return upload_file
|
||||
|
||||
|
@ -602,7 +602,7 @@ async def test_dict_mutation_detection__plain_list(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"fixture, expected",
|
||||
"fixture, delta",
|
||||
[
|
||||
(
|
||||
"upload_state",
|
||||
@ -626,22 +626,23 @@ async def test_dict_mutation_detection__plain_list(
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_upload_file(fixture, request, expected):
|
||||
async def test_upload_file(fixture, request, delta):
|
||||
"""Test that file upload works correctly.
|
||||
|
||||
Args:
|
||||
fixture: The state.
|
||||
request: Fixture request.
|
||||
expected: Expected delta
|
||||
delta: Expected delta
|
||||
"""
|
||||
app = App(state=request.getfixturevalue(fixture))
|
||||
app.event_namespace.emit = AsyncMock() # type: ignore
|
||||
current_state = app.state_manager.get_state("token")
|
||||
data = b"This is binary data"
|
||||
|
||||
# Create a binary IO object and write data to it
|
||||
bio = io.BytesIO()
|
||||
bio.write(data)
|
||||
|
||||
app = App(state=request.getfixturevalue(fixture))
|
||||
|
||||
file1 = UploadFile(
|
||||
filename="token:file_upload_state.multi_handle_upload:True:image1.jpg",
|
||||
file=bio,
|
||||
@ -650,10 +651,17 @@ async def test_upload_file(fixture, request, expected):
|
||||
filename="token:file_upload_state.multi_handle_upload:True:image2.jpg",
|
||||
file=bio,
|
||||
)
|
||||
fn = upload(app)
|
||||
result = await fn([file1, file2]) # type: ignore
|
||||
assert isinstance(result, StateUpdate)
|
||||
assert result.delta == expected
|
||||
upload_fn = upload(app)
|
||||
await upload_fn([file1, file2])
|
||||
state_update = StateUpdate(delta=delta, events=[], final=True)
|
||||
|
||||
app.event_namespace.emit.assert_called_with( # type: ignore
|
||||
"event", state_update.json(), to=current_state.get_sid()
|
||||
)
|
||||
assert app.state_manager.get_state("token").dict()["img_list"] == [
|
||||
"image1.jpg",
|
||||
"image2.jpg",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
Loading…
Reference in New Issue
Block a user