Notebooks
M
Mistral AI
Batch Api Example

Batch Api Example

image_understandingmistral-cookbookmistral

Batch API Basics with Mistral AI

In this notebook, we will guide you through an example of extracting information from multiple receipts using the Mistral batch API and returning the data in a pandas DataFrame.

[1]
Collecting mistralai
  Downloading mistralai-1.2.3-py3-none-any.whl.metadata (26 kB)
Collecting datasets
  Downloading datasets-3.1.0-py3-none-any.whl.metadata (20 kB)
Requirement already satisfied: eval-type-backport<0.3.0,>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from mistralai) (0.2.0)
Requirement already satisfied: httpx<0.28.0,>=0.27.0 in /usr/local/lib/python3.10/dist-packages (from mistralai) (0.27.2)
Collecting jsonpath-python<2.0.0,>=1.0.6 (from mistralai)
  Downloading jsonpath_python-1.0.6-py3-none-any.whl.metadata (12 kB)
Requirement already satisfied: pydantic<3.0.0,>=2.9.0 in /usr/local/lib/python3.10/dist-packages (from mistralai) (2.9.2)
Requirement already satisfied: python-dateutil==2.8.2 in /usr/local/lib/python3.10/dist-packages (from mistralai) (2.8.2)
Collecting typing-inspect<0.10.0,>=0.9.0 (from mistralai)
  Downloading typing_inspect-0.9.0-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil==2.8.2->mistralai) (1.16.0)
Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from datasets) (3.16.1)
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from datasets) (1.26.4)
Requirement already satisfied: pyarrow>=15.0.0 in /usr/local/lib/python3.10/dist-packages (from datasets) (17.0.0)
Collecting dill<0.3.9,>=0.3.0 (from datasets)
  Downloading dill-0.3.8-py3-none-any.whl.metadata (10 kB)
Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from datasets) (2.2.2)
Requirement already satisfied: requests>=2.32.2 in /usr/local/lib/python3.10/dist-packages (from datasets) (2.32.3)
Requirement already satisfied: tqdm>=4.66.3 in /usr/local/lib/python3.10/dist-packages (from datasets) (4.66.6)
Collecting xxhash (from datasets)
  Downloading xxhash-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (12 kB)
Collecting multiprocess<0.70.17 (from datasets)
  Downloading multiprocess-0.70.16-py310-none-any.whl.metadata (7.2 kB)
Collecting fsspec<=2024.9.0,>=2023.1.0 (from fsspec[http]<=2024.9.0,>=2023.1.0->datasets)
  Downloading fsspec-2024.9.0-py3-none-any.whl.metadata (11 kB)
Requirement already satisfied: aiohttp in /usr/local/lib/python3.10/dist-packages (from datasets) (3.11.2)
Requirement already satisfied: huggingface-hub>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from datasets) (0.26.2)
Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from datasets) (24.2)
Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from datasets) (6.0.2)
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (2.4.3)
Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.3.1)
Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (24.2.0)
Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.5.0)
Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (6.1.0)
Requirement already satisfied: propcache>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (0.2.0)
Requirement already satisfied: yarl<2.0,>=1.17.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (1.17.2)
Requirement already satisfied: async-timeout<6.0,>=4.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets) (4.0.3)
Requirement already satisfied: anyio in /usr/local/lib/python3.10/dist-packages (from httpx<0.28.0,>=0.27.0->mistralai) (3.7.1)
Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from httpx<0.28.0,>=0.27.0->mistralai) (2024.8.30)
Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.10/dist-packages (from httpx<0.28.0,>=0.27.0->mistralai) (1.0.7)
Requirement already satisfied: idna in /usr/local/lib/python3.10/dist-packages (from httpx<0.28.0,>=0.27.0->mistralai) (3.10)
Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from httpx<0.28.0,>=0.27.0->mistralai) (1.3.1)
Requirement already satisfied: h11<0.15,>=0.13 in /usr/local/lib/python3.10/dist-packages (from httpcore==1.*->httpx<0.28.0,>=0.27.0->mistralai) (0.14.0)
Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.23.0->datasets) (4.12.2)
Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3.0.0,>=2.9.0->mistralai) (0.7.0)
Requirement already satisfied: pydantic-core==2.23.4 in /usr/local/lib/python3.10/dist-packages (from pydantic<3.0.0,>=2.9.0->mistralai) (2.23.4)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (3.4.0)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.32.2->datasets) (2.2.3)
Collecting mypy-extensions>=0.3.0 (from typing-inspect<0.10.0,>=0.9.0->mistralai)
  Downloading mypy_extensions-1.0.0-py3-none-any.whl.metadata (1.1 kB)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets) (2024.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets) (2024.2)
Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio->httpx<0.28.0,>=0.27.0->mistralai) (1.2.2)
Downloading mistralai-1.2.3-py3-none-any.whl (256 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 256.9/256.9 kB 8.2 MB/s eta 0:00:00
Downloading datasets-3.1.0-py3-none-any.whl (480 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 480.6/480.6 kB 18.1 MB/s eta 0:00:00
Downloading dill-0.3.8-py3-none-any.whl (116 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 116.3/116.3 kB 7.5 MB/s eta 0:00:00
Downloading fsspec-2024.9.0-py3-none-any.whl (179 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 179.3/179.3 kB 11.3 MB/s eta 0:00:00
Downloading jsonpath_python-1.0.6-py3-none-any.whl (7.6 kB)
Downloading multiprocess-0.70.16-py310-none-any.whl (134 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.8/134.8 kB 6.5 MB/s eta 0:00:00
Downloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)
Downloading xxhash-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (194 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 194.1/194.1 kB 12.8 MB/s eta 0:00:00
Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)
Installing collected packages: xxhash, mypy-extensions, jsonpath-python, fsspec, dill, typing-inspect, multiprocess, mistralai, datasets
  Attempting uninstall: fsspec
    Found existing installation: fsspec 2024.10.0
    Uninstalling fsspec-2024.10.0:
      Successfully uninstalled fsspec-2024.10.0
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
gcsfs 2024.10.0 requires fsspec==2024.10.0, but you have fsspec 2024.9.0 which is incompatible.
Successfully installed datasets-3.1.0 dill-0.3.8 fsspec-2024.9.0 jsonpath-python-1.0.6 mistralai-1.2.3 multiprocess-0.70.16 mypy-extensions-1.0.0 typing-inspect-0.9.0 xxhash-3.5.0

Get receipts images

We found some receipts images from Hugging Face:

[2]
README.md:   0%|          | 0.00/509 [00:00<?, ?B/s]
train-00000-of-00001.parquet:   0%|          | 0.00/245M [00:00<?, ?B/s]
test-00000-of-00001.parquet:   0%|          | 0.00/60.3M [00:00<?, ?B/s]
Generating train split:   0%|          | 0/153 [00:00<?, ? examples/s]
Generating test split:   0%|          | 0/39 [00:00<?, ? examples/s]

Take a look at one image

Let's start with one image and get info from this image with Pixtral Large.

[3]
Output

let's extract information from a single image using the Mistral API.

[4]
[5]
[6]
{
  "items": [
    {
      "name": "Maple glazed",
      "price": 25.000,
      "classification": "Food"
    },
    {
      "name": "Plastic Bag Small",
      "price": 0,
      "classification": "Other"
    }
  ]
}

Use batch API to process many images

Create a batch

Let's process 10 images as an example.

[ ]

Upload your batch

[ ]
[ ]
UploadFileOut(id='30f63bb3-6f9e-4dd5-9295-a9cdbdeabf75', object='file', bytes=1769058, created_at=1732400347, filename='file.jsonl', purpose='batch', sample_type='batch_request', source='upload', num_lines=10)

Create a batch job

[ ]
[ ]
BatchJobOut(id='5befe8c6-b8cb-4858-a068-d600cf5ed73f', input_files=['30f63bb3-6f9e-4dd5-9295-a9cdbdeabf75'], endpoint='/v1/chat/completions', model='pixtral-large-latest', errors=[], status='QUEUED', created_at=1732400351, total_requests=0, completed_requests=0, succeeded_requests=0, failed_requests=0, OBJECT='batch', metadata={'job_type': 'testing'}, output_file=None, error_file=None, started_at=None, completed_at=None)

Get batch job details

[ ]
BatchJobOut(id='5befe8c6-b8cb-4858-a068-d600cf5ed73f', input_files=['30f63bb3-6f9e-4dd5-9295-a9cdbdeabf75'], endpoint='/v1/chat/completions', model='pixtral-large-latest', errors=[], status='SUCCESS', created_at=1732400351, total_requests=10, completed_requests=10, succeeded_requests=10, failed_requests=0, OBJECT='batch', metadata={'job_type': 'testing'}, output_file='950fae83-2802-40c0-a677-c7839a4e238a', error_file=None, started_at=1732400351, completed_at=1732400376)
[ ]
Total requests: 10
Failed requests: 0
Successful requests: 10
Percent done: 100.0

Get batch results

[ ]
[ ]
{"id":"0-61c18c3c-1873-4288-9f92-af97f696fb2c","custom_id":"0","response":{"status_code":200,"body":{"id":"7f3874116cb943fea58853d60cf17ff3","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2898,"completion_tokens":88,"total_tokens":2986},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"VANCOOLEN\",\n      \"price\": 8182,\n      \"classification\": \"Medical\"\n    },\n    {\n      \"name\": \"PLASTIK 25\",\n      \"price\": 0,\n      \"classification\": \"Other\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"1-18219f09-acff-4644-baec-a73b15788364","custom_id":"1","response":{"status_code":200,"body":{"id":"aaee50ed69384fe9ae8e9fe9c4bc0c55","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2080,"completion_tokens":86,"total_tokens":2166},"created":1732400354,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"Maple glazed\",\n      \"price\": 25.000,\n      \"classification\": \"Food\"\n    },\n    {\n      \"name\": \"Plastic Bag Small\",\n      \"price\": 0,\n      \"classification\": \"Other\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"2-6ae7d6cb-4c00-4836-b182-b3a37c315c51","custom_id":"2","response":{"status_code":200,"body":{"id":"c5e88f4a35374ec3becfd756ceb7e80e","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2450,"completion_tokens":88,"total_tokens":2538},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"DEPT04\",\n      \"price\": 24000,\n      \"classification\": \"Other\"\n    },\n    {\n      \"name\": \"DEPT01\",\n      \"price\": 22000,\n      \"classification\": \"Other\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"3-8a7f98e8-1e79-4b7b-8872-5675f56ab42e","custom_id":"3","response":{"status_code":200,"body":{"id":"8dd62429cb5b406ca120339fccc0cd55","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2898,"completion_tokens":58,"total_tokens":2956},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"TAKOYAKI 12PCS\",\n      \"price\": 30000,\n      \"classification\": \"Food\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"4-f14a0083-95c5-4f60-bae0-baf591aef3f2","custom_id":"4","response":{"status_code":200,"body":{"id":"c4c63eb1f77e44de8bb615b33a4d96ad","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2130,"completion_tokens":168,"total_tokens":2298},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"Jamur Crispy\",\n      \"price\": 13500,\n      \"classification\": \"Food\"\n    },\n    {\n      \"name\": \"Nasi Putih\",\n      \"price\": 7000,\n      \"classification\": \"Food\"\n    },\n    {\n      \"name\": \"Sambel Kecap\",\n      \"price\": 4500,\n      \"classification\": \"Food\"\n    },\n    {\n      \"name\": \"Es Teh\",\n      \"price\": 7500,\n      \"classification\": \"Beverage\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"5-aacc6428-9266-4690-aa2c-47b84ec06189","custom_id":"5","response":{"status_code":200,"body":{"id":"bd959d8edc234e5585dbfb8d0005ffe4","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":3218,"completion_tokens":100,"total_tokens":3318},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"118 Round Wagyu (1gr)\",\n      \"price\": 47.200,\n      \"classification\": \"Food\"\n    },\n    {\n      \"name\": \"1 Wagyu Rice Box\",\n      \"price\": 10.000,\n      \"classification\": \"Food\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"6-70a513f7-732d-47d4-a4fe-52941107e534","custom_id":"6","response":{"status_code":200,"body":{"id":"7ed84ab380d54ad69f774b4149a26147","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2080,"completion_tokens":94,"total_tokens":2174},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"Silky Green Tea\",\n      \"price\": 12500,\n      \"classification\": \"Beverage\"\n    },\n    {\n      \"name\": \"Silky Hazelnut\",\n      \"price\": 12500,\n      \"classification\": \"Beverage\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"7-e6225030-c9d7-42a5-8834-eb655a0afdaa","custom_id":"7","response":{"status_code":200,"body":{"id":"28e76cc88e5249188ec4ecc1b63856fd","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2898,"completion_tokens":55,"total_tokens":2953},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"THAI ICED TEA\",\n      \"price\": 40.000,\n      \"classification\": \"Beverage\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"8-9614eb6b-cb35-4d86-aa2c-1432db6d7874","custom_id":"8","response":{"status_code":200,"body":{"id":"8b55ceb5bb554091a7b6d88083c9a49e","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2080,"completion_tokens":51,"total_tokens":2131},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"BBQ Chicken\",\n      \"price\": 41000,\n      \"classification\": \"Food\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}
{"id":"0-5565de65-a128-4828-bec1-5162f1b8c376","custom_id":"9","response":{"status_code":200,"body":{"id":"8096776b2d25495d9e226000f58f08fe","object":"chat.completion","model":"pixtral-large-latest","usage":{"prompt_tokens":2080,"completion_tokens":57,"total_tokens":2137},"created":1732400353,"choices":[{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"{\n  \"items\": [\n    {\n      \"name\": \"KOREAN CURRY M\",\n      \"price\": 40.909,\n      \"classification\": \"Food\"\n    }\n  ]\n}","tool_calls":null}}]}},"error":null}

Extract info to a Pandas dataframe

[ ]
[ ]
[ ]