Sweety / API_DOCS.md
mythaitts's picture
Upload 5 files
e735481 verified

Sweety.dev API Documentation

Base URL: https://your-space.hf.space

Storage: /data (HF Spaces persistent storage)


Build APIs

POST /api/build

Create a new build for a React project.

Request Body:

{
  "user_id": "user123",
  "project_id": "proj456",  // optional, auto-generated if omitted
  "files": {
    "src/App.jsx": "export default function App() { return <div>Hello</div> }",
    "src/components/Button.jsx": "export const Button = () => <button>Click</button>",
    "public/logo.png": "base64_encoded_image"
  },
  "dependencies": {
    "lucide-react": "^0.300",
    "framer-motion": "^10.0"
  },
  "framework": "react"
}

Response:

{
  "project_id": "proj456",
  "user_id": "user123",
  "status": "pending"
}

Build Status Values:

  • pending - Build queued
  • installing - npm install running
  • building - vite build running
  • success - Build complete, preview ready
  • failed - Build failed (check error field)

GET /api/status/{user_id}/{project_id}

Check build status.

Response:

{
  "project_id": "proj456",
  "user_id": "user123",
  "status": "success",
  "url": "/preview/user123/proj456/",
  "error": null
}

DELETE /api/build/{user_id}/{project_id}

Delete a build and its artifacts.

Response:

{
  "deleted": true
}

File Management APIs

POST /api/file

Create or upload a file to user storage.

Request Body:

{
  "user_id": "user123",
  "project_id": "proj456",
  "filename": "src/components/Header.jsx",
  "content": "export const Header = () => <header>Header</header>"
}

Response:

{
  "created": true,
  "path": "/data/users/user123/files/src/components/Header.jsx"
}

GET /api/file/{user_id}/{filename:path}

Read a file from user storage.

Response:

{
  "content": "export const Header = () => <header>Header</header>"
}

PUT /api/file

Update an existing file.

Request Body:

{
  "user_id": "user123",
  "project_id": "proj456",
  "filename": "src/components/Header.jsx",
  "content": "export const Header = () => <header>New Header</header>"
}

Response:

{
  "updated": true
}

DELETE /api/file/{user_id}/{filename:path}

Delete a file.

Response:

{
  "deleted": true
}

GET /api/files/{user_id}

List all files for a user.

Response:

[
  {
    "filename": "src/App.jsx",
    "size": 1234
  },
  {
    "filename": "src/components/Header.jsx",
    "size": 567
  }
]

Project Management APIs

GET /api/projects/{user_id}

List all projects for a user.

Response:

[
  {
    "project_id": "proj456",
    "files": ["src/App.jsx", "src/components/Button.jsx"],
    "dependencies": {"lucide-react": "^0.300"},
    "created_at": "123456.789"
  },
  {
    "project_id": "proj789",
    "files": ["src/App.jsx"],
    "dependencies": {},
    "created_at": "123457.890"
  }
]

Preview

GET /preview/{user_id}/{project_id}/{path:path}

Serve built static files.

Examples:

  • /preview/user123/proj456/ - Main index.html
  • /preview/user123/proj456/assets/index.abc123.js - JavaScript bundle
  • /preview/user123/proj456/assets/index.def456.css - CSS

Note: SPA routing automatically falls back to index.html for non-existent paths.


Storage Structure

/data/
β”œβ”€β”€ users/
β”‚   └── {user_id}/
β”‚       β”œβ”€β”€ files/              # User file storage
β”‚       β”‚   β”œβ”€β”€ src/
β”‚       β”‚   β”‚   β”œβ”€β”€ App.jsx
β”‚       β”‚   β”‚   └── components/
β”‚       β”‚   β”‚       └── Header.jsx
β”‚       β”‚   └── public/
β”‚       β”‚       └── logo.png
β”‚       └── projects/           # Project metadata
β”‚           β”œβ”€β”€ proj456.json
β”‚           └── proj789.json
└── builds/
    └── {user_id}/
        └── {project_id}/       # React build artifacts
            β”œβ”€β”€ src/
            β”œβ”€β”€ package.json
            β”œβ”€β”€ vite.config.js
            β”œβ”€β”€ index.html
            └── dist/           # Built static files
                β”œβ”€β”€ index.html
                └── assets/

Example Usage

1. Create a Build

const response = await fetch('/api/build', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_id: 'user123',
    files: {
      'src/App.jsx': `export default function App() {
        return (
          <div className="p-8">
            <h1>Hello Sweety!</h1>
          </div>
        )
      }`,
      'src/components/Button.jsx': `export const Button = () => <button>Click</button>`
    },
    dependencies: {
      'lucide-react': '^0.300'
    }
  })
});

const { project_id, user_id, status } = await response.json();

2. Poll Build Status

const checkStatus = async () => {
  const res = await fetch(`/api/status/${user_id}/${project_id}`);
  const data = await res.json();
  
  if (data.status === 'success') {
    console.log('Preview ready:', data.url);
    // Load in iframe: <iframe src={data.url} />
  } else if (data.status === 'failed') {
    console.error('Build failed:', data.error);
  }
};

setInterval(checkStatus, 1000);

3. Store Files Before Build

// Save individual files
await fetch('/api/file', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_id: 'user123',
    project_id: 'proj456',
    filename: 'src/App.jsx',
    content: 'export default function App() { return <div>Hello</div> }'
  })
});

// List files
const files = await fetch(`/api/files/${user_id}`).then(r => r.json());

Rate Limits & Concurrency

  • Concurrent Builds: 5 per user
  • File Size: 10MB per file
  • Build Timeout: 2 minutes
  • Storage: 1GB per user (HF Spaces limit)

Upgrade to CPU Upgrade for higher limits and faster builds.