First Check
What is the issue you are experiencing?
I have my setup using the language Portuguese and I'm using the Gemini OpenAI API to import recipes using images and also to parse the ingredients on the recipes.
The recipe import works fine but then I try to use OpenAI with Gemini to parse the recipe ingredients I receive an error. If I use the default OpenAI API its works without any problem.
Looking at the logs I see that there is a parsing error from the Gemini response.
I checked the recipe_ingredient.py and it is expecting a confidence value in the response, but in the Gemini response I don't see one, at least in the debug logs, I don't know how I can get a full view of the http packets without modifying the code or use a http forward proxy.
If I used the debug parse tool in the webui it works fine and I'm able to correctly parse the ingredient.
I don't know if the issue is related to the OpenAI prompt or something in the code.
Steps to Reproduce
1 - Configure OpenAI Gemini API.
OPENAI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/
OPENAI_API_KEY=apikey
OPENAI_MODEL=gemini-1.5-flash
2 - Try to parse the ingredient list in a recipe using OpenAI
Please provide relevant logs
Relevant log:
DEBUG 2025-01-04T20:07:19 - Failed to parse OpenAI response as <class 'mealie.schema.openai.recipe_ingredient.OpenAIIngredients'>. Response: {"ingredients":[{"quantity":100,"unit":"ml","food":"molho de soja","note":null},{"quantity":3,"unit":"colheres de sopa","food":"mel","note":null}]}
INFO 2025-01-04T20:07:19 - [192.168.1.1:0] 500 Internal Server Error "POST /api/parser/ingredients HTTP/1.1"
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Full log:
INFO 2025-01-04T20:07:18 - [192.168.1.1:0] 200 OK "GET /api/recipes/asas-de-frango-com-molho-de-mel HTTP/1.1"
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["100ml molho de soja","3 colheres de sopa de mel"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de sopa de a\u00e7\u00facar amarelo","1 colher de sopa de \u00f3leo"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de ch\u00e1 de gengibre ralado","2 dentes de alho picado"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["500g asas de frango","1 colher de ch\u00e1 de sal"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de ch\u00e1 de sementes de s\u00e9samo","coentros frescos q.b."]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bce720>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1998985550> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bce900>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b27ed0> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bced20>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b93450> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bceb10>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b91ad0> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcf080>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996bb8d50> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdbe0>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdd30>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdfd0>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bc0080>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcde80>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:18 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=608'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1166'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1173'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1173'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1195'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - Failed to parse OpenAI response as <class 'mealie.schema.openai.recipe_ingredient.OpenAIIngredients'>. Response: {"ingredients":[{"quantity":100,"unit":"ml","food":"molho de soja","note":null},{"quantity":3,"unit":"colheres de sopa","food":"mel","note":null}]}
INFO 2025-01-04T20:07:19 - [192.168.1.1:0] 500 Internal Server Error "POST /api/parser/ingredients HTTP/1.1"
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Traceback (most recent call last):
File "/app/mealie/services/parser_services/openai/parser.py", line 90, in _parse
OpenAIIngredients.parse_openai_response(response_json)
File "/app/mealie/schema/openai/_base.py", line 24, in parse_openai_response
return cls.model_validate_json(response or "")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/pydantic/main.py", line 656, in model_validate_json
return cls.pydantic_validator.validate_json(json_data, strict=strict, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 2 validation errors for OpenAIIngredients
ingredients.0.input
Field required [type=missing, input_value={'quantity': 100, 'unit':... de soja', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
ingredients.1.input
Field required [type=missing, input_value={'quantity': 3, 'unit': '...d': 'mel', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in call
await super().call(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in call
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in call
await self.app(scope, receive, _send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/sessions.py", line 85, in call
await self.app(scope, receive, send_wrapper)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 20, in call
await responder(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 39, in call
await self.app(scope, receive, self.send_with_gzip)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
await route.handle(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
await self.app(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/routes/parser/ingredient_parser.py", line 22, in parse_ingredients
return await parser.parse(ingredients.ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 109, in parse
response = await self._parse(ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 95, in _parse
raise Exception("Failed to parse OpenAI response") from e
Exception: Failed to parse OpenAI response
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Traceback (most recent call last):
File "/app/mealie/services/parser_services/openai/parser.py", line 90, in _parse
OpenAIIngredients.parse_openai_response(response_json)
File "/app/mealie/schema/openai/_base.py", line 24, in parse_openai_response
return cls.model_validate_json(response or "")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/pydantic/main.py", line 656, in model_validate_json
return cls.pydantic_validator.validate_json(json_data, strict=strict, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 2 validation errors for OpenAIIngredients
ingredients.0.input
Field required [type=missing, input_value={'quantity': 100, 'unit':... de soja', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
ingredients.1.input
Field required [type=missing, input_value={'quantity': 3, 'unit': '...d': 'mel', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in call
await super().call(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in call
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in call
await self.app(scope, receive, _send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/sessions.py", line 85, in call
await self.app(scope, receive, send_wrapper)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 20, in call
await responder(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 39, in call
await self.app(scope, receive, self.send_with_gzip)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
await route.handle(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
await self.app(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/routes/parser/ingredient_parser.py", line 22, in parse_ingredients
return await parser.parse(ingredients.ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 109, in parse
response = await self._parse(ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 95, in _parse
raise Exception("Failed to parse OpenAI response") from e
Exception: Failed to parse OpenAI response
INFO 2025-01-04T20:07:26 - [127.0.0.1:60166] 200 OK "GET /api/app/about HTTP/1.1"
Mealie Version
v2.4.1
Deployment
Docker (Linux)
Additional Deployment Details
No response
First Check
What is the issue you are experiencing?
I have my setup using the language Portuguese and I'm using the Gemini OpenAI API to import recipes using images and also to parse the ingredients on the recipes.
The recipe import works fine but then I try to use OpenAI with Gemini to parse the recipe ingredients I receive an error. If I use the default OpenAI API its works without any problem.
Looking at the logs I see that there is a parsing error from the Gemini response.
I checked the recipe_ingredient.py and it is expecting a confidence value in the response, but in the Gemini response I don't see one, at least in the debug logs, I don't know how I can get a full view of the http packets without modifying the code or use a http forward proxy.
If I used the debug parse tool in the webui it works fine and I'm able to correctly parse the ingredient.
I don't know if the issue is related to the OpenAI prompt or something in the code.
Steps to Reproduce
1 - Configure OpenAI Gemini API.
OPENAI_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/
OPENAI_API_KEY=apikey
OPENAI_MODEL=gemini-1.5-flash
2 - Try to parse the ingredient list in a recipe using OpenAI
Please provide relevant logs
Relevant log:
DEBUG 2025-01-04T20:07:19 - Failed to parse OpenAI response as <class 'mealie.schema.openai.recipe_ingredient.OpenAIIngredients'>. Response: {"ingredients":[{"quantity":100,"unit":"ml","food":"molho de soja","note":null},{"quantity":3,"unit":"colheres de sopa","food":"mel","note":null}]}
INFO 2025-01-04T20:07:19 - [192.168.1.1:0] 500 Internal Server Error "POST /api/parser/ingredients HTTP/1.1"
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Full log:
INFO 2025-01-04T20:07:18 - [192.168.1.1:0] 200 OK "GET /api/recipes/asas-de-frango-com-molho-de-mel HTTP/1.1"
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["100ml molho de soja","3 colheres de sopa de mel"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de sopa de a\u00e7\u00facar amarelo","1 colher de sopa de \u00f3leo"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de ch\u00e1 de gengibre ralado","2 dentes de alho picado"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["500g asas de frango","1 colher de ch\u00e1 de sal"]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': 'You are a bot that parses user input into recipe ingredients. You will receive a list of one or more ingredients, each containing one or more of the following components: quantity, unit, food, and note. Their definitions are stated in the JSON schema below. While parsing the ingredients, there are some things to keep in mind:\n - If you cannot accurately determine the quantity, unit, food, or note, you should place everything into the note field and leave everything else empty. It's better to err on the side of putting everything in the note field than being wrong\n - You may receive recipe ingredients from multiple different languages. You should adhere to the grammar rules of the input language when trying to parse the ingredient string\n - Sometimes foods or units will be in their singular, plural, or other grammatical forms. You must interpret all of them appropriately\n - Sometimes ingredients will have text in parenthesis (like this). Parenthesis typically indicate something that should appear in the notes. For example: an input of "3 potatoes (roughly chopped)" would parse "roughly chopped" into the notes. Notice that when this occurs, the parenthesis are dropped, and you should use "roughly chopped" instead of "(roughly chopped)" in the note\n - It's possible for the input to contain typos. For instance, you might see the word "potatos" instead of "potatoes". If it is a common misspelling, you may correct it\n - Pay close attention to what can be considered a unit of measurement. There are common measurements such as tablespoon, teaspoon, and gram, abbreviations such as tsp, tbsp, and oz, and others such as sprig, can, bundle, bunch, unit, cube, package, and pinch\n - Sometimes quantities can be given a range, such as "3-5" or "1 to 2" or "three or four". In this instance, choose the lower quantity; do not try to average or otherwise calculate the quantity. For instance, if the input it "2-3 lbs of chicken breast" the quantity should be "2"\n - Any text that does not appear in the unit or food must appear in the notes. No text should be left off. The only exception for this is if a quantity is converted from text into a number. For instance, if you convert "2 dozen" into the number "24", you should not put the word "dozen" into any other field\n\nIt is imperative that you do not create any data or otherwise make up any information. Failure to adhere to this rule is illegal and will result in harsh punishment. If you are unsure, place the entire string into the note section of the response. Do not make things up.\n\nBelow you will receive the JSON schema for your response. Your response must be in valid JSON in the below schema as provided. You must respond in this JSON schema; failure to do so is illegal. It is imperative that you follow the schema precisely to avoid punishment. You must follow the JSON schema.\n\nThe user message that you receive will be the list of one or more recipe ingredients for you to parse. Your response should have exactly one item for each item provided. For instance, if you receive 12 items to parse, then your response should be an array of 12 parsed items.\n\n\n###\nThis is the JSON response schema. You must respond in valid JSON that follows this schema. Your payload should be as compact as possible, eliminating unncessesary whitespace. Any fields with default values which you do not populate should not be in the payload.\n---\n\n{"$defs":{"OpenAIIngredient":{"properties":{"input":{"description":"\nThe input is simply the ingredient string you are processing as-is. It is forbidden to\nmodify this at all, you must provide the input exactly as you received it.\n","title":"Input","type":"string"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"\nThis value is a float between 0 - 100, where 100 is full confidence that the result is correct,\nand 0 is no confidence that the result is correct. If you're unable to parse anything,\nand you put the entire string in the notes, you should return 0 confidence. If you can easily\nparse the string into each component, then you should return a confidence of 100. If you have to\nguess which part is the unit and which part is the food, your confidence should be lower, such as 60.\nEven if there is no unit or note, if you're able to determine the food, you may use a higher confidence.\nIf the entire ingredient consists of only a food, you can use a confidence of 100.\n","title":"Confidence"},"quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"default":0,"description":"\nThe numerical representation of how much of this ingredient. For instance, if you receive\n\"3 1/2 grams of minced garlic\", the quantity is \"3 1/2\". Quantity may be represented as a whole number\n(integer), a float or decimal, or a fraction. You should output quantity in only whole numbers or\nfloats, converting fractions into floats. Floats longer than 10 decimal places should be\nrounded to 10 decimal places.\n","title":"Quantity"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe unit of measurement for this ingredient. For instance, if you receive\n\"2 lbs chicken breast\", the unit is \"lbs\" (short for \"pounds\").\n","title":"Unit"},"food":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe actual physical ingredient used in the recipe. For instance, if you receive\n\"3 cups of onions, chopped\", the food is \"onions\".\n","title":"Food"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"\nThe rest of the text that represents more detail on how to prepare the ingredient.\nAnything that is not one of the above should be the note. For instance, if you receive\n\"one can of butter beans, drained\" the note would be \"drained\". If you receive\n\"3 cloves of garlic peeled and finely chopped\", the note would be \"peeled and finely chopped\".\n","title":"Note"}},"required":["input"],"title":"OpenAIIngredient","type":"object"}},"properties":{"ingredients":{"default":[],"items":{"$ref":"#/$defs/OpenAIIngredient"},"title":"Ingredients","type":"array"}},"title":"OpenAIIngredients","type":"object"}\n\n\n###\nBelow is a list of units found in the units database. While parsing, you should reference this list when determining which part of the input is the unit. You may find a unit in the input that does not exist in this list. This should not prevent you from parsing that text as a unit, however it may lower your confidence level.\n---\n\n["tracos","pitada","dente","l","pintas","colheres de sobremesa","gal","onca","litro","embalagens","chavenas","q.b.","porcao","c. de cafe","lb","quarto","grama","doses","galoes","chavena","oncas fluidas","colheres de sopa","quilogramas","latas","qt","onca fluida","colher de sopa","gramas","miligramas","kg","c. de sobremesa","pint","quartos","csp","punhados","colheres de cafe","molho","miligrama","salpicos","dentes","qb","g","galao","colher de cafe","lbs","cabecas","mg","lata","colheres de cha","colher de cha","fl oz","quilograma","csm","pt","libras","ml","oz","c","oncas","mililitro","libra","mililitros","punhado","cabeca","embalagem","colher de sobremesa","litros","splash"]\n'}, {'role': 'user', 'content': [{'type': 'text', 'text': '["1 colher de ch\u00e1 de sementes de s\u00e9samo","coentros frescos q.b."]'}]}], 'model': 'gemini-1.5-flash', 'response_format': {'type': 'json_object'}, 'temperature': 0.2}}
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.started host='generativelanguage.googleapis.com' port=443 local_address=None timeout=60 socket_options=None
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bce720>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1998985550> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bce900>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b27ed0> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bced20>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b93450> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bceb10>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996b91ad0> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - connect_tcp.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcf080>
DEBUG 2025-01-04T20:07:18 - start_tls.started ssl_context=<ssl.SSLContext object at 0x7e1996bb8d50> server_hostname='generativelanguage.googleapis.com' timeout=60
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdbe0>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdd30>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcdfd0>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bc0080>
DEBUG 2025-01-04T20:07:18 - start_tls.complete return_value=<httpcore._backends.anyio.AnyIOStream object at 0x7e1996bcde80>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_headers.complete
DEBUG 2025-01-04T20:07:18 - send_request_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:18 - send_request_body.complete
DEBUG 2025-01-04T20:07:18 - receive_response_headers.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:18 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=608'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1166'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1173'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1173'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'application/json'), (b'Vary', b'Origin'), (b'Vary', b'X-Origin'), (b'Vary', b'Referer'), (b'Content-Encoding', b'gzip'), (b'Date', b'Sat, 04 Jan 2025 20:07:19 GMT'), (b'Server', b'scaffolding on HTTPServer2'), (b'X-XSS-Protection', b'0'), (b'X-Frame-Options', b'SAMEORIGIN'), (b'X-Content-Type-Options', b'nosniff'), (b'Server-Timing', b'gfet4t7; dur=1195'), (b'Alt-Svc', b'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'), (b'Transfer-Encoding', b'chunked')])
INFO 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "HTTP/1.1 200 OK"
DEBUG 2025-01-04T20:07:19 - receive_response_body.started request=<Request [b'POST']>
DEBUG 2025-01-04T20:07:19 - receive_response_body.complete
DEBUG 2025-01-04T20:07:19 - response_closed.started
DEBUG 2025-01-04T20:07:19 - response_closed.complete
DEBUG 2025-01-04T20:07:19 - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/openai/chat/completions "200 OK"
DEBUG 2025-01-04T20:07:19 - Failed to parse OpenAI response as <class 'mealie.schema.openai.recipe_ingredient.OpenAIIngredients'>. Response: {"ingredients":[{"quantity":100,"unit":"ml","food":"molho de soja","note":null},{"quantity":3,"unit":"colheres de sopa","food":"mel","note":null}]}
INFO 2025-01-04T20:07:19 - [192.168.1.1:0] 500 Internal Server Error "POST /api/parser/ingredients HTTP/1.1"
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Traceback (most recent call last):
File "/app/mealie/services/parser_services/openai/parser.py", line 90, in _parse
OpenAIIngredients.parse_openai_response(response_json)
File "/app/mealie/schema/openai/_base.py", line 24, in parse_openai_response
return cls.model_validate_json(response or "")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/pydantic/main.py", line 656, in model_validate_json
return cls.pydantic_validator.validate_json(json_data, strict=strict, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 2 validation errors for OpenAIIngredients
ingredients.0.input
Field required [type=missing, input_value={'quantity': 100, 'unit':... de soja', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
ingredients.1.input
Field required [type=missing, input_value={'quantity': 3, 'unit': '...d': 'mel', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in call
await super().call(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in call
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in call
await self.app(scope, receive, _send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/sessions.py", line 85, in call
await self.app(scope, receive, send_wrapper)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 20, in call
await responder(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 39, in call
await self.app(scope, receive, self.send_with_gzip)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
await route.handle(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
await self.app(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/routes/parser/ingredient_parser.py", line 22, in parse_ingredients
return await parser.parse(ingredients.ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 109, in parse
response = await self._parse(ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 95, in _parse
raise Exception("Failed to parse OpenAI response") from e
Exception: Failed to parse OpenAI response
ERROR 2025-01-04T20:07:19 - Exception in ASGI application
Traceback (most recent call last):
File "/app/mealie/services/parser_services/openai/parser.py", line 90, in _parse
OpenAIIngredients.parse_openai_response(response_json)
File "/app/mealie/schema/openai/_base.py", line 24, in parse_openai_response
return cls.model_validate_json(response or "")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/pydantic/main.py", line 656, in model_validate_json
return cls.pydantic_validator.validate_json(json_data, strict=strict, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 2 validation errors for OpenAIIngredients
ingredients.0.input
Field required [type=missing, input_value={'quantity': 100, 'unit':... de soja', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
ingredients.1.input
Field required [type=missing, input_value={'quantity': 3, 'unit': '...d': 'mel', 'note': None}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.10/v/missing
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in call
await super().call(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in call
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in call
await self.app(scope, receive, _send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/sessions.py", line 85, in call
await self.app(scope, receive, send_wrapper)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 20, in call
await responder(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/gzip.py", line 39, in call
await self.app(scope, receive, self.send_with_gzip)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in call
await self.middleware_stack(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
await route.handle(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
await self.app(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/opt/pysetup/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/routes/parser/ingredient_parser.py", line 22, in parse_ingredients
return await parser.parse(ingredients.ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 109, in parse
response = await self._parse(ingredients)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/mealie/services/parser_services/openai/parser.py", line 95, in _parse
raise Exception("Failed to parse OpenAI response") from e
Exception: Failed to parse OpenAI response
INFO 2025-01-04T20:07:26 - [127.0.0.1:60166] 200 OK "GET /api/app/about HTTP/1.1"
Mealie Version
v2.4.1
Deployment
Docker (Linux)
Additional Deployment Details
No response