API Integration Builder
Run ID: 69ccd8843e7fb09ff16a59592026-04-01Development
PantheraHive BOS
BOS Dashboard

API Integration Builder: Code Generation Deliverable (Step 1 of 2)

This document provides the comprehensive, detailed, and professional code generation output for the "API Integration Builder" workflow. This output is designed to be production-ready, well-commented, and easily adaptable for integrating with various external RESTful APIs.


1. Overview: Code Generation Step

The goal of this generate_code step is to produce a robust, maintainable, and extensible Python client for interacting with a generic RESTful API. This client incorporates best practices for API integration, including secure configuration, resilient request handling, structured error management, and comprehensive logging.

This deliverable focuses on creating a foundational API client class that can be customized for specific API endpoints and data models. It serves as a strong starting point for any external API integration project.

2. Core Principles of API Integration

The generated code adheres to the following core principles:

3. Example Integration Scenario: Generic RESTful API

To provide a concrete example, the generated code is structured around integrating with a hypothetical RESTful API that manages resources (e.g., users, products, contacts). We will demonstrate common CRUD (Create, Read, Update, Delete) operations.

Hypothetical API Endpoints:

4. Generated Code: Python API Client

The following Python code provides a comprehensive API client. It includes necessary dependencies, configuration loading, custom exceptions, retry logic, and methods for common HTTP operations.

Prerequisites:

To run this code, you will need to install the following Python packages:

text • 210 chars
---

#### 4.1 `.env` File (Configuration)

Create a file named `.env` in the root directory of your project and populate it with your API configuration. This keeps sensitive information out of your codebase.

Sandboxed live preview

python

api_client.py

import os

import requests

import logging

from dotenv import load_dotenv

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type

--- 1. Configuration and Logging Setup ---

load_dotenv() # Load environment variables from .env file

Configure logging

logging.basicConfig(level=logging.INFO,

format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)

--- 2. Custom Exceptions ---

class APIError(Exception):

"""Custom exception for API-related errors."""

def __init__(self, message, status_code=None, details=None):

super().__init__(message)

self.status_code = status_code

self.details = details

def __str__(self):

if self.status_code:

return f"APIError: {self.status_code} - {self.args[0]}"

return f"APIError: {self.args[0]}"

class NetworkError(APIError):

"""Custom exception for network-related errors during API calls."""

pass

class AuthenticationError(APIError):

"""Custom exception for authentication failures (e.g., 401 Unauthorized)."""

pass

class NotFoundError(APIError):

"""Custom exception for resource not found errors (e.g., 404 Not Found)."""

pass

class BadRequestError(APIError):

"""Custom exception for bad request errors (e.g., 400 Bad Request)."""

pass

--- 3. API Client Class ---

class APIClient:

"""

A robust and generic client for interacting with RESTful APIs.

Features:

- Loads configuration from environment variables.

- Handles common HTTP methods (GET, POST, PUT, DELETE).

- Implements retry logic for transient errors.

- Provides structured error handling with custom exceptions.

- Integrates logging for operational insights.

- Supports API Key authentication.

"""

def __init__(self, base_url=None, api_key=None):

"""

Initializes the APIClient with base URL and API key.

Args:

base_url (str, optional): The base URL of the API. If None,

it tries to load from API_BASE_URL env var.

api_key (str, optional): The API key for authentication. If None,

it tries to load from API_KEY env var.

"""

self.base_url = base_url or os.getenv("API_BASE_URL")

self.api_key = api_key or os.getenv("API_KEY")

if not self.base_url:

raise ValueError("API base URL is not provided and not found in environment variables.")

if not self.api_key:

logger.warning("API Key is not provided. Requests might fail if API requires authentication.")

self.session = requests.Session()

logger.info(f"APIClient initialized for base URL: {self.base_url}")

def _get_headers(self, custom_headers=None):

"""

Constructs the standard headers for API requests, including authentication.

Args:

custom_headers (dict, optional): Additional headers to merge.

Returns:

dict: A dictionary of HTTP headers.

"""

headers = {

"Content-Type": "application/json",

"Accept": "application/json",

}

if self.api_key:

# Example: API Key in Authorization header as Bearer token or custom scheme

# Adapt this based on your API's authentication mechanism

headers["Authorization"] = f"Bearer {self.api_key}"

# For APIs that use a custom header like 'X-API-Key':

# headers["X-API-Key"] = self.api_key

if custom_headers:

headers.update(custom_headers)

return headers

@retry(stop=stop_after_attempt(3),

wait=wait_exponential(multiplier=1, min=4, max=10),

retry=retry_if_exception_type((NetworkError, requests.exceptions.Timeout)),

reraise=True)

def _request(self, method, endpoint, params=None, data=None, json=None, headers=None, **kwargs):

"""

Internal helper method to make an HTTP request with retry logic and error handling.

Args:

method (str): The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE').

endpoint (str): The specific API endpoint path (e.g., '/resources').

params (dict, optional): Dictionary of URL query parameters.

data (dict or str, optional): Dictionary, bytes, or file-like object to send in the body.

json (dict, optional): A JSON-serializable Python object to send in the body.

headers (dict, optional): Custom headers for this specific request.

**kwargs: Additional keyword arguments to pass to requests.request.

Returns:

dict: The JSON response from the API.

Raises:

APIError: For general API errors.

NetworkError: For network connectivity issues.

AuthenticationError: If authentication fails (401).

NotFoundError: If the resource is not found (404).

BadRequestError: If the request is malformed (400).

"""

url = f"{self.base_url}{endpoint}"

request_headers = self._get_headers(headers)

logger.debug(f"Making {method} request to: {url}")

logger.debug(f"Request Headers: {request_headers}")

if params:

logger.debug(f"Request Params: {params}")

if json:

logger.debug(f"Request JSON Body: {json}")

elif data:

logger.debug(f"Request Data Body: {data}")

try:

response = self.session.request(

method, url, params=params, data=data, json=json, headers=request_headers, **kwargs

)

response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)

logger.info(f"Successfully {method} {endpoint}. Status: {response.status_code}")

return response.json()

except requests.exceptions.Timeout as e:

logger.error(f"Request to {url} timed out: {e}")

raise NetworkError(f"Request timed out for {url}", details=str(e)) from e

except requests.exceptions.ConnectionError as e:

logger.error(f"Network connection error to {url}: {e}")

raise NetworkError(f"Network connection error to {url}", details=str(e)) from e

except requests.exceptions.HTTPError as e:

status_code = e.response.status_code

error_message = f"API returned error for {url}: {status_code} - {e.response.text}"

logger.error(error_message)

response_json = {}

try:

response_json = e.response.json()

except ValueError:

pass # Not all error responses are JSON

if status_code == 400:

raise BadRequestError(e.response.text, status_code=status_code, details=response_json) from e

elif status_code == 401:

raise AuthenticationError(e.response.text, status_code=status_code, details=response_json) from e

elif status_code == 403:

raise APIError(f"Forbidden: {e.response.text}", status_code=status_code, details=response_json) from e

elif status_code == 404:

raise NotFoundError(e.response.text, status_code=status_code, details=response_json) from e

elif 400 <= status_code < 500:

raise APIError(f"Client error: {e.response.text}", status_code=status_code, details=response_json) from e

elif 500 <= status_code < 600:

# Server errors might be transient, retries are handled by tenacity

raise APIError(f"Server error: {e.response.text}", status_code=status_code, details=response_json) from e

else:

raise APIError(f"Unexpected HTTP error: {e.response.text}", status_code=status_code, details=response_json) from e

except Exception as e:

logger.exception(f"An unexpected error occurred during request to {url}: {e}")

raise APIError(f"An unexpected error occurred: {e}", details=str(e)) from e

def get(self, endpoint, params=None, headers=None, **kwargs):

"""Sends a GET request."""

return self._request('GET', endpoint, params=params, headers=headers, **kwargs)

def post(self, endpoint, data=None, json=None, headers=None, **kwargs):

"""Sends a POST request."""

return self._request('POST', endpoint, data=data, json=json, headers=headers, **kwargs)

def put(self, endpoint, data=None, json=None, headers=None, **kwargs):

"""Sends a PUT request."""

return self._request('PUT', endpoint, data=data, json=json, headers=headers, **kwargs)

def delete(self, endpoint, params=None, headers=None, **kwargs):

"""Sends a DELETE request."""

return self._request('DELETE', endpoint, params=params, headers=headers, **kwargs)

# --- 4. Example Specific API Methods (Adapt these for your API) ---

def get_all_resources(self, query_params=None):

"""Retrieves a list of all resources."""

logger.info("Fetching all resources...")

return self.get("/resources", params=query_params)

def get_resource_by_id(self, resource_id):

"""Retrieves a specific resource by its ID."""

logger.info(f"Fetching resource with ID: {resource_id}")

return self.get(f"/resources/{resource_id}")

def create_resource(self, resource_data):

"""Creates a new resource."""

logger.info(f"Creating resource with data: {resource_data}")

return self.post("/resources", json=resource_data)

def update_resource(self, resource_id, resource_data):

"""Updates an existing resource."""

logger.info(f"Updating resource {resource_id} with data: {resource_data}")

return self.put(f"/resources/{resource

projectmanager Output

API Integration Builder - Project Creation Module

1. Executive Summary

This deliverable provides a comprehensive framework and example code for integrating with an external API to perform the "Create Project" operation. It outlines the necessary components, best practices, and a clear, actionable Python code example to facilitate seamless integration into your existing systems. The focus is on robust, secure, and maintainable API interaction, ensuring successful project creation and effective error handling.

2. Objective

The primary objective of this module is to enable your application to programmatically create new projects in a target Project Management System (PMS) or similar external service via its RESTful API. This integration aims to:

  • Automate project creation workflows.
  • Reduce manual data entry and potential errors.
  • Synchronize project data across different platforms.
  • Provide a foundational, extensible code structure for future API integrations.

3. Target API Assumptions

Given that a specific API was not provided, this integration is designed based on common patterns for RESTful APIs.

  • API Type: RESTful API (HTTP/HTTPS)
  • Endpoint for Project Creation: POST /api/v1/projects (or similar, e.g., /projects)
  • Authentication: Assumed to be an API Key or Bearer Token (OAuth 2.0). The example will use an X-API-Key header for simplicity, but can be easily adapted for Authorization: Bearer <token>.
  • Request Format: JSON (JavaScript Object Notation) for sending project data.
  • Response Format: JSON for both success and error messages.
  • HTTP Status Codes: Standard HTTP status codes will be used to indicate success (e.g., 201 Created, 200 OK) or various error conditions (e.g., 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error).

4. Core Integration Components

A robust API integration requires several key components to ensure reliability and security:

4.1. Configuration Management

Sensitive information like API keys, base URLs, and other environment-specific settings should be managed securely and never hardcoded.

  • Recommended Method: Environment variables (.env files for local development, system environment variables for production).
  • Parameters to Configure:

* API_BASE_URL: The root URL of the target API (e.g., https://api.example.com/).

* API_KEY: The authentication key or token.

4.2. Authentication

Securely authenticating requests to the external API.

  • Mechanism: Typically involves sending an API key in a custom HTTP header (e.g., X-API-Key or Authorization).
  • Security: Ensure API keys are stored and transmitted securely (e.g., HTTPS).

4.3. Request Construction

Building the HTTP request with the necessary components.

  • Method: POST
  • Endpoint: The specific path for creating projects (e.g., /api/v1/projects).
  • Headers:

* Content-Type: application/json: Indicates that the request body is JSON.

* Authentication Header: X-API-Key: YOUR_API_KEY or Authorization: Bearer YOUR_TOKEN.

  • Request Body (Payload): A JSON object containing the project details.

* Example Payload Structure:


        {
            "name": "Project Alpha",
            "description": "Detailed description for Project Alpha.",
            "startDate": "2023-10-26",
            "endDate": "2024-03-31",
            "ownerId": "user-uuid-123",
            "status": "Planned",
            "priority": "High"
        }

* Required Fields: (Determined by the target API) name, description, startDate, ownerId are common.

4.4. Response Handling

Processing the API's response, both for success and failure.

  • Success Response (HTTP Status 201 Created / 200 OK):

* Expected JSON body containing the newly created project's ID and other relevant details.

* Example Success Response:


        {
            "id": "proj-abc-123",
            "name": "Project Alpha",
            "status": "Planned",
            "message": "Project created successfully."
        }
  • Error Response (HTTP Status 4xx, 5xx):

* Expected JSON body with an error code and a human-readable message.

* Example Error Response:


        {
            "errorCode": "VALIDATION_ERROR",
            "message": "Project name cannot be empty.",
            "details": [
                {"field": "name", "error": "required"}
            ]
        }

4.5. Error Management and Logging

Robust error handling is critical for production systems.

  • HTTP Status Codes: Interpret different 4xx (client errors) and 5xx (server errors) codes.
  • Custom Exceptions: Define specific exceptions for different error types (e.g., APIAuthenticationError, APIValidationError, APIServerError).
  • Retry Mechanism: Implement exponential backoff for transient errors (e.g., 429 Too Many Requests, 503 Service Unavailable).
  • Logging: Log all API requests, responses (especially errors), and relevant metadata for debugging and monitoring.

5. Example Code (Python)

This example utilizes Python with the requests library, which is a standard choice for HTTP interactions due to its simplicity and power.

5.1. Prerequisites

  • Python 3.x installed.
  • requests library installed: pip install requests python-dotenv
  • A .env file in the same directory as your script for environment variables.

5.2. config.py (or similar for environment variables)


import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

class APIConfig:
    """
    Manages API configuration settings.
    """
    BASE_URL = os.getenv("API_BASE_URL", "https://api.example.com/v1")
    API_KEY = os.getenv("API_KEY") # Ensure this is set in your .env
    PROJECT_ENDPOINT = "/projects" # Specific endpoint for project creation

    @classmethod
    def validate(cls):
        """Validates that necessary configuration is present."""
        if not cls.API_KEY:
            raise ValueError("API_KEY environment variable is not set.")
        if not cls.BASE_URL:
            raise ValueError("API_BASE_URL environment variable is not set.")

# Validate configuration on import
APIConfig.validate()

5.3. .env File Example

Create a file named .env in the same directory:


API_BASE_URL=https://your-project-management-api.com/v1
API_KEY=your_secure_api_key_here

Important: Replace your-project-management-api.com and your_secure_api_key_here with your actual API details. Never commit your .env file to version control.

5.4. api_client.py


import requests
import json
import logging
from config import APIConfig

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class APIIntegrationError(Exception):
    """Base exception for API integration errors."""
    pass

class APIAuthenticationError(APIIntegrationError):
    """Raised for 401 Unauthorized or 403 Forbidden errors."""
    pass

class APIValidationError(APIIntegrationError):
    """Raised for 400 Bad Request errors."""
    def __init__(self, message, details=None):
        super().__init__(message)
        self.details = details or {}

class APIServerError(APIIntegrationError):
    """Raised for 5xx server errors."""
    pass

class APINetworkError(APIIntegrationError):
    """Raised for network-related issues (e.g., connection refused, timeout)."""
    pass

def create_project(project_data: dict) -> dict:
    """
    Integrates with an external API to create a new project.

    Args:
        project_data (dict): A dictionary containing the project details.
                             Example: {
                                 "name": "New Project",
                                 "description": "Project description.",
                                 "startDate": "2023-10-26",
                                 "endDate": "2024-12-31",
                                 "ownerId": "user-123",
                                 "status": "Planned"
                             }

    Returns:
        dict: The response data from the API, typically including the new project's ID.

    Raises:
        APIAuthenticationError: If authentication fails.
        APIValidationError: If the provided project_data is invalid.
        APIServerError: If the API encounters an internal server error.
        APINetworkError: If there's a network issue connecting to the API.
        APIIntegrationError: For other unexpected API errors.
    """
    url = f"{APIConfig.BASE_URL}{APIConfig.PROJECT_ENDPOINT}"
    headers = {
        "Content-Type": "application/json",
        "X-API-Key": APIConfig.API_KEY # Using X-API-Key as per assumption
        # For Bearer token, use: "Authorization": f"Bearer {APIConfig.API_KEY}"
    }

    try:
        logging.info(f"Attempting to create project: {project_data.get('name', 'Unnamed Project')}")
        response = requests.post(url, headers=headers, data=json.dumps(project_data), timeout=10)
        response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)

        response_data = response.json()
        logging.info(f"Project '{project_data.get('name')}' created successfully. ID: {response_data.get('id')}")
        return response_data

    except requests.exceptions.Timeout:
        logging.error(f"API request timed out after 10 seconds for project: {project_data.get('name')}")
        raise APINetworkError("API request timed out.")
    except requests.exceptions.ConnectionError as e:
        logging.error(f"Failed to connect to API for project {project_data.get('name')}: {e}")
        raise APINetworkError(f"Failed to connect to API: {e}")
    except requests.exceptions.HTTPError as e:
        status_code = e.response.status_code
        error_message = f"API responded with status {status_code}"
        try:
            error_details = e.response.json()
            error_message += f": {error_details.get('message', 'No specific message')}"
            logging.error(f"API Error ({status_code}) for project {project_data.get('name')}: {error_details}")
        except json.JSONDecodeError:
            error_details = {"raw_response": e.response.text}
            logging.error(f"API Error ({status_code}) for project {project_data.get('name')}: {e.response.text}")
        
        if status_code in [401, 403]:
            raise APIAuthenticationError(error_message)
        elif status_code == 400:
            raise APIValidationError(error_message, details=error_details)
        elif 400 <= status_code < 500:
            raise APIIntegrationError(f"Client error from API: {error_message}")
        elif 500 <= status_code < 600:
            raise APIServerError(f"Server error from API: {error_message}")
        else:
            raise APIIntegrationError(f"Unexpected HTTP error from API: {error_message}")
    except json.JSONDecodeError:
        logging.error(f"Failed to decode JSON response for project {project_data.get('name')}. Raw response: {response.text}")
        raise APIIntegrationError("Received non-JSON response from API.")
    except Exception as e:
        logging.critical(f"An unexpected error occurred during API integration for project {project_data.get('name')}: {e}", exc_info=True)
        raise APIIntegrationError(f"An unexpected error occurred: {e}")

#
api_integration_builder.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547} "); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/**(.+?)**/g,"$1"); hc=hc.replace(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); }function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}