API Rate Limiter
Run ID: 69cae789c8ebe3066ba6f4742026-03-30Development
PantheraHive BOS
BOS Dashboard

Step 2: Code Generation for API Rate Limiter

This output provides a comprehensive, detailed, and professional code generation for an API Rate Limiter. We will cover the fundamental concepts, provide production-ready Python code examples using Flask, demonstrating both in-memory and Redis-backed implementations, and discuss crucial deployment and integration considerations.


1. Introduction to API Rate Limiting

API Rate Limiting is a critical mechanism used to control the number of requests a client can make to an API within a given timeframe. Its primary objectives are:

2. Key Rate Limiting Algorithms

Several algorithms exist to implement rate limiting, each with its strengths and weaknesses:

For our code examples, we will focus on the Fixed Window Counter due to its simplicity in demonstration and its common use case, especially when backed by a distributed store like Redis.

3. Code Implementation: Fixed Window Counter (In-Memory)

This implementation is suitable for a single application instance where state does not need to be shared across multiple servers. It uses a Python dictionary to store request counts.

rate_limiter_in_memory.py

text • 2,573 chars
#### Explanation of In-Memory Code:

1.  **Configuration**: `DEFAULT_LIMIT` and `DEFAULT_WINDOW` define the default rate limit. `RATE_LIMIT_STORE` is a dictionary acting as our in-memory database.
2.  **`rate_limit` Decorator**:
    *   Takes `limit`, `window`, and `key_prefix` as arguments, allowing flexible rate limiting rules per endpoint.
    *   `@wraps(f)` ensures the decorated function retains its original metadata.
    *   **Client Identification**: It determines `client_id` based on `key_prefix`. Options include `request.remote_addr` (IP), `X-User-ID` header, or `X-API-Key` header. This is crucial for distinguishing different clients.
    *   **Fixed Window Logic**:
        *   It retrieves the client's data from `RATE_LIMIT_STORE`.
        *   If `client_data` exists, it checks if the current request falls within the *existing* window (`current_time - window_start_time < window`).
        *   If within the window and the `count` is less than `limit`, the `count` is incremented.
        *   If within the window and `count` *exceeds* `limit`, a `429 Too Many Requests` response is returned, including a `Retry-After` header indicating when the client can try again.
        *   If a *new* window has started (`current_time - window_start_time >= window`), the `timestamp` is reset to `current_time`, and `count` is set to `1`.
        *   If `client_data` does not exist (first request from this client), a new entry is created.
    *   **Request Handling**: If the rate limit is not exceeded, the original function `f` is called.
3.  **API Endpoints**:
    *   `/public`: No rate limit.
    *   `/limited`: Uses the decorator for IP-based rate limiting (3 requests per 30 seconds).
    *   `/user-limited`: Uses the decorator for User-ID-based rate limiting (2 requests per 10 seconds), expecting `X-User-ID` in headers.
    *   `/api-key-limited`: Uses the decorator for API-Key-based rate limiting (1 request per 5 seconds), expecting `X-API-Key` in headers.

### 4. Code Implementation: Fixed Window Counter (Distributed with Redis)

For production environments with multiple application instances (e.g., microservices, load-balanced web servers), an in-memory solution is insufficient as each instance would have its own independent rate limit store. Redis is an excellent choice for a distributed rate limiter due to its speed and atomic operations.

#### Prerequisites:
*   **Redis Server**: Ensure a Redis server is running and accessible.
*   **Python Redis Client**: Install `redis-py`: `pip install redis`

#### `rate_limiter_redis.py`

Sandboxed live preview

Comprehensive Study Plan: Mastering API Rate Limiting

This document outlines a detailed and actionable study plan designed to equip you with a profound understanding of API Rate Limiting, from fundamental concepts to advanced architectural patterns and practical implementation strategies. This plan is structured to provide a professional, in-depth learning experience, culminating in the ability to design, implement, and operate robust rate limiting solutions.


1. Overall Goal

The primary goal of this study plan is to achieve a comprehensive mastery of API Rate Limiting. Upon completion, you will be able to:

  • Understand the critical role of rate limiting in modern API ecosystems.
  • Evaluate and select appropriate rate limiting algorithms for diverse use cases.
  • Design scalable, fault-tolerant, and performant distributed rate limiting systems.
  • Implement rate limiting solutions using various technologies and frameworks.
  • Monitor, troubleshoot, and optimize rate limiting systems in production environments.
  • Discuss advanced topics and integration with other system resilience patterns.

2. Weekly Schedule

This 4-week intensive study plan is designed for approximately 10-15 hours of focused study per week, including reading, hands-on exercises, and project work.

Week 1: Fundamentals & Core Algorithms

  • Focus Areas:

* Introduction to Rate Limiting: Why it's essential (DDoS protection, resource abuse prevention, fair usage, cost control).

* Key Concepts: Requests per second (RPS), burst limits, quotas, rate limiting vs. throttling.

* Basic Algorithms:

* Fixed Window Counter: Simple, but susceptible to "bursty" traffic at window edges.

* Sliding Window Log: Accurate but memory-intensive.

* Sliding Window Counter: A more efficient approximation.

* Token Bucket: Allows for bursts, good for sustained traffic.

* Leaky Bucket: Smooths out bursts, ideal for consistent processing.

* Algorithm Comparison: Pros, cons, and appropriate use cases for each.

* Scope of Rate Limiting: Per-user, per-IP, per-endpoint, global.

  • Activities:

* Read foundational articles and documentation.

* Whiteboard discussions on algorithm mechanics.

* Simple coding exercises to simulate each algorithm (e.g., in Python or Java).

Week 2: System Design & Architecture

  • Focus Areas:

* Placement of Rate Limiters: API Gateway, service mesh (e.g., Envoy), application layer, load balancer.

* Distributed Rate Limiting Challenges: Consistency, latency, fault tolerance, race conditions.

* Data Stores for Rate Limiting: Redis as a distributed counter/store, in-memory caches.

* High-Level Design Patterns: Centralized vs. decentralized approaches, hybrid models.

* Scalability Considerations: Horizontal scaling, sharding, eventual consistency.

* Handling Overloads: Graceful degradation, error responses (HTTP 429 Too Many Requests).

* Authentication & Authorization: How rate limiting integrates with identity management.

  • Activities:

* Study architectural diagrams of major companies' rate limiting systems.

* Participate in system design exercises focusing on distributed rate limiting.

* Propose a high-level architecture for a distributed rate limiter for a hypothetical service.

Week 3: Implementation & Practical Applications

  • Focus Areas:

* Hands-on Implementation with Redis: Using Redis data structures (INCR, ZSET, HASH) to build Token Bucket and Sliding Window Counter algorithms.

* Proxy-based Rate Limiting:

* Nginx limit_req module configuration and best practices.

* Envoy Proxy rate limit filter integration (local and global rate limiting service).

* Language-Specific Libraries: Explore and experiment with popular rate limiting libraries in your preferred language (e.g., ratelimit for Python, resilience4j for Java, golang.org/x/time/rate for Go).

* Configuration Management: Dynamic configuration, A/B testing rate limits.

* Testing Rate Limiters: Unit tests, integration tests, load testing scenarios.

* Monitoring & Alerting: Key metrics to track (rate limit hits, throttled requests, latency), setting up alerts.

  • Activities:

* Build a functional rate limiter using Redis and a backend service.

* Configure Nginx or Envoy to act as a rate limiting gateway for a sample API.

* Develop a test suite to validate the rate limiter's behavior under various loads.

Week 4: Advanced Topics & Case Studies

  • Focus Areas:

* Adaptive Rate Limiting: Dynamically adjusting limits based on system health or traffic patterns.

* Throttling vs. Rate Limiting Revisited: Deeper dive into their distinct purposes and combined usage.

* Integration with Other Resilience Patterns: Circuit breakers, bulkheads, backpressure.

* Cloud Provider Services: Rate limiting capabilities in AWS API Gateway, GCP Cloud Endpoints, Azure API Management.

* Security Implications: Protecting against bypass techniques, IP spoofing.

* Real-World Case Studies: Analyze rate limiting strategies from companies like Stripe, Twitter, Uber, and Netflix.

* Future Trends: Machine learning for anomaly detection and predictive rate limiting.

  • Activities:

* Research and present on a specific company's rate limiting solution.

* Explore how to integrate a rate limiter with a circuit breaker library.

* Discuss potential vulnerabilities and mitigation strategies for rate limit bypass.


3. Learning Objectives

Upon successful completion of this study plan, you will be able to:

  1. Fundamental Understanding: Clearly define API rate limiting, its necessity, and differentiate between various algorithms (Fixed Window, Sliding Window, Token Bucket, Leaky Bucket).
  2. Algorithm Selection: Critically evaluate and select the most appropriate rate limiting algorithm(s) for specific business requirements and traffic patterns.
  3. System Design: Design a scalable, fault-tolerant, and performant distributed API rate limiting system, considering data consistency, latency, and resource utilization.
  4. Technology Proficiency: Demonstrate practical proficiency in using technologies like Redis, Nginx, and Envoy Proxy for implementing and managing rate limiters.
  5. Implementation Skills: Implement a functional rate limiter using a chosen programming language and relevant libraries, or configure a proxy-based solution.
  6. Operational Excellence: Establish effective monitoring, logging, and alerting strategies for rate limiting systems, and troubleshoot common operational issues.
  7. Advanced Concepts: Understand and discuss advanced topics such as adaptive rate limiting, the interplay with other resilience patterns (circuit breakers, backpressure), and cloud-native solutions.
  8. Critical Analysis: Analyze real-world rate limiting implementations and identify potential improvements or vulnerabilities.

4. Recommended Resources

Books & Online Guides:

  • "System Design Interview – An Insider's Guide" by Alex Xu (specifically chapters on API Gateway and Rate Limiter).
  • "Designing Data-Intensive Applications" by Martin Kleppmann (chapters on distributed systems, consistency, and scalability).
  • ByteByteGo.com / Educative.io / Udemy: Search for "System Design Interview" courses that cover API Rate Limiting in depth.
  • Stripe Engineering Blog: Search for articles on rate limiting and API design.
  • Uber Engineering Blog: Articles on their distributed rate limiting system.
  • Nginx Documentation: ngx_http_limit_req_module and ngx_http_limit_conn_module.
  • Envoy Proxy Documentation: Rate Limit filter and Global Rate Limit Service.
  • Redis Documentation: For understanding data structures like INCR, ZSET, HASH.

Online Articles & Tutorials:

  • "How to Design a Scalable Rate Limiting Algorithm" - Gaurav Sen (YouTube/Blog).
  • "Rate Limiting in Distributed Systems" - DigitalOcean Community.
  • "System Design: Rate Limiter" - InterviewBit/GeeksforGeeks.
  • Tutorials on implementing rate limiters using Redis in Python/Java/Go/Node.js.

Tools & Libraries:

  • Redis: Essential for hands-on distributed rate limiting implementation.
  • Docker/Docker Compose: For easily setting up local Redis, Nginx, or Envoy environments.
  • Postman/Insomnia: For API testing and simulating traffic.
  • Load Testing Tools: Apache JMeter, k6, Locust for simulating high traffic.
  • Programming Language-Specific Libraries:

* Python: ratelimit, limits

* Java: resilience4j-ratelimiter, Guava RateLimiter

* Go: golang.org/x/time/rate

* Node.js: express-rate-limit, rate-limiter-flexible


5. Milestones

Achieving these milestones will mark significant progress and validate your understanding at each stage of the study plan.

  • Milestone 1 (End of Week 1): Foundational Understanding

* Deliverable: A short presentation or written summary comparing the four core rate limiting algorithms (Fixed Window, Sliding Window Log/Counter, Token Bucket, Leaky Bucket), including their pros, cons, and a specific use case for each.

* Assessment: Peer review or self-assessment against a rubric for clarity and accuracy.

  • Milestone 2 (End of Week 2): Architectural Design Capability

* Deliverable: A high-level system design document (including diagrams) for a distributed rate limiting service for a hypothetical e-commerce API. The design should address scalability, consistency, and fault tolerance.

* Assessment: Review by a mentor or senior engineer for architectural soundness and consideration of distributed system challenges.

  • Milestone 3 (End of Week 3): Practical Implementation

* Deliverable: A working proof-of-concept (PoC) of an API rate limiter. This could be:

* A backend service with a Redis-backed rate limiter (e.g., Token Bucket or Sliding Window

python

import time

from functools import wraps

from flask import Flask, request, jsonify

import redis

--- Configuration ---

Default rate limit: 5 requests per 60 seconds

DEFAULT_LIMIT = 5

DEFAULT_WINDOW = 60 # seconds

Redis connection settings

REDIS_HOST = 'localhost'

REDIS_PORT = 6379

REDIS_DB = 0

Connect to Redis

try:

r = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, decode_responses=True)

r.ping() # Test connection

print("Successfully connected to Redis.")

except redis.exceptions.ConnectionError as e:

print(f"Could not connect to Redis: {e}")

print("Please ensure Redis server is running and accessible.")

# Exit or handle gracefully if Redis is critical for startup

exit(1)

app = Flask(__name__)

--- Rate Limit Decorator (Redis-backed) ---

def rate_limit_redis(limit=DEFAULT_LIMIT, window=DEFAULT_WINDOW, key_prefix="ip"):

"""

A Redis-backed rate limiting decorator for Flask endpoints.

Uses a

gemini Output

As a professional AI assistant, I have thoroughly reviewed and documented the topic of "API Rate Limiter." This deliverable provides a comprehensive, detailed, and actionable overview, covering its purpose, common algorithms, implementation considerations, and best practices for both providers and consumers.


API Rate Limiter: Comprehensive Overview and Best Practices

1. Introduction to API Rate Limiting

An API Rate Limiter is a critical component in modern web infrastructure designed to control the number of requests a client can make to an API within a defined timeframe. It acts as a gatekeeper, preventing abuse, ensuring fair usage, and maintaining the stability and performance of the API service.

2. Why API Rate Limiting is Essential

Implementing an API Rate Limiter provides numerous benefits for both API providers and consumers:

  • Preventing Abuse and Misuse: Protects against malicious activities such as Denial-of-Service (DoS) attacks, brute-force attempts, and data scraping by bots.
  • Ensuring Fair Usage: Distributes available resources equitably among all users, preventing a single user or a few users from monopolizing the API and degrading performance for others.
  • Maintaining System Stability and Performance: Protects backend services, databases, and other infrastructure from being overwhelmed by excessive requests, ensuring consistent response times and availability.
  • Cost Management: For cloud-based services, limiting requests can help control operational costs associated with compute, bandwidth, and database operations.
  • Monetization and Tiered Services: Enables API providers to offer different service tiers (e.g., free, premium, enterprise) with varying rate limits, allowing for monetization strategies.
  • Improved User Experience: By preventing system overload, rate limiting indirectly contributes to a more reliable and responsive API for legitimate users.

3. Common Rate Limiting Algorithms

Several algorithms are employed to implement rate limiting, each with its own advantages and trade-offs:

3.1. Fixed Window Counter

  • Mechanism: Divides time into fixed-size windows (e.g., 60 seconds). Each window has a counter. When a request arrives, the counter for the current window is incremented. If the counter exceeds the limit within that window, the request is blocked.
  • Pros: Simple to implement, low memory footprint.
  • Cons: Can suffer from a "bursty" problem where requests at the very end of one window and the very beginning of the next window can effectively double the allowed rate within a short period.
  • Example: 100 requests per 60 seconds. A client makes 100 requests at 0:59 and another 100 requests at 1:01. Within a 2-second span, 200 requests are processed.

3.2. Sliding Window Log

  • Mechanism: For each client, stores a timestamp for every request made within the rate limit window. When a new request arrives, it counts how many timestamps fall within the current window (e.g., the last 60 seconds). If the count exceeds the limit, the request is blocked.
  • Pros: Very accurate, avoids the "bursty" problem of Fixed Window Counter.
  • Cons: High memory consumption, especially for high request volumes and long windows, as it needs to store all timestamps.
  • Example: 100 requests per 60 seconds. If a client has 99 requests logged in the last 60 seconds, the 100th request is allowed. If the 101st request comes, it's blocked.

3.3. Sliding Window Counter (Hybrid)

  • Mechanism: A hybrid approach that combines the Fixed Window Counter with a weighted average. It uses two fixed windows: the current window and the previous window. When a request comes in, it calculates the allowed requests in the current window by taking a fraction of the previous window's count (based on how much of that window has passed) and adding it to the current window's count.
  • Pros: Mitigates the "bursty" problem better than Fixed Window Counter while being more memory-efficient than Sliding Window Log.
  • Cons: Not perfectly accurate, as it's an approximation. More complex to implement than Fixed Window Counter.
  • Example: If 50% of the previous 60-second window has passed, and it had 80 requests, the current window's effective count starts with 0.5 * 80 = 40 requests, plus any requests made in the current window.

3.4. Token Bucket

  • Mechanism: Imagine a bucket with a fixed capacity that holds "tokens." Tokens are added to the bucket at a constant "refill rate." Each incoming request consumes one token. If the bucket is empty, the request is delayed or dropped. The bucket capacity allows for bursts of requests up to its size.
  • Pros: Allows for bursts of traffic up to the bucket capacity, simple to understand and implement.
  • Cons: Can be challenging to tune the refill rate and bucket size for optimal performance.
  • Example: A bucket with a capacity of 100 tokens, refilling at 10 tokens per second. A client can make 100 requests instantly (emptying the bucket), then has to wait for tokens to refill.

3.5. Leaky Bucket

  • Mechanism: Similar to Token Bucket but with a different analogy. Requests are "water" poured into a bucket. The bucket "leaks" at a constant rate, meaning requests are processed at a steady output rate. If the bucket overflows (receives more requests than it can hold before they leak out), new requests are dropped.
  • Pros: Smooths out traffic, ensures a constant output rate, good for backend stability.
  • Cons: Does not allow for bursts; all requests are processed at the fixed leak rate. Can introduce latency for requests during high traffic.
  • Example: A bucket that can hold 100 requests, leaking 10 requests per second. If 150 requests arrive instantly, 50 are dropped, and the remaining 100 are processed at 10 requests per second.

4. Key Considerations for API Providers

When implementing an API Rate Limiter, consider the following aspects:

  • Granularity:

* Per User/Client: Apply limits based on authenticated user IDs or API keys. This is common for most APIs.

* Per IP Address: Useful for unauthenticated endpoints or to catch bot traffic, but can be problematic for users behind shared NATs or proxies.

* Per Endpoint: Different limits for different API endpoints (e.g., read operations might have higher limits than write operations).

* Hybrid: A combination of the above for robust protection.

  • Distributed Systems: In a microservices architecture or cloud environment, rate limiters must be distributed and share state (e.g., using Redis or a distributed cache) to ensure consistent enforcement across multiple instances.
  • Bursting: Decide if you want to allow for short bursts of requests above the average rate. Token Bucket is ideal for this.
  • Grace Periods/Backoff: Implement a mechanism to allow clients a short grace period before strict blocking, or recommend exponential backoff strategies for retries.
  • Error Handling and Communication:

* HTTP Status Codes: Use 429 Too Many Requests (RFC 6585) when a client exceeds the rate limit.

* Response Headers: Provide clear information to clients about their current rate limit status:

* X-RateLimit-Limit: The maximum number of requests allowed in the current window.

* X-RateLimit-Remaining: The number of requests remaining in the current window.

* X-RateLimit-Reset: The time (usually in UTC epoch seconds) when the current rate limit window resets.

* Documentation: Clearly document your rate limiting policies in your API documentation.

  • Monitoring and Alerting: Monitor rate limit hits, blocked requests, and identify patterns of abuse. Set up alerts for unusual activity.
  • Edge Cases:

* Whitelisting: Allow specific IP addresses or client IDs (e.g., internal services, trusted partners) to bypass rate limits.

* DDoS Protection: While rate limiting helps, it's not a full DDoS solution. Consider integrating with dedicated DDoS protection services.

* Bot Traffic: Implement additional measures like CAPTCHAs or bot detection services for sophisticated bots.

  • Configuration Management: Make rate limit rules configurable, allowing for dynamic adjustments without code redeployment.

5. Best Practices for API Consumers

Developers consuming rate-limited APIs should adopt the following practices:

  • Read API Documentation: Understand the specific rate limits, headers, and retry policies provided by the API.
  • Respect 429 Too Many Requests: Do not immediately retry failed requests. This will only exacerbate the problem.
  • Utilize Rate Limit Headers: Parse and use X-RateLimit-Limit, X-RateLimit-Remaining, and especially X-RateLimit-Reset to intelligently manage request frequency.
  • Implement Retry Mechanisms with Exponential Backoff:

* When a 429 is received, wait for the time specified in X-RateLimit-Reset before retrying, or implement an exponential backoff strategy (e.g., wait 1 second, then 2 seconds, then 4 seconds, etc., with some jitter).

* Cap the maximum backoff time to prevent excessively long waits.

* Limit the number of retry attempts.

  • Client-Side Throttling: Implement your own client-side rate limiting to prevent hitting the API's limits in the first place. This is more efficient than waiting for 429 errors.
  • Batch Requests: Where possible, combine multiple smaller requests into a single, larger request to reduce the total number of API calls.
  • Cache Responses: Cache API responses on your end for data that doesn't change frequently, reducing the need for repeated API calls.

6. Example Use Cases

API Rate Limiters are crucial in various scenarios:

  • Social Media APIs: Limiting post creations, friend requests, or data fetches to prevent spam and abuse.
  • E-commerce APIs: Controlling the number of product searches, order placements, or inventory updates.
  • Payment Gateway APIs: Restricting the frequency of transaction requests to prevent fraud and system overload.
  • Cloud Provider APIs: Limiting resource provisioning or management calls to ensure infrastructure stability.
  • Search Engine APIs: Managing query volumes to maintain search performance and prevent scraping.

7. Conclusion

API Rate Limiting is an indispensable security and performance feature for any public-facing or critical internal API. By carefully selecting an appropriate algorithm, configuring granular limits, providing transparent communication through HTTP headers, and encouraging best practices for consumers, API providers can build robust, scalable, and resilient services that deliver a consistent and reliable experience.

api_rate_limiter.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);}});}