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

Generate code to integrate with external APIs

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

This document provides the generated, production-ready code for integrating with an external RESTful API. This deliverable focuses on providing a robust, flexible, and well-structured Python client that handles common API interaction patterns, including various HTTP methods, error handling, and authentication.


1. Introduction & Overview

This first step of the "API Integration Builder" workflow delivers a foundational Python client designed to streamline your interactions with a generic RESTful API. The generated code is built with best practices in mind, emphasizing modularity, error handling, and ease of use.

Key Features of the Generated Code:

  • Modular ApiClient Class: Encapsulates all API interaction logic, making your code clean and maintainable.
  • Support for Standard HTTP Methods: Includes GET, POST, PUT, and DELETE operations.
  • Robust Error Handling: Catches network errors, HTTP status code errors (4xx, 5xx), and JSON parsing issues.
  • Configurable Authentication: Designed to easily integrate API keys or bearer tokens via headers.
  • Automatic JSON Handling: Simplifies sending and receiving JSON data.
  • Logging: Integrates Python's standard logging module for better debuggability and operational monitoring.
  • Type Hinting: Enhances code readability and maintainability.

2. Generated Code: api_client.py

Below is the Python code for your API client. This code is designed to be highly adaptable; you will need to configure it with your specific API's base URL and authentication details.


import requests
import json
import logging
from typing import Dict, Any, Optional, Union

# --- Configure Logging ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# --- Custom Exceptions for API Client ---
class ApiException(Exception):
    """Base exception for API-related errors."""
    def __init__(self, message: str, status_code: Optional[int] = None, response_data: Optional[Any] = None):
        super().__init__(message)
        self.status_code = status_code
        self.response_data = response_data

    def __str__(self):
        detail = f"Status Code: {self.status_code}" if self.status_code else ""
        if self.response_data:
            detail += f", Response: {json.dumps(self.response_data)}"
        return f"{super().__str__()} ({detail})"

class NetworkError(ApiException):
    """Exception for network-related issues (e.g., connection refused, timeout)."""
    pass

class ServerError(ApiException):
    """Exception for 5xx HTTP status codes."""
    pass

class ClientError(ApiException):
    """Exception for 4xx HTTP status codes."""
    pass

class JsonDecodingError(ApiException):
    """Exception for issues decoding JSON response."""
    pass

# --- API Client Class ---
class ApiClient:
    """
    A robust and configurable client for interacting with RESTful APIs.

    Handles HTTP requests, error parsing, and provides a structured way to
    communicate with external services.
    """

    def __init__(
        self,
        base_url: str,
        api_key: Optional[str] = None,
        bearer_token: Optional[str] = None,
        default_headers: Optional[Dict[str, str]] = None,
        timeout: int = 30
    ):
        """
        Initializes the API client.

        Args:
            base_url (str): The base URL of the API (e.g., "https://api.example.com/v1").
            api_key (Optional[str]): An API key to include in 'X-API-Key' header.
                                     Mutually exclusive with bearer_token.
            bearer_token (Optional[str]): A bearer token for 'Authorization' header.
                                          Mutually exclusive with api_key.
            default_headers (Optional[Dict[str, str]]): Additional headers to send with every request.
            timeout (int): Default timeout for requests in seconds.
        """
        if not base_url:
            raise ValueError("base_url cannot be empty.")

        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        self.session = requests.Session()
        self.headers = {
            "Content-Type": "application/json",
            "Accept": "application/json",
        }

        if default_headers:
            self.headers.update(default_headers)

        if api_key and bearer_token:
            raise ValueError("Cannot provide both api_key and bearer_token. Choose one authentication method.")
        elif api_key:
            self.headers["X-API-Key"] = api_key
            logger.info("API Client initialized with API Key authentication.")
        elif bearer_token:
            self.headers["Authorization"] = f"Bearer {bearer_token}"
            logger.info("API Client initialized with Bearer Token authentication.")
        else:
            logger.warning("API Client initialized without specific API key or bearer token authentication.")

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

    def _build_url(self, endpoint: str) -> str:
        """Constructs the full URL for an API endpoint."""
        return f"{self.base_url}/{endpoint.lstrip('/')}"

    def _make_request(
        self,
        method: str,
        endpoint: str,
        params: Optional[Dict[str, Any]] = None,
        data: Optional[Union[Dict, str]] = None,
        json_data: Optional[Dict[str, Any]] = None,
        headers: Optional[Dict[str, str]] = None
    ) -> Any:
        """
        Internal helper to make an HTTP request and handle common responses/errors.

        Args:
            method (str): HTTP method (GET, POST, PUT, DELETE).
            endpoint (str): API endpoint (e.g., "users", "products/123").
            params (Optional[Dict[str, Any]]): Query parameters for the URL.
            data (Optional[Union[Dict, str]]): Request body for POST/PUT (e.g., form data, raw string).
            json_data (Optional[Dict[str, Any]]): Request body for POST/PUT as JSON.
            headers (Optional[Dict[str, str]]): Additional headers for this specific request.

        Returns:
            Any: The JSON response body if successful.

        Raises:
            NetworkError: For network connectivity issues.
            ClientError: For 4xx HTTP status codes.
            ServerError: For 5xx HTTP status codes.
            JsonDecodingError: If the response cannot be decoded as JSON.
            ApiException: For other unexpected API errors.
        """
        url = self._build_url(endpoint)
        request_headers = self.headers.copy()
        if headers:
            request_headers.update(headers)

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

        try:
            response = self.session.request(
                method,
                url,
                params=params,
                data=data,
                json=json_data,
                headers=request_headers,
                timeout=self.timeout
            )
            response.raise_for_status()  # Raises HTTPError for bad responses (4xx or 5xx)

            # Attempt to parse JSON response
            if response.text:
                try:
                    return response.json()
                except json.JSONDecodeError as e:
                    logger.error(f"Failed to decode JSON from response for {url}: {e}. Response text: {response.text}")
                    raise JsonDecodingError(f"Failed to decode JSON response.", status_code=response.status_code, response_data=response.text)
            return None # No content in response
        except requests.exceptions.Timeout as e:
            logger.error(f"Request to {url} timed out after {self.timeout} seconds: {e}")
            raise NetworkError(f"Request timed out.", response_data=str(e))
        except requests.exceptions.ConnectionError as e:
            logger.error(f"Connection error to {url}: {e}")
            raise NetworkError(f"Connection to API failed.", response_data=str(e))
        except requests.exceptions.HTTPError as e:
            status_code = e.response.status_code
            error_message = f"HTTP Error {status_code} for {url}"
            response_data = None
            try:
                response_data = e.response.json()
            except json.JSONDecodeError:
                response_data = e.response.text # Fallback to raw text if not JSON

            logger.error(f"{error_message}: {response_data}")

            if 400 <= status_code < 500:
                raise ClientError(error_message, status_code=status_code, response_data=response_data)
            elif 500 <= status_code < 600:
                raise ServerError(error_message, status_code=status_code, response_data=response_data)
            else:
                raise ApiException(error_message, status_code=status_code, response_data=response_data)
        except requests.exceptions.RequestException as e:
            logger.error(f"An unexpected request error occurred for {url}: {e}")
            raise ApiException(f"An unexpected error occurred during API request.", response_data=str(e))
        except Exception as e:
            logger.critical(f"An unhandled exception occurred during API request to {url}: {e}", exc_info=True)
            raise ApiException(f"An unhandled error occurred: {str(e)}")

    def get(
        self,
        endpoint: str,
        params: Optional[Dict[str, Any]] = None,
        headers: Optional[Dict[str, str]] = None
    ) -> Any:
        """Performs a GET request."""
        logger.debug(f"Calling GET {endpoint} with params: {params}")
        return self._make_request("GET", endpoint, params=params, headers=headers)

    def post(
        self,
        endpoint: str,
        data: Optional[Union[Dict, str]] = None,
        json_data: Optional[Dict[str, Any]] = None,
        headers: Optional[Dict[str, str]] = None
    ) -> Any:
        """Performs a POST request."""
        logger.debug(f"Calling POST {endpoint} with data: {data}, json: {json_data}")
        return self._make_request("POST", endpoint, data=data, json_data=json_data, headers=headers)

    def put(
        self,
        endpoint: str,
        data: Optional[Union[Dict, str]] = None,
        json_data: Optional[Dict[str, Any]] = None,
        headers: Optional[Dict[str, str]] = None
    ) -> Any:
        """Performs a PUT request."""
        logger.debug(f"Calling PUT {endpoint} with data: {data}, json: {json_data}")
        return self._make_request("PUT", endpoint, data=data, json_data=json_data, headers=headers)

    def delete(
        self,
        endpoint: str,
        headers: Optional[Dict[str, str]] = None
    ) -> Any:
        """Performs a DELETE request."""
        logger.debug(f"Calling DELETE {endpoint}")
        return self._make_request("DELETE", endpoint, headers=headers)

# --- Example Usage (for demonstration purposes) ---
if __name__ == "__main__":
    # IMPORTANT: Replace with your actual API details
    # For testing, you can use a public API like JSONPlaceholder
    # e.g., "https://jsonplaceholder.typicode.com"
    
    # --- Configuration ---
    # Option 1: No specific auth (useful for public APIs or testing)
    # API_BASE_URL = "https://jsonplaceholder.typicode.com"
    # client = ApiClient(base_url=API_BASE_URL)

    # Option 2: API Key authentication (replace with your key)
    # API_BASE_URL = "https://api.example.com/v1"
    # MY_API_KEY = "your_secret_api_key_here"
    # client = ApiClient(base_url=API_BASE_URL, api_key=MY_API_KEY)

    # Option 3: Bearer Token authentication (replace with your token)
    API_BASE_URL = "https://api.example.com/v1" # Placeholder - update this
    MY_BEARER_TOKEN = "your_jwt_bearer_token_here" # Placeholder - update this
    client = ApiClient(base_url=API_BASE_URL, bearer_token=MY_BEARER_TOKEN)

    # For JSONPlaceholder example, let's use a dummy base URL and no auth for the actual calls
    # As the `ApiClient` constructor forces a choice, we'll demonstrate using a public API
    # without specific auth for the example calls below.
    # For real use, configure `client` once with the correct auth.
    jsonplaceholder_client = ApiClient(base_url="https://jsonplaceholder.typicode.com")

    print("\n--- Testing GET Request ---")
    try:
        posts = jsonplaceholder_client.get("posts")
        print(f"Fetched {len(posts)} posts. First post title: {posts[0]['title']}")
    except ApiException as e:
        print(f"Error fetching posts: {e}")

    print("\n--- Testing GET Request (Single Resource) ---")
    try:
        post_id = 1
        single_post = jsonplaceholder_client.get(f"posts/{post_id}")
        print(f"Fetched post {post_id}: {single_post['title']}")
    except ApiException as e:
        print(f"Error fetching post {post_id}: {e}")

    print("\n--- Testing POST Request ---")
    try:
        new_post_data = {
            "title": "foo",
            "body": "bar",
            "userId": 1
        }
        
projectmanager Output

As part of the "API Integration Builder" workflow, we are now executing the "projectmanager → create_project" step. This crucial initial phase lays the foundation for a successful API integration by defining the scope, objectives, technical requirements, and key deliverables.

This document serves as the project initiation output, outlining the framework for your API integration project.


API Integration Project: Project Creation & Definition

1. Project Overview

Project Name: [Customer to Define - e.g., "CRM-ERP Data Sync Integration Project"]

Purpose: To establish a robust and secure integration between your internal systems/applications and one or more external APIs, enabling seamless data exchange and automated workflows. This project aims to leverage external services to enhance your business capabilities, streamline operations, and improve data consistency.

Goal of this Step: To formally initiate the API integration project by defining its core parameters, gathering essential preliminary information, and setting clear expectations for the subsequent phases.

2. Key Project Objectives

The primary objectives for this API Integration Project include:

  • Define Target API(s): Clearly identify the external API(s) to be integrated, along with their primary functionalities and documentation.
  • Identify Core Business Processes: Pinpoint the specific business processes and data flows that will be impacted and enhanced by this integration.
  • Establish Data Synchronization Strategy: Determine the direction (one-way, two-way) and frequency of data exchange, including any necessary data transformations.
  • Outline Security & Authentication: Define the required security protocols and authentication mechanisms for secure communication with the external API(s).
  • Plan for Error Handling & Monitoring: Incorporate strategies for robust error detection, logging, and recovery to ensure integration stability.
  • Resource & Timeline Planning: Begin preliminary planning for the resources required and a high-level timeline for the project's execution.

3. Scope Definition (Preliminary)

This section outlines the initial understanding of what will be included and excluded from this integration project. This will be refined in subsequent design phases.

3.1. In-Scope Components:

  • Integration Target: Integration with [Customer to Specify External API Name(s), e.g., Salesforce API, Stripe API, HubSpot API].
  • Core Functionalities: Implementation of specific functionalities such as:

* [Customer to Specify, e.g., retrieving customer data, submitting order details, syncing product inventory, triggering webhooks].

  • Authentication: Setup and configuration of the agreed-upon authentication method (e.g., OAuth 2.0, API Key, JWT).
  • Basic Data Mapping: Initial design and implementation of mapping between your internal data structures and the external API's data models.
  • Error Handling: Basic error detection, logging, and retry mechanisms for common integration failures.
  • Proof of Concept (PoC): Development of a minimal viable integration to validate connectivity and core data exchange (if required).

3.2. Out-of-Scope Components (Unless explicitly added later):

  • Extensive UI/UX Development: Creation of complex user interfaces specifically for managing or viewing integrated data within your existing applications (beyond necessary configuration interfaces).
  • Advanced Analytics & Reporting: Development of custom dashboards or advanced analytical tools based on integrated data (focus is on data flow).
  • Integration with Other Third-Party Services: Any external services not explicitly identified in the "Integration Target" above.
  • Long-Term Maintenance & Support: Ongoing operational support, monitoring, and future enhancements are typically covered under separate agreements.
  • Data Migration: Large-scale historical data migration (focus is on continuous synchronization).

4. Preliminary API Integration Details

To proceed effectively, we require the following initial information about the target API(s):

  • Target External API Name(s):

* [e.g., "Salesforce REST API"]

* [e.g., "Stripe Payments API"]

  • API Documentation Link(s):

* [e.g., https://developer.salesforce.com/docs/api/latest/rest]

* [e.g., https://stripe.com/docs/api]

  • Key Endpoints/Resources for Integration: (Please provide an initial list of critical endpoints you envision using)

* [e.g., /services/data/vXX.0/sobjects/Account, /v1/charges]

  • Preferred Authentication Method: (e.g., API Key, OAuth 2.0, JWT, Basic Auth)
  • Expected Data Models: (e.g., Customers, Products, Orders, Leads, Payments)
  • Estimated Transaction Volume/Frequency: (e.g., "Hundreds of transactions per hour," "Daily batch updates")

5. Technical Requirements & Considerations

This section outlines the technical environment and specific requirements for the integration.

  • Integration Platform/Language:

* Preferred: [Customer to Specify, e.g., Python, Node.js, Java, C#, Go, or an iPaaS like Zapier, Workato, Mulesoft]

* Rationale (Optional): [e.g., "Aligns with existing tech stack," "Leverages serverless capabilities"]

  • Hosting Environment:

* Preferred: [Customer to Specify, e.g., AWS Lambda, Azure Functions, Google Cloud Run, Kubernetes, Dedicated VM, On-premise server]

* Region (if cloud-based): [e.g., us-east-1]

  • Security Requirements:

* Credential Management: How will API keys/secrets be securely stored and accessed? (e.g., AWS Secrets Manager, Azure Key Vault, HashiCorp Vault)

* Data Encryption: Any specific requirements for data encryption in transit or at rest?

* IP Whitelisting: Is this required by the external API or your internal systems?

  • Monitoring & Logging:

* Preferred Tools: [e.g., CloudWatch, Azure Monitor, Splunk, ELK Stack, Prometheus/Grafana]

* Alerting: What conditions should trigger alerts (e.g., failed requests, rate limit breaches)?

  • Version Control: Integration code will be managed using [e.g., Git, GitHub, GitLab, Bitbucket].

6. Deliverables for This "Project Creation" Phase

Upon completion of this initial phase, you will receive:

  • Project Definition Document (This Output): A comprehensive outline of the project's scope, objectives, and preliminary requirements.
  • Initial Project Plan & High-Level Timeline: A conceptual roadmap for the integration project, including key milestones.
  • Stakeholder Identification: A list of key personnel from both your team and ours who will be involved in the project.
  • Preliminary Risk Assessment: An initial identification of potential risks (technical, operational, security) and proposed mitigation strategies.

7. Next Steps

Following the successful completion of the "projectmanager → create_project" step, the workflow will proceed as follows:

  1. Detailed API Analysis & Design: Deep dive into the external API documentation, specific endpoints, data models, and authentication flows.
  2. Technical Specification Document (TSD): Creation of a detailed technical blueprint, including data flow diagrams, API request/response structures, error handling logic, and security architecture.
  3. Development & Testing: Implementation of the integration logic, unit testing, integration testing, and user acceptance testing (UAT).
  4. Deployment & Monitoring: Production deployment, establishment of monitoring dashboards, and initial operational support.

8. Action Items for Customer (Required Input)

To ensure the project proceeds smoothly and effectively, we kindly request your prompt attention to the following:

  • Review and Confirm: Please review this Project Definition Document and confirm that the objectives, preliminary scope, and technical considerations align with your vision and requirements. Provide any feedback or necessary adjustments.
  • Provide API Details: Furnish the detailed information requested in Section 4 ("Preliminary API Integration Details"), including API documentation links, target endpoints, and desired authentication methods.
  • Identify Business Processes: Clearly articulate the specific business processes you intend to optimize or enable through this API integration.
  • Key Stakeholder Identification: Provide contact information for your key technical and business stakeholders who will be involved in decision-making and providing input throughout the project.
  • Access to Sandbox/Development Environment: If available, please provide access (or guidance on obtaining access) to a sandbox or development environment for the external API and any relevant internal systems.

We look forward to collaborating with you to make this API integration project a resounding success!

api_integration_builder.md
Download as Markdown
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);}});}