feat: Add Docker Compose setup for fullstack deployment
- Add Frontend Dockerfile with Next.js standalone build - Add docker-compose.yml for production deployment - Add docker-compose.dev.yml for development with hot-reload - Configure Frontend next.config.js with standalone output - Add .dockerignore files for both backend and frontend - Add comprehensive README-DOCKER.md documentation - Update .gitignore to exclude node_modules and build artifacts - Remove obsolete component files (CycleCalculator.tsx, PHDiagram.tsx) - Backend and Frontend communicate via Docker network - Healthchecks configured for both services - Environment variables configured for API URL
This commit is contained in:
parent
59c4e3857a
commit
6ff041d2a8
14
.dockerignore
Normal file
14
.dockerignore
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
__pycache__/
|
||||||
|
.venv/
|
||||||
|
test_outputs/
|
||||||
|
tests/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
.pytest_cache/
|
||||||
|
.git/
|
||||||
|
tests_notebook/
|
||||||
|
IPM_DLL/
|
||||||
|
IPM_SO/
|
||||||
|
*.xlsm
|
||||||
|
datasets-2025-10-18-14-21.csv
|
||||||
|
|
||||||
43
Dockerfile
Normal file
43
Dockerfile
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system deps required by numpy/pandas/matplotlib and building wheels
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
gcc \
|
||||||
|
gfortran \
|
||||||
|
libatlas3-base \
|
||||||
|
libopenblas-dev \
|
||||||
|
liblapack-dev \
|
||||||
|
libfreetype6-dev \
|
||||||
|
libpng-dev \
|
||||||
|
pkg-config \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
libglib2.0-0 \
|
||||||
|
libxrender1 \
|
||||||
|
libxext6 \
|
||||||
|
libsm6 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy only requirements first for better layer caching
|
||||||
|
COPY requirements.txt /app/requirements.txt
|
||||||
|
|
||||||
|
# Upgrade pip and install python deps
|
||||||
|
RUN python -m pip install --upgrade pip setuptools wheel && \
|
||||||
|
python -m pip install -r /app/requirements.txt
|
||||||
|
|
||||||
|
# Copy project
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
# Ensure Python and dynamic linker will find the native libs if mounted
|
||||||
|
ENV PYTHONPATH="/app:/app/IPM_SO:/app/IPM_DLL"
|
||||||
|
ENV LD_LIBRARY_PATH="/app/IPM_SO:/app/IPM_DLL"
|
||||||
|
|
||||||
|
EXPOSE 8001
|
||||||
|
|
||||||
|
# Default command runs uvicorn (use docker-compose override for development)
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
|
||||||
0
Frontend/.dockerignore
Normal file
0
Frontend/.dockerignore
Normal file
0
Frontend/Dockerfile
Normal file
0
Frontend/Dockerfile
Normal file
15
Frontend/next.config.js
Normal file
15
Frontend/next.config.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
output: 'standalone',
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/api/v1/:path*',
|
||||||
|
destination: process.env.NEXT_PUBLIC_API_URL || 'http://backend:8001/api/v1/:path*',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = nextConfig
|
||||||
3213
Frontend/package-lock.json
generated
Normal file
3213
Frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
36
Frontend/package.json
Normal file
36
Frontend/package.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "diagram-ph-frontend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"dependencies": {
|
||||||
|
"@hookform/resolvers": "^5.2.2",
|
||||||
|
"@types/node": "^24.8.1",
|
||||||
|
"@types/react": "^19.2.2",
|
||||||
|
"axios": "^1.12.2",
|
||||||
|
"lucide-react": "^0.546.0",
|
||||||
|
"next": "^15.5.6",
|
||||||
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0",
|
||||||
|
"react-hook-form": "^7.65.0",
|
||||||
|
"recharts": "^3.3.0",
|
||||||
|
"typescript": "^5.9.3",
|
||||||
|
"zod": "^4.1.12"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.21",
|
||||||
|
"postcss": "^8.5.6",
|
||||||
|
"tailwindcss": "^3.4.18"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Frontend/public/sample_test_data.csv
Normal file
11
Frontend/public/sample_test_data.csv
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Pressure (bar),Enthalpy (kJ/kg)
|
||||||
|
3.2,580
|
||||||
|
3.5,595
|
||||||
|
11.8,650
|
||||||
|
12.1,652
|
||||||
|
12.0,380
|
||||||
|
11.9,375
|
||||||
|
3.3,378
|
||||||
|
8.5,500
|
||||||
|
5.0,450
|
||||||
|
7.2,520
|
||||||
|
16
Frontend/public/sample_test_data.json
Normal file
16
Frontend/public/sample_test_data.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"description": "Sample test points for R290 refrigeration cycle",
|
||||||
|
"refrigerant": "R290",
|
||||||
|
"points": [
|
||||||
|
{ "pressure": 3.2, "enthalpy": 580 },
|
||||||
|
{ "pressure": 3.5, "enthalpy": 595 },
|
||||||
|
{ "pressure": 11.8, "enthalpy": 650 },
|
||||||
|
{ "pressure": 12.1, "enthalpy": 652 },
|
||||||
|
{ "pressure": 12.0, "enthalpy": 380 },
|
||||||
|
{ "pressure": 11.9, "enthalpy": 375 },
|
||||||
|
{ "pressure": 3.3, "enthalpy": 378 },
|
||||||
|
{ "pressure": 8.5, "enthalpy": 500 },
|
||||||
|
{ "pressure": 5.0, "enthalpy": 450 },
|
||||||
|
{ "pressure": 7.2, "enthalpy": 520 }
|
||||||
|
]
|
||||||
|
}
|
||||||
30
Frontend/src/app/globals.css
Normal file
30
Frontend/src/app/globals.css
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
||||||
|
background: #0a0e1a;
|
||||||
|
min-height: 100vh;
|
||||||
|
color: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #0a0e1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #2d3548;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #3d4558;
|
||||||
|
}
|
||||||
19
Frontend/src/app/layout.tsx
Normal file
19
Frontend/src/app/layout.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import type { Metadata } from 'next'
|
||||||
|
import './globals.css'
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Diagram PH - Refrigeration Cycle Calculator',
|
||||||
|
description: 'Calculate and visualize refrigeration cycles',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body>{children}</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
67
Frontend/src/app/page.tsx
Normal file
67
Frontend/src/app/page.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import PHDiagramModern from "@/components/PHDiagramModern";
|
||||||
|
import CycleCalculatorModern from "@/components/CycleCalculatorModern";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
const [activeView, setActiveView] = useState<'calculator' | 'diagram'>('diagram');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: 'relative' }}>
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: '2rem',
|
||||||
|
right: '2rem',
|
||||||
|
zIndex: 1000,
|
||||||
|
display: 'flex',
|
||||||
|
gap: '0.75rem',
|
||||||
|
background: 'rgba(30, 58, 95, 0.95)',
|
||||||
|
backdropFilter: 'blur(10px)',
|
||||||
|
padding: '0.5rem',
|
||||||
|
borderRadius: '16px',
|
||||||
|
boxShadow: '0 8px 32px rgba(0,0,0,0.3)',
|
||||||
|
border: '1px solid rgba(255,255,255,0.1)'
|
||||||
|
}}>
|
||||||
|
<button
|
||||||
|
onClick={() => setActiveView('diagram')}
|
||||||
|
style={{
|
||||||
|
padding: '0.75rem 1.5rem',
|
||||||
|
background: activeView === 'diagram' ? 'linear-gradient(135deg, #38b2ac 0%, #2c7a7b 100%)' : 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '12px',
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
fontWeight: '700',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'all 0.3s',
|
||||||
|
boxShadow: activeView === 'diagram' ? '0 4px 12px rgba(56, 178, 172, 0.4)' : 'none',
|
||||||
|
letterSpacing: '0.3px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
📊 P-h Diagram
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setActiveView('calculator')}
|
||||||
|
style={{
|
||||||
|
padding: '0.75rem 1.5rem',
|
||||||
|
background: activeView === 'calculator' ? 'linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)' : 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '12px',
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
fontWeight: '700',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'all 0.3s',
|
||||||
|
boxShadow: activeView === 'calculator' ? '0 4px 12px rgba(59, 130, 246, 0.4)' : 'none',
|
||||||
|
letterSpacing: '0.3px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
🧮 Cycle Calculator
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{activeView === 'diagram' && <PHDiagramModern />}
|
||||||
|
{activeView === 'calculator' && <CycleCalculatorModern />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
1067
Frontend/src/components/CycleCalculatorModern.tsx
Normal file
1067
Frontend/src/components/CycleCalculatorModern.tsx
Normal file
File diff suppressed because it is too large
Load Diff
1498
Frontend/src/components/PHDiagramModern.tsx
Normal file
1498
Frontend/src/components/PHDiagramModern.tsx
Normal file
File diff suppressed because it is too large
Load Diff
65
Frontend/src/lib/api-client.ts
Normal file
65
Frontend/src/lib/api-client.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import {
|
||||||
|
CycleCalculationRequest,
|
||||||
|
CycleCalculationResponse,
|
||||||
|
DiagramRequest,
|
||||||
|
DiagramResponse,
|
||||||
|
RefrigerantInfo,
|
||||||
|
RefrigerantsListResponse,
|
||||||
|
} from '@/types/api';
|
||||||
|
|
||||||
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8001/api/v1';
|
||||||
|
|
||||||
|
export class ApiClient {
|
||||||
|
private baseUrl: string;
|
||||||
|
|
||||||
|
constructor(baseUrl: string = API_BASE_URL) {
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRefrigerants(): Promise<RefrigerantInfo[]> {
|
||||||
|
const response = await fetch(`${this.baseUrl}/refrigerants/`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to fetch refrigerants');
|
||||||
|
}
|
||||||
|
const data: RefrigerantsListResponse = await response.json();
|
||||||
|
return data.refrigerants;
|
||||||
|
}
|
||||||
|
|
||||||
|
async calculateCycle(
|
||||||
|
request: CycleCalculationRequest
|
||||||
|
): Promise<CycleCalculationResponse> {
|
||||||
|
const response = await fetch(`${this.baseUrl}/cycles/simple`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(request),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.json();
|
||||||
|
throw new Error(error.detail || 'Failed to calculate cycle');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateDiagram(request: DiagramRequest): Promise<DiagramResponse> {
|
||||||
|
const response = await fetch(`${this.baseUrl}/diagrams/ph`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(request),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.json();
|
||||||
|
throw new Error(error.detail || 'Failed to generate diagram');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const apiClient = new ApiClient();
|
||||||
84
Frontend/src/types/api.ts
Normal file
84
Frontend/src/types/api.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
export interface CycleCalculationRequest {
|
||||||
|
refrigerant: string;
|
||||||
|
evap_temperature?: number;
|
||||||
|
cond_temperature?: number;
|
||||||
|
evap_pressure?: number;
|
||||||
|
cond_pressure?: number;
|
||||||
|
compressor_efficiency?: number;
|
||||||
|
superheat?: number;
|
||||||
|
subcool?: number;
|
||||||
|
mass_flow?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CyclePoint {
|
||||||
|
point_id: string;
|
||||||
|
pressure: number;
|
||||||
|
temperature?: number;
|
||||||
|
enthalpy?: number;
|
||||||
|
entropy?: number;
|
||||||
|
quality?: number;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CyclePerformance {
|
||||||
|
cop: number;
|
||||||
|
cooling_capacity: number;
|
||||||
|
heating_capacity: number;
|
||||||
|
compressor_power: number;
|
||||||
|
compressor_efficiency: number;
|
||||||
|
mass_flow: number;
|
||||||
|
volumetric_flow?: number;
|
||||||
|
compression_ratio: number;
|
||||||
|
discharge_temperature: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CycleCalculationResponse {
|
||||||
|
success: boolean;
|
||||||
|
refrigerant: string;
|
||||||
|
points: CyclePoint[];
|
||||||
|
performance: CyclePerformance;
|
||||||
|
diagram_data?: any;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiagramRequest {
|
||||||
|
refrigerant: string;
|
||||||
|
pressure_range: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
enthalpy_range?: {
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
};
|
||||||
|
include_isotherms?: boolean;
|
||||||
|
isotherm_values?: number[];
|
||||||
|
cycle_points?: Array<{ enthalpy: number; pressure: number }>;
|
||||||
|
title?: string;
|
||||||
|
format?: string;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
dpi?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiagramResponse {
|
||||||
|
success: boolean;
|
||||||
|
image?: string;
|
||||||
|
data?: any;
|
||||||
|
metadata: any;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RefrigerantInfo {
|
||||||
|
name: string;
|
||||||
|
formula?: string;
|
||||||
|
available: boolean;
|
||||||
|
loaded?: boolean;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RefrigerantsListResponse {
|
||||||
|
refrigerants: RefrigerantInfo[];
|
||||||
|
total: number;
|
||||||
|
available_count: number;
|
||||||
|
}
|
||||||
24
Frontend/tsconfig.json
Normal file
24
Frontend/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [{ "name": "next" }],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
0
README-DOCKER.md
Normal file
0
README-DOCKER.md
Normal file
0
docker-compose.dev.yml
Normal file
0
docker-compose.dev.yml
Normal file
59
docker-compose.yml
Normal file
59
docker-compose.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Backend API Service
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: diagramph-backend
|
||||||
|
ports:
|
||||||
|
- "8001:8001"
|
||||||
|
volumes:
|
||||||
|
- ./app:/app/app:cached
|
||||||
|
- ./IPM_SO:/app/IPM_SO:cached
|
||||||
|
- ./IPM_DLL:/app/IPM_DLL:cached
|
||||||
|
environment:
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
- PYTHONPATH=/app:/app/IPM_SO:/app/IPM_DLL
|
||||||
|
- LD_LIBRARY_PATH=/app/IPM_SO:/app/IPM_DLL
|
||||||
|
command: uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload
|
||||||
|
networks:
|
||||||
|
- diagramph-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8001/api/v1/refrigerants/"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# Frontend Service
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./Frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: diagramph-frontend
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- NEXT_PUBLIC_API_URL=http://backend:8001/api/v1
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- diagramph-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
networks:
|
||||||
|
diagramph-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
backend-data:
|
||||||
|
frontend-data:
|
||||||
BIN
libs/so/libR12.so
Normal file
BIN
libs/so/libR12.so
Normal file
Binary file not shown.
BIN
libs/so/libR1233zd.so
Normal file
BIN
libs/so/libR1233zd.so
Normal file
Binary file not shown.
BIN
libs/so/libR1234ze.so
Normal file
BIN
libs/so/libR1234ze.so
Normal file
Binary file not shown.
BIN
libs/so/libR134a.so
Normal file
BIN
libs/so/libR134a.so
Normal file
Binary file not shown.
BIN
libs/so/libR22.so
Normal file
BIN
libs/so/libR22.so
Normal file
Binary file not shown.
BIN
libs/so/libR290.so
Normal file
BIN
libs/so/libR290.so
Normal file
Binary file not shown.
BIN
libs/so/libR32.so
Normal file
BIN
libs/so/libR32.so
Normal file
Binary file not shown.
BIN
libs/so/libR404A.so
Normal file
BIN
libs/so/libR404A.so
Normal file
Binary file not shown.
BIN
libs/so/libR410A.so
Normal file
BIN
libs/so/libR410A.so
Normal file
Binary file not shown.
BIN
libs/so/libR502.so
Normal file
BIN
libs/so/libR502.so
Normal file
Binary file not shown.
BIN
libs/so/libR507A.so
Normal file
BIN
libs/so/libR507A.so
Normal file
Binary file not shown.
BIN
libs/so/libR717.so
Normal file
BIN
libs/so/libR717.so
Normal file
Binary file not shown.
BIN
libs/so/libR744.so
Normal file
BIN
libs/so/libR744.so
Normal file
Binary file not shown.
5
requirements-dev.txt
Normal file
5
requirements-dev.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pytest
|
||||||
|
httpx
|
||||||
|
requests
|
||||||
|
fastapi
|
||||||
|
starlette
|
||||||
11
requirements.txt
Normal file
11
requirements.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fastapi==0.109.0
|
||||||
|
uvicorn[standard]==0.27.0
|
||||||
|
pydantic==2.5.0
|
||||||
|
pydantic-settings==2.1.0
|
||||||
|
numpy==1.26.3
|
||||||
|
pandas==2.2.0
|
||||||
|
matplotlib==3.8.2
|
||||||
|
plotly==5.18.0
|
||||||
|
python-multipart==0.0.6
|
||||||
|
cachetools==5.3.2
|
||||||
|
python-json-logger==2.0.7
|
||||||
Loading…
x
Reference in New Issue
Block a user