Payload Builder
Turns the aggregated result of a generation into three payloads: the MongoDB record, the files for Storage and the response returned to the client.
On this page
Source: src/image_generation/utils/payload_builder.py. This page's original notebook was empty; the content was written from the code.
#Overview
The PayloadBuilder class takes the job_id and the dictionary produced by parse_responses (see Image Generator Service). Missing keys have a default value: text_input and text_responses become empty and generate_config uses DEFAULT_CONTENT_CONFIG.
#generate_payloads
Returns the tuple (mongo_payload, storage_payload, response_payload).
| Payload | Destination | Content |
|---|---|---|
mongo_payload | MongoDB | jobId, user_input, text_response, image_response, generate_config and cost_information. It does not include the image bytes. |
storage_payload | Supabase Storage | List with id, url, mime_type and byte of each image. |
response_payload | API client | text_response and images (list of URLs). |
#Images
For each image with mime_type and data, the builder generates an id with IDGenerator.timestamp(prefix=ID_PREFIX) and builds the URL as BASE_URL/<id>. Images without mime_type or without data are skipped. The text_response field uses only the first text of text_responses, or None if the list is empty.
#Cost
cost_information comes from CostCalculator (see Cost Calculator). With a single entry in usage_metadata, it is used directly; with several, they are summed by merge_cost_information; with none, the tokens are 0. The number of images comes from number_of_images in the configuration. The result is cached for the lifetime of the object.
#Usage example
from src.image_generation.utils.payload_builder import PayloadBuilder
from src.utils.unique_id_factory import IDGenerator
# Aggregated result of ImageGeneratorService.parse_responses
parsed = {
"text_responses": ["Aqui está a imagem."],
"images": [{"mime_type": "image/png", "data": b"..."}],
"generate_config": {"model": "gemini-2.5-flash-image", "number_of_images": 1},
"usage_metadata": [{"prompt_tokens": 587, "output_tokens": 1320, "total_tokens": 1907}],
}
builder = PayloadBuilder(IDGenerator.timestamp(prefix="job_"), parsed)
mongo_payload, storage_payload, response_payload = builder.generate_payloads()
print(response_payload["images"])#Notes
URL and file name. The URL uses the id without an extension, and save_to_supabase also uploads the file with the id as its name. The ext variable is computed in the builder, but does not go into the URL.
The file ends with an if __name__ == "__main__" block with sample data, runnable with python -m src.image_generation.utils.payload_builder.
Source: src/image_generation/utils/payload_builder.py