Agent-native job state management API service for async APIs.
Define your request/response payload models and create the Flask app:
from sandjig import create_app
from sandjig.models import RequestPostPayloadBaseModel, ResponsePostPayloadBaseModel
class MyRequestPostPayload(RequestPostPayloadBaseModel):
examplevalue: str
class MyResponsePostPayload(ResponsePostPayloadBaseModel):
result_value: int
app = create_app(MyRequestPostPayload, MyResponsePostPayload, config={})from sandjig import create_app
from sandjig.models import RequestPostPayloadBaseModel, ResponsePostPayloadBaseModel, SettingsBaseModel
class MyRequestPostPayload(RequestPostPayloadBaseModel):
examplevalue: str
class MyResponsePostPayload(ResponsePostPayloadBaseModel):
result_value: int
class MySettings(SettingsBaseModel):
adjust: float = 0.5
app = create_app(MyRequestPostPayload, MyResponsePostPayload, MySettings, config={})export AWS_PROFILE={profile}
export AWS_DEFAULT_REGION={region}
export BASIC_AUTH_USERNAME={username}
export BASIC_AUTH_PASSWORD={password}
sandjig deploy -s {SUFFIX} -n {APP_PYTHON_FILE} --stage {stg|dev|prd}If
ENDPOINT_PREFIXis set in config, it prepends/jobsand/settingsendpoints. Example:ENDPOINT_PREFIX="/api"produces/api/jobs.
POST /jobs- Submit a new jobGET /jobs- List jobs (paginated)GET /jobs/{JOB_ID}- Get job statusPATCH /jobs/{JOB_ID}- Update job status
| Parameter | Description |
|---|---|
limit |
Items per page (50-500, default 250) |
job_id |
Comma-separated UUIDs to filter (max 175) |
status |
Filter by status (pending, queued, validating, processing, completed, error, cancelled) |
registered_datetime_gte |
ISO-8601 datetime lower bound |
registered_datetime_lte |
ISO-8601 datetime upper bound |
Only available when a SettingsBaseModel subclass is passed to create_app().
GET /settingsPATCH /settings
GET /openapi- Swagger UIGET /openapi/schema- OpenAPI YAML specGET /healthcheck- 200 OK health check
{
"job_id": "{JOB_ID}",
"registered_datetime": "2026-04-16T14:53:18+09:00",
"updated_datetime": "2026-04-16T14:53:20+09:00",
"completed_datetime": null,
"status": "pending",
"result_count": 0,
"settings": null,
"request_payload": {
"examplevalue": "my example"
},
"response_payload": null
}| Field | Description |
|---|---|
API_TITLE |
Display title for OpenAPI UI |
API_VERSION |
OpenAPI displayed version |
BASIC_AUTH_FORCE |
When True, basic auth is required. BASIC_AUTH_USERNAME and BASIC_AUTH_PASSWORD env vars must be set. |
BASIC_AUTH_USERNAME |
Username for basic auth (when BASIC_AUTH_FORCE=True) |
BASIC_AUTH_PASSWORD |
Password for basic auth (when BASIC_AUTH_FORCE=True) |
SQS_QUEUE_URL |
If set, job requests are sent as messages to this SQS queue |
ENDPOINT_PREFIX |
Prefix for /jobs endpoints (must start with /) |
JOBREQUEST_CALLBACK_FUNCTION |
Callable invoked on successful job request with job_id argument |
JSON_AS_ASCII |
If True, JSON dumped as ASCII (default False) |
sandjig deploy [-h] [-b BUCKET] [--stage STAGE] -n APPNAME
sandjig update [-h] [-b BUCKET] [--stage STAGE] -n APPNAME
sandjig destroy [-h]
sandjig package [-h] [--stage STAGE] -n APPNAME -o OUTPUT_DIRECTORY
sandjig template [-h] [-o OUTPUT]Python: 3.14
Requires uv for dependency management
-
Install
pre-commithooks:pre-commit install
-
Install project and development dependencies:
uv sync
uv run poe checkuv run poe typecheckRequires localstack (docker-compose):
docker compose up -d
uv run poe testRequired for local development (.env):
AWS_ACCOUNT_ID=dummyid
S3_SERVICE_ENDPOINT=http://localhost:4566
SQS_SERVICE_ENDPOINT=http://localhost:4566
STS_SERVICE_ENDPOINT=http://localhost:4566
DYNAMODB_SERVICE_ENDPOINT=http://localhost:4566