0

I have developed a simple backend in Python, using Quart, Quart-CORS and SQLAlchemy. When I try the different endpoints on localhost with Postman, the CORS headers are correctly returned. As soon as I deploy it on Google Cloud Run, it seems like Google removes all the CORS headers on every response that the backend returns, so my frontend rejects the responses.

Has anyone come across this issue before? Any ideas on how to fix it? Please let me know if any additional information from my side is needed.

Thank you,

rafamartinc
  • 125
  • 1
  • 1
  • 10
  • 1
    Could you please upload a sample of what are you trying? In the meantime, could you try adding this to your main function: `headers = { 'Access-Control-Allow-Origin': "*"}` – Pamela Chup Mar 19 '21 at 21:49
  • Here is a [question](https://stackoverflow.com/questions/61347316/how-to-allow-cors-in-google-cloud-run) very similar to yours, but please provide a py to try and replicate – Pamela Chup Mar 19 '21 at 22:14
  • 1
    Thank you @MarioGranados, it's finally working. I have attached a solution down below. Seems to be working so far. – rafamartinc Mar 21 '21 at 22:16

1 Answers1

2

I kept working on it and it seems to be working so far. The following code combines two different solutions:

  • Adding the CORS headers manually to the make_response method provided by Quart.
  • Using methods from the add-on library Quart-CORS.

It would probably be enough with any of these solutions by itself, but somehow it's only with both that I managed to fix the issue.

Python code:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Script used to launch the API.
"""

from __future__ import print_function
from quart import Quart, Blueprint, request, make_response, jsonify
from quart_cors import cors, route_cors
from http import HTTPStatus
import secrets

blueprint_v0_login_options = Blueprint('v0_login_options', __name__)
blueprint_v0_login_post = Blueprint('v0_login_post', __name__)


CORS_SETTINGS = {'allow_origin': '*'}


@blueprint_v0_login_options.route('/v0/login', methods=['OPTIONS'], provide_automatic_options=False)
@route_cors(**CORS_SETTINGS, provide_automatic_options=False)
async def v0_login_options():
    return await make_response(
        jsonify(None),
        HTTPStatus.ACCEPTED,
        {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
            'Access-Control-Allow-Methods': 'OPTIONS, POST'
        }
    )


@blueprint_v0_login_post.route('/v0/login', methods=['POST'], provide_automatic_options=False)
@route_cors(**CORS_SETTINGS, provide_automatic_options=False)
async def v0_login_post():

    json = await request.get_json()

    return await make_response(
        jsonify(json),
        HTTPStatus.ACCEPTED,
        {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
        }
    )


def main():

    # Start API server.
    quart_app = Quart(__name__)
    quart_app = cors(quart_app, **CORS_SETTINGS)
    quart_app.secret_key = secrets.token_urlsafe(16)

    # Register blueprints.
    quart_app.register_blueprint(blueprint_v0_login_options)
    quart_app.register_blueprint(blueprint_v0_login_post)

    quart_app.run(host='0.0.0.0', port=8081)


if __name__ == "__main__":
    main()

Dockerfile:

FROM python:3.8

COPY . /api
WORKDIR /api

# Prepare Python.
RUN apt-get update
RUN pip install --upgrade pip
ENV PYTHONUNBUFFERED=1

# Install module.
RUN python setup.py install

# Run.
CMD PYTHONPATH=. api

Thank you!!

rafamartinc
  • 125
  • 1
  • 1
  • 10