API Rate Limiter
Run ID: 69cb661961b1021a29a88a8d2026-03-31Development
PantheraHive BOS
BOS Dashboard

API Rate Limiter: Comprehensive Study Plan

This document outlines a detailed, three-week study plan designed to equip you with a deep understanding of API Rate Limiters, covering their fundamental concepts, architectural design, and practical implementation strategies. This plan is structured to provide a professional and actionable learning path, culminating in the ability to design and discuss robust rate-limiting solutions.


1. Introduction & Importance of API Rate Limiters

API Rate Limiters are critical components in modern distributed systems, serving as gatekeepers for resource access. They regulate the number of requests a client can make to an API within a defined timeframe. Implementing effective rate limiting is crucial for:

  • Preventing Abuse & Misuse: Mitigating DoS/DDoS attacks, brute-force attempts, and spamming.
  • Ensuring Fair Usage: Distributing API resources equitably among all consumers.
  • Maintaining System Stability: Protecting backend services from overload and cascading failures.
  • Cost Control: Managing infrastructure costs associated with excessive resource consumption.
  • Monetization & Tiering: Implementing different service levels based on access rates.

This study plan will guide you through the intricacies of designing and implementing such a vital system component.


2. Learning Objectives

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

  • Understand Core Concepts: Articulate the purpose, benefits, and common challenges associated with API rate limiting.
  • Evaluate Algorithms: Comprehend and critically compare various rate-limiting algorithms (Fixed Window, Sliding Log, Sliding Window Counter, Leaky Bucket, Token Bucket), identifying their strengths and weaknesses.
  • Design Distributed Systems: Architect a scalable and fault-tolerant distributed API rate limiter, considering consistency, concurrency, and performance.
  • Select Technologies: Identify and justify appropriate data structures and technologies (e.g., Redis, in-memory caches) for implementing rate limiters.
  • Implement & Test: Develop a basic working rate limiter and define strategies for testing and monitoring its effectiveness.
  • Discuss Advanced Topics: Engage in informed discussions about advanced rate-limiting scenarios, including burst handling, throttling, and dynamic adjustments.

3. Weekly Schedule

This three-week schedule progressively builds knowledge from foundational concepts to advanced design and implementation.

Week 1: Fundamentals & Core Algorithms

Focus: Understanding the "Why" and "How" of basic rate limiting.

  • Day 1-2: Introduction to Rate Limiting

* What is an API Rate Limiter? (Purpose, Use Cases, Benefits)

* Why is it necessary? (Security, Stability, Cost, Fair Usage)

* Key metrics: requests per second (RPS), requests per minute (RPM), concurrency limits.

* Client-side vs. Server-side considerations.

  • Day 3-4: Basic Rate Limiting Algorithms

* Fixed Window Counter: Concept, implementation details, pros (simplicity), cons (burst problem at window edges).

* Sliding Log: Concept, implementation details (timestamps), pros (accurate), cons (memory usage for large windows).

  • Day 5-6: Advanced Rate Limiting Algorithms (Part 1)

* Sliding Window Counter: Concept (combining fixed window with sliding average), implementation, pros (mitigates burst problem, less memory than sliding log), cons (approximate).

* Leaky Bucket: Concept (fixed output rate, queue), implementation (queue, timer), pros (smooth outgoing traffic), cons (bursts might fill bucket quickly, latency).

  • Day 7: Review & Self-Assessment

* Compare and contrast all algorithms learned.

* Quiz yourself on scenarios where each algorithm is best suited.

Week 2: System Design & Architecture

Focus: Designing a robust, scalable, and distributed API Rate Limiter.

  • Day 1-2: Components of a Distributed Rate Limiter

* Where to place the rate limiter: API Gateway (e.g., NGINX, Envoy), dedicated service, application layer.

* Role of Load Balancers and Proxies.

* Data storage considerations: In-memory vs. Persistent storage (Redis, Memcached).

* Choosing keys for rate limiting (IP address, User ID, API Key, combination).

  • Day 3-4: Handling Distributed Challenges

* Consistency: How to ensure all nodes agree on the current rate count.

* Concurrency & Race Conditions: Strategies for atomic increments/decrements (e.g., Redis INCR, Lua scripts, distributed locks).

* Fault Tolerance: What happens if a rate limiter node fails? Redundancy, replication.

* Scalability: Horizontal scaling strategies for the rate limiting service.

  • Day 5-6: Advanced Rate Limiting Algorithms (Part 2) & Edge Cases

* Token Bucket: Concept (tokens generated at fixed rate, consumed per request), implementation, pros (handles bursts gracefully, simple to implement), cons (token "capacity" needs tuning).

* Throttling vs. Rate Limiting: Understanding the distinction and when to apply each.

* Grace Periods & Overages: How to handle slight превышения of limits.

* Client-side considerations: Retry-After headers, exponential backoff.

  • Day 7: Design Exercise & Review

* Draft a high-level design for a distributed rate limiter for a hypothetical API.

* Identify potential bottlenecks and how to address them.

Week 3: Implementation, Deployment & Operations

Focus: Practical implementation, testing, monitoring, and operational aspects.

  • Day 1-2: Technology Deep Dive & Basic Implementation

* Redis as a Rate Limiter Backend: Explore Redis data structures (Sorted Sets, Hashes, Strings) and commands relevant to rate limiting.

* Implement a Fixed Window Counter using Redis (e.g., INCR, EXPIRE).

* Implement a Sliding Window Counter approximation using Redis (e.g., ZADD, ZREMRANGEBYSCORE, ZCARD).

  • Day 3-4: Implementing Token Bucket / Leaky Bucket

* Implement a Token Bucket algorithm (e.g., using Redis Lua scripts for atomicity or in-memory logic).

* Consider implementing a Leaky Bucket (e.g., using a queue and a background process).

* Discuss trade-offs of in-memory vs. Redis-backed implementations for specific scenarios.

  • Day 5-6: Testing, Monitoring & Optimization

* Testing Strategies: Unit tests for algorithms, integration tests with chosen backend, load testing to verify limits.

* Monitoring & Alerting: Key metrics to track (blocked requests, allowed requests, latency of rate limiter service). Setting up alerts for anomalies.

* Optimization Techniques: Batching updates, local caching, circuit breakers.

* Dynamic Configuration: How to change rate limits on the fly without redeploying.

  • Day 7: Final Project & Comprehensive Review

* Refine your design document from Week 2 with implementation details and operational considerations.

* Present your design or a working prototype.

* Consolidate all learned concepts.


4. Recommended Resources

Leverage a variety of resources to gain a comprehensive understanding.

  • Books:

* "Designing Data-Intensive Applications" by Martin Kleppmann (Chapters on consistency, distributed systems).

* "System Design Interview – An Insider's Guide" by Alex Xu (Often includes rate limiter examples).

  • Online Articles & Blogs:

* Stripe Engineering Blog: Search for articles on rate limiting and API design.

* Uber Engineering Blog: Similar to Stripe, often has excellent system design deep dives.

* Medium/Dev.to: Search for "API Rate Limiting Algorithms Explained" or "System Design Rate Limiter".

* Redis Documentation: Explore commands like INCR, EXPIRE, ZADD, ZREMRANGEBYSCORE, Lua scripting.

* NGINX/Envoy Documentation: Learn how these proxies implement rate limiting.

  • Video Tutorials & Courses:

* YouTube: Search for "System Design Rate Limiter" (e.g., Gaurav Sen, ByteByteGo, Hussein Nasser).

* Educative.io / Grokking the System Design Interview: Often includes a dedicated section on rate limiting.

* Pluralsight/Coursera/Udemy: Look for courses on distributed systems or API design.

  • Open Source Projects:

* Envoy Proxy: Examine its rate limiting configuration and architecture.

* NGINX: Understand its limit_req module.

* Go/Python/Java Rate Limiting Libraries: Explore implementations to see practical code.

* Redis modules: Some Redis modules provide advanced rate-limiting capabilities.


5. Milestones

Tracking progress through defined milestones ensures a structured learning experience.

  • End of Week 1:

* Milestone: Clearly articulate the differences between Fixed Window, Sliding Log, Sliding Window Counter, Leaky Bucket, and Token Bucket algorithms.

* Deliverable: A short summary comparing each algorithm with its pros and cons.

  • End of Week 2:

* Milestone: Develop a high-level architectural design for a distributed rate limiter, identifying key components and addressing consistency challenges.

* Deliverable: A System Design document (2-3 pages) outlining the proposed architecture, data structures, and handling of distributed concerns.

  • End of Week 3:

* Milestone: Implement a functional rate limiter using a chosen algorithm (e.g., Token Bucket or Sliding Window Counter) backed by Redis.

* Deliverable: A working code prototype (e.g., in Python, Go, Node.js) with basic tests, along with a brief explanation of the implementation choices and a plan for monitoring.

  • Overall Completion:

* Milestone: Comprehensive understanding of API Rate Limiters, from concept to scalable implementation.

* Deliverable: A consolidated presentation or report summarizing the entire learning journey, including design rationale, implementation details, and operational considerations.


6. Assessment Strategies

Regular assessment ensures a solid grasp of the material and identifies areas for further study.

  • Self-Assessment Quizzes: At the end of each week, create and answer questions covering the key concepts and algorithms learned.
  • Design Case Studies: Tackle hypothetical system design problems that require integrating a rate limiter (e.g., "Design a rate limiter for Twitter's API," "How would you rate limit a payment gateway?").
  • Code Challenges: Implement specific rate-limiting algorithms from scratch using your preferred programming language and Redis. Focus on correctness, efficiency, and atomicity.
  • Peer Review (Optional): If working with a study group, review each other's design documents and code implementations, providing constructive feedback.
  • Mock System Design Interviews: Practice explaining your rate limiter design, discussing trade-offs, and defending your choices in a mock interview setting.
  • Documentation Review: Evaluate the clarity, completeness, and accuracy of your design documents and code comments.

By diligently following this study plan, you will gain a profound and practical understanding of API Rate Limiters, empowering you to design, implement, and operate them effectively in real-world systems.

gemini Output

This deliverable provides a comprehensive, detailed, and professional implementation of an API Rate Limiter using a Sliding Window Log strategy, backed by Redis for robust, distributed, and scalable operation. The solution includes production-ready Python code, detailed explanations, usage instructions, and considerations for advanced scenarios.


API Rate Limiter: Production-Ready Implementation

1. Introduction to API Rate Limiting

API Rate Limiting is a critical mechanism for controlling the number of requests a client can make to a server within a given timeframe. Its primary purposes include:

  • Preventing Abuse: Mitigating denial-of-service (DoS) attacks, brute-force attacks, and excessive scraping.
  • Ensuring Fair Usage: Distributing API access equitably
gemini Output

This document outlines a comprehensive understanding of API Rate Limiting, a critical component for robust and scalable API management. This deliverable serves as a detailed guide for its implementation, benefits, strategies, and best practices.


API Rate Limiter: Comprehensive Overview and Implementation Guide

1. Introduction to API Rate Limiting

API Rate Limiting is a fundamental mechanism used to control the number of requests a user or client can make to an API within a given timeframe. It acts as a protective layer, ensuring fair usage, maintaining API stability, and preventing abuse or malicious activities.

2. Purpose and Core Objectives

The primary objectives of implementing an API Rate Limiter include:

  • Preventing Abuse and Misuse: Thwarting denial-of-service (DoS) attacks, brute-force attempts, and excessive data scraping.
  • Ensuring API Stability and Performance: Protecting backend services from being overwhelmed by a sudden surge in requests, maintaining responsiveness for all legitimate users.
  • Fair Resource Allocation: Distributing API access equitably among all consumers, preventing a single client from monopolizing resources.
  • Cost Management: Reducing infrastructure costs associated with processing an excessive number of requests.
  • Monetization and Tiered Services: Enabling the creation of different service tiers (e.g., free, standard, premium) with varying rate limits.
  • Security Enhancement: Limiting the speed at which an attacker can test for vulnerabilities or enumerate resources.

3. Key Benefits of API Rate Limiting

Implementing a well-designed API Rate Limiter offers significant advantages:

  • Improved System Reliability: Prevents cascading failures due to overload.
  • Enhanced Security Posture: Mitigates various types of attacks.
  • Predictable Performance: Ensures consistent API response times under normal load.
  • Scalability Support: Helps manage growth by controlling access during peak times.
  • Better User Experience: Prevents one user's excessive usage from degrading service for others.
  • Operational Efficiency: Reduces the need for reactive scaling or incident response to overload situations.

4. Common Rate Limiting Strategies and Algorithms

Several algorithms can be employed for rate limiting, each with its own characteristics:

4.1. Fixed Window Counter

  • Description: Divides time into fixed-size windows (e.g., 60 seconds). Each window has a counter, and requests increment this counter. If the counter exceeds the limit within the window, subsequent requests are blocked until the next window begins.
  • Pros: Simple to implement, low memory usage.
  • Cons: Can suffer from a "bursty" problem at window edges (e.g., 100 requests at the very end of window 1 and 100 requests at the very beginning of window 2, effectively allowing 200 requests in a short span).

4.2. Sliding Window Log

  • Description: Stores a timestamp for each request made by a user. When a new request arrives, it removes all timestamps older than the current time minus the window duration. If the remaining number of timestamps exceeds the limit, the request is denied.
  • Pros: Very accurate, smooth rate limiting, no "bursty" problem.
  • Cons: High memory usage (stores all timestamps), computationally more intensive for large numbers of requests.

4.3. Sliding Window Counter

  • Description: A hybrid approach. It uses two fixed windows: the current window and the previous window. It calculates the allowed requests in the current window based on the percentage of the current window that has passed and the request count from the previous window.
  • Pros: Better accuracy than Fixed Window, lower memory usage than Sliding Window Log.
  • Cons: Still has some potential for burstiness, though less severe than Fixed Window. Offers a good balance between accuracy and resource usage.

4.4. Token Bucket

  • Description: A "bucket" with a fixed capacity is filled with "tokens" at a constant rate. Each API request consumes one token. If the bucket is empty, the request is denied until a new token is added.
  • Pros: Allows for bursts of requests (up to the bucket capacity), simple to understand and implement.
  • Cons: Does not strictly limit the rate but rather the average rate over time, allowing for initial bursts.

4.5. Leaky Bucket

  • Description: Similar to a bucket, but requests are added to the bucket and "leak" out at a constant rate. If the bucket is full, new requests are dropped.
  • Pros: Smooths out request bursts, ensures a steady processing rate.
  • Cons: All requests are processed at a constant rate, which might introduce artificial delays even if the system could handle bursts.

5. Implementation Considerations

When designing and implementing an API Rate Limiter, several factors must be carefully considered:

  • Granularity:

* Per User/Client: Apply limits based on authenticated user IDs or client API keys.

* Per IP Address: Useful for unauthenticated endpoints or to catch widespread abuse.

* Per Endpoint: Different endpoints might have different rate limits (e.g., read operations might be less restricted than write operations).

* Global: A universal limit across the entire API.

  • Distributed Systems: In a microservices architecture, rate limits must be consistent across all instances. This typically requires a shared, highly available data store (e.g., Redis, Cassandra) for counters and timestamps.
  • Client Communication (HTTP Headers):

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

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

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

* HTTP Status Code 429 Too Many Requests: This standard status code should be returned when a client exceeds their rate limit.

  • Error Handling and User Experience:

* Provide clear, informative error messages when a 429 is returned, explaining the rate limit and when the client can retry.

* Consider exponential backoff for clients to automatically retry requests after a delay.

  • Bypass Mechanisms:

* Allow specific internal services or premium clients to bypass rate limits.

* Implement an allowlist for trusted IP addresses or API keys.

  • Edge Cases:

* What happens if the rate limiting service fails? (Fail open/fail close)

* How to handle sudden, legitimate spikes in traffic (e.g., flash sales)?

* Distinguish between malicious attacks and legitimate high-volume users.

6. Key Metrics and Monitoring

Effective monitoring is crucial for understanding the impact and effectiveness of your rate limiting strategy:

  • 429 Response Rate: Track the percentage of requests resulting in a 429 status code.
  • Blocked Request Counts: Monitor the total number of requests blocked by the rate limiter, categorized by client/IP.
  • API Latency: Observe API response times to ensure rate limiting isn't introducing unexpected delays.
  • Resource Utilization: Monitor CPU, memory, and network usage of your API services to ensure they remain within healthy bounds.
  • Active Users/Clients: Track the number of unique clients accessing the API to identify potential anomalies.
  • Alerting: Set up alerts for unusually high 429 rates, indicating potential attacks or misbehaving clients.

7. Best Practices for API Consumers

To ensure smooth interaction with a rate-limited API, clients should adhere to the following best practices:

  • Respect Rate Limit Headers: Always read and respect X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
  • Implement Retry Logic with Exponential Backoff and Jitter: When a 429 is received, wait for the X-RateLimit-Reset time or implement an exponential backoff strategy (e.g., wait 1s, then 2s, then 4s, etc., plus a random jitter to prevent thundering herd problems).
  • Cache Responses: Cache API responses where appropriate to reduce the number of requests made.
  • Batch Requests: If the API supports it, combine multiple operations into a single request to reduce the overall request count.
  • Monitor Your Usage: Clients should track their own API usage to avoid hitting limits unexpectedly.
  • Contact Support: If legitimate business needs require higher limits, clients should contact the API provider to discuss options.

8. Potential Challenges and Mitigations

| Challenge | Mitigation

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