Advertisement
m3nt0r1313

grafana api json converrt scrypt

Feb 23rd, 2025
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.24 KB | Fixit | 0 0
  1. import csv
  2. import os
  3. import time
  4. import zipfile
  5. import logging
  6. import math
  7. from datetime import datetime, timezone
  8. from flask import Flask, jsonify, request
  9. from flask_cors import CORS
  10. import pandas as pd
  11.  
  12. # logowanie
  13. logging.basicConfig(
  14.     level=logging.INFO,
  15.     format="%(asctime)s - %(levelname)s - %(message)s",
  16.     datefmt="%Y-%m-%d %H:%M:%S"
  17. )
  18.  
  19. # Stałe
  20. CACHE_DURATION = 5  #
  21. BASE_DIR = r"D:\skrypty\Grafanaskrypt_prealpha"
  22.  
  23. # Globalne zmienne
  24. cached_data = None
  25. historical_data = []  # dane po lokalu
  26. last_cache_time = 0
  27.  
  28. app = Flask(__name__)
  29. CORS(app)
  30.  
  31. def get_file_path():
  32.     """data entry."""
  33.     while True:
  34.         file_name = input("Podaj nazwę pliku (np. data.csv lub data.zip): ").strip()
  35.         file_path = os.path.join(BASE_DIR, file_name)
  36.        
  37.         if not os.path.exists(file_path):
  38.             logging.error(f"Plik nie istnieje: {file_path}")
  39.             continue
  40.  
  41.         if file_path.lower().endswith('.zip'):
  42.             return extract_zip(file_path)
  43.        
  44.         logging.info(f"Wybrano plik: {file_path}")
  45.         return file_path
  46.  
  47. def extract_zip(zip_path):
  48.     """Rozpakowuje archiwum ZIP i zwraca ścieżkę do pierwszego pliku CSV lub TXT."""
  49.     extract_dir = os.path.join(BASE_DIR, "extracted")
  50.     os.makedirs(extract_dir, exist_ok=True)
  51.    
  52.     try:
  53.         with zipfile.ZipFile(zip_path, 'r') as zip_ref:
  54.             zip_ref.extractall(extract_dir)
  55.        
  56.         for file in os.listdir(extract_dir):
  57.             file_path = os.path.join(extract_dir, file)
  58.             if os.path.isfile(file_path) and file.lower().endswith(('.csv', '.txt')):
  59.                 logging.info(f"Wybrano plik z archiwum: {file_path}")
  60.                 return file_path
  61.        
  62.         logging.error("Brak plików CSV lub TXT w archiwum ZIP")
  63.         return None
  64.     except Exception as e:
  65.         logging.error(f"Błąd rozpakowywania ZIP: {str(e)}")
  66.         return None
  67.  
  68. def parse_timestamp(raw_timestamp):
  69.     """Parsuje czas w różnych formatach."""
  70.     raw_timestamp = str(raw_timestamp).strip()
  71.    
  72.     # Próba parsowania jako timestamp Unix
  73.     try:
  74.         ts = float(raw_timestamp.replace(',', '.'))
  75.         return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
  76.     except (ValueError, OverflowError):
  77.         pass
  78.    
  79.     # parsowanie
  80.     formats = [
  81.         "%d.%m.%Y %H:%M:%S",    # np. 23.02.2025 12:34:56
  82.         "%Y-%m-%d %H:%M:%S",     # np. 2025-02-23 12:34:56
  83.         "%Y/%m/%d %H:%M:%S",     # np. 2025/02/23 12:34:56
  84.         "%d-%m-%Y %H:%M:%S",     # np. 23-02-2025 12:34:56
  85.         "%Y%m%d %H%M%S"          # np. 20250223 123456
  86.     ]
  87.    
  88.     for fmt in formats:
  89.         try:
  90.             dt = datetime.strptime(raw_timestamp, fmt)
  91.             return dt.replace(tzinfo=timezone.utc).isoformat()
  92.         except ValueError:
  93.             continue
  94.    
  95.     logging.error(f"Nieznany format czasu: {raw_timestamp}")
  96.     return datetime.now(timezone.utc).isoformat()
  97.  
  98. def detect_delimiter(file_path):
  99.     """Wykrywa separator w pliku CSV."""
  100.     with open(file_path, 'r', encoding='utf-8-sig') as f:
  101.         first_line = f.readline()
  102.         for delim in [';', ',', '\t']:
  103.             if delim in first_line:
  104.                 return delim
  105.     return ';'
  106.  
  107. def load_and_parse_data(file_path):
  108.     """
  109.    restruktura gdy zle entry
  110.    """
  111.     try:
  112.         delimiter = detect_delimiter(file_path)
  113.         df = pd.read_csv(
  114.             file_path,
  115.             delimiter=delimiter,
  116.             skiprows=[1],  
  117.             dtype=str,
  118.             on_bad_lines='warn'
  119.         )
  120.        
  121.         df = df.rename(columns=lambda x: x.strip())
  122.        
  123.         if 'Aufnahme Zeit' not in df.columns:
  124.             raise ValueError("Brak kolumny 'Aufnahme Zeit'")
  125.        
  126.         # Lista wszystkich kolumn wartości (wszystkie oprócz "Aufnahme Zeit")
  127.         value_columns = [col for col in df.columns if col != 'Aufnahme Zeit']
  128.        
  129.         results = []
  130.         for _, row in df.iterrows():
  131.             try:
  132.                 timestamp = parse_timestamp(row['Aufnahme Zeit'])
  133.                 values = {}
  134.                 # Dla każdej kolumny z listy value_columns, uzupełniamy brakujące wartości wartością None
  135.                 for col in value_columns:
  136.                     raw_value = row[col] if col in row else ""
  137.                     raw_value = str(raw_value).strip().replace(',', '.')
  138.                     if raw_value == "":
  139.                         values[col] = None
  140.                     else:
  141.                         try:
  142.                             num_value = float(raw_value)
  143.                             if math.isnan(num_value):
  144.                                 num_value = None
  145.                             values[col] = num_value
  146.                         except ValueError:
  147.                             values[col] = None
  148.                             logging.warning(f"Niepoprawna wartość w kolumnie '{col}': {raw_value}")
  149.                
  150.                 results.append({
  151.                     'timestamp': timestamp,
  152.                     'values': values
  153.                 })
  154.             except Exception as e:
  155.                 logging.error(f"Błąd przetwarzania wiersza: {str(e)}")
  156.                 continue
  157.        
  158.         return results
  159.    
  160.     except Exception as e:
  161.         logging.error(f"Błąd przetwarzania pliku: {str(e)}")
  162.         return None
  163.  
  164. def update_cache():
  165.     """Aktualizuje cache danych i log insertz."""
  166.     global cached_data, historical_data, last_cache_time
  167.     file_path = get_file_path()
  168.     if not file_path:
  169.         return
  170.    
  171.     new_data = load_and_parse_data(file_path)
  172.     if new_data:
  173.         if cached_data is None:
  174.             cached_data = new_data
  175.         else:
  176.             # duplikat extra
  177.             cached_data.extend(new_data)
  178.         historical_data = cached_data  
  179.         last_cache_time = time.time()
  180.         logging.info("Cache zaktualizowany i dane zostały dołączone do historycznych.")
  181.     else:
  182.         logging.error("Nie udało się załadować danych")
  183.  
  184. @app.route('/health', methods=['GET'])
  185. def health_check():
  186.     return jsonify({'status': 'ok'})
  187.  
  188. # row data
  189. @app.route('/', methods=['GET'])
  190. def get_raw_data():
  191.     global historical_data
  192.     if not historical_data:
  193.         return jsonify({'error': 'Brak danych'}), 500
  194.     return jsonify(historical_data)
  195.  
  196. # y GET oraz POST
  197. @app.route('/query', methods=['GET', 'POST'])
  198. def query_all_variables():
  199.     global historical_data
  200.     if not historical_data:
  201.         return jsonify({'error': 'Brak danych'}), 500
  202.  
  203.     series = {}
  204.     for entry in historical_data:
  205.         try:
  206.             # Konwersja timestamp na milisekundy
  207.             ts = int(datetime.fromisoformat(entry['timestamp']).timestamp() * 1000)
  208.             for metric, value in entry['values'].items():
  209.                 series.setdefault(metric, []).append([value, ts])
  210.         except Exception as e:
  211.             logging.error(f"Błąd przetwarzania wpisu: {str(e)}")
  212.             continue
  213.  
  214.     formatted = [{
  215.         'target': metric,
  216.         'datapoints': sorted(points, key=lambda x: x[1])
  217.     } for metric, points in series.items()]
  218.  
  219.     return jsonify(formatted)
  220.  
  221. if __name__ == '__main__':
  222.     update_cache()
  223.     app.run(host='0.0.0.0', port=5000, debug=False)
  224.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement