diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 0000000..60b60ef --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,243 @@ +# Banatie API Reference + +Banatie is a REST API service for AI-powered image generation using the Gemini Flash Image model. + +## Base URL + +``` +http://localhost:3000 +``` + +## Authentication + +API key required via `GEMINI_API_KEY` environment variable (server-side configuration). + +## Content Types + +- **Request**: `multipart/form-data` for file uploads, `application/json` for other endpoints +- **Response**: `application/json` + +## Rate Limits + +Standard Express rate limiting applies. Configure via environment variables. + +--- + +## Endpoints + +### Health Check + +#### `GET /health` + +Health check endpoint with server status. + +**Response:** +```json +{ + "status": "healthy", + "timestamp": "2023-11-20T10:00:00.000Z", + "uptime": 12345.67, + "environment": "development", + "version": "1.0.0" +} +``` + +--- + +### API Information + +#### `GET /api/info` + +Returns API metadata and configuration limits. + +**Response:** +```json +{ + "name": "Banatie - Nano Banana Image Generation API", + "version": "1.0.0", + "description": "REST API service for AI-powered image generation using Gemini Flash Image model", + "endpoints": { + "GET /health": "Health check", + "GET /api/info": "API information", + "POST /api/generate": "Generate images from text prompt with optional reference images", + "POST /api/enhance": "Enhance and optimize prompts for better image generation" + }, + "limits": { + "maxFileSize": "5MB", + "maxFiles": 3, + "supportedFormats": ["PNG", "JPEG", "JPG", "WebP"] + } +} +``` + +--- + +### Generate Image + +#### `POST /api/generate` + +Generate images from text prompts with optional reference images. + +**Content-Type:** `multipart/form-data` + +**Parameters:** + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `prompt` | string | Yes | Text description of the image to generate (1-5000 chars) | +| `filename` | string | Yes | Desired filename for the generated image | +| `files` | file[] | No | Reference images (max 3 files, 5MB each) | +| `autoEnhance` | boolean | No | Enable automatic prompt enhancement | +| `enhancementOptions` | object | No | Enhancement configuration options | + +**Enhancement Options:** + +| Field | Type | Options | Description | +|-------|------|---------|-------------| +| `imageStyle` | string | `photorealistic`, `illustration`, `minimalist`, `sticker`, `product`, `comic` | Visual style | +| `aspectRatio` | string | `square`, `portrait`, `landscape`, `wide`, `ultrawide` | Image proportions | +| `mood` | string | - | Mood description (max 100 chars) | +| `lighting` | string | - | Lighting description (max 100 chars) | +| `cameraAngle` | string | - | Camera angle description (max 100 chars) | +| `negativePrompts` | string[] | - | What to avoid (max 10 items, 100 chars each) | + +**Example Request:** +```bash +curl -X POST http://localhost:3000/api/generate \ + -F "prompt=A majestic mountain landscape at sunset" \ + -F "filename=mountain-sunset" \ + -F "autoEnhance=true" \ + -F "files=@reference1.jpg" \ + -F "files=@reference2.png" +``` + +**Success Response (200):** +```json +{ + "success": true, + "message": "Image generated successfully", + "data": { + "filename": "mountain-sunset-20231120-100000.png", + "filepath": "./results/mountain-sunset-20231120-100000.png", + "description": "Generated image description", + "model": "gemini-1.5-flash", + "generatedAt": "2023-11-20T10:00:00.000Z", + "promptEnhancement": { + "originalPrompt": "A mountain landscape", + "enhancedPrompt": "A majestic mountain landscape at golden hour with dramatic lighting", + "detectedLanguage": "en", + "appliedTemplate": "scenic_landscape", + "enhancements": ["lighting_enhancement", "composition_improvement"] + } + } +} +``` + +**Error Response (400/500):** +```json +{ + "success": false, + "message": "Image generation failed", + "error": "Validation failed: Prompt is required" +} +``` + +--- + +### Enhance Prompt + +#### `POST /api/enhance` + +Enhance and optimize text prompts for better image generation results. + +**Content-Type:** `application/json` + +**Request Body:** +```json +{ + "prompt": "A mountain landscape", + "options": { + "imageStyle": "photorealistic", + "aspectRatio": "landscape", + "mood": "serene and peaceful", + "lighting": "golden hour", + "cameraAngle": "wide shot", + "outputFormat": "detailed", + "negativePrompts": ["blurry", "low quality"] + } +} +``` + +**Parameters:** + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `prompt` | string | Yes | Original text prompt (1-5000 chars) | +| `options` | object | No | Enhancement configuration | + +**Success Response (200):** +```json +{ + "success": true, + "originalPrompt": "A mountain landscape", + "enhancedPrompt": "A breathtaking photorealistic mountain landscape during golden hour, featuring dramatic peaks and valleys with warm, soft lighting creating a serene and peaceful atmosphere, captured in a wide shot composition with rich detail and depth", + "detectedLanguage": "en", + "appliedTemplate": "scenic_landscape", + "metadata": { + "style": "photorealistic", + "aspectRatio": "landscape", + "enhancements": [ + "lighting_enhancement", + "composition_improvement", + "atmosphere_addition", + "detail_specification" + ] + } +} +``` + +**Error Response (400/500):** +```json +{ + "success": false, + "originalPrompt": "A mountain landscape", + "error": "Validation failed: Prompt is required" +} +``` + +--- + +## Error Codes + +| Code | Description | +|------|-------------| +| 400 | Bad Request - Invalid parameters or validation failure | +| 404 | Not Found - Endpoint does not exist | +| 500 | Internal Server Error - Server configuration or processing error | + +## Common Error Messages + +- `"Prompt is required"` - Missing or empty prompt parameter +- `"Reference image validation failed"` - Invalid file format or size +- `"Server configuration error"` - Missing GEMINI_API_KEY +- `"Image generation failed"` - AI service error +- `"Validation failed"` - Parameter validation error + +--- + +## File Upload Specifications + +**Supported Formats:** PNG, JPEG, JPG, WebP +**Maximum File Size:** 5MB per file +**Maximum Files:** 3 files per request +**Storage:** Temporary files in `./uploads/temp`, results in `./results` + +## Request Headers + +| Header | Value | Description | +|--------|-------|-------------| +| `X-Request-ID` | string | Unique request identifier (auto-generated) | + +## CORS + +Cross-origin requests supported. Configure via `CORS_ORIGIN` environment variable. \ No newline at end of file diff --git a/docs/api/api.rest b/docs/api/api.rest new file mode 100644 index 0000000..c71637c --- /dev/null +++ b/docs/api/api.rest @@ -0,0 +1,51 @@ +@base = http://localhost:3000 + +### Info + +GET {{base}}/api/info + + +### enhance + +POST {{base}}/api/enhance +Content-Type: application/json + +{ + "prompt": "Два мага сражаются в снежном лесу. У одного из них в руках посох, из которого вырывается молния, а другой маг защищается щитом из льда. Вокруг них падают снежинки, и на заднем плане видны заснеженные деревья и горы.", + "options": { + "imageStyle": "photorealistic", + "aspectRatio": "landscape", + "mood": "serene and peaceful", + "lighting": "golden hour", + "cameraAngle": "wide shot", + "outputFormat": "detailed", + "negativePrompts": ["blurry", "low quality"] + } +} + +### Generate Image with Files +POST {{base}}/api/generate +Content-Type: multipart/form-data; boundary=----WebKitFormBoundary + +------WebKitFormBoundary +Content-Disposition: form-data; name="prompt" + +A majestic dragon soaring through a crystal cave filled with glowing blue crystals, sunbeams piercing through cracks in the ceiling creating dramatic lighting, highly detailed fantasy art style +------WebKitFormBoundary +Content-Disposition: form-data; name="filename" + +dragon-crystal-cave +------WebKitFormBoundary +Content-Disposition: form-data; name="autoEnhance" + +true +------WebKitFormBoundary +Content-Disposition: form-data; name="enhancementOptions" + +{"imageStyle":"illustration","aspectRatio":"landscape","mood":"mystical and dramatic","lighting":"magical glow with sunbeams","cameraAngle":"wide shot","negativePrompts":["blurry","low quality","amateur"]} +------WebKitFormBoundary +Content-Disposition: form-data; name="referenceImages"; filename="reference.jpg" +Content-Type: image/jpeg + +< ./reference.jpg +------WebKitFormBoundary-- diff --git a/src/middleware/validation.ts b/src/middleware/validation.ts index a9cd255..36b0a54 100644 --- a/src/middleware/validation.ts +++ b/src/middleware/validation.ts @@ -35,9 +35,24 @@ export const validateGenerateRequest = ( next: NextFunction, ): void | Response => { const timestamp = new Date().toISOString(); - const { prompt, filename, autoEnhance, enhancementOptions } = req.body; + let { prompt, filename, autoEnhance, enhancementOptions } = req.body; const errors: string[] = []; + // Convert string values from multipart form data + if (typeof autoEnhance === "string") { + autoEnhance = autoEnhance.toLowerCase() === "true"; + req.body.autoEnhance = autoEnhance; + } + + if (typeof enhancementOptions === "string") { + try { + enhancementOptions = JSON.parse(enhancementOptions); + req.body.enhancementOptions = enhancementOptions; + } catch (error) { + errors.push("enhancementOptions must be valid JSON"); + } + } + console.log(`[${timestamp}] [${req.requestId}] Validating generate request`); // Validate prompt