Automating Baota Panel API Deployments with Python: File Uploads, ZIP Extraction, and Site Start/Stop Control

This is an automated deployment approach for small to medium Linux servers managed by Baota Panel. Its core capabilities include API signature authentication, a unified request wrapper, file uploads, ZIP extraction, and website start/stop control. It solves the repetitive, error-prone nature of manual deployments across multiple sites. Keywords: Baota Panel API, automated deployment, Python.

Technical specifications are summarized below

Parameter Description
Language Python
Communication Protocol HTTP/HTTPS + POST
Deployment Target Websites managed by Baota Panel on Linux
Authentication Method request_time + request_token signature
Core Dependencies requests, hashlib, time, os, urllib.parse
Key Capabilities Upload files, extract archives, retrieve sites, stop/start websites
Typical Use Case Low- to medium-frequency, multi-site, lightweight automated releases
Source Context Technical practice summary adapted from a CNBlogs post

This approach fits lightweight release workflows without a full CI/CD pipeline

For servers that host only a few sites, a full delivery pipeline is often too heavy. Manual deployment, however, still involves multiple steps such as stopping the site, building artifacts, uploading files, extracting packages, and restarting services. Once updates become frequent, the chance of human error rises significantly.

The value of this approach is not that it replaces a DevOps platform. Instead, it uses Baota’s native API to quickly build a deployment script that is stable enough for real use. It is especially suitable for small to medium systems that include admin panels, mobile backends, and static sites.

Baota Panel must enable API access first

After logging in to Baota Panel, you can retrieve the API key under Settings / Panel Settings / API Interface and configure the IP allowlist. The allowlist forms the first security boundary, while the API key is used to generate the access signature.

apiconfig AI Visual Insight: The image shows the Baota Panel API configuration page, highlighting both the API key entry point and the IP allowlist configuration area. This indicates that API access depends not only on the key itself, but also on source IP restrictions. In practice, this makes it suitable to run the deployment script from a fixed, trusted release machine to reduce abuse risk if the key is ever exposed.

The signature mechanism is a prerequisite for every successful request

Baota API calls must include signature parameters. The rule is to concatenate the current timestamp with the MD5 hash of the API key, then apply MD5 again to generate request_token, while also sending request_time.

import time
import hashlib

def generate_sign(api_key: str) -> dict:
    now_time = int(time.time())  # Generate the current Unix timestamp in seconds
    api_key_md5 = hashlib.md5(api_key.encode()).hexdigest()  # Compute the MD5 hash of the API key
    token_str = str(now_time) + api_key_md5  # Concatenate the timestamp and key digest
    token = hashlib.md5(token_str.encode()).hexdigest()  # Generate the final request signature
    return {
        "request_token": token,
        "request_time": now_time
    }

This function dynamically generates the authentication parameters required by Baota for each API request.

A unified request wrapper significantly reduces business logic complexity

If every API call repeats signature assembly, exception handling, and response validation, the script quickly becomes bloated. A better approach is to encapsulate everything in a unified _post method so the business layer only needs to care about the endpoint and parameters.

import requests
from urllib.parse import urljoin

def post(panel_url: str, endpoint: str, api_key: str, data: dict | None = None, timeout: int = 20) -> dict:
    data = data or {}
    sign_params = generate_sign(api_key)  # Automatically append signature parameters
    payload = {**data, **sign_params}
    url = urljoin(panel_url, endpoint)

    response = requests.post(
        url,
        data=payload,
        timeout=timeout,
        verify=False  # Common in internal networks or self-signed setups; enable certificate validation in production whenever possible
    )
    response.raise_for_status()  # Raise immediately on HTTP-level errors
    result = response.json()

    if result.get("status") is False:
        raise Exception(f"Baota API error: {result.get('msg', 'Unknown error')}")
    return result

This wrapper standardizes signature injection, request dispatch, and error handling, making it the core infrastructure for all subsequent API calls.

File upload is the most specialized step in automated deployment

Most endpoints only send form fields, but the upload endpoint must also carry a binary file stream. In addition, the Baota upload API requires the target directory, file name, file size, and starting offset to be passed explicitly.

import os
import requests
from urllib.parse import urljoin

def upload_file(panel_url: str, api_key: str, local_path: str, remote_path: str, timeout: int = 60) -> bool:
    file_name = os.path.basename(local_path)
    file_size = os.path.getsize(local_path)
    remote_dir = os.path.dirname(remote_path)
    sign_data = generate_sign(api_key)  # Generate the signature before uploading

    data = {
        "f_path": remote_dir,
        "f_name": remote_path,
        "f_size": file_size,
        "f_start": 0,
        "request_token": sign_data["request_token"],
        "request_time": sign_data["request_time"]
    }

    with open(local_path, "rb") as fp:  # Read the local file in binary mode
        files = {
            "blob": (file_name, fp, "application/octet-stream")
        }
        response = requests.post(
            urljoin(panel_url, "/files?action=upload"),
            data=data,
            files=files,
            timeout=timeout,
            verify=False
        )

    response.raise_for_status()
    result = response.json()
    return result.get("status") is not False

This function uploads local build artifacts to the target path on the Baota-managed server.

Archive extraction and temporary package cleanup are critical for static asset releases

When frontend build artifacts contain many files, compressing them before upload is usually faster than transferring files one by one. After the upload succeeds, call the extraction endpoint to unpack the ZIP into the site directory, then delete the temporary archive to keep the server directory clean.

def deploy_zip(api, remote_zip: str, web_site_path: str) -> None:
    unzip_result = api._post("/files?action=UnZip", {
        "sfile": remote_zip,      # ZIP path on the server
        "dfile": web_site_path,   # Target extraction directory
        "encoding": "utf-8"
    })

    if unzip_result.get("status"):
        api._post("/files?action=DeleteFile", {
            "path": remote_zip     # Delete the temporary ZIP after extraction
        })

This function handles both archive extraction and temporary file cleanup, making it ideal for static site updates.

Website stop/start control makes backend replacement safer

If a backend service does not support hot updates, directly overwriting files can cause runtime issues for users. A safer approach is to retrieve the site list, locate the site_id and site_name, then stop the site, perform the update, and start it again.

def restart_site(api, site_id: int, site_name: str) -> None:
    api._post("/site?action=SiteStop", {
        "id": site_id,
        "name": site_name  # Stop the site first to avoid serving a partially updated state during deployment
    })

    api._post("/site?action=SiteStart", {
        "id": site_id,
        "name": site_name  # Start the site again after deployment completes
    })

This function controls site stop/start operations and is well suited for overwrite-based backend deployments.

A reusable list of core endpoints shortens integration time

In real deployments, the following endpoints cover most lightweight release workflows. Test connectivity, upload files, extract archives, delete temporary packages, query the website list, stop a site, and start a site. Combined, they form a complete deployment chain.

Function Endpoint Method
Test connectivity /system?action=GetNetWork POST
Upload file /files?action=upload POST
Extract archive /files?action=UnZip POST
Delete file /files?action=DeleteFile POST
Get website list /data?action=getData POST
Stop website /site?action=SiteStop POST
Start website /site?action=SiteStart POST

Security and rollback must be part of the implementation

Automated deployment reduces repetitive work, but it does not remove operational responsibility. At a minimum, add three capabilities: pre-deployment backup, failure interruption, and a rollback entry point. This is especially important for overwrite-based backend uploads. Without versioned directories or backup copies, recovery can become expensive.

At the same time, verify=False should only be used in controlled environments. If the script needs to call the panel across the public internet, enable HTTPS, restrict the allowlist, rotate keys regularly, and never hardcode the API key in a repository.

FAQ

1. What kinds of projects are best suited for Baota API automated deployment?

It works best for projects with a limited number of sites, moderate release frequency, and no immediate need for a full CI/CD platform. It is especially useful for admin systems, mobile APIs, and static frontend sites maintained by small to medium teams.

2. Why should you build a unified request wrapper before writing deployment logic?

Because every endpoint depends on the same signature generation, timeout settings, exception handling, and response validation. Once unified, operations such as upload, extraction, site stop, and site start can all reuse the same calling convention, which lowers maintenance cost.

3. What is the biggest risk in this approach?

The main risks are security and rollback. API key leakage, an overly broad allowlist, disabled certificate validation, and missing backups after a failed deployment can turn an efficiency tool into a failure amplifier.

Core Summary: This article restructures an automated deployment approach built on the Baota Panel API, focusing on signature generation, a unified request wrapper, file upload and extraction, and website stop/start control. It is well suited for small to medium multi-site servers that want to replace manual releases with scripts, reduce deployment errors, and improve delivery efficiency.