Experimentování s API

Dokončeno! :slightly_smiling_face:

Povedlo se mi sestavit program, který počítá hmotnost využitého filamentu za daný časový úsek.

Jak to funguje?
Po spuštění python kódu se Vás program zeptá z kolika dní z minulosti by jste chtěli data zobrazit. Po zadání odešle žádost do Vašeho Karmen API získá potřebné informace a během cca 45 sekund Vám zobrazí sečtený počet vytištěných nesmazaných souborů a kolik filamentu spotřebovaly.

Před spuštěním kódu je potřeba do něj vložit API klíč a Vaše group_id.

import subprocess
import json
from datetime import datetime, timedelta

def get_print_jobs(page):
    curl_command = [
        "curl", "-k", "-H", "Authorization: Token <api_key>", 
        f"https://backend.next.karmen.tech/api/2/groups/<group_id>/print-jobs/?page={page}"
    ]
    result = subprocess.run(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    if result.returncode != 0:
        return None
    
    return json.loads(result.stdout.decode())

def get_files(page):
    curl_command = [
        "curl", "-k", "-H", "Authorization: Token <api_key>", 
        f"https://backend.next.karmen.tech/api/2/groups/<group_id>/files/?page={page}"
    ]
    result = subprocess.run(curl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    if result.returncode != 0:
        return None
    
    return json.loads(result.stdout.decode())

def get_print_jobs_within_days(days_past):
    id_file_started_on_list = []
    page = 1
    cutoff_date = datetime.now() - timedelta(days=days_past)

    while True:
        print_jobs_data = get_print_jobs(page)
        
        if not print_jobs_data or 'results' not in print_jobs_data:
            break
        
        print_jobs = print_jobs_data['results']
        
        for print_job in print_jobs:
            job_id = print_job.get('id', None)
            started_on = print_job.get('started_on', None)
            file_id = print_job.get('file_id', None) 
            
            if job_id and started_on and file_id:
                job_started_on = datetime.strptime(started_on, "%Y-%m-%dT%H:%M:%S.%fZ")
                
                if job_started_on < cutoff_date:
                    return id_file_started_on_list
                
                id_file_started_on_list.append({'id': job_id, 'file_id': file_id, 'started_on': started_on})
        
        if print_jobs_data.get('next'):
            page += 1
        else:
            break
    
    return id_file_started_on_list

def get_filament_weight_for_files(print_jobs):
    total_filament_used = 0
    page = 1
    file_id_to_filament = {}

    while True:
        files_data = get_files(page)
        
        if not files_data or 'results' not in files_data:
            break
        
        files = files_data['results']
        
        for file in files:
            file_id = file.get('id')
            filament_used = file.get('filament_used_g', 0)
            if file_id:
                file_id_to_filament[file_id] = filament_used
        
        if files_data.get('next'):
            page += 1
        else:
            break
    
    for print_job in print_jobs:
        file_id = print_job['file_id']
        if file_id in file_id_to_filament:
            total_filament_used += file_id_to_filament[file_id]
    
    return total_filament_used

if __name__ == "__main__":
    days = int(input("Enter the number of days to filter print jobs from: "))
    
    print_jobs = get_print_jobs_within_days(days)
    
    total_filament_used = get_filament_weight_for_files(print_jobs)
    
    print(f"Total print jobs in the past {days} days: {len(print_jobs)}")
    print(f"Total filament used in the past {days} days: {round(total_filament_used)}g")

Problém z posledního postu a tím i další menší problémy, které zbývaly, jsem vyřešil tím, že jsem předělal celou strukturu.
Začal jsem tedy tím, že jsem vytvořil funkce, která získávala časy a file_id z print-jobs a z nich rovnou sestavila list tisků, které se staly za dobu danou uživatelem. Také jsem otočil procházení stránek a zavedl jsem zastavení poté co se dostane za časový horizont, čímž se celý proces velmi zrychlil.
Až po těchto všech úkonech se přiřadí hmotnosti filamentu z files pomocí shodných id. Počítá se s tím, že soubory mohou být tisknuty víckrát a proto se id může přiřadit i k více tiskům. Následně se vše sečte a zobrazí se výsledná data uživateli.

Patrik

1 Like