added frontend and script examples

This commit is contained in:
CaffeineFueled 2025-04-15 23:33:44 +02:00
parent 368c4de6fe
commit 61b10a2bc2
6 changed files with 385 additions and 0 deletions

View file

@ -101,6 +101,59 @@ Response:
- CSV files: Must have a header row with column names
- JSON files: Must contain valid JSON data
## Using the API in External Applications
### Python Example
Here's how to consume the API data in a Python script:
```python
import requests
import pandas as pd
from pprint import pprint
# Base URL of the API
API_BASE_URL = 'http://localhost:8000'
# Example 1: Get users data
response = requests.get(f"{API_BASE_URL}/api/users")
users_data = response.json()
pprint(users_data)
# Example 2: Get contacts and convert to DataFrame
response = requests.get(f"{API_BASE_URL}/api/contacts")
contacts_data = response.json()
contacts_df = pd.DataFrame(contacts_data)
print(contacts_df)
# Example 3: Extract specific information
contacts_response = requests.get(f"{API_BASE_URL}/api/contacts")
contacts = contacts_response.json()
locations = [contact['location'] for contact in contacts]
print(f"Available locations: {locations}")
# Example 4: Filtering data
users_response = requests.get(f"{API_BASE_URL}/api/users")
users_data = users_response.json()
filtered_users = [user for user in users_data.get('users', [])
if user.get('name') == 'John']
print(f"Filtered users: {filtered_users}")
```
Output:
```
{'users': [{'name': 'John', 'email': 'john@example.com'},
{'name': 'Jane', 'email': 'jane@example.com'}]}
location contact
0 dortmund achim
1 madrid santos
Available locations: ['dortmund', 'madrid']
Filtered users: [{'name': 'John', 'email': 'john@example.com'}]
```
## Manual Container Setup
### Docker

33
frontend/README.md Normal file
View file

@ -0,0 +1,33 @@
# Static2API Frontend
This is a simple frontend that displays data from the Static2API application. It's designed to work with the API without requiring any changes to the container or backend.
## Usage
1. Start the Static2API application either directly or via container:
```
python main.py
```
or
```
./run_container.sh
```
2. Open the `index.html` file in your browser:
- You can use any static file server
- Or simply open the file directly in your browser
3. The frontend will fetch data from the following endpoints:
- `/` - Root endpoint
- `/api/users` - Users data
- `/api/contacts` - Contacts data
## CORS Support
The FastAPI application has been updated with CORS middleware to allow cross-origin requests from this frontend. This means you can:
1. Open the HTML file directly in your browser
2. Access the API endpoints without CORS restrictions
3. Serve the frontend from any static file server
No additional configuration is needed for CORS support.

110
frontend/index.html Normal file
View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Static2API Frontend</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1000px;
margin: 0 auto;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.endpoints {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.endpoint {
flex: 1;
min-width: 300px;
border: 1px solid #ddd;
border-radius: 6px;
padding: 15px;
}
.endpoint h2 {
margin-top: 0;
color: #2c3e50;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
pre {
background-color: #f8f9fa;
padding: 12px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
}
.loading {
text-align: center;
color: #666;
font-style: italic;
}
.example {
margin-top: 40px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 6px;
border-left: 4px solid #4a90e2;
}
.example h2 {
margin-top: 0;
color: #2c3e50;
}
.location-list {
list-style-type: none;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.location-item {
background-color: #e8f4fd;
padding: 8px 15px;
border-radius: 20px;
border: 1px solid #c8e1fb;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<h1>Static2API Frontend</h1>
<div class="endpoints">
<div class="endpoint">
<h2>Root Endpoint</h2>
<div id="root-data" class="loading">Loading...</div>
</div>
<div class="endpoint">
<h2>Users API</h2>
<div id="users-data" class="loading">Loading...</div>
</div>
<div class="endpoint">
<h2>Contacts API</h2>
<div id="contacts-data" class="loading">Loading...</div>
</div>
</div>
<div class="example">
<h2>Example: Locations from Contacts</h2>
<p>This example extracts and displays all unique locations from the contacts data:</p>
<div id="locations-example" class="loading">Loading locations...</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

88
frontend/script.js Normal file
View file

@ -0,0 +1,88 @@
document.addEventListener('DOMContentLoaded', () => {
// Set the base URL for the API
// When running locally without the container, you would use:
const API_BASE_URL = 'http://localhost:8000';
// When accessing the API running in a container, you would use:
// const API_BASE_URL = 'http://localhost:8000';
// Adjust the port if needed according to your container setup
// Function to fetch data from the API and update the UI
async function fetchEndpoint(endpoint, elementId) {
const dataElement = document.getElementById(elementId);
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
// Create a formatted JSON string with syntax highlighting
const formattedJson = JSON.stringify(data, null, 2);
// Update the UI with the fetched data
dataElement.innerHTML = `<pre>${formattedJson}</pre>`;
return data; // Return the data for potential further processing
} catch (error) {
dataElement.innerHTML = `<div class="error">Error: ${error.message}</div>`;
console.error(`Failed to fetch ${endpoint}:`, error);
return null;
}
}
// Fetch data from all endpoints
fetchEndpoint('/', 'root-data');
fetchEndpoint('/api/users', 'users-data');
// Fetch contacts data and then process it to display locations
fetchEndpoint('/api/contacts', 'contacts-data')
.then(contactsData => {
if (contactsData) {
// Process the contacts data to extract unique locations
displayLocationsExample(contactsData);
}
});
// Function to display the locations example
function displayLocationsExample(contactsData) {
const locationsElement = document.getElementById('locations-example');
try {
// Extract all unique locations from the contacts data
const locations = [...new Set(contactsData.map(contact => contact.location))];
if (locations.length === 0) {
locationsElement.innerHTML = '<p>No locations found in the contacts data.</p>';
return;
}
// Create HTML for the locations list
const locationsHTML = `
<p>Found ${locations.length} unique location(s):</p>
<ul class="location-list">
${locations.map(location => `
<li class="location-item">${location}</li>
`).join('')}
</ul>
<p>Code example:</p>
<pre>
// JavaScript to extract unique locations
const locations = [...new Set(
contactsData.map(contact => contact.location)
)];
console.log(locations); // ${JSON.stringify(locations)}
</pre>
`;
locationsElement.innerHTML = locationsHTML;
} catch (error) {
locationsElement.innerHTML = `<div class="error">Error processing locations: ${error.message}</div>`;
console.error('Error processing locations:', error);
}
}
});

10
main.py
View file

@ -1,5 +1,6 @@
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
import os
import csv
import json
@ -7,6 +8,15 @@ from pathlib import Path
app = FastAPI(title="Static2API")
# Add CORS middleware to allow cross-origin requests
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all methods
allow_headers=["*"], # Allows all headers
)
@app.get("/")
async def root():
return {"message": "Welcome to Static2API"}

91
scripts/access_devices.sh Executable file
View file

@ -0,0 +1,91 @@
#!/bin/bash
# Configuration
API_URL="http://localhost:8000/api/devices"
# Create a logs directory for output files
LOGS_DIR="./device_logs"
mkdir -p $LOGS_DIR
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check if curl or wget is available
if command_exists curl; then
echo "Using curl to fetch data..."
RESPONSE=$(curl -s $API_URL)
elif command_exists wget; then
echo "Using wget to fetch data..."
RESPONSE=$(wget -qO- $API_URL)
else
echo "Error: Neither curl nor wget is available. Please install one of them."
exit 1
fi
# Check if response is empty
if [ -z "$RESPONSE" ]; then
echo "Error: Received empty response from $API_URL"
echo "Make sure the API server is running and the /api/devices endpoint exists."
exit 1
fi
# Check if jq is available for JSON parsing
if command_exists jq; then
echo "Using jq to parse JSON..."
# Extract devices using jq
# This is flexible to handle different JSON structures
# Try to parse top-level array first
DEVICE_COUNT=$(echo $RESPONSE | jq '. | length' 2>/dev/null)
# If not an array or empty, try .devices field (common pattern)
if [ -z "$DEVICE_COUNT" ] || [ "$DEVICE_COUNT" = "0" ]; then
DEVICE_COUNT=$(echo $RESPONSE | jq '.devices | length' 2>/dev/null)
if [ -n "$DEVICE_COUNT" ] && [ "$DEVICE_COUNT" -gt 0 ]; then
echo "Found $DEVICE_COUNT devices in .devices field"
echo "-------------------------------------"
for i in $(seq 0 $(($DEVICE_COUNT-1))); do
NAME=$(echo $RESPONSE | jq -r ".devices[$i].name // .devices[$i].hostname // .devices[$i].device // \"Unknown\"")
IP=$(echo $RESPONSE | jq -r ".devices[$i].ip // .devices[$i].ipaddress // .devices[$i].ip_address // \"Unknown\"")
TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "Connecting to $NAME ($IP) at $TIME"
ssh user@$IP "get vpn ssl monitor" > "$LOGS_DIR/${NAME}_${TIME}.log"
done
else
echo "No devices found or unexpected JSON structure."
echo "Raw API response:"
echo "$RESPONSE"
fi
else
echo "Found $DEVICE_COUNT devices in top-level array"
echo "-------------------------------------"
for i in $(seq 0 $(($DEVICE_COUNT-1))); do
NAME=$(echo $RESPONSE | jq -r ".[$i].name // .[$i].hostname // .[$i].device // \"Unknown\"")
IP=$(echo $RESPONSE | jq -r ".[$i].ip // .[$i].ipaddress // .[$i].ip_address // \"Unknown\"")
TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "Connecting to $NAME ($IP) at $TIME"
ssh user@$IP "get vpn ssl monitor" > "$LOGS_DIR/${NAME}_${TIME}.log"
done
fi
else
echo "Warning: jq is not available for proper JSON parsing. Using basic parsing..."
# Very basic parsing fallback without jq (limited)
# Extract name and IP with grep and sed - this is fragile but better than nothing
echo "$RESPONSE" | grep -o '"name"\s*:\s*"[^"]*"\|"ip"\s*:\s*"[^"]*"' | sed 's/"name"\s*:\s*"\([^"]*\)"/\1/g; s/"ip"\s*:\s*"\([^"]*\)"/\1/g' | paste -d " " - - | while read -r NAME IP; do
TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "Connecting to $NAME ($IP) at $TIME"
ssh user@$IP "get vpn ssl monitor" > "$LOGS_DIR/${NAME}_${TIME}.log"
done
fi
echo "-------------------------------------"
echo "Script completed. Log files saved to $LOGS_DIR directory."