Created
March 26, 2025 12:01
-
-
Save msankhala/b20ad8621398ec86b72df822168332bb to your computer and use it in GitHub Desktop.
CORS issue Content-Disposition header issue serverless
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def export_recipes_to_csv(event): | |
""" | |
Exports recipes to a CSV file. | |
:param recipe_list: List of recipe dictionaries. | |
:param filename: Output CSV file name. | |
""" | |
body = json.loads(event.get("body", "{}")) | |
# Get the list of recipe IDs from the request body. | |
recipe_ids = body.get("recipe_ids", []) # List of recipe IDs. | |
filename = f"/tmp/exported_recipes_{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}.csv" | |
if recipe_ids: | |
try: | |
if not isinstance(recipe_ids, list): | |
raise ValueError("recipeIds must be a list.") | |
# Validate all items are strings or numbers | |
for recipe_id in recipe_ids: | |
if not isinstance(recipe_id, (str, int, float)): | |
raise ValueError( | |
f"Invalid recipeId: {recipe_id}. Must be a string or number." | |
) | |
# Convert all IDs to string format | |
recipe_ids = [str(recipe_id) for recipe_id in recipe_ids] | |
except (json.JSONDecodeError, ValueError, TypeError) as e: | |
return { | |
"error": f"Invalid 'recipeIds' format: {str(e)}" | |
}, HTTPStatus.BAD_REQUEST | |
recipe_list = ( | |
food_store.get_by_ids(recipe_ids) if recipe_ids else food_store.get_all() | |
) | |
if not recipe_list: | |
print("No recipe data available to export.") | |
return | |
csv_buffer = io.StringIO() | |
writer = csv.writer(csv_buffer) | |
for index, recipe in enumerate(recipe_list): | |
# Loop through recipe and add rows to the CSV file. | |
writer.writerow( | |
[ | |
recipe_id, | |
name, | |
source, | |
total_time, | |
servings, | |
ingredients, | |
steps, | |
additional_notes, | |
] | |
+ macro_nutrition_values | |
+ micro_nutrition_values | |
+ category_dietary_values | |
+ category_exclusion_values | |
+ category_course_values | |
+ category_meal_values | |
+ category_advanced_values | |
+ category_other_values | |
) | |
csv_content = csv_buffer.getvalue() | |
csv_buffer.close() | |
print(f"Recipes exported to: {filename}") | |
return { | |
"statusCode": HTTPStatus.OK, | |
"headers": { | |
"Content-Type": "text/csv", | |
"Content-Disposition": f"attachment; filename=\"{filename}\"", | |
"Access-Control-Allow-Origin": "*", | |
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", | |
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, X-Api-Key, X-User-Id,", | |
# Allow the browser to access the Content-Disposition header. | |
# This will fix the CORS issue when downloading the file. | |
"Access-Control-Expose-Headers": "Content-Disposition", | |
}, | |
"body": csv_content, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
custom: | |
lambda_env: &lambda_env | |
IMAGE_URL: ${self:custom.s3_url} | |
IMAGE_URL_THUMBNAILS: ${self:custom.s3_url}thumbnails/ | |
MEAL_PLAN_TIMEOUT: 5000 | |
S3_BUCKET_NAME: ${self:custom.s3_bucket_name} | |
S3_IMAGE_BUCKET_NAME: ${self:custom.s3_image_bucket_name} | |
JWT_KEY: ${env:JWT_KEY} | |
JWT_ALGO: "RS256" | |
authorizer: &jwt_authorizer | |
name: authorizerFunc | |
identitySource: method.request.header.Authorization | |
type: token | |
resultTtlInSeconds: 300 | |
cors: &cors_policy | |
origins: | |
- http://localhost:3000 | |
- https://localhost:3000 | |
- http://myproject.ddev.site | |
- https://myproject.ddev.site | |
- http://dev.myproject.org | |
- https://dev.myproject.org | |
headers: | |
- Content-Type | |
- X-Amz-Date | |
- Authorization | |
- X-Api-Key | |
- X-Amz-Security-Token | |
- X-Amz-User-Agent | |
- X-User-Id | |
- Access-Control-Allow-Origin | |
- Access-Control-Allow-Headers | |
- x-user-id | |
- Content-Disposition | |
allowCredentials: false | |
functions: | |
exportRecipe: | |
handler: endpoints/export_recipe.handler | |
environment: *lambda_env | |
package: *meal_plan_excludes | |
layers: | |
- !Ref RequirementsLambdaLayer | |
# @todo: Remove the dependency on the OrToolsPandas layer, if it is not | |
# needed. | |
- !Ref OrToolsPandasLambdaLayer | |
events: | |
- http: | |
method: POST | |
path: /export-recipe | |
cors: *cors_policy | |
private: true | |
authorizer: *jwt_authorizer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment