Python Signature SDK Integration Guide

Function

The Python Signature SDK uses an AK/SK pair to generate the Authorization and X-Sdk-Date headers required by Meitu Open Platform APIs. It returns a requests.PreparedRequest that can be sent directly. The SDK signs the request; request fields and response structures are defined by the target API documentation.

Environment requirements

  • Python 3.6 or later
  • The requests library
  • HTTPS access to openapi.meitu.com

Download and import

Current version: AIGCP-API-python-sdk-1.0.3

Download Python SDK 1.0.3

Main files in the extracted archive:

AIGCP-API-python-sdk-1.0.3/
├── demo.py
└── sign_sdk/
    ├── __init__.py
    └── sign.py

Copy the entire sign_sdk directory into your project and install the dependency:

python3 -m pip install requests

Import the SDK with from sign_sdk import sign.

API reference

Create a signer

sign.Signer(access_key, secret_key)

ParameterTypeDescription
access_keystrOpen Platform AK
secret_keystrOpen Platform SK

Sign a request

signer.sign(url, method, headers, body)

ParameterTypeDescription
urlstrComplete request URL, including the path and query string
methodstrUppercase HTTP method, such as GET or POST
headersdictHeaders to sign; must contain a Host that matches the URL
bodystrFinal request body; pass an empty string "" when there is no body
Return valuerequests.PreparedRequestA request that can be sent directly with requests.Session.send()

If X-Sdk-Date is absent, the SDK adds the current UTC time. It also writes Authorization into the supplied headers dictionary.

Python SDK 1.0.1 and later support the X-Sdk-Content-Sha256: UNSIGNED-PAYLOAD header. When set, the literal value UNSIGNED-PAYLOAD is used in the canonical request's body-hash position, while the request body is still transmitted normally.

Complete POST example

The following example calls the production task-submission endpoint. The body contains five top-level fields: task, task_type, init_images, params, and sync_timeout. The params value must be a JSON string. Replace the task name, task type, image, algorithm parameters, and timeout with the values specified by the target API documentation.

import json

import requests
from sign_sdk import sign

ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
URL = "https://openapi.meitu.com/api/v1/sdk/sync/push"

params = {
    "parameter": {
        "rsp_media_type": "url",
    }
}
payload = {
    "task": "/v1/replace-with-product-task",
    "task_type": "formula",
    "init_images": [
        {
            "url": "https://example.com/input.jpg",
            "profile": {
                "media_profiles": {
                    "media_data_type": "url",
                },
                "version": "v1",
            },
        }
    ],
    "params": json.dumps(
        params,
        ensure_ascii=True,
        separators=(",", ":"),
    ),
    "sync_timeout": 30,
}
body = json.dumps(
    payload,
    ensure_ascii=True,
    separators=(",", ":"),
)
headers = {
    "Content-Type": "application/json",
    sign.HeaderHost: "openapi.meitu.com",
}

signer = sign.Signer(ACCESS_KEY, SECRET_KEY)
signed_request = signer.sign(URL, "POST", headers, body)

with requests.Session() as session:
    response = session.send(
        signed_request,
        timeout=(5, 30),
        verify=True,
    )
    response.raise_for_status()
    print(response.json())

GET example

The following example queries task status. Replace YOUR_TASK_ID with the task ID returned by the submission endpoint.

import requests
from sign_sdk import sign

ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
URL = (
    "https://openapi.meitu.com/api/v1/sdk/status"
    "?task_id=YOUR_TASK_ID"
)
headers = {
    sign.HeaderHost: "openapi.meitu.com",
}

signer = sign.Signer(ACCESS_KEY, SECRET_KEY)
signed_request = signer.sign(URL, "GET", headers, "")

with requests.Session() as session:
    response = session.send(
        signed_request,
        timeout=(5, 30),
        verify=True,
    )
    response.raise_for_status()
    print(response.json())

Notes

  • Host must match the host in the URL. For this platform, use openapi.meitu.com.
  • The HTTP method must be uppercase. Do not modify the URL, query string, signed headers, or body after signing.
  • params is a JSON string, not a JSON object. Serialize params first, then serialize the outer request body.
  • The body must be a string. Use the same string for signing and sending, and do not serialize it again after signing.
  • Create a new headers dictionary for every request. Do not reuse a dictionary into which the SDK has already written Authorization.
  • Keep the server clock synchronized and set connection and read timeouts.
  • Use HTTPS with certificate verification for production requests. Store the SK only on the server.

Common errors

SymptomResolution
401 or signature verification failureCheck the AK/SK, HTTP method, Host, URL, query string, headers, and body against the values used during signing.
The second request fails signature verificationDo not reuse the headers dictionary from the previous signed request. Create a new one each time.
AttributeError: ... encodeThe body is not a string. Serialize it with json.dumps() or pass "" when there is no body.
Request timestamp errorSynchronize the server clock and do not supply an expired or malformed X-Sdk-Date.
Request timeoutCheck network connectivity and API processing time, then adjust timeout for the use case.
TLS certificate errorCheck the domain, system time, and certificate chain, and keep verify=True.
HTTP succeeds but the API operation failsCheck the business status code and error message in the response JSON.