Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heroku API #359

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions New_APIs/Heroku API/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Heroku API

## Description

A basic API built using Node.js and Express to interact with the Heroku platform. It allows users to deploy applications, scale dynos, and retrieve logs programmatically.

## Installation

To install the required packages, run:

```bash
npm install express
npm install axios
npm install nodemon
npm install
15 changes: 15 additions & 0 deletions New_APIs/Heroku API/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"short_name": "HerokuAPI",
"name": "Heroku API",
"icons": [
{
"src": "icon.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
20 changes: 20 additions & 0 deletions New_APIs/Heroku API/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "heroku-api",
"version": "1.0.0",
"description": "A simple API to interact with Heroku platform for deployments, scaling, and logs.",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.27.2",
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^2.0.22"
}
}

20 changes: 20 additions & 0 deletions New_APIs/Heroku API/packet-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "heroku-api",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "heroku-api",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"axios": "^0.27.2",
"express": "^4.18.2",
"nodemon": "^2.0.22"
}
},
// Other dependencies
}
}

62 changes: 62 additions & 0 deletions New_APIs/Heroku API/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Heroku API</title>
</head>
<body>
<h1>Heroku API</h1>
<div id="app">
<h2>Deploy</h2>
<input type="text" id="deployAppName" placeholder="App Name">
<input type="text" id="deploySourceUrl" placeholder="Source URL">
<button id="deployButton">Deploy</button>
<h2>Scale</h2>
<input type="text" id="scaleAppName" placeholder="App Name">
<input type="text" id="scaleDynoType" placeholder="Dyno Type">
<input type="number" id="scaleQuantity" placeholder="Quantity">
<button id="scaleButton">Scale</button>
<h2>Logs</h2>
<input type="text" id="logsAppName" placeholder="App Name">
<button id="logsButton">Get Logs</button>
<ul id="results"></ul>
</div>

<script>
document.getElementById('deployButton').addEventListener('click', async () => {
const appName = document.getElementById('deployAppName').value;
const sourceUrl = document.getElementById('deploySourceUrl').value;
const response = await fetch('/deploy', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ app_name: appName, source_url: sourceUrl })
});
const result = await response.json();
console.log(result);
});

document.getElementById('scaleButton').addEventListener('click', async () => {
const appName = document.getElementById('scaleAppName').value;
const dynoType = document.getElementById('scaleDynoType').value;
const quantity = document.getElementById('scaleQuantity').value;
const response = await fetch('/scale', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ app_name: appName, dyno_type: dynoType, quantity: parseInt(quantity) })
});
const result = await response.json();
console.log(result);
});

document.getElementById('logsButton').addEventListener('click', async () => {
const appName = document.getElementById('logsAppName').value;
const response = await fetch(`/logs?app_name=${appName}`);
const result = await response.json();
const results = document.getElementById('results');
results.innerHTML = JSON.stringify(result, null, 2);
});
</script>
</body>
</html>
76 changes: 76 additions & 0 deletions New_APIs/Heroku API/public/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
background: linear-gradient(135deg, #f06, #00f);
color: #fff;
}

h1 {
margin-top: 30px;
font-size: 2.5em;
}

h2 {
margin-top: 20px;
font-size: 1.8em;
}

#app {
margin-top: 20px;
width: 90%;
max-width: 600px;
background-color: rgba(255, 255, 255, 0.8);
color: #333;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}

input, button, select {
margin: 10px 0;
padding: 12px;
width: 100%;
box-sizing: border-box;
border-radius: 5px;
border: 1px solid #ddd;
font-size: 1em;
}

button {
background-color: #007BFF;
color: #fff;
border: none;
cursor: pointer;
transition: background-color 0.3s ease;
}

button:hover {
background-color: #0056b3;
}

ul {
list-style-type: none;
padding: 0;
margin-top: 20px;
background: rgba(255, 255, 255, 0.9);
color: #333;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

li {
margin: 10px 0;
padding: 10px;
background-color: rgba(233, 233, 233, 0.9);
border-radius: 5px;
border: 1px solid #ccc;
}

input::placeholder, select::placeholder {
color: #aaa;
}
59 changes: 59 additions & 0 deletions New_APIs/Heroku API/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const express = require('express');
const axios = require('axios');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.json());
app.use(express.static(path.join(__dirname, '../public')));

const HEROKU_API_KEY = 'your_heroku_api_key';

const headers = {
'Authorization': `Bearer ${HEROKU_API_KEY}`,
'Accept': 'application/vnd.heroku+json; version=3',
'Content-Type': 'application/json'
};

app.post('/deploy', async (req, res) => {
const { app_name, source_url } = req.body;
const url = `https://api.heroku.com/apps/${app_name}/builds`;
const payload = { source_blob: { url: source_url } };

try {
const response = await axios.post(url, payload, { headers });
res.json(response.data);
} catch (error) {
res.status(error.response.status).json(error.response.data);
}
});

app.post('/scale', async (req, res) => {
const { app_name, dyno_type, quantity } = req.body;
const url = `https://api.heroku.com/apps/${app_name}/formation`;
const payload = { updates: [{ type: dyno_type, quantity }] };

try {
const response = await axios.patch(url, payload, { headers });
res.json(response.data);
} catch (error) {
res.status(error.response.status).json(error.response.data);
}
});

app.get('/logs', async (req, res) => {
const { app_name } = req.query;
const url = `https://api.heroku.com/apps/${app_name}/log-sessions`;
const payload = { dyno: 'web', lines: 100, source: 'app', tail: true };

try {
const response = await axios.post(url, payload, { headers });
res.json(response.data);
} catch (error) {
res.status(error.response.status).json(error.response.data);
}
});

app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Loading