Compare commits
3 Commits
2f308584c0
...
22268781cb
| Author | SHA1 | Date | |
|---|---|---|---|
| 22268781cb | |||
| 93cb11d7bb | |||
| 45397c069c |
19
README.md
19
README.md
@@ -1,3 +1,22 @@
|
|||||||
Internes Tool zur Kalkulation von Blechteilen.
|
Internes Tool zur Kalkulation von Blechteilen.
|
||||||
|
|
||||||
Derzeit keine Unterstützung von Baugruppen!
|
Derzeit keine Unterstützung von Baugruppen!
|
||||||
|
|
||||||
|
Zur Installation:
|
||||||
|
|
||||||
|
1. venv erzeugen
|
||||||
|
2. . .venv/bin/activate
|
||||||
|
3. pip install -r requirements
|
||||||
|
|
||||||
|
|
||||||
|
Web server mit fastapi starten:
|
||||||
|
|
||||||
|
uvicorn main:app --host 0.0.0.0 --port 8001 --reload
|
||||||
|
|
||||||
|
mit folgender URL im Browser ist der Einstiegpunkt:
|
||||||
|
|
||||||
|
http://127.0.0.1:8001/static/upload.html
|
||||||
|
|
||||||
|
Ein Viewer für die hochgeladenen STEP files
|
||||||
|
http://127.0.0.1:8001/static/viewer.html
|
||||||
|
|
||||||
|
|||||||
58
main.py
Normal file
58
main.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from fastapi import FastAPI, UploadFile, File, HTTPException
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
|
||||||
|
# Für lokales Testen mit separatem Frontend (z.B. file:// oder anderer Port)
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"], # in Produktion einschränken!
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
UPLOAD_DIR = Path("uploads")
|
||||||
|
UPLOAD_DIR.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def read_root():
|
||||||
|
return {"Hello": "World"}
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
def health():
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
@app.post("/upload")
|
||||||
|
async def upload_file(file: UploadFile = File(...)):
|
||||||
|
filename = (file.filename or "").lower()
|
||||||
|
safe_name = ""
|
||||||
|
if not (filename.endswith(".step") or filename.endswith(".stp")):
|
||||||
|
raise HTTPException(status_code=400, detail="Upload a .step or .stp file")
|
||||||
|
|
||||||
|
# eindeutiger Dateiname, um Kollisionen zu vermeiden
|
||||||
|
suffix = Path(file.filename).suffix
|
||||||
|
safe_name = f"{uuid.uuid4().hex}{suffix}"
|
||||||
|
target = UPLOAD_DIR / safe_name
|
||||||
|
|
||||||
|
# Datei speichern (streaming)
|
||||||
|
with target.open("wb") as f:
|
||||||
|
while chunk := await file.read(1024 * 1024):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"original_filename": file.filename,
|
||||||
|
"stored_as": safe_name,
|
||||||
|
"content_type": file.content_type,
|
||||||
|
"size_bytes": target.stat().st_size,
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
flask==3.0.3
|
flask==3.0.3
|
||||||
gunicorn==22.0.0
|
gunicorn==22.0.0
|
||||||
ezdxf==1.3.4
|
ezdxf==1.3.4
|
||||||
pillow==10.4.0
|
pillow==10.4.0
|
||||||
|
fastapi[standard]==0.133.1
|
||||||
|
|||||||
67
static/upload.html
Normal file
67
static/upload.html
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Datei Upload</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: system-ui, sans-serif; max-width: 720px; margin: 40px auto; padding: 0 16px; }
|
||||||
|
.card { border: 1px solid #ddd; border-radius: 12px; padding: 16px; }
|
||||||
|
button { padding: 10px 14px; border-radius: 10px; border: 1px solid #ccc; cursor: pointer; }
|
||||||
|
pre { background: #f6f6f6; padding: 12px; border-radius: 10px; overflow: auto; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Datei Upload</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<input id="fileInput" type="file" />
|
||||||
|
<button id="uploadBtn">Hochladen</button>
|
||||||
|
<p id="status"></p>
|
||||||
|
<pre id="result"></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const API_URL = "http://127.0.0.1:8001/upload";
|
||||||
|
|
||||||
|
const fileInput = document.getElementById("fileInput");
|
||||||
|
const uploadBtn = document.getElementById("uploadBtn");
|
||||||
|
const statusEl = document.getElementById("status");
|
||||||
|
const resultEl = document.getElementById("result");
|
||||||
|
|
||||||
|
uploadBtn.addEventListener("click", async () => {
|
||||||
|
resultEl.textContent = "";
|
||||||
|
statusEl.textContent = "";
|
||||||
|
|
||||||
|
const file = fileInput.files[0];
|
||||||
|
if (!file) {
|
||||||
|
statusEl.textContent = "Bitte zuerst eine Datei auswählen.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file); // Name muss zu FastAPI-Parameter passen: file
|
||||||
|
|
||||||
|
statusEl.textContent = "Upload läuft...";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(API_URL, { method: "POST", body: formData });
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
statusEl.textContent = "Fehler beim Upload.";
|
||||||
|
resultEl.textContent = JSON.stringify(data, null, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusEl.textContent = "Upload erfolgreich ✅";
|
||||||
|
resultEl.textContent = JSON.stringify(data, null, 2);
|
||||||
|
} catch (err) {
|
||||||
|
statusEl.textContent = "Netzwerkfehler (läuft FastAPI? CORS?)";
|
||||||
|
resultEl.textContent = String(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Reference in New Issue
Block a user