Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

SHOP Server REST API endpoints

iLab Assistant

This document describes the REST API endpoints that are exposed when shop_server_host has been set up as a service on a remote machine. HTTP requests can be made to these endpoint to run SHOP models and retrieve the results using the SHOP JSON data format. For testing purposes on local machines, starting the shop_server_host application in one terminal and sending requests with a small python script using the requests module from another terminal should work:

import requests

# Check that SHOP Server is running by using the GET method on the general path '/'
response = requests.get("http://127.0.0.1:8000/", json={})

# Should get "OK" back, see general endpoint section below
print(response.text)

Initial configuration

It is possible to specify a number of command line arguments when starting the SHOP Server application:

OptionValue typeDefaultDescription
-l, --listenstring0.0.0.0Bind network address
-p, --portint8000Listening port
-m, --max-sessionsintCPU_threads * 4Max concurrent sessions
-t, --logging-endpoint-timeoutint3Timeout in seconds for logging endpoint
--shop-log-filestring(empty)Output file path for SHOP logs
--solver-log-filestring(empty)Output file path for CPLEX logs
--minimal-infeasible-problem-filestring(empty)Output file path for minimal infeasible problem data
--silent-shop-consoleboolfalseSilence logging of SHOP messages to stdout on the server side

Example usage:

./shop_server --listen 127.0.0.1 --port 9000

Note that setting the --max-sessions flag can be important when running many SHOP optimizations in parallel. Remember to carefully select how many threads CPLEX can use in each parallel optimization with the max_num_threads SHOP attribute so that it matches with the available hardware resources. The total number of parallel runs multiplied with max_num_threads should not be larger than the total number of threads on the system, otherwise CPLEX from one session will fight to use the same threads as CPLEX in another. This will be detrimental to calculation times.

Specifying the SHOP and CPLEX log file paths is possible, but the SHOP log messages can also be sent to a specified logging endpoint. When models are infeasible, CPLEX will dump a minimal infeasible problem to the path pointed to by minimal_infeasible_problem_file. This attribute can also be specified in the --minimal-infeasible-problem-file option to SHOP Server.

General

SHOP Server implements the following general endpoints for testing purposes:

MethodPathDescriptionRequest BodyHeadersResponse (200)
GET/Health check to confirm SHOP server is running(none)(none)OK\r\n\r\n (type is text/plain)

Session

SHOP Server has built in support for running several parallel SHOP optimization sessions. A session is required to hold the SHOP model itself.

MethodPathDescriptionRequest BodyHeadersResponse (200)Notes
GET/sessionGet information about the current session(none)session_idSessionSchemaReturns 4xx/5xx if session not found
POST/sessionCreate a new sessionSessionSchema (without session_id)(none)SessionSchema (with session_id)429 if too many sessions
POST/session/cancelCancel the current session by aborting CPLEX and any further SHOP commands(none)session_id(empty body)4xx/5xx if session not found
DELETE/sessionDelete a session(none)session_id(empty body)422 if session_id missing/invalid
GET/sessionsList all existing sessions(none)(none)Array of SessionSchema

SessionSchema:

FieldTypeDescription
session_idintAssigned by the server when a session is created
session_namestringUser-defined session name

Example:

{
  "session_id": 1,
  "session_name": "day-ahead bidding 1"
}

Model

After a session has been created, a SHOP model can be created and solved in that session.

MethodPathDescriptionRequest BodyHeadersQuery ParamsResponse (200)Notes
PUT/modelUpload a full model to the session and apply itModelSchemasession_idreturn_model (bool, default true)Resulting ModelSchema filtered by including input and output objects and attributes. Nothing is returned if return_model is falseThe input ModelSchema does not need to contain all data, multiple requests can be made to build up the model
GET/modelFetch model data, optionally filtered(none)session_idobjectType, objectName, attributeName, datatype, isInput, isOutput, includeTime, includeConnections, compressTxyModelSchema filtered by query paramsAll query params are optional filters, the first four are strings and the remaining are booleans
GET/model/:object_type/informationGet information about a specific object type(none)session_idverbose (bool, default false)ObjectTypeInfoSchemaThe verbose = true filter will include all attribute information, similar to the /model/information path
GET/model/informationGet information about all possible attributes and object types(none)session_id(none)ModelInfoSchemaThe same information that is provided in the attribute table on the SHOP Portal
GET/model/commandsGet information about all available commands(none)session_id(none)CommandInfoSchemaThe same information that is provided in the command table on the SHOP Portal

The ModelSchema mentioned in the model endpoints should be on the SHOP JSON data format. The format has four root nodes (“time”, “model”, “connections”, and “commands”), but not all nodes must be present for a valid POST request if the user wants to build the model in stages. Setting the static topology data with connections first, then setting time resolution and time series data, and finally running commands is therefore a valid option.

ObjectTypeInfoSchema:

FieldTypeDescription
object_typestringThe object type in question
instancesArray of stringsThe object names of all instances of the object_type in the current model
attributesAttributesSchemaA map where all existing attribute names for object_type are the keys and AttributeInfoSchema are the values

If verbose = false, the resulting AttributeInfoSchema is a single string which is the datatype of the attribute. When verbose = true, the AttributeInfoSchema becomes:

FieldTypeDescription
attribute_namestringThe attribute name
legacy_datatypestringThe datatype of the attribute
is_inputboolTrue if the attribute can be given as input
is_outputboolTrue if the attribute is an output attribute
x_unitstringThe unit of the x coordinate
y_unitstringThe unit of the y coordinate
license_namestringThe name of the license required to get or set the attribute
full_namestringUnused
data_func_namestringAttribute name alias
descriptionstringA description of the attribute
documentation_urlstringReserved for future use
example_url_prefixstringReserved for future use
examplestringReserved for future use
default_valuestringString representation of the default attribute value
requiredboolIs true for attributes marked as required SHOP input

Example of ObjectTypeInfoSchema with verbose = false:

{
    "object_type": "reservoir",
    "instances": [
        "Rsv_1",
        "Rsv_2"
    ],
    "attributes": {
        "max_vol": "double",
        "lrl": "double",
        "hrl": "double",
        /* Remaining reservoir attributes... */
    }
}

Example of ObjectTypeInfoSchema with verbose = true:

{
    "object_type": "reservoir",
    "instances": [
        "Rsv_1",
        "Rsv_2"
    ],
    "attributes": {
        "max_vol": {
            "attribute_name": "max_vol",
            "legacy_datatype": "double",
            "is_input": true,
            "is_output": false,
            "x_unit": "MM3",
            "y_unit": "MM3",
            "license_name": "SHOP_OPEN",
            "full_name": "Max volume",
            "data_func_name": "",
            "description": "Maximum volume of the reservoir",
            "documentation_url": "https://docs.shop.sintef.energy/attribute-table.html",
            "example_url_prefix": "https://docs.shop.sintef.energy",
            "example": "",
            "default_value": "0.0",
            "required": false
        },
        /* Remaining reservoir attributes... */
    }
}

The ModelInfoSchema is a map where the object type names of all possible objects in SHOP are keys, and attribute maps are the values. Each attribute map has all possible attribute names for the object type as keys, and verbose AttributesSchemas as values. Unlike the ObjectTypeInfoSchema, instances of the object types are not reported.

The CommandInfoSchema contains all SHOP commands. The available information for each command is the possible command options, a description of possible values, the required license name, the SHOP version the command was added, and a more detailed description. An excerpt is shown below:

{
    "set simtimestep": {
        "options": [],
        "value_description": "double",
        "license_name": "SHOP_SIMULATION",
        "version_added": "16.5.0",
        "description": "Set the length of the internal time steps of the SHOP simulator in seconds (default is 20 sec). (...)"
    },
    "set universal_strict_pq_uploading": {
        "options": [
            "on",
            "off",
            "not_set"
        ],
        "value_description": "",
        "license_name": "SHOP_OPEN",
        "version_added": "16.5.0",
        "description": "Turn on or off the building on strict PQ curve uploading for all generators in all hours. (...)"
    },
        /* Remaining commands... */
}

Logging

It is possible to specify a logging endpoint in SHOP Server to catch the SHOP log messages.

MethodPathDescriptionRequest BodyHeadersResponse (200)Notes
POST/logging/endpointRegister a logging endpoint for this sessionLogEndpointSchemasession_id(empty body)Subsequent logs will be sent as LogMessageSchema to the registered endpoint

LogEndpointSchema:

FieldTypeDescription
endpointstringURL to which the session will send log messages

Example:

{
  "endpoint": "https://my_logging_endpoint.shop.com"
}

LogMessageSchema:

FieldTypeDescription
messagestringLog message text from SHOP
levelstringLog level, either "INFO","WARNING", or "ERROR"
calleridstringThe session_name of the session sending the log message

Example:

{
  "message": "Head optimization on.\n",
  "level": "INFO",
  "callerid": "my_session_1"
}

Time resolution

The time resolution can be retrieved with a request to the dedicated “/time_resolution” endpoint.

MethodPathDescriptionRequest BodyHeadersResponse (200)
GET/time_resolutionRetrieve the time resolution data from the current session(none)session_idTimeResolutionSchema

The TimeResolutionSchema is the same as described in the SHOP JSON data standard documentation under “Time”.

Utility commands

Some additional commands have been implemented under the /internal endpoint:

MethodPathDescriptionRequest BodyHeadersResponse (200)Notes
POST/internal/GetLicenseInfoGet information about the license file(none)session_idArray of stringsThe strings in the response array are of the form “SHOP_TUNNEL:Unlimited access”
POST/internal/DumpYamlStringDump the model to YAML formatUtilityCommandSchema: three boolssession_idstringThe entire model is returned as a single string on YAML format. The three parameters describe: if only input data should be included, if the timeseries’ should be compressed, if the connections should be compressed
POST/internal/SaveStateSave the model to a binary format using the Online SHOP functionalityUtilityCommandSchema: one boolsession_idstringThe entire model is serialized to bytes and returned as a hex encoded string. The boolean input argument specifies if only a partial serialization should be performed
POST/internal/LoadStateLoad a previously saved model using the Online SHOP functionalityUtilityCommandSchema: string and boolsession_idstringThe input string must originate from an earlier call to SaveState, and the boolean (partial or full serialization) must match the boolean of the SaveState call

The UtilityCommandSchema is generic:

FieldTypeDescription
argsArray of int, double, bool, and string valuesSee the endpoint description above for the valid arguments in each utility endpoint

Example:

{
  "args": [
        true,      
        true,
        false
  ]
}