diff --git a/README.md b/README.md
index d5a4390..4b50be8 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..9242156
--- /dev/null
+++ b/frontend/README.md
@@ -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.
\ No newline at end of file
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..3d9ea8c
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+ Static2API Frontend
+
+
+
+
+
Static2API Frontend
+
+
+
Root Endpoint
+
Loading...
+
+
+
Users API
+
Loading...
+
+
+
Contacts API
+
Loading...
+
+
+
+
+
Example: Locations from Contacts
+
This example extracts and displays all unique locations from the contacts data:
+
Loading locations...
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/script.js b/frontend/script.js
new file mode 100644
index 0000000..ee18170
--- /dev/null
+++ b/frontend/script.js
@@ -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 = `${formattedJson}
`;
+
+ return data; // Return the data for potential further processing
+ } catch (error) {
+ dataElement.innerHTML = `Error: ${error.message}
`;
+ 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 = 'No locations found in the contacts data.
';
+ return;
+ }
+
+ // Create HTML for the locations list
+ const locationsHTML = `
+ Found ${locations.length} unique location(s):
+
+ ${locations.map(location => `
+ - ${location}
+ `).join('')}
+
+ Code example:
+
+// JavaScript to extract unique locations
+const locations = [...new Set(
+ contactsData.map(contact => contact.location)
+)];
+
+console.log(locations); // ${JSON.stringify(locations)}
+
+ `;
+
+ locationsElement.innerHTML = locationsHTML;
+ } catch (error) {
+ locationsElement.innerHTML = `Error processing locations: ${error.message}
`;
+ console.error('Error processing locations:', error);
+ }
+ }
+});
\ No newline at end of file
diff --git a/main.py b/main.py
index bc2dd32..b427f44 100644
--- a/main.py
+++ b/main.py
@@ -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"}
diff --git a/scripts/access_devices.sh b/scripts/access_devices.sh
new file mode 100755
index 0000000..6018fff
--- /dev/null
+++ b/scripts/access_devices.sh
@@ -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."