This skill wraps kujiale_upload.py — a self-contained Python script that
validates the complete Kujiale OpenAPI 3D model upload pipeline in exactly 5 steps.
The script uses Python requests / oss2 only, and explicitly disables
environment-derived proxy / certificate overrides ( trust_env=False) because
those settings can cause TLS handshake failures in some Windows environments:
StepMethodEndpointDescription1GET/v2/commodity/upload/stsObtain OSS STS credentials + uploadTaskId2PUTAlibaba OSS ( oss2)Upload ZIP bytes to OSS3POST/v2/commodity/upload/createTrigger server-side model parsing4GET/v2/commodity/upload/statusPoll parse status until status == 35POST/v2/commodity/upload/submitSubmit parsed model → returns brandGoodId
Authentication: md5(appSecret + appKey + timestamp_ms)
API Key: Apply at Manycore OpenAPI Console
bash
# 1. Install dependencies
pip install requests oss2
# 2. Copy the example env file and fill in YOUR credentials
cp .env.example .env
# Windows PowerShell:
# Copy-Item .env.example .env
# 3. Set env vars for the current shell session
export KUJIALE_APP_KEY=your_app_key_here
export KUJIALE_APP_SECRET=your_app_secret_here
# Windows PowerShell:
# $env:KUJIALE_APP_KEY="your_app_key_here"
# $env:KUJIALE_APP_SECRET="your_app_secret_here"
# 4. Run a safe local smoke test first
python kujiale_upload.py --dry-run
# 5. Run the real flow
python kujiale_upload.py
This skill is intended for users who already have:
appKey / appSecret — Apply at Manycore OpenAPI Console.zip package that matches Kujiale's 3D model import requirementsopenapi.kujiale.com and the OSS endpoint returned by Step 1This repository does not include:
kujiale_upload.pyThe auto-generated ZIP is only for API connectivity and workflow smoke testing.
You must supply your own Kujiale OpenAPI credentials. There are no built-in defaults.
MethodHow to setEnvironment variable (recommended)export KUJIALE_APP_KEY=xxx / export KUJIALE_APP_SECRET=xxxCLI flag--app-key xxx --app-secret xxxProgrammatic dictrun_skill({"app_key": "xxx", "app_secret": "xxx"})
Priority: explicit CLI/dict value > environment variable
If credentials are missing, you will see:
text
FAILED: Missing required credentials: app_key (env: KUJIALE_APP_KEY), app_secret (env: KUJIALE_APP_SECRET).
Set environment variables or pass via --app-key / --app-secret.
See .env.example for reference.
ParameterEnv var / dict keyDefaultDescriptionapp_key``KUJIALE_APP_KEY_(required)Kujiale OpenAPI appKeyapp_secret``KUJIALE_APP_SECRET(required)Kujiale OpenAPI appSecretzip_path—(auto-generated test ZIP)_Path to the ZIP file to uploadpoll_interval—5.0Seconds between status pollspoll_timeout—300.0Max seconds to wait for parse completiondry_run—FalseIf True, skip all network calls and return mock data
requests; OSS upload uses oss2trust_env=Falseopenapi.kujiale.com and the returned OSS endpoint. The script now reports this case explicitly and tells you to rerun with network permissions enabled.kujiale_upload.py currently submits with these sample defaults:
location = 1brandCats = ["3FO4K6E984C7"]These values are not universal. They appear to be business defaults from the original implementation and may be wrong for another tenant or another catalog tree. If your account requires different category metadata, update the script before using the real submit step.
bash
# Install dependencies
pip install requests oss2
# Run with credentials from environment variables (recommended)
python kujiale_upload.py
# Run with explicit credentials
python kujiale_upload.py \
--app-key YOUR_APP_KEY \
--app-secret YOUR_APP_SECRET
# Run with a specific ZIP file
python kujiale_upload.py \
--app-key YOUR_APP_KEY \
--app-secret YOUR_APP_SECRET \
--zip /path/to/your/model.zip
# Dry run — no network calls, no credentials needed
python kujiale_upload.py --dry-run
# Custom polling parameters
python kujiale_upload.py \
--app-key YOUR_APP_KEY \
--app-secret YOUR_APP_SECRET \
--poll-interval 3 \
--poll-timeout 120
Import and call run_skill(params) directly:
python
from kujiale_upload import run_skill
# Credentials from environment variables KUJIALE_APP_KEY / KUJIALE_APP_SECRET
summary = run_skill({})
print(summary)
# {
# "uploadTaskId": "...",
# "filePath": "...",
# "previewImg": "...",
# "brandGoodId": "..."
# }
# Or pass credentials explicitly
summary = run_skill({
"app_key": "YOUR_APP_KEY",
"app_secret": "YOUR_APP_SECRET",
})
# With a specific zip and overridden polling
summary = run_skill({
"app_key": "YOUR_APP_KEY",
"app_secret": "YOUR_APP_SECRET",
"zip_path": "/path/to/model.zip",
"poll_interval": 3.0,
"poll_timeout": 120.0,
})
# Dry run — no network calls, no credentials needed
mock = run_skill({"dry_run": True})
print(mock)
# {
# "uploadTaskId": "DRY_RUN_TASK_ID",
# "filePath": "dry_run/path/test_model_for_api_test.zip",
# "previewImg": "",
# "brandGoodId": "DRY_RUN_BRAND_GOOD_ID",
# "dry_run": True
# }
text
============================================================
Kujiale OpenAPI Full Flow
appKey=<your_key> zip=test_model_for_api_test.zip
============================================================
[INFO] Created test zip: test_model_for_api_test.zip
[Step 1] GET https://openapi.kujiale.com/v2/commodity/upload/sts file_name=test_model_for_api_test.zip
[Step 1] OK uploadTaskId=1234567890 filePath=kujiale-models/xxx/test_model_for_api_test.zip
[Step 2] OSS PUT endpoint=https://oss-cn-hangzhou.aliyuncs.com bucket=xxx key=... size=212
[Step 2] OK status=200 etag="..."
[Step 3] POST https://openapi.kujiale.com/v2/commodity/upload/create upload_task_id=1234567890
[Step 3] OK m=
[Step 4] Polling status for uploadTaskId=1234567890 (timeout=300.0s)
[Step 4] Attempt 1 status=1
[Step 4] Attempt 2 status=3
[Step 4] OK status=3 (zip parse success, ready to submit) previewImg=https://...
[Step 5] POST https://openapi.kujiale.com/v2/commodity/upload/submit name=test_model_for_api_test uploadTaskId=1234567890
[Step 5] OK brandGoodId=ABCxyz123 successFlag=True
============================================================
ALL STEPS PASSED
{
"uploadTaskId": "1234567890",
"filePath": "kujiale-models/xxx/test_model_for_api_test.zip",
"previewImg": "https://...",
"brandGoodId": "ABCxyz123"
}
============================================================
StatusMeaning0Generating1Parsing ZIP2ZIP parse failed → raises RuntimeError3ZIP parse success, ready to submit → proceed to Step 54Submit success5Submit task exception → raises RuntimeError
ErrorCauseFixFAILED: Missing required credentialsNo credentials configuredSet KUJIALE_APP_KEY / KUJIALE_APP_SECRET env vars, or pass via --app-key / --app-secret``Step 1 error: c=10001Invalid appKey/appSecretCheck credentials on Kujiale open platformFAILED: ZIP file not found: ...Invalid --zip pathPass an existing local .zip fileFAILED: ZIP file must end with .zip: ...Wrong file typePackage the model as .zip before uploadStep 4 poll timeout after 300sParse taking too longIncrease --poll-timeout``Step 4 FAILED: status=2Invalid ZIP formatEnsure ZIP contains valid model filesStep 1 request failed: ... / Step 5 request failed: ...Network/API connectivity or a local environment overrideCheck firewall, VPN, DNS, and whether your shell injects custom proxy / CA env varsoutbound network access appears to be blocked by the current runtime or sandboxThe tool is running in a restricted sandbox/agent sessionRe-run the same command with unrestricted network access, or allow the agent/tool to escalate network permissionsStep 2 OSS PUT failed: ...OSS connectivity or STS issueCheck returned OSS region/bucket and network reachability
text
requests>=2.20.0
oss2>=2.14.0
Install:
bash
pip install requests oss2
Before publishing externally, verify:
No real credentials in any tracked file — run: bash
grep -rn "app_key\|app_secret" . --include="*.py" --include="*.json" --include="*.md" | grep -v ".env.example" | grep -v "YOUR_APP"
Confirm only placeholder / env-var references remain.
.env is not committed (keep it local only)
.env.example is committed with placeholder values only
Add .env to .gitignore in the repo that vendors this skill
README / SKILL.md directs users to set KUJIALE_APP_KEY / KUJIALE_APP_SECRET
python kujiale_upload.py --dry-run succeeds on a clean machine
python kujiale_upload.py without credentials fails with a single-line FAILED: message, not a traceback
appKey (for traceability) but never logs appSecret or the computed sign.appSecret flows only through the in-memory _sign() function and is never serialised to disk or printed.appKey/ appSecret have been exposed, rotate them immediately on the Manycore OpenAPI Console.text
kujiale-3D-model-upload/
├── SKILL.md # This file
├── .env.example # Credential template — copy to .env and fill in your keys
└── kujiale_upload.py # Main script (CLI + run_skill entrypoint)