jonra1993 / fastapi-alembic-sqlmodel-async

This is a project template which uses FastAPI, Pydantic 2.0, Alembic and async SQLModel as ORM. It shows a complete async CRUD using authentication and role base access control.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Frontend unable to upload image due to CORS blocking

jymchng opened this issue · comments

Hi @jonra1993, my frontend developer says that he is unable to upload any user image due to CORS blocking.

In my .env file, I already have the following:

...
BACKEND_CORS_ORIGINS=["http://localhost:3000", "https://mycustomdomain.com"] 
...

It is most likely due to Minio having issue: minio/minio#11111

Do you have any resolution?

Hello @jymchng does it work if you use ["*"] ?

I went to get the logs and this is what I found:

fastapi_server       | 2023-05-09 17:49:21,648 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:21,651 DEBUG    [multipart.py:583] Calling on_header_field with data[42:61]
fastapi_server       | 2023-05-09 17:49:21,651 DEBUG    [multipart.py:583] Calling on_header_value with data[63:86]
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:583] Calling on_header_field with data[134:153]
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:583] Calling on_header_value with data[155:184]
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:21,652 DEBUG    [multipart.py:583] Calling on_header_field with data[232:251]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_header_value with data[253:319]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_header_field with data[321:333]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_header_value with data[335:344]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_part_data with data[348:4466]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_part_data with data[0:1]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:583] Calling on_part_data with data[4467:30614]
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:21,653 DEBUG    [multipart.py:586] Calling on_end with no data
fastapi_server       | 2023-05-09 17:49:30,384 DEBUG    [multipart.py:586] Calling on_field_start with no data
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_name with data[0:10]
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_data with data[11:19]
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:586] Calling on_field_end with no data
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:586] Calling on_field_start with no data
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_name with data[20:28]
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_data with data[29:46]
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:586] Calling on_field_end with no data
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:586] Calling on_field_start with no data
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_name with data[47:55]
fastapi_server       | 2023-05-09 17:49:30,385 DEBUG    [multipart.py:583] Calling on_field_data with data[56:61]
fastapi_server       | 2023-05-09 17:49:30,387 DEBUG    [multipart.py:586] Calling on_field_end with no data
fastapi_server       | 2023-05-09 17:49:30,388 DEBUG    [multipart.py:586] Calling on_end with no data
fastapi_server       | 2023-05-09 17:49:30,512 DEBUG    [bcrypt.py:625] detected 'bcrypt' backend, version '4.0.1'
fastapi_server       | 2023-05-09 17:49:30,516 DEBUG    [bcrypt.py:406] 'bcrypt' backend lacks $2$ support, enabling workaround
fastapi_server       | 2023-05-09 17:49:33,817 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:33,818 DEBUG    [multipart.py:583] Calling on_header_field with data[42:61]
fastapi_server       | 2023-05-09 17:49:33,818 DEBUG    [multipart.py:583] Calling on_header_value with data[63:86]
fastapi_server       | 2023-05-09 17:49:33,824 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:583] Calling on_header_field with data[134:153]
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:583] Calling on_header_value with data[155:184]
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_part_begin with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:583] Calling on_header_field with data[232:251]
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:583] Calling on_header_value with data[253:319]
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:33,825 DEBUG    [multipart.py:583] Calling on_header_field with data[321:333]
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:583] Calling on_header_value with data[335:344]
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:586] Calling on_header_end with no data
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:586] Calling on_headers_finished with no data
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:583] Calling on_part_data with data[348:30614]
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:586] Calling on_part_end with no data
fastapi_server       | 2023-05-09 17:49:33,826 DEBUG    [multipart.py:586] Calling on_end with no data
fastapi_server       | 2023-05-09 17:49:33,912 DEBUG    [connectionpool.py:228] Starting new HTTP connection (1): storage.localhost:80
fastapi_server       | 2023-05-09 17:49:33,921 DEBUG    [connectionpool.py:456] http://storage.localhost:80 "GET /fastapi-minio?location= HTTP/1.1" 308 0
fastapi_server       | 2023-05-09 17:49:33,925 DEBUG    [retry.py:594] Incremented Retry for (url='http://storage.localhost/fastapi-minio?location='): Retry(total=2, connect=None, read=None, redirect=None, status=None)
fastapi_server       | 2023-05-09 17:49:33,925 INFO     [poolmanager.py:415] Redirecting http://storage.localhost/fastapi-minio?location= -> https://storage.localhost/fastapi-minio?location=
fastapi_server       | 2023-05-09 17:49:33,925 DEBUG    [connectionpool.py:1003] Starting new HTTPS connection (1): storage.localhost:443
fastapi_server       | 2023-05-09 17:49:33,967 DEBUG    [retry.py:594] Incremented Retry for (url='/fastapi-minio?location='): Retry(total=1, connect=None, read=None, redirect=None, status=None)
fastapi_server       | 2023-05-09 17:49:33,968 WARNING  [connectionpool.py:812] Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)'))': /fastapi-minio?location=
fastapi_server       | 2023-05-09 17:49:33,968 DEBUG    [connectionpool.py:1003] Starting new HTTPS connection (2): storage.localhost:443
fastapi_server       | 2023-05-09 17:49:33,980 DEBUG    [retry.py:594] Incremented Retry for (url='/fastapi-minio?location='): Retry(total=0, connect=None, read=None, redirect=None, status=None)
fastapi_server       | 2023-05-09 17:49:33,980 WARNING  [connectionpool.py:812] Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)'))': /fastapi-minio?location=
fastapi_server       | 2023-05-09 17:49:33,981 DEBUG    [connectionpool.py:1003] Starting new HTTPS connection (3): storage.localhost:443
fastapi_server       | [2023-05-09 17:49:33 +0000] [15] [ERROR] Exception in ASGI application
fastapi_server       | Traceback (most recent call last):
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 94, in receive
fastapi_server       |     return self.receive_nowait()
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 89, in receive_nowait
fastapi_server       |     raise WouldBlock
fastapi_server       | anyio.WouldBlock
fastapi_server       |
fastapi_server       | During handling of the above exception, another exception occurred:
fastapi_server       |
fastapi_server       | Traceback (most recent call last):
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 78, in call_next
fastapi_server       |     message = await recv_stream.receive()
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/streams/memory.py", line 114, in receive
fastapi_server       |     raise EndOfStream
fastapi_server       | anyio.EndOfStream
fastapi_server       |
fastapi_server       | During handling of the above exception, another exception occurred:
fastapi_server       |
fastapi_server       | Traceback (most recent call last):
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
fastapi_server       |     result = await app(self.scope, self.receive, self.send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
fastapi_server       |     return await self.app(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 276, in __call__
fastapi_server       |     await super().__call__(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 122, in __call__fastapi_server       |     await self.middleware_stack(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
fastapi_server       |     raise exc
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
fastapi_server       |     await self.app(scope, receive, _send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/cors.py", line 92, in __call__
fastapi_server       |     await self.simple_response(scope, receive, send, request_headers=headers)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/cors.py", line 147, in simple_response
fastapi_server       |     await self.app(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 108, in __call__
fastapi_server       |     response = await self.dispatch_func(request, call_next)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi_async_sqlalchemy/middleware.py", line 45, in dispatch
fastapi_server       |     return await call_next(request)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 84, in call_next
fastapi_server       |     raise app_exc
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 70, in coro
fastapi_server       |     await self.app(scope, receive_or_disconnect, send_no_error)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
fastapi_server       |     raise exc
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
fastapi_server       |     await self.app(scope, receive, sender)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
fastapi_server       |     raise e
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
fastapi_server       |     await self.app(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 718, in __call__
fastapi_server       |     await route.handle(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
fastapi_server       |     await self.app(scope, receive, send)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
fastapi_server       |     response = await func(request)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 227, in app
fastapi_server       |     solved_result = await solve_dependencies(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 623, in solve_dependencies
fastapi_server       |     solved = await run_in_threadpool(call, **sub_values)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
fastapi_server       |     return await anyio.to_thread.run_sync(func, *args)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/to_thread.py", line 31, in run_sync
fastapi_server       |     return await get_asynclib().run_sync_in_worker_thread(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
fastapi_server       |     return await future
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 867, in run
fastapi_server       |     result = context.run(func, *args)
fastapi_server       |   File "/code/app/api/deps.py", line 96, in minio_auth
fastapi_server       |     minio_client = MinioClient(
fastapi_server       |   File "/code/app/utils/minio_client.py", line 32, in __init__
fastapi_server       |     self.make_bucket()
fastapi_server       |   File "/code/app/utils/minio_client.py", line 35, in make_bucket
fastapi_server       |     if not self.client.bucket_exists(self.bucket_name):
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/minio/api.py", line 661, in bucket_exists
fastapi_server       |     self._execute("HEAD", bucket_name)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/minio/api.py", line 403, in _execute
fastapi_server       |     region = self._get_region(bucket_name, None)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/minio/api.py", line 470, in _get_region
fastapi_server       |     response = self._url_open(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/minio/api.py", line 269, in _url_open
fastapi_server       |     response = self._http.urlopen(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/poolmanager.py", line 418, in urlopen
fastapi_server       |     return self.urlopen(method, redirect_location, **kw)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/poolmanager.py", line 376, in urlopen
fastapi_server       |     response = conn.urlopen(method, u.request_uri, **kw)
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 815, in urlopen
fastapi_server       |     return self.urlopen(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 815, in urlopen
fastapi_server       |     return self.urlopen(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
fastapi_server       |     retries = retries.increment(
fastapi_server       |   File "/usr/local/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
fastapi_server       |     raise MaxRetryError(_pool, url, error or ResponseError(cause))
fastapi_server       | urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='storage.localhost', port=443): Max retries exceeded with url: /fastapi-minio?location= (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')))

What do you think could be wrong?

I also notice when I try to go to https://storage.mycustomdomain.com/ it redirects me to stash.localhost.

Hello @jymchng I am going to check it is there any direction to replicate the error or can you create a branch that has this issue?

@jonra1993

Could it be because

minio_server:
    image: minio/minio:latest
    restart: always
    container_name: minio_server
    volumes:
      - ./minio/data:/data
    expose:
      - 9000
      - 9091
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
      MINIO_BROWSER_REDIRECT_URL: http://stash.localhost
    command: "server /data --console-address ':9090'" 

that we should expose port 9090 instead of 9091?

Or maybe I need to change localhost to mycustomdomain.com?

#############################################
# Minio variables
#############################################
MINIO_URL=storage.localhost <==== HERE
MINIO_BUCKET=fastapi-minio
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin

Or maybe I need to change localhost to mycustomdomain.com?

#############################################
# Minio variables
#############################################
MINIO_URL=storage.localhost <==== HERE
MINIO_BUCKET=fastapi-minio
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin

I tested this, it does not work.

Hello @jymchng if you plan to use mycustomdomain.com. Have you test if a external client is able to connect with minio? Does it worked when using ["*"]