Reference: Handle HTTP Requests
This page offers a quick reference for handling HTTP requests in service assets. If you have not done this before, then follow the "Handle HTTP Requests" guide first.
Declare the capability to handle HTTP requests
Services must declare that they can handle HTTP requests before the Intrinsic Platform will route requests to them.
Declare that your service can handle HTTP requests by adding http_config: {} to the service_def section of your service's manifest.
service_def {
# ...
http_config: {}
}
Translate HTTP requests to gRPC requests
Intrinsic recommends you handle HTTP requests by building a gRPC service, and then translating HTTP requests to gRPC.
Annotate your gRPC service
Import google/api/annotations.proto and add google.api.http options to your RPC methods.
import "google/api/annotations.proto";
service AdditionService {
rpc AddTwoInts(AddTwoIntsRequest) returns (AddTwoIntsResponse) {
option (google.api.http) = {
post: "/v0/addition:add"
body: "*"
};
}
}
Add @com_google_googleapis//google/api:annotations_proto to your proto_library dependencies in BUILD.
Design Guidelines
Follow Resource-oriented design principles:
- URL Format:
/<version>/<resource>/<method>(e.g.,/v1/cameras,/v1/cameras:capture). - Version: Always include a version (e.g.,
v1, orv0for unversioned). - Resource: Use plural nouns for resources (e.g.,
cameras). UsecamelCasefor multi-word collections. - Method: Use standard verbs (
Get,List,Create,Update,Delete) or custom verbs (using:verb). UsecamelCasefor multi-word verbs.
Parameter Mapping
- Path Parameters: Wrap field names in curly braces (e.g.,
/v1/cameras/{name}). - Body Parameters: Use
body: "*"to map the entire JSON body to the request, orbody: "field"for a specific field (supported byPOST,PUT,PATCH). - Query Parameters: Fields not bound to the path or body automatically become URL query parameters (nested fields flatten to dot-notation).
Use intrinsic_http_image
Use the intrinsic_http_image Bazel macro to create an image that translates HTTP to gRPC.
load("@ai_intrinsic_sdks//intrinsic/httpjson:intrinsic_http_image.bzl", "intrinsic_http_image")
intrinsic_http_image(
name = "my_backend_service_http_image",
go_proto = ":my_backend_service_go_proto", # Requires go_proto_library
grpc_service = "com.example.my_backend_service.AdditionService",
proto = ":my_backend_service_proto",
)
Add the image to your intrinsic_service images list and service manifest.
BUILD:
intrinsic_service(
name = "my_backend_service_service",
images = [":my_backend_service_http_image.tar"],
)
Manifest (.textproto):
real_spec {
extra_images { archive_filename: "my_backend_service_http_image.tar" }
}
sim_spec {
extra_images { archive_filename: "my_backend_service_http_image.tar" }
}
Handle HTTP requests manually
While Intrinsic recommends you translate HTTP requests to gRPC requests, you may handle them manually without using gRPC.
Services must listen for HTTP requests on the port assigned by the Intrinsic Platform.
Get this port from the RuntimeContext.
- Python
- C++
from intrinsic.resources.proto import runtime_context_pb2
# ...
# Read the RuntimeContext
with open('/etc/intrinsic/runtime_config.pb', 'rb') as fin:
context = runtime_context_pb2.RuntimeContext.FromString(fin.read())
# Begin listening for HTTP requests
start_your_http_server(address="0.0.0.0", port=context.http_port)
#include <string>
#include "intrinsic/resources/proto/runtime_context.pb.h"
// ...
// Read the RuntimeContext
constexpr std::string_view kContextFilePath = "/etc/intrinsic/runtime_config.pb";
auto context_result = intrinsic::GetBinaryProto<intrinsic_proto::config::RuntimeContext>(std::string(kContextFilePath));
if (!context_result.ok()) {
std::cerr << "[FATAL] Reading runtime context failed." << std::endl;
return 1;
}
const auto& context = *context_result;
// Begin listening for HTTP requests
std::string address{"0.0.0.0"};
int32_t port = context.GetHttpPort();
StartYourHTTPServer(address, port);
Access your HTTP endpoints
If your service asset is running on a physical workcell, send HTTP requests to your endpoints at this base URL:
http://intrinsic.local/ext/services/$SERVICE_INSTANCE_NAME/
If Intrinsic has configured your organization to allow HTTP requests via the cloud, then:
-
Request a token using
inctlTOKEN=inctl auth print-access-token --org $INTRINSIC_ORGANIZATION -
Send requests to your service at this base URL:
https://flowstate.intrinsic.ai/web-proxy-onprem/$PROJECT/$CLUSTER/ext/services/$SERVICE_INSTANCE_NAME/Include the HTTP header
auth-proxy=$TOKENin the request.
Where above:
$PROJECT: the name of your project. If your organization isuser@my-project, usemy-project.$CLUSTER: means the name of your cluster (ex:vmp-123-abcdefgh).$SERVICE_INSTANCE_NAME: means the name of an instance of your service asset running in your Solution.