#!/usr/bin/env python3.7# Copyright 2025, Gurobi Optimization, LLC# This example reads a MIP model from a file, solves it in batch mode,# and prints the JSON solution string.## You will need a Compute Server license for this example to work.importsysimporttimeimportjsonimportgurobipyasgpfromgurobipyimportGRB# Set up the environment for batch mode optimization.## The function creates an empty environment, sets all necessary parameters,# and returns the ready-to-be-started Env object to caller. It is the# caller's responsibility to dispose of this environment when it's no# longer needed.defsetupbatchenv():env=gp.Env(empty=True)env.setParam('LogFile','batchmode.log')env.setParam('CSManager','http://localhost:61080')env.setParam('UserName','gurobi')env.setParam('ServerPassword','pass')env.setParam('CSBatchMode',1)# No network communication happened up to this point. This will happen# once the caller invokes the start() method of the returned Env object.returnenv# Print batch job error information, if anydefprintbatcherrorinfo(batch):ifbatchisNoneorbatch.BatchErrorCode==0:returnprint("Batch ID {}: Error code {} ({})".format(batch.BatchID,batch.BatchErrorCode,batch.BatchErrorMessage))# Create a batch request for given problem filedefnewbatchrequest(filename):# Start environment, create Model object from file## By using the context handlers for env and model, it is ensured that# model.dispose() and env.dispose() are called automaticallywithsetupbatchenv().start()asenv,gp.read(filename,env=env)asmodel:# Set some parametersmodel.Params.MIPGap=0.01model.Params.JSONSolDetail=1# Define tags for some variables in order to access their values laterforcount,vinenumerate(model.getVars()):v.VTag="Variable{}".format(count)ifcount>=10:break# Submit batch requestbatchID=model.optimizeBatch()returnbatchID# Wait for the final status of the batch.# Initially the status of a batch is "submitted"; the status will change# once the batch has been processed (by a compute server).defwaitforfinalstatus(batchID):# Wait no longer than one hourmaxwaittime=3600# Setup and start environment, create local Batch handle objectwithsetupbatchenv().start()asenv,gp.Batch(batchID,env)asbatch:starttime=time.time()whilebatch.BatchStatus==GRB.BATCH_SUBMITTED:# Abort this batch if it is taking too longcurtime=time.time()ifcurtime-starttime>maxwaittime:batch.abort()break# Wait for two secondstime.sleep(2)# Update the resident attribute cache of the Batch object with the# latest values from the cluster manager.batch.update()# If the batch failed, we retry itifbatch.BatchStatus==GRB.BATCH_FAILED:batch.retry()# Print information about error status of the job that processed the batchprintbatcherrorinfo(batch)defprintfinalreport(batchID):# Setup and start environment, create local Batch handle objectwithsetupbatchenv().start()asenv,gp.Batch(batchID,env)asbatch:ifbatch.BatchStatus==GRB.BATCH_CREATED:print("Batch status is 'CREATED'")elifbatch.BatchStatus==GRB.BATCH_SUBMITTED:print("Batch is 'SUBMITTED")elifbatch.BatchStatus==GRB.BATCH_ABORTED:print("Batch is 'ABORTED'")elifbatch.BatchStatus==GRB.BATCH_FAILED:print("Batch is 'FAILED'")elifbatch.BatchStatus==GRB.BATCH_COMPLETED:print("Batch is 'COMPLETED'")print("JSON solution:")# Get JSON solution as string, create dict from itsol=json.loads(batch.getJSONSolution())# Pretty printing the general solution informationprint(json.dumps(sol["SolutionInfo"],indent=4))# Write the full JSON solution string to a filebatch.writeJSONSolution('batch-sol.json.gz')else:# Should not happenprint("Batch has unknown BatchStatus")printbatcherrorinfo(batch)# Instruct the cluster manager to discard all data relating to this BatchIDdefbatchdiscard(batchID):# Setup and start environment, create local Batch handle objectwithsetupbatchenv().start()asenv,gp.Batch(batchID,env)asbatch:# Remove batch request from managerbatch.discard()# Solve a given model using batch optimizationif__name__=='__main__':# Ensure we have an input fileiflen(sys.argv)<2:print("Usage: {} filename".format(sys.argv[0]))sys.exit(0)# Submit new batch requestbatchID=newbatchrequest(sys.argv[1])# Wait for final statuswaitforfinalstatus(batchID)# Report final status infoprintfinalreport(batchID)# Remove batch request from managerbatchdiscard(batchID)print('Batch optimization OK')