travisvn / openai-edge-tts

Text-to-speech API endpoint compatible with OpenAI's TTS API endpoint, using Microsoft Edge TTS to generate speech for free locally
https://tts.travisvn.com
GNU General Public License v3.0
128 stars 22 forks source link

403 error when deployed on cloud #10

Closed XU-Nuo closed 1 hour ago

XU-Nuo commented 2 hours ago

Hello, I really like this project and I use it to read my web clipping articles in obsidian with a few tweaks to fix the CORS issue (I use traefik as a reverse proxy to add the CORS headers). It works perfectly on my local machine using localhost, and I am now trying to extend my usage to mobile apps by deploying it on cloud, where I encountered 403 errors:

edge-tts-openai-edge-tts-1  | [2024-11-18 07:31:41,910] ERROR in app: Exception on /v1/audio/speech [POST]
edge-tts-openai-edge-tts-1  | Traceback (most recent call last):
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 1473, in wsgi_app
edge-tts-openai-edge-tts-1  |     response = self.full_dispatch_request()
edge-tts-openai-edge-tts-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 882, in full_dispatch_request
edge-tts-openai-edge-tts-1  |     rv = self.handle_user_exception(e)
edge-tts-openai-edge-tts-1  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 880, in full_dispatch_request
edge-tts-openai-edge-tts-1  |     rv = self.dispatch_request()
edge-tts-openai-edge-tts-1  |          ^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/flask/app.py", line 865, in dispatch_request
edge-tts-openai-edge-tts-1  |     return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/app/utils.py", line 27, in decorated_function
edge-tts-openai-edge-tts-1  |     return f(*args, **kwargs)
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/app/server.py", line 40, in text_to_speech
edge-tts-openai-edge-tts-1  |     output_file_path = generate_speech(text, voice, response_format, speed)
edge-tts-openai-edge-tts-1  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/app/tts_handler.py", line 55, in generate_speech
edge-tts-openai-edge-tts-1  |     return asyncio.run(_generate_audio(text, voice, response_format, speed))
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/asyncio/runners.py", line 194, in run
edge-tts-openai-edge-tts-1  |     return runner.run(main)
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
edge-tts-openai-edge-tts-1  |     return self._loop.run_until_complete(task)
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
edge-tts-openai-edge-tts-1  |     return future.result()
edge-tts-openai-edge-tts-1  |            ^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/app/tts_handler.py", line 29, in _generate_audio
edge-tts-openai-edge-tts-1  |     await communicator.save(temp_output_file.name)
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/edge_tts/communicate.py", line 523, in save
edge-tts-openai-edge-tts-1  |     async for message in self.stream():
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/edge_tts/communicate.py", line 506, in stream
edge-tts-openai-edge-tts-1  |     async for message in self.__stream():
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/edge_tts/communicate.py", line 368, in __stream
edge-tts-openai-edge-tts-1  |     ) as session, session.ws_connect(
edge-tts-openai-edge-tts-1  |                   ^^^^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 1359, in __aenter__
edge-tts-openai-edge-tts-1  |     self._resp: _RetType = await self._coro
edge-tts-openai-edge-tts-1  |                            ^^^^^^^^^^^^^^^^
edge-tts-openai-edge-tts-1  |   File "/usr/local/lib/python3.12/site-packages/aiohttp/client.py", line 953, in _ws_connect
edge-tts-openai-edge-tts-1  |     raise WSServerHandshakeError(
edge-tts-openai-edge-tts-1  | aiohttp.client_exceptions.WSServerHandshakeError: 403, message='Invalid response status', url='wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=6A5AA1D4EAFF4E9FB37E23D68491D6F4&ConnectionId=d3ba7b34c9104a308bca3dd9b106e471'
edge-tts-openai-edge-tts-1  | 192.168.32.3 - - [2024-11-18 07:31:41] "POST /v1/audio/speech HTTP/1.1" 500 401 1.031227

and here is my docker-compose.yaml:

services:
  openai-edge-tts:
    image: travisvn/openai-edge-tts:latest
    environment:
      API_KEY: tts
      PORT: 5050
    labels:
        - traefik.enable=true
        - traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST
        - traefik.http.middlewares.cors.headers.accessControlAllowOriginList=*
        - traefik.http.middlewares.cors.headers.accesscontrolmaxage=100
        - traefik.http.middlewares.cors.headers.accessControlAllowHeaders=authorization,content-type
        - traefik.http.middlewares.cors.headers.addvaryheader=true
        - traefik.http.middlewares.stripprefix.stripprefix.prefixes=/tts
        - traefik.http.routers.openai-edge-tts.middlewares=cors,stripprefix
        - traefik.http.routers.openai-edge-tts.rule=PathPrefix(`/tts`)
        - traefik.http.services.openai-edge-tts.loadbalancer.server.port=5050
  traefik:
    image: traefik:latest
    restart: unless-stopped
    container_name: traefik
    command:
      - --api.insecure=true # remove in production
      - --providers.docker
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --global.sendAnonymousUsage=false
    ports:
      - 27896:80
      - 8443:443
      - 8080:8080 # web UI (enabled with api.insecure)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/certificates:/certificates

Does this mean my server IP is probably on the blacklist of this service, or caused by some other reasons? Thank you for sharing this fantastic project!

XU-Nuo commented 1 hour ago

It turns out to be an issued fixed in the edge-tts library 6.1.16: rany2/edge-tts#303, and build a new image using the dockerfile in this repo can fix this problem. Hope this fix can help people with the same issue, and probably @travisvn will publish an official one to the dockerhub. I will close this for now