diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..979d3d6 Binary files /dev/null and b/.DS_Store differ diff --git a/pipeline/inspection.py b/pipeline/inspection.py index c9bd828..9feece3 100644 --- a/pipeline/inspection.py +++ b/pipeline/inspection.py @@ -1,60 +1,58 @@ import re from typing import List, Optional + from pydantic import BaseModel, Field, field_validator, model_validator + class npkError(ValueError): pass + def extract_first_number(string: str) -> Optional[str]: if string is not None: - match = re.search(r'\d+(\.\d+)?', string) + match = re.search(r"\d+(\.\d+)?", string) if match: return match.group() return None + class NutrientValue(BaseModel): nutrient: str value: Optional[float] = None unit: Optional[str] = None - @field_validator('value', mode='before', check_fields=False) + @field_validator("value", mode="before", check_fields=False) def convert_value(cls, v): - if isinstance(v, bool): - return None - elif isinstance(v, (int, float)): - return str(v) - elif isinstance(v, (str)): + if type(v) in (int, float): + return float(v) + if type(v) is str: return extract_first_number(v) - return None - + + class Value(BaseModel): value: Optional[float] unit: Optional[str] - @field_validator('value', mode='before', check_fields=False) + @field_validator("value", mode="before", check_fields=False) def convert_value(cls, v): - if isinstance(v, bool): - return None - elif isinstance(v, (int, float)): - return str(v) - elif isinstance(v, (str)): + if type(v) in (int, float): + return float(v) + if type(v) is str: return extract_first_number(v) - return None + class Specification(BaseModel): - humidity: Optional[float] = Field(..., alias='humidity') - ph: Optional[float] = Field(..., alias='ph') + humidity: Optional[float] = Field(..., alias="humidity") + ph: Optional[float] = Field(..., alias="ph") solubility: Optional[float] - @field_validator('humidity', 'ph', 'solubility', mode='before', check_fields=False) - def convert_specification_values(cls, v): - if isinstance(v, bool): - return None - elif isinstance(v, (int, float)): - return str(v) - elif isinstance(v, (str)): + @field_validator("humidity", "ph", "solubility", mode="before", check_fields=False) + def convert_value(cls, v): + if type(v) in (int, float): + return float(v) + if type(v) is str: return extract_first_number(v) - return None + class FertilizerInspection(BaseModel): company_name: Optional[str] = None @@ -86,23 +84,31 @@ class FertilizerInspection(BaseModel): ingredients_fr: List[NutrientValue] = [] specifications_fr: List[Specification] = [] first_aid_fr: List[str] = None - - @field_validator('npk', mode='before') + + @field_validator("npk", mode="before") def validate_npk(cls, v): if v is not None: - pattern = re.compile(r'^\d+(\.\d+)?-\d+(\.\d+)?-\d+(\.\d+)?$') + pattern = re.compile(r"^\d+(\.\d+)?-\d+(\.\d+)?-\d+(\.\d+)?$") if not pattern.match(v): return None return v - @model_validator(mode='before') + @model_validator(mode="before") def replace_none_with_empty_list(cls, values): fields_to_check = [ - 'cautions_en', 'first_aid_en', 'cautions_fr', 'first_aid_fr', - 'instructions_en', 'micronutrients_en', 'ingredients_en', - 'specifications_en', 'instructions_fr', - 'micronutrients_fr', 'ingredients_fr', - 'specifications_fr', 'guaranteed_analysis' + "cautions_en", + "first_aid_en", + "cautions_fr", + "first_aid_fr", + "instructions_en", + "micronutrients_en", + "ingredients_en", + "specifications_en", + "instructions_fr", + "micronutrients_fr", + "ingredients_fr", + "specifications_fr", + "guaranteed_analysis", ] for field in fields_to_check: if values.get(field) is None: diff --git a/script.py b/script.py new file mode 100644 index 0000000..c5911d4 --- /dev/null +++ b/script.py @@ -0,0 +1,7 @@ +import json + +from pydantic import BaseModel +from pipeline.inspection import FertilizerInspection + + +print(json.dumps(BaseModel.model_dump(FertilizerInspection))) diff --git a/script2.py b/script2.py new file mode 100644 index 0000000..c50bca1 --- /dev/null +++ b/script2.py @@ -0,0 +1,39 @@ +import os +from pprint import pprint +from tests import curl_file +from dotenv import load_dotenv +# from pipeline.inspection import FertilizerInspection +from pipeline import LabelStorage, OCR, GPT, analyze + +# Load environment variables +load_dotenv() + +# Set up the required objects +log_dir_path = 'test_logs' +image_path = 'granulaine.png' # Path to your test image + +# Ensure the log directory exists +if not os.path.exists(log_dir_path): + os.mkdir(log_dir_path) + +# Download the test image +# curl_file(url='https://tlhort.com/cdn/shop/products/10-52-0MAP.jpg', path=image_path) + +# Mock environment setup for OCR and GPT +api_endpoint_ocr = os.getenv('AZURE_API_ENDPOINT') +api_key_ocr = os.getenv('AZURE_API_KEY') +api_endpoint_gpt = os.getenv('AZURE_OPENAI_ENDPOINT') +api_key_gpt = os.getenv('AZURE_OPENAI_KEY') +api_deployment_gpt = os.getenv('AZURE_OPENAI_DEPLOYMENT') + +# Initialize the objects +label_storage = LabelStorage() +label_storage.add_image(image_path) +ocr = OCR(api_endpoint=api_endpoint_ocr, api_key=api_key_ocr) +gpt = GPT(api_endpoint=api_endpoint_gpt, api_key=api_key_gpt, deployment_id=api_deployment_gpt) + +# Run the analyze function +form = analyze(label_storage, ocr, gpt, log_dir_path=log_dir_path) + +# Pretty print the form +print(form.model_dump_json()) diff --git a/script3.py b/script3.py new file mode 100644 index 0000000..5cf1861 --- /dev/null +++ b/script3.py @@ -0,0 +1,68 @@ +import re +from pydantic import BaseModel, ValidationError, field_validator +from typing import Optional + +# Helper function to extract first number +def extract_first_number(string: str) -> Optional[float]: + if string is not None: + match = re.search(r"\d+(\.\d+)?", string) + if match: + return float(match.group()) + return None + +# NutrientValue model with updated field type +class NutrientValue(BaseModel): + nutrient: str + value: float | None = None + unit: Optional[str] = None + + @field_validator("value", mode="before") + def convert_value(cls, v): + if type(v) in (int, float): + return float(v) + if type(v) is str: + return extract_first_number(v) + + +# Test cases +def test_nutrient_value(): + # Case 1: Integer value + nv1 = NutrientValue(nutrient="Protein", value=15, unit="g") + print(nv1.model_dump_json()) + assert nv1.value == 15, f"Expected 15, but got {nv1.value} (type: {type(nv1.value)})" + + # Case 2: Float value + nv2 = NutrientValue(nutrient="Fat", value=10.5, unit="g") + assert nv2.value == 10.5, f"Expected 10.5, but got {nv2.value} (type: {type(nv2.value)})" + + # Case 3: String containing a number + nv3 = NutrientValue(nutrient="Carbohydrates", value="20g", unit="g") + assert nv3.value == 20.0, f"Expected 20.0, but got {nv3.value} (type: {type(nv3.value)})" + + # Case 4: String without a number + nv4 = NutrientValue(nutrient="Fiber", value="N/A", unit="g") + assert nv4.value is None, f"Expected None, but got {nv4.value} (type: {type(nv4.value)})" + + # Case 5: None value + nv5 = NutrientValue(nutrient="Sugar", value=None, unit="g") + assert nv5.value is None, f"Expected None, but got {nv5.value} (type: {type(nv5.value)})" + + # Case 6: Boolean value (should result in ValidationError as it's unsupported input) + try: + NutrientValue(nutrient="Vitamins", value=True, unit="mg") + except ValidationError as e: + print(f"Expected ValidationError, got: {e}") + + # Case 7: Boolean value (should result in ValidationError as it's unsupported input) + try: + nv6 = NutrientValue(nutrient="Vitamins", value=False, unit="mg") + print(nv6) + except ValidationError as e: + print(f"Expected ValidationError for boolean input, got: {e}") + +if __name__ == "__main__": + try: + test_nutrient_value() + print("All tests passed!") + except AssertionError as e: + print(f"Assertion failed: {e}") diff --git a/z.json b/z.json new file mode 100644 index 0000000..31a64c3 --- /dev/null +++ b/z.json @@ -0,0 +1,354 @@ +{ + "$defs": { + "NutrientValue": { + "properties": { + "nutrient": { + "description": "The name of the nutrient or ingredient", + "examples": ["Iron (Fe)", "Zinc (Zn)", "Bone meal"], + "title": "Nutrient", + "type": "string" + }, + "value": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "The amount or concentration of the nutrient", + "examples": ["0.10", "5"], + "title": "Value" + }, + "unit": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "The unit of measurement for the value", + "examples": ["%", "mg/kg"], + "title": "Unit" + } + }, + "required": ["nutrient"], + "title": "NutrientValue", + "type": "object" + }, + "Specification": { + "properties": { + "humidity": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "description": "The humidity level, typically as a percentage", + "examples": ["10"], + "title": "Humidity" + }, + "ph": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "description": "The pH level, indicating acidity or alkalinity", + "examples": ["6.5"], + "title": "Ph" + }, + "solubility": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "The solubility value, often measured in grams per liter", + "examples": ["100"], + "title": "Solubility" + } + }, + "required": ["humidity", "ph"], + "title": "Specification", + "type": "object" + }, + "Value": { + "properties": { + "value": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "The numerical value of the measurement", + "examples": ["25", "55", "1.2", "20.8"], + "title": "Value" + }, + "unit": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "The unit of measurement", + "examples": ["kg", "lb", "g/cm", "L"], + "title": "Unit" + } + }, + "title": "Value", + "type": "object" + } + }, + "properties": { + "company_name": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Name of the company", + "examples": ["GreenGrow Fertilizers Inc."], + "title": "Company Name" + }, + "company_address": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Address of the company", + "examples": ["123 Greenway Blvd, Springfield IL 62701 USA"], + "title": "Company Address" + }, + "company_website": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Website of the company", + "examples": ["www.greengrowfertilizers.com"], + "title": "Company Website" + }, + "company_phone_number": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Phone number of the company", + "examples": ["+1 800 555 0199"], + "title": "Company Phone Number" + }, + "manufacturer_name": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Name of the manufacturer", + "examples": ["AgroTech Industries Ltd."], + "title": "Manufacturer Name" + }, + "manufacturer_address": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Address of the manufacturer", + "examples": ["456 Industrial Park Rd, Oakville ON L6H 5V4 Canada"], + "title": "Manufacturer Address" + }, + "manufacturer_website": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Website of the manufacturer", + "examples": ["www.agrotechindustries.com"], + "title": "Manufacturer Website" + }, + "manufacturer_phone_number": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Phone number of the manufacturer", + "examples": ["+1 416 555 0123"], + "title": "Manufacturer Phone Number" + }, + "fertiliser_name": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Name of the fertiliser", + "examples": ["SuperGrow 20-20-20"], + "title": "Fertiliser Name" + }, + "registration_number": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Registration number of the fertiliser", + "examples": ["F12345678"], + "title": "Registration Number" + }, + "lot_number": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Lot number of the fertiliser", + "examples": ["L987654321"], + "title": "Lot Number" + }, + "weight": { + "description": "List of weights with units", + "examples": [ + [ + { "unit": "kg", "value": "25" }, + { "unit": "lb", "value": "55" } + ] + ], + "items": { "$ref": "#/$defs/Value" }, + "title": "Weight", + "type": "array" + }, + "density": { + "anyOf": [{ "$ref": "#/$defs/Value" }, { "type": "null" }], + "default": null, + "description": "Density of the fertiliser", + "examples": [{ "unit": "g/cm", "value": "1.2" }] + }, + "volume": { + "anyOf": [{ "$ref": "#/$defs/Value" }, { "type": "null" }], + "default": null, + "description": "Volume of the fertiliser", + "examples": [{ "unit": "L", "value": "20.8" }] + }, + "npk": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "N-P-K ratio of the fertiliser", + "examples": ["20-20-20"], + "title": "Npk" + }, + "guaranteed_analysis": { + "description": "Guaranteed analysis of primary nutrients", + "examples": [ + [ + { "nutrient": "Total Nitrogen (N)", "unit": "%", "value": "20" }, + { + "nutrient": "Available Phosphate (P2O5)", + "unit": "%", + "value": "20" + }, + { "nutrient": "Soluble Potash (K2O)", "unit": "%", "value": "20" } + ] + ], + "items": { "$ref": "#/$defs/NutrientValue" }, + "title": "Guaranteed Analysis", + "type": "array" + }, + "warranty": { + "anyOf": [{ "type": "string" }, { "type": "null" }], + "default": null, + "description": "Warranty information", + "examples": ["Guaranteed analysis of nutrients."], + "title": "Warranty" + }, + "cautions_en": { + "description": "List of caution statements in English", + "examples": [ + ["Keep out of reach of children.", "Avoid contact with skin and eyes."] + ], + "items": { "type": "string" }, + "title": "Cautions En", + "type": "array" + }, + "instructions_en": { + "description": "Usage instructions in English", + "examples": [ + [ + "1. Dissolve 50g in 10L of water.", + "2. Apply every 2 weeks.", + "3. Store in a cool, dry place." + ] + ], + "items": { "type": "string" }, + "title": "Instructions En", + "type": "array" + }, + "micronutrients_en": { + "description": "List of micronutrients in English", + "examples": [ + [ + { "nutrient": "Iron (Fe)", "unit": "%", "value": "0.10" }, + { "nutrient": "Zinc (Zn)", "unit": "%", "value": "0.05" }, + { "nutrient": "Manganese (Mn)", "unit": "%", "value": "0.05" } + ] + ], + "items": { "$ref": "#/$defs/NutrientValue" }, + "title": "Micronutrients En", + "type": "array" + }, + "ingredients_en": { + "description": "List of ingredients in English", + "examples": [ + [ + { "nutrient": "Bone meal", "unit": "%", "value": "5" }, + { "nutrient": "Seaweed extract", "unit": "%", "value": "3" }, + { "nutrient": "Humic acid", "unit": "%", "value": "2" }, + { "nutrient": "Clay", "unit": "", "value": "" }, + { "nutrient": "Sand", "unit": "", "value": "" }, + { "nutrient": "Perlite", "unit": "", "value": "" } + ] + ], + "items": { "$ref": "#/$defs/NutrientValue" }, + "title": "Ingredients En", + "type": "array" + }, + "specifications_en": { + "description": "Specifications of the product in English", + "examples": [[{ "humidity": "10", "ph": "6.5", "solubility": "100" }]], + "items": { "$ref": "#/$defs/Specification" }, + "title": "Specifications En", + "type": "array" + }, + "first_aid_en": { + "description": "First aid instructions in English", + "examples": [ + [ + "In case of contact with eyes, rinse immediately with plenty of water and seek medical advice." + ] + ], + "items": { "type": "string" }, + "title": "First Aid En", + "type": "array" + }, + "cautions_fr": { + "description": "List of caution statements in French", + "examples": [ + [ + "Tenir hors de port\u00e9e des enfants.", + "\u00c9viter le contact avec la peau et les yeux." + ] + ], + "items": { "type": "string" }, + "title": "Cautions Fr", + "type": "array" + }, + "instructions_fr": { + "description": "Usage instructions in French", + "examples": [ + [ + "1. Dissoudre 50g dans 10L d'eau.", + "2. Appliquer toutes les 2 semaines.", + "3. Conserver dans un endroit frais et sec." + ] + ], + "items": { "type": "string" }, + "title": "Instructions Fr", + "type": "array" + }, + "micronutrients_fr": { + "description": "List of micronutrients in French", + "examples": [ + [ + { "nutrient": "Fer (Fe)", "unit": "%", "value": "0.10" }, + { "nutrient": "Zinc (Zn)", "unit": "%", "value": "0.05" }, + { "nutrient": "Mangan\u00e8se (Mn)", "unit": "%", "value": "0.05" } + ] + ], + "items": { "$ref": "#/$defs/NutrientValue" }, + "title": "Micronutrients Fr", + "type": "array" + }, + "ingredients_fr": { + "description": "List of ingredients in French", + "examples": [ + [ + { "nutrient": "Farine d'os", "unit": "%", "value": "5" }, + { "nutrient": "Extrait d'algues", "unit": "%", "value": "3" }, + { "nutrient": "Acide humique", "unit": "%", "value": "2" }, + { "nutrient": "Argile", "unit": "", "value": "" }, + { "nutrient": "Sable", "unit": "", "value": "" }, + { "nutrient": "Perlite", "unit": "", "value": "" } + ] + ], + "items": { "$ref": "#/$defs/NutrientValue" }, + "title": "Ingredients Fr", + "type": "array" + }, + "specifications_fr": { + "description": "Specifications of the product in French", + "examples": [[{ "humidity": "10", "ph": "6.5", "solubility": "100" }]], + "items": { "$ref": "#/$defs/Specification" }, + "title": "Specifications Fr", + "type": "array" + }, + "first_aid_fr": { + "description": "First aid instructions in French", + "examples": [ + [ + "En cas de contact avec les yeux, rincer imm\u00e9diatement \u00e0 grande eau et consulter un m\u00e9decin." + ] + ], + "items": { "type": "string" }, + "title": "First Aid Fr", + "type": "array" + } + }, + "title": "FertilizerInspection", + "type": "object" +} diff --git a/z1.json b/z1.json new file mode 100644 index 0000000..13c24d1 --- /dev/null +++ b/z1.json @@ -0,0 +1,55 @@ +{ + "company_name": null, + "company_address": null, + "company_website": "lesgranulaines.com", + "company_phone_number": null, + "manufacturer_name": null, + "manufacturer_address": null, + "manufacturer_website": null, + "manufacturer_phone_number": null, + "fertiliser_name": "Granu-Laines", + "registration_number": null, + "lot_number": "L-1", + "weight": [], + "density": null, + "volume": null, + "npk": "10-0-4", + "guaranteed_analysis": [ + { "nutrient": "Total nitrogen (N)", "value": "10", "unit": "%" }, + { "nutrient": "Soluble potash (K20)", "value": "4", "unit": "%" }, + { "nutrient": "Organic matter", "value": "61.5", "unit": "%" }, + { "nutrient": "Maximum moisture content", "value": "14.8", "unit": "%" } + ], + "warranty": null, + "cautions_en": ["Wash your hands after use.", "Keep away from children."], + "instructions_en": [ + "Garden: incorporate 150 to 200 grams of Granu-Laines per m2 into first top 10 cm of soil before seeding.", + "Tomato: incorporate 150 grams underneath each plant.", + "Cucumber and squash: incorporate 100 grams underneath each plant.", + "For cultivating in pots or large containers, mix in 50 grams of Granu-Laines per 4 liters of soil.", + "For any questions, please contact your garden center." + ], + "micronutrients_en": [], + "ingredients_en": [ + { "nutrient": "100% raw sheep wool", "value": null, "unit": null } + ], + "specifications_en": [], + "first_aid_en": [], + "cautions_fr": [ + "Se laver les mains après chaque utilisation.", + "Garder hors de la portée des enfants." + ], + "instructions_fr": [ + "Pour votre potager, incorporer 150 à 200g de Granu-Laines par m2 de sol.", + "Tomate: incorporer 150g sous chaque plant.", + "Concombre et courge: incorporer 100g sous chaque plante.", + "Pour la culture en pot ou en bac, incorporer 50g par 4 litres de terre.", + "Et en cas de besoin, renseignez-vous à votre centre jardin." + ], + "micronutrients_fr": [], + "ingredients_fr": [ + { "nutrient": "100% laine brute de moutons", "value": null, "unit": null } + ], + "specifications_fr": [], + "first_aid_fr": [] +} diff --git a/z2.json b/z2.json new file mode 100644 index 0000000..641bc10 --- /dev/null +++ b/z2.json @@ -0,0 +1,60 @@ +{ + "company_name": null, + "company_address": null, + "company_website": "lesgranulaines.com", + "company_phone_number": null, + "manufacturer_name": null, + "manufacturer_address": null, + "manufacturer_website": null, + "manufacturer_phone_number": null, + "fertiliser_name": "ALL - PURPOSE NATURAL FERTILISER", + "registration_number": null, + "lot_number": "L-1", + "weight": [], + "density": null, + "volume": null, + "npk": "10-0-4", + "guaranteed_analysis": [ + { "nutrient": "Total nitrogen (N)", "value": "10", "unit": null }, + { "nutrient": "Soluble potash (K20)", "value": "4", "unit": null }, + { "nutrient": "Organic matter", "value": "61.5", "unit": null } + ], + "warranty": null, + "cautions_en": ["Wash your hands after use.", "Keep away from children."], + "instructions_en": [ + "1 application per season", + "Garden: incorporate 150 to 200 grams of Granu-Laines per m2 into first top 10 cm of soil before seeding.", + "Tomato: incorporate 150 grams underneath each plant.", + "Cucumber and squash: incorporate 100 grams underneath each plant.", + "For cultivating in pots or large containers, mix in 50 grams of Granu-Laines per 4 liters of soil.", + "For any questions, please contact your garden center." + ], + "micronutrients_en": [], + "ingredients_en": [ + { "nutrient": "Ingredients", "value": "100", "unit": null } + ], + "specifications_en": [ + { "humidity": "14.8%", "ph": null, "solubility": null } + ], + "first_aid_en": [], + "cautions_fr": [ + "Se laver les mains après chaque utilisation.", + "Garder hors de la portée des enfants." + ], + "instructions_fr": [ + "1 seule application par saison", + "Pour votre potager, incorporer 150 à 200g de Granu-Laines par m2 de sol.", + "Tomate: incorporer 150g sous chaque plant.", + "Concombre et courge: incorporer 100g sous chaque plante.", + "Pour la culture en pot ou en bac, incorporer 50g par 4 litres de terre.", + "Et en cas de besoin, renseignez-vous à votre centre jardin." + ], + "micronutrients_fr": [], + "ingredients_fr": [ + { "nutrient": "Ingrédients", "value": "100", "unit": null } + ], + "specifications_fr": [ + { "humidity": "14.8%", "ph": null, "solubility": null } + ], + "first_aid_fr": [] +} diff --git a/z3.json b/z3.json new file mode 100644 index 0000000..13c24d1 --- /dev/null +++ b/z3.json @@ -0,0 +1,55 @@ +{ + "company_name": null, + "company_address": null, + "company_website": "lesgranulaines.com", + "company_phone_number": null, + "manufacturer_name": null, + "manufacturer_address": null, + "manufacturer_website": null, + "manufacturer_phone_number": null, + "fertiliser_name": "Granu-Laines", + "registration_number": null, + "lot_number": "L-1", + "weight": [], + "density": null, + "volume": null, + "npk": "10-0-4", + "guaranteed_analysis": [ + { "nutrient": "Total nitrogen (N)", "value": "10", "unit": "%" }, + { "nutrient": "Soluble potash (K20)", "value": "4", "unit": "%" }, + { "nutrient": "Organic matter", "value": "61.5", "unit": "%" }, + { "nutrient": "Maximum moisture content", "value": "14.8", "unit": "%" } + ], + "warranty": null, + "cautions_en": ["Wash your hands after use.", "Keep away from children."], + "instructions_en": [ + "Garden: incorporate 150 to 200 grams of Granu-Laines per m2 into first top 10 cm of soil before seeding.", + "Tomato: incorporate 150 grams underneath each plant.", + "Cucumber and squash: incorporate 100 grams underneath each plant.", + "For cultivating in pots or large containers, mix in 50 grams of Granu-Laines per 4 liters of soil.", + "For any questions, please contact your garden center." + ], + "micronutrients_en": [], + "ingredients_en": [ + { "nutrient": "100% raw sheep wool", "value": null, "unit": null } + ], + "specifications_en": [], + "first_aid_en": [], + "cautions_fr": [ + "Se laver les mains après chaque utilisation.", + "Garder hors de la portée des enfants." + ], + "instructions_fr": [ + "Pour votre potager, incorporer 150 à 200g de Granu-Laines par m2 de sol.", + "Tomate: incorporer 150g sous chaque plant.", + "Concombre et courge: incorporer 100g sous chaque plante.", + "Pour la culture en pot ou en bac, incorporer 50g par 4 litres de terre.", + "Et en cas de besoin, renseignez-vous à votre centre jardin." + ], + "micronutrients_fr": [], + "ingredients_fr": [ + { "nutrient": "100% laine brute de moutons", "value": null, "unit": null } + ], + "specifications_fr": [], + "first_aid_fr": [] +} diff --git a/z4.json b/z4.json new file mode 100644 index 0000000..641bc10 --- /dev/null +++ b/z4.json @@ -0,0 +1,60 @@ +{ + "company_name": null, + "company_address": null, + "company_website": "lesgranulaines.com", + "company_phone_number": null, + "manufacturer_name": null, + "manufacturer_address": null, + "manufacturer_website": null, + "manufacturer_phone_number": null, + "fertiliser_name": "ALL - PURPOSE NATURAL FERTILISER", + "registration_number": null, + "lot_number": "L-1", + "weight": [], + "density": null, + "volume": null, + "npk": "10-0-4", + "guaranteed_analysis": [ + { "nutrient": "Total nitrogen (N)", "value": "10", "unit": null }, + { "nutrient": "Soluble potash (K20)", "value": "4", "unit": null }, + { "nutrient": "Organic matter", "value": "61.5", "unit": null } + ], + "warranty": null, + "cautions_en": ["Wash your hands after use.", "Keep away from children."], + "instructions_en": [ + "1 application per season", + "Garden: incorporate 150 to 200 grams of Granu-Laines per m2 into first top 10 cm of soil before seeding.", + "Tomato: incorporate 150 grams underneath each plant.", + "Cucumber and squash: incorporate 100 grams underneath each plant.", + "For cultivating in pots or large containers, mix in 50 grams of Granu-Laines per 4 liters of soil.", + "For any questions, please contact your garden center." + ], + "micronutrients_en": [], + "ingredients_en": [ + { "nutrient": "Ingredients", "value": "100", "unit": null } + ], + "specifications_en": [ + { "humidity": "14.8%", "ph": null, "solubility": null } + ], + "first_aid_en": [], + "cautions_fr": [ + "Se laver les mains après chaque utilisation.", + "Garder hors de la portée des enfants." + ], + "instructions_fr": [ + "1 seule application par saison", + "Pour votre potager, incorporer 150 à 200g de Granu-Laines par m2 de sol.", + "Tomate: incorporer 150g sous chaque plant.", + "Concombre et courge: incorporer 100g sous chaque plante.", + "Pour la culture en pot ou en bac, incorporer 50g par 4 litres de terre.", + "Et en cas de besoin, renseignez-vous à votre centre jardin." + ], + "micronutrients_fr": [], + "ingredients_fr": [ + { "nutrient": "Ingrédients", "value": "100", "unit": null } + ], + "specifications_fr": [ + { "humidity": "14.8%", "ph": null, "solubility": null } + ], + "first_aid_fr": [] +}