API Integration Builder
Run ID: 69cbd45361b1021a29a8ca602026-03-31Development
PantheraHive BOS
BOS Dashboard

API Integration Builder: Code Generation Deliverable

This document provides the generated code for integrating with an external API, designed for clarity, robustness, and ease of use. This deliverable fulfills Step 1 of 2 in the "API Integration Builder" workflow.


1. Overview and Purpose

This output provides a foundational Python library for interacting with a RESTful API. It encapsulates common API integration patterns such as making HTTP requests (GET, POST, PUT, DELETE), handling request parameters, processing JSON responses, and implementing robust error handling.

The code is designed to be highly modular and extensible, allowing you to easily adapt it to various external APIs by simply configuring the base URL and implementing specific API key or authentication mechanisms as needed.

2. Key Features of the Integration Code

3. Assumptions Made (for this example)

To provide a concrete and actionable code example, the following assumptions have been made:

4. Prerequisites

Before running the provided code, ensure you have Python 3.x installed and the requests library.

To install requests, open your terminal or command prompt and run:

text • 972 chars
### 5. Code Structure

The generated code consists of:

*   **`APIIntegrationError` (Custom Exception):** A custom exception class for handling API-specific errors, providing more context than generic HTTP exceptions.
*   **`APIClient` Class:**
    *   `__init__`: Initializes the client with the API's base URL and optional API key/headers.
    *   `_make_request`: A private helper method that handles the core logic of making an HTTP request, including setting headers, handling JSON, and basic error checking.
    *   `get`, `post`, `put`, `delete`: Public methods that wrap `_make_request` for each respective HTTP verb, providing a clean interface for interaction.
*   **Example Usage Block:** Demonstrates how to instantiate the `APIClient` and use its methods to perform various operations (GET, POST, PUT, DELETE) against the example API.

### 6. Generated Code

Below is the comprehensive, well-commented, and production-ready Python code for API integration.

Sandboxed live preview

python

import requests

import json

import logging

Configure logging for better visibility

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

logger = logging.getLogger(__name__)

class APIIntegrationError(Exception):

"""

Custom exception for API integration errors.

Provides more context about the error, including status code and response body.

"""

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

super().__init__(message)

self.status_code = status_code

self.response_data = response_data

logger.error(f"API Error: {message} | Status: {status_code} | Response: {response_data}")

class APIClient:

"""

A generic API client for interacting with RESTful APIs.

Supports GET, POST, PUT, DELETE operations with JSON handling and robust error management.

"""

def __init__(self, base_url: str, api_key: str = None, default_headers: dict = None):

"""

Initializes the API client.

Args:

base_url (str): The base URL of the API (e.g., "https://api.example.com/v1").

api_key (str, optional): An API key for authentication, if required by the API.

This will be added as an 'Authorization' header.

default_headers (dict, optional): A dictionary of default headers to send with every request.

"""

if not base_url:

raise ValueError("Base URL cannot be empty.")

self.base_url = base_url.rstrip('/') # Ensure no trailing slash for consistent path joining

self.headers = {

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

'Accept': 'application/json'

}

if api_key:

self.headers['Authorization'] = f'Bearer {api_key}' # Common pattern for API keys

if default_headers:

self.headers.update(default_headers)

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

def _make_request(self, method: str, endpoint: str, data: dict = None, params: dict = None, headers: dict = None):

"""

Internal helper method to make an HTTP request to the API.

Args:

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

endpoint (str): The API endpoint relative to the base URL (e.g., '/posts').

data (dict, optional): Dictionary of data to send in the request body (for POST/PUT).

Will be JSON-encoded.

params (dict, optional): Dictionary of query parameters to append to the URL (for GET).

headers (dict, optional): Additional headers specific to this request, overriding defaults.

Returns:

dict: The JSON response from the API.

Raises:

APIIntegrationError: If the request fails due to network issues,

unsuccessful HTTP status code, or JSON decoding errors.

"""

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

request_headers = self.headers.copy()

if headers:

request_headers.update(headers)

try:

logger.debug(f"Making {method} request to {url} with params={params}, data={data}, headers={request_headers}")

response = requests.request(

method,

url,

json=data, # json parameter automatically sets Content-Type to application/json and serializes dict

params=params,

headers=request_headers,

timeout=10 # Set a timeout for requests

)

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

# Attempt to parse JSON response. Some successful responses (e.g., 204 No Content) might not have a body.

if response.status_code == 204:

return {} # Return empty dict for No Content responses

return response.json()

except requests.exceptions.Timeout:

logger.error(f"Request timed out after 10 seconds for {method} {url}")

raise APIIntegrationError(f"Request timed out for {url}", status_code=408)

except requests.exceptions.ConnectionError as e:

logger.error(f"Connection error occurred for {method} {url}: {e}")

raise APIIntegrationError(f"Network connection error: {e}", status_code=503)

except requests.exceptions.HTTPError as e:

status_code = e.response.status_code

response_data = None

try:

response_data = e.response.json()

except json.JSONDecodeError:

response_data = e.response.text # Fallback to text if not JSON

logger.error(f"HTTP Error for {method} {url}: {status_code} - {response_data}")

raise APIIntegrationError(

f"API request failed with status code {status_code}: {e.response.reason}",

status_code=status_code,

response_data=response_data

)

except json.JSONDecodeError as e:

logger.error(f"Failed to decode JSON response from {url}: {e}")

raise APIIntegrationError(f"Invalid JSON response from API: {e}", status_code=200, response_data=response.text)

except Exception as e:

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

raise APIIntegrationError(f"An unexpected error occurred: {e}")

def get(self, endpoint: str, params: dict = None, headers: dict = None):

"""Performs a GET request."""

logger.info(f"GET request to {endpoint} with params: {params}")

return self._make_request('GET', endpoint, params=params, headers=headers)

def post(self, endpoint: str, data: dict, headers: dict = None):

"""Performs a POST request."""

logger.info(f"POST request to {endpoint} with data: {data}")

return self._make_request('POST', endpoint, data=data, headers=headers)

def put(self, endpoint: str, data: dict, headers: dict = None):

"""Performs a PUT request."""

logger.info(f"PUT request to {endpoint} with data: {data}")

return self._make_request('PUT', endpoint, data=data, headers=headers)

def delete(self, endpoint: str, headers: dict = None):

"""Performs a DELETE request."""

logger.info(f"DELETE request to {endpoint}")

return self._make_request('DELETE', endpoint, headers=headers)

--- Example Usage ---

if __name__ == "__main__":

# 1. Initialize the API Client

# For JSONPlaceholder, no API key is needed. If your API needs one, provide it here.

# api_key = "YOUR_API_KEY_HERE"

api_client = APIClient(base_url="https://jsonplaceholder.typicode.com") #, api_key=api_key)

print("\n--- API Integration Example (JSONPlaceholder) ---")

# 2. Example: GET Request (Retrieve all posts)

print("\nAttempting to GET all posts...")

try:

posts = api_client.get('/posts')

print(f"Successfully retrieved {len(posts)} posts. First post title: '{posts[0]['title']}'")

# print(json.dumps(posts[0], indent=2)) # Uncomment to see full first post

except APIIntegrationError as e:

print(f"Failed to retrieve posts: {e}")

# 3. Example: GET Request (Retrieve a specific post)

print("\nAttempting to GET post with ID 1...")

try:

single_post = api_client.get('/posts/1')

print(f"Successfully retrieved post ID 1: '{single_post['title']}'")

# print(json.dumps(single_post, indent=2))

except APIIntegrationError as e:

print(f"Failed to retrieve post ID 1: {e}")

# 4. Example: POST Request (Create a new post)

print("\nAttempting to POST a new post...")

new_post_data = {

'title': 'My New API Integration Post',

'body': 'This is the body of my newly created post via the API client.',

'userId': 1

}

try:

created_post = api_client.post('/posts', data=new_post_data)

print(f"Successfully created new post with ID: {created_post.get('id')}")

print(f"Created Post Title: '{created_post['title']}'")

# print(json.dumps(created_post, indent=2))

except APIIntegrationError as e:

print(f"Failed to create new post: {e}")

# 5. Example: PUT Request (Update an existing post - using the ID from the created_post if available)

if 'id' in created_post:

post_to_update_id = created_post['id']

else:

# Fallback for example if POST failed, use a known ID

post_to_update_id = 1

print(f"\nPOST failed previously, using existing post ID {post_to_update_id} for PUT example.")

print(f"\nAttempting to PUT (update) post with ID {post_to_update_id}...")

updated_post_data = {

'id': post_to_update_id, # JSONPlaceholder requires ID in body for PUT

'title': 'Updated Title from API Client',

'body': 'This post body has been updated.',

'userId': 1

}

try:

updated_post = api_client.put(f'/posts/{post_to_update_id}', data=updated_post_data)

print(f"Successfully updated post ID {updated_post['id']}. New title: '{updated_post['title']

projectmanager Output

As part of the "API Integration Builder" workflow, this output details the second and final step, focusing on generating the necessary code and strategy to integrate with an external API for the purpose of creating projects.


API Integration Builder - Step 2/2: Project Creation Integration

This deliverable provides a comprehensive, detailed, and actionable plan, including code examples, for integrating with an external API to perform the create_project operation. Our goal is to equip you with the foundational knowledge and reusable components to programmatically manage project creation within your chosen external system.


Objective: Integrating for Project Creation (create_project)

The primary objective of this step is to enable your system to create new projects in an external Project Management (or similar) system via its exposed Application Programming Interface (API). This integration will allow for automated project setup, reducing manual effort and ensuring data consistency across systems.


Key Considerations for a Robust Project Creation Integration

Before diving into the code, it's crucial to consider several aspects that ensure a reliable, secure, and maintainable integration:

  • API Documentation: The single most important resource. It specifies endpoints, methods, authentication, required parameters, data types, and error codes.
  • Authentication & Authorization: How do you securely connect to the API? (e.g., API Keys, OAuth2, Bearer Tokens). What permissions does your integration user/application need?
  • API Endpoint & HTTP Method: Identify the specific URL and HTTP method (e.g., POST) for creating a project.
  • Request Body Structure: Understand the exact JSON or XML payload required by the API to create a project, including mandatory and optional fields.
  • Response Handling: How does the API confirm success? What data does it return upon successful creation (e.g., project_id, status)?
  • Error Handling: How does the API communicate failures (e.g., HTTP status codes like 400, 401, 500, and error messages in the response body)? Your integration must gracefully handle these.
  • Idempotency: For creation operations, consider if the API supports idempotency or if your system needs to ensure a project isn't accidentally created multiple times if a request is retried.
  • Rate Limiting: Be aware of any limits on how many requests you can make within a certain timeframe to avoid being blocked.
  • Security: Ensure API keys/tokens are stored and transmitted securely.
  • Configuration: Externalize API URLs, keys, and other changeable parameters from your code.

Assumptions for This Integration Example

To provide a concrete example, we'll make the following common assumptions about the external API:

  • API Type: It is a RESTful API.
  • Data Format: It expects and returns JSON payloads.
  • Authentication: It uses an API Key or Bearer Token passed in the Authorization header.
  • Endpoint: A POST request to /projects or a similar path creates a new project.
  • Success Status: A successful creation returns an HTTP 201 Created status code.
  • Error Statuses: Common errors include 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 5xx Server Error.

Proposed Integration Architecture & Strategy

We recommend encapsulating API interactions within a dedicated service or module. This promotes modularity, reusability, and easier maintenance. For the code example, we will use Python with the popular requests library, which is widely used for HTTP interactions due to its simplicity and power.

Strategy:

  1. Configuration Management: Store API credentials and base URLs securely and externalized (e.g., environment variables, configuration files).
  2. API Client Class/Module: Create a Python class or module (ProjectAPIClient) specifically for interacting with the external project API.
  3. Dedicated Method: Implement a specific method within the client (e.g., create_project) that handles the request construction, execution, and response parsing for project creation.
  4. Robust Error Handling: Implement try-except blocks to catch network issues, API-specific errors, and handle them gracefully.
  5. Logging: Integrate logging to track API calls, responses, and errors for debugging and monitoring.

Core Code Implementation Example (Python)

This example demonstrates how to structure your Python code for creating a project using an external API.

Prerequisites

You'll need the requests library. Install it using pip:


pip install requests

Configuration & Authentication (Example using Environment Variables)

It's best practice to load sensitive information like API keys from environment variables or a secure configuration store.


import os
import requests
import json
import logging

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

class ProjectAPIClient:
    """
    A client for interacting with an external Project Management API.
    """
    def __init__(self, base_url: str, api_key: str):
        if not base_url or not api_key:
            raise ValueError("API Base URL and API Key must be provided.")
        self.base_url = base_url.rstrip('/')
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}" # Or "X-API-KEY": api_key depending on the API
        }
        logging.info(f"ProjectAPIClient initialized for {self.base_url}")

    def _make_request(self, method: str, endpoint: str, data: dict = None):
        """
        Internal helper to make HTTP requests and handle common errors.
        """
        url = f"{self.base_url}{endpoint}"
        try:
            response = requests.request(method, url, headers=self.headers, json=data, timeout=10)
            response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)
            return response.json()
        except requests.exceptions.HTTPError as http_err:
            logging.error(f"HTTP error occurred: {http_err} - Response: {response.text}")
            raise APIError(f"API returned an error: {response.status_code} - {response.text}") from http_err
        except requests.exceptions.ConnectionError as conn_err:
            logging.error(f"Connection error occurred: {conn_err}")
            raise APIError(f"Network connection error: {conn_err}") from conn_err
        except requests.exceptions.Timeout as timeout_err:
            logging.error(f"Request timed out: {timeout_err}")
            raise APIError(f"API request timed out: {timeout_err}") from timeout_err
        except requests.exceptions.RequestException as req_err:
            logging.error(f"An unexpected request error occurred: {req_err}")
            raise APIError(f"An unexpected error occurred: {req_err}") from req_err
        except json.JSONDecodeError:
            logging.error(f"Failed to decode JSON from response: {response.text}")
            raise APIError(f"Invalid JSON response from API: {response.text}")

    def create_project(self, project_data: dict) -> dict:
        """
        Creates a new project in the external system.

        Args:
            project_data (dict): A dictionary containing project details.
                                 Example: {"name": "New Marketing Campaign", "description": "Launch Q3 products", "startDate": "2023-09-01"}

        Returns:
            dict: The response from the API, typically including the newly created project's ID and details.
        """
        logging.info(f"Attempting to create project with data: {project_data.get('name', 'N/A')}")
        endpoint = "/projects" # This should match your API's specific endpoint for project creation
        try:
            response_data = self._make_request("POST", endpoint, data=project_data)
            logging.info(f"Project created successfully. API Response: {response_data}")
            return response_data
        except APIError as e:
            logging.error(f"Failed to create project: {e}")
            raise # Re-raise the custom APIError for upstream handling

class APIError(Exception):
    """Custom exception for API-related errors."""
    pass

# --- Example Usage ---
if __name__ == "__main__":
    # Load configuration from environment variables
    # For demonstration, you might hardcode these, but for production, use os.environ.get()
    # Example: export EXTERNAL_API_BASE_URL="https://api.externalprojectmanager.com/v1"
    # Example: export EXTERNAL_API_KEY="your_super_secret_api_key"
    
    API_BASE_URL = os.environ.get("EXTERNAL_API_BASE_URL", "https://api.example.com/v1") # Replace with your actual API base URL
    API_KEY = os.environ.get("EXTERNAL_API_KEY", "your_api_key_here") # Replace with your actual API key

    if "your_api_key_here" in API_KEY or "https://api.example.com" in API_BASE_URL:
        logging.warning("Using placeholder API_BASE_URL or API_KEY. Please set EXTERNAL_API_BASE_URL and EXTERNAL_API_KEY environment variables.")

    try:
        project_client = ProjectAPIClient(base_url=API_BASE_URL, api_key=API_KEY)

        new_project_data = {
            "name": "PantheraHive Product Launch Q4 2023",
            "description": "Oversee the launch of new AI-powered features for PantheraHive platform.",
            "startDate": "2023-10-01",
            "endDate": "2023-12-31",
            "status": "Planning",
            "priority": "High",
            "owner": "john.doe@pantherahive.com"
            # Add any other fields required by your external API
        }

        created_project = project_client.create_project(new_project_data)
        print("\n--- Project Creation Successful ---")
        print(f"Project Name: {created_project.get('name', 'N/A')}")
        print(f"Project ID: {created_project.get('id', 'N/A')}")
        print(f"Status: {created_project.get('status', 'N/A')}")
        # You might want to store the 'id' in your local system for future reference

    except ValueError as ve:
        logging.error(f"Configuration Error: {ve}")
    except APIError as ae:
        logging.error(f"Application Error during project creation: {ae}")
    except Exception as e:
        logging.critical(f"An unhandled error occurred: {e}")


Detailed Explanation of Code Components

1. ProjectAPIClient Class

  • Initialization (__init__):

* Takes base_url (the root URL of the API, e.g., https://api.example.com/v1) and api_key as arguments.

Constructs the headers dictionary, including Content-Type: application/json (standard for JSON APIs) and the Authorization header with the API key (e.g., Bearer <API_KEY> or X-API-KEY: <API_KEY> - check your API documentation for the exact header name and format*).

  • _make_request Method:

* A private helper method to centralize HTTP request logic and common error handling.

* Constructs the full URL by joining base_url and endpoint.

* Uses requests.request() for flexibility (can handle GET, POST, PUT, etc.).

* json=data: Automatically serializes the data dictionary into a JSON string and sets the Content-Type header (if not already set).

* timeout=10: Sets a timeout for the request to prevent indefinite waiting.

* response.raise_for_status(): A crucial requests feature that raises an HTTPError for 4xx (client error) or 5xx (server error) response status codes.

* return response.json(): Parses the successful JSON response body into a Python dictionary.

* Error Handling: Catches various requests.exceptions (HTTPError, ConnectionError, Timeout, RequestException) and json.JSONDecodeError. It logs the error and re-raises a custom APIError for consistent upstream handling.

2. create_project Method

  • This is the public interface for creating a project.
  • It takes project_data (a dictionary representing the project's attributes) as input.
  • It defines the specific endpoint for project creation (e.g., /projects).
  • It calls the internal _make_request method with POST as the HTTP method and the project_data.
  • It returns the parsed JSON response, which typically contains the newly created project's ID and other details from the external system.

3. `

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
\n\n\n"); 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'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); 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'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); 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'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); 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}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "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"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); 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';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); 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}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- 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:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== 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(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } 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);}});}