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

API Integration Builder: Code Generation Deliverable

This document provides the comprehensive, detailed, and professional code output for the "generate_code" step of the "API Integration Builder" workflow. This deliverable is designed to provide you with production-ready, well-commented code to integrate with an external API, along with explanations, usage instructions, and best practices.


1. Introduction and Purpose

This output delivers a robust, modular, and extensible Python-based API client example. It demonstrates how to interact with a typical RESTful API, covering essential aspects such as configuration, authentication, making various HTTP requests, handling responses, and robust error management.

While this example uses JSONPlaceholder (a free fake API for testing and prototyping) for demonstration purposes, the patterns and principles applied are universally applicable to integrating with any RESTful API. You can easily adapt this structure and code to your specific API integration needs by modifying the configuration and endpoint methods.

Key Features of the Generated Code:


2. Core Concepts for API Integration

Before diving into the code, it's important to understand some core concepts crucial for successful API integration:


3. Example Scenario: JSONPlaceholder Integration

For this deliverable, we will integrate with JSONPlaceholder to perform the following operations:


4. Technology Stack

Prerequisites:

Before running the code, ensure you have Python 3 installed and install the necessary libraries:

text • 247 chars
---

### 5. Generated Code

Below is the production-ready, well-commented code for the `JSONPlaceholder` API integration.

#### `api_client.py`

This file contains the `JSONPlaceholderClient` class, which encapsulates all API interaction logic.

Sandboxed live preview

python

from api_client import JSONPlaceholderClient, APIConfig, APIRequestError, APIClientError, APIServerError

import logging

Set up logging for the main script

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

projectmanager Output

API Integration Builder: Project Creation Output

This document provides a comprehensive, detailed, and professional output for the "API Integration Builder" workflow, specifically for the projectmanager → create_project step. This deliverable is designed to guide you through the process of integrating with an external Project Management System (PMS) API to programmatically create new projects.


1. Introduction & Workflow Context

Workflow: API Integration Builder

Current Step: projectmanager → create_project

Objective: To generate the necessary code and guidance for integrating with an external API to create new projects within a chosen Project Management System (PMS). This output will enable you to automate project creation based on triggers or other system events.

The projectmanager → create_project action is a critical component for automating project lifecycle management. By integrating with a PMS API, you can ensure consistency, reduce manual effort, and streamline your operational workflows.


2. Understanding the "create_project" Action

The create_project action typically involves sending a structured request to a Project Management System's API endpoint. This request contains all the necessary data to define a new project.

Common Parameters for Project Creation:

  • projectName (Required): The unique name for the new project.
  • description (Optional but Recommended): A detailed description of the project's purpose, scope, and objectives.
  • projectLeadId / projectOwner (Required/Optional): The ID or username of the individual responsible for leading the project.
  • startDate (Optional): The planned start date for the project (e.g., "YYYY-MM-DD").
  • endDate (Optional): The planned end date for the project (e.g., "YYYY-MM-DD").
  • projectKey (Optional, often system-generated): A short, unique identifier for the project, common in systems like Jira.
  • templateId / templateKey (Optional): If the PMS supports project templates, the ID or key of the template to use.
  • category / type (Optional): The category or type of project (e.g., "Software Development", "Marketing Campaign").
  • teamMembers (Optional): A list of initial team members to be assigned to the project.
  • status (Optional): Initial status of the project (e.g., "New", "Proposed", "Active").
  • customFields (Optional): Any additional custom fields configured in your PMS that need to be populated.

3. Prerequisites for API Integration

Before implementing the code, ensure you have the following:

  1. Target PMS API Documentation: Access to the official API documentation of your chosen Project Management System (e.g., Jira API, Asana API, Trello API, Monday.com API). This documentation will provide the exact endpoint URLs, required parameters, authentication methods, and response formats.
  2. API Base URL: The root URL for the API endpoints (e.g., https://your-domain.atlassian.net/rest/api/2/ for Jira, https://app.asana.com/api/1.0/ for Asana).
  3. Authentication Credentials:

* API Key / Personal Access Token: A token generated from your PMS account with sufficient permissions to create projects.

* OAuth 2.0 Client Credentials: If using OAuth, you'll need a Client ID, Client Secret, and the necessary scope(s) to obtain an access token.

  1. Required Project Data: The specific data points you intend to use for creating new projects (e.g., project name, description, lead).

4. General API Integration Principles for Project Creation

Most create_project operations follow a standard RESTful API pattern:

  • HTTP Method: POST
  • Endpoint: Typically something like /projects or /project appended to the base URL.
  • Request Headers:

* Content-Type: application/json (to indicate the body format)

* Authorization: Bearer YOUR_ACCESS_TOKEN or Basic YOUR_ENCODED_API_KEY (for authentication)

  • Request Body (Payload): A JSON object containing the project details as defined by the PMS API.
  • Success Response: Typically a 200 OK or 201 Created status code, often returning the newly created project's ID and details.
  • Error Response: Non-2xx status codes (e.g., 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error) with an error message in the response body.

5. Code Generation Example (Python)

Below is a generic Python code template for creating a project via a REST API. This example uses the requests library, which is standard for HTTP requests in Python.

Assumptions for this example:

  • The API uses a POST request.
  • The API expects a JSON payload.
  • Authentication is handled via an Authorization: Bearer token.
  • The API returns a JSON response upon success.

import requests
import json
import os # For environment variables

def create_project(project_name: str, description: str, project_lead_id: str,
                   start_date: str = None, end_date: str = None, **kwargs) -> dict:
    """
    Integrates with an external Project Management System (PMS) API to create a new project.

    This function is a generic template. You MUST customize the API_BASE_URL,
    API_ENDPOINT, and the structure of the 'payload' and 'headers'
    according to your specific PMS API documentation (e.g., Jira, Asana, Monday.com).

    Args:
        project_name (str): The name of the new project.
        description (str): A detailed description for the project.
        project_lead_id (str): The ID or identifier of the project lead/owner.
        start_date (str, optional): The planned start date (e.g., "YYYY-MM-DD"). Defaults to None.
        end_date (str, optional): The planned end date (e.g., "YYYY-MM-DD"). Defaults to None.
        **kwargs: Additional parameters specific to the target PMS API
                  (e.g., 'project_key', 'template_id', 'category', 'team_members', 'custom_fields').

    Returns:
        dict: A dictionary containing the response from the API, or an error message.
    """

    # --- Configuration (MUST BE CUSTOMIZED) ---
    # It's recommended to store sensitive information like API keys in environment variables.
    API_BASE_URL = os.getenv("PMS_API_BASE_URL", "https://api.example-pms.com/v1")
    API_ENDPOINT = "/projects" # e.g., "/rest/api/2/project" for Jira, "/projects" for Asana
    API_TOKEN = os.getenv("PMS_API_TOKEN", "YOUR_SECURE_API_TOKEN_HERE") # Replace or use env var
    # API_USERNAME = os.getenv("PMS_API_USERNAME", "your_username") # For Basic Auth
    # API_PASSWORD = os.getenv("PMS_API_PASSWORD", "your_password") # For Basic Auth

    # Construct the full API URL
    full_api_url = f"{API_BASE_URL}{API_ENDPOINT}"

    # --- Request Headers (Customize based on your PMS API) ---
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Authorization": f"Bearer {API_TOKEN}" # Common for OAuth/Personal Access Tokens
        # For Basic Auth (e.g., some Jira APIs with API token as password):
        # "Authorization": f"Basic {base64.b64encode(f'{API_USERNAME}:{API_TOKEN}'.encode()).decode()}"
    }

    # --- Request Body (Payload - CUSTOMIZE SIGNIFICANTLY) ---
    # This payload structure is GENERIC. Refer to your PMS API documentation
    # for the exact required and optional fields.
    payload = {
        "name": project_name,
        "description": description,
        "lead": {
            "id": project_lead_id # Or "emailAddress", "accountId", etc., depending on PMS
        },
        "startDate": start_date,
        "endDate": end_date,
        # Add any additional parameters passed via kwargs
        **kwargs
    }

    # Remove None values from payload if the API doesn't handle them well
    payload = {k: v for k, v in payload.items() if v is not None}

    print(f"Attempting to create project at: {full_api_url}")
    print(f"Payload: {json.dumps(payload, indent=2)}")

    try:
        response = requests.post(full_api_url, headers=headers, json=payload, timeout=30)
        response.raise_for_status()  # Raise an HTTPError for bad responses (4xx or 5xx)

        # Parse the JSON response
        response_data = response.json()

        print(f"Project '{project_name}' created successfully!")
        print(f"API Response: {json.dumps(response_data, indent=2)}")
        return response_data

    except requests.exceptions.HTTPError as http_err:
        error_message = f"HTTP error occurred: {http_err}"
        if response.content:
            try:
                error_details = response.json()
                error_message += f"\nAPI Error Details: {json.dumps(error_details, indent=2)}"
            except json.JSONDecodeError:
                error_message += f"\nAPI Raw Error Response: {response.text}"
        print(f"Error creating project: {error_message}")
        return {"status": "error", "message": error_message}
    except requests.exceptions.ConnectionError as conn_err:
        print(f"Connection error occurred: {conn_err}")
        return {"status": "error", "message": f"Network connection error: {conn_err}"}
    except requests.exceptions.Timeout as timeout_err:
        print(f"Timeout error occurred: {timeout_err}")
        return {"status": "error", "message": f"Request timed out: {timeout_err}"}
    except requests.exceptions.RequestException as req_err:
        print(f"An unexpected request error occurred: {req_err}")
        return {"status": "error", "message": f"An unexpected error: {req_err}"}
    except Exception as e:
        print(f"An unknown error occurred: {e}")
        return {"status": "error", "message": f"An unknown error: {e}"}

# --- Example Usage ---
if __name__ == "__main__":
    # IMPORTANT: Set these environment variables or replace placeholders for testing.
    # os.environ["PMS_API_BASE_URL"] = "YOUR_PMS_API_BASE_URL"
    # os.environ["PMS_API_TOKEN"] = "YOUR_PMS_API_TOKEN"

    # Example 1: Basic project creation
    print("\n--- Running Example 1: Basic Project ---")
    new_project_data_1 = create_project(
        project_name="PantheraHive Q3 Initiative",
        description="Launch a new AI-driven workflow automation platform for enterprise clients.",
        project_lead_id="johndoe", # This ID needs to exist in your PMS
        start_date="2023-07-01",
        end_date="2023-09-30"
    )
    # print(new_project_data_1)

    # Example 2: Project with additional custom fields (requires PMS support)
    print("\n--- Running Example 2: Project with Custom Fields ---")
    new_project_data_2 = create_project(
        project_name="Internal HR System Upgrade",
        description="Upgrade the legacy HR system to a modern cloud-based solution.",
        project_lead_id="janedoe",
        start_date="2023-08-15",
        category="Internal IT", # Example of a custom field or specific PMS field
        priority="High",        # Another example
        department="IT"         # Another example
    )
    # print(new_project_data_2)

    # Example 3: Simulating a failed request (e.g., wrong endpoint or auth)
    # For this to actually fail, you'd need to modify API_ENDPOINT or API_TOKEN in the function.
    # For demonstration, we'll just show how the error handling would print.
    print("\n--- Running Example 3: Simulated Failed Request (due to invalid lead) ---")
    # This assumes the PMS API would return an error if project_lead_id is invalid
    # In a real scenario, you might get a 400 or 404 error from the API.
    # To truly test failure, you might deliberately use a wrong URL or token.
    failed_project_data = create_project(
        project_name="Test Failed Project",
        description="This project should fail due to an invalid lead.",
        project_lead_id="invalid_user_id_12
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);}});}