question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Uploading files using websockets

See original GitHub issue

Hi, I am building a chat application where I wanna have a feature of sending files alongside with messages here is my code so far:

main.py:

@app.websocket("/api/user-chat")
async def chat(websocket: views.WebSocket):
    # get message sender
    sender = helper.get_current_user()
    try:
        while True:
            # get receiver and file information
            data = await websocket.receive_json()
            receiver = data['receiver']
            filename = data['filename']
            # get message file
            file = await websocket.receive_bytes()                
            file_dir = helper.gen_file_dir(sender, __file__)
            file_url = helper.create_file(file_dir, filename, file)
            data.update({
                    "file": file_url,
                    "filename": filename
             })                        
             await socket_manager.send_msg(data)
    except WebSocketDisconnect:
        socket_manager.disconnect(websocket, user)
        print("error occurred")

helper.py

# generate file url
def gen_file_dir(directory, file):
    root = pathlib.Path(file).parent.absolute()
    relative_path = "/static/media/uploads"
    absolute_path = str(root) + relative_path
    target_url = os.path.join(absolute_path, directory)    
    return target_url

# create file on disk
def create_file(dir, name, file):
    path = dir + "/" + name
    os.mkdir(dir)
    with open(path, "wb") as f:
        f.write(file)
    return path

The above code gets the file from frontend and stores the file on the server. But it seems to work for images and application files (jpg, png, pdf, docx, txt). I tried it with mp3 and gif it gives error occurred how would I allow any type of file to upload using websockets ?

Edit:

After adding try except block as suggested in the comments:

    try:
         file = await websocket.receive_bytes()                
         # reset of the code 
    except Exception as e:
         print("error was: ")
         print(e) 

I get the following error:

error was: 
1006
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/myenv/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 154, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/home/myenv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/fastapi/applications.py", line 179, in __call__
    await super().__call__(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/routing.py", line 283, in handle
    await self.app(scope, receive, send)
  File "/home/myenv/lib/python3.8/site-packages/starlette/routing.py", line 57, in app
    await func(session)
  File "/home/myenv/lib/python3.8/site-packages/fastapi/routing.py", line 228, in app
    await dependant.call(**values)
  File "./main.py", line 232, in direct_chat
    data = await websocket.receive_json()
  File "/home/myenv/lib/python3.8/site-packages/starlette/websockets.py", line 97, in receive_json
    message = await self.receive()
  File "/home/myenv/lib/python3.8/site-packages/starlette/websockets.py", line 47, in receive
    raise RuntimeError(
RuntimeError: Cannot call "receive" once a disconnect message has been received.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
wiseaidevcommented, Nov 10, 2022

Hey everyone. The other day, I was working on a similar task of sending and receiving images between a javascript client, react in my case, and FastAPI. The only way that worked for me is by encoding the image into base64 at the client(you can look at this example in case you are using react-dropzone) and then decoding the image at the server side with the base64 module. This way, you don’t have to use the receive_json function as receive_text would suffice. That’s it, I hope this might help someone in the wild. Have a nice day/evening, fellas!

1reaction
Mausecommented, Nov 30, 2020

Have you tried printing the exception to see what the error is?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Large file upload with WebSocket - Stack Overflow
Websockets have less overhead for bidirectional communication, yes, but uploading a file is simply sending a POST request to a server with the ......
Read more >
WebSocket Upload Files from Javascript - eSeGeCe
Upload files to a websocket server is very easy, just send file as binary data. ... Once binary message is received by server,...
Read more >
Web File Uploads: Ajax and Web Sockets - Accelebrate
Performing a web sockets-based file upload requires several steps. First, APIs are needed to load the file from the file system, then the...
Read more >
Is using web sockets between client-server to tranfer files the ...
Is using web sockets between client-server to transfer files the right approach? It concretely depends upon the size of the file.
Read more >
How to upload a file | Socket.IO
Files can be sent as is:
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found