10 Commits

Author SHA1 Message Date
Repo Bot
d22184cf70 chore: add libs directory (native binaries) for CI/testing 2025-10-19 13:15:58 +02:00
Repo Bot
24db8ad426 docs: split root README into English README.md and README_fr.md (French preserved) 2025-10-19 13:04:39 +02:00
Repo Bot
c0c0e6e3ea chore: add librefifc.so native library for CI/testing 2025-10-19 13:00:56 +02:00
Repo Bot
60f951a823 docs(ipm): ensure remote-readme is English-only (minimal) 2025-10-19 12:59:06 +02:00
Repo Bot
ec73a755c2 docs(ipm): remove README_en.md and keep canonical English README.md with link to README_fr.md 2025-10-19 12:50:36 +02:00
Repo Bot
1c2f622a2f docs(ipm): canonicalize README.md to English (from README_en.md) 2025-10-19 12:48:59 +02:00
Repo Bot
0f6df68f7c chore: allow tracking linux .so in app/ipm/lib/linux by removing gitignore rule 2025-10-19 12:45:40 +02:00
Repo Bot
d48d7828f5 docs(ipm): ensure README.md is English default 2025-10-19 12:41:20 +02:00
Repo Bot
6ff041d2a8 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
2025-10-19 12:38:19 +02:00
Repo Bot
59c4e3857a docs(ipm): add default README.md (English) and cross-link English/French READMEs 2025-10-19 12:33:46 +02:00
41 changed files with 6534 additions and 186 deletions

14
.dockerignore Normal file
View 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

5
.gitignore vendored
View File

@@ -52,6 +52,5 @@ htmlcov/
*.bak *.bak
*.swp *.swp
# Ignore platform native binaries copied into app/ipm/lib # Ignore platform native binaries copied into app/ipm/lib (Windows dlls still ignored)
app/ipm/lib/windows/*.dll app/ipm/lib/windows/*.dll
app/ipm/lib/linux/*.so

43
Dockerfile Normal file
View 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
View File

0
Frontend/Dockerfile Normal file
View File

15
Frontend/next.config.js Normal file
View 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

File diff suppressed because it is too large Load Diff

36
Frontend/package.json Normal file
View 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"
}
}

View 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
1 Pressure (bar) Enthalpy (kJ/kg)
2 3.2 580
3 3.5 595
4 11.8 650
5 12.1 652
6 12.0 380
7 11.9 375
8 3.3 378
9 8.5 500
10 5.0 450
11 7.2 520

View 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 }
]
}

View 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;
}

View 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
View 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>
);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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
View File

116
README.md
View File

@@ -41,113 +41,29 @@ graph TB
F[CloudFront CDN] F[CloudFront CDN]
G[Application Load Balancer] G[Application Load Balancer]
subgraph "Elastic Beanstalk Environment" # API Diagramme PH - Project Overview (English)
H1[API Server 1<br/>Docker Container]
H2[API Server 2<br/>Docker Container]
H3[API Server N<br/>Docker Container]
end
I[CloudWatch<br/>Logs & Metrics]
J[S3 Bucket<br/>Static Assets]
end
subgraph "API Container"
K[FastAPI Application]
L[RefrigerantEngine<br/>DLL/SO Wrapper]
M[DiagramGenerator<br/>Matplotlib/Plotly]
N[CycleCalculator<br/>Thermodynamics]
O[Cache Layer<br/>LRU + TTL]
end
subgraph "Native Libraries"
P[R134a.so]
Q[R410A.so]
R[refifc.so]
S[Other refrigerants...]
end
A & B & C & D --> E
E --> F
F --> G
G --> H1 & H2 & H3
H1 & H2 & H3 --> I
H1 & H2 & H3 -.-> J
H1 --> K
K --> L & M & N & O
L --> P & Q & R & S
style A fill:#e1f5ff
style B fill:#e1f5ff
style C fill:#e1f5ff
style D fill:#e1f5ff
style G fill:#ff9999
style H1 fill:#99ff99
style H2 fill:#99ff99
style H3 fill:#99ff99
style K fill:#ffcc99
style L fill:#ffff99
style M fill:#ffff99
style N fill:#ffff99
```
--- This repository contains a FastAPI-based REST API for generating Pressure-Enthalpy (PH) diagrams
and performing advanced refrigeration thermodynamic calculations.
## 📁 Structure du projet For the full French documentation, see: `README_fr.md` (converted from the original README).
``` Badges
diagram-ph-api/ - Python 3.12+
├── 📄 API_SPECIFICATION.md # Spécifications complètes des endpoints - FastAPI
├── 📄 ARCHITECTURE.md # Architecture technique détaillée - Docker-ready
├── 📄 DEPLOYMENT.md # Guide de déploiement AWS
├── 📄 IMPLEMENTATION_PLAN.md # Plan d'implémentation par phases
├── 📄 README.md # Ce fichier
├── app/ # Code source de l'API
│ ├── main.py # Point d'entrée FastAPI
│ ├── config.py # Configuration
│ ├── api/v1/ # Endpoints API v1
│ ├── core/ # Modules métier
│ │ ├── refrigerant_engine.py
│ │ ├── diagram_generator.py
│ │ ├── cycle_calculator.py
│ │ └── economizer.py
│ ├── models/ # Modèles Pydantic
│ ├── services/ # Business logic
│ └── utils/ # Utilitaires
├── libs/ # Bibliothèques natives
│ ├── dll/ # DLL Windows
│ └── so/ # Shared Objects Linux
├── tests/ # Tests automatisés
├── docker/ # Configuration Docker
├── deployment/ # Scripts et config AWS
└── docs/ # Documentation
```
--- Quick start
- Install dependencies and run with uvicorn (see documentation in the `docs/` folder).
## 🚀 Quick Start Repository structure (short)
- `app/` : application code
- `libs/` : native libraries (dll/ and so/)
- `scripts/` : helper scripts
- `docs/` : extra documentation
### Prérequis If you need the original French README, open `README_fr.md`.
- Python 3.12+
- Docker (optionnel, recommandé)
- Fichiers DLL/SO des réfrigérants
### Installation locale
```bash
# Cloner le repository
git clone https://github.com/votre-org/diagram-ph-api.git
cd diagram-ph-api
# Créer environnement virtuel
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Installer dépendances
pip install -r requirements.txt pip install -r requirements.txt
# Copier et configurer .env # Copier et configurer .env

99
README_fr.md Normal file
View File

@@ -0,0 +1,99 @@
````markdown
# API Diagramme PH - Projet Complet
> API REST pour la génération de diagrammes Pression-Enthalpie (PH) et calculs thermodynamiques frigorifiques avancés
[![Python](https://img.shields.io/badge/Python-3.12+-blue.svg)](https://www.python.org/)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.109+-green.svg)](https://fastapi.tiangolo.com/)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/)
[![AWS](https://img.shields.io/badge/AWS-Elastic%20Beanstalk-orange.svg)](https://aws.amazon.com/elasticbeanstalk/)
---
## 📋 Vue d'ensemble
Cette API permet de:
- ✅ Générer des diagrammes PH interactifs (Plotly) ou statiques (Matplotlib)
- ✅ Calculer les propriétés thermodynamiques des réfrigérants
- ✅ Analyser les cycles frigorifiques (COP, puissance, rendements)
- ✅ Supporter les cycles avec économiseur
- ✅ Calculer la puissance entre deux points d'un cycle
- ✅ Supporter 17 réfrigérants différents
### Réfrigérants supportés
R12, R22, R32, **R134a**, R290, R404A, **R410A**, R452A, R454A, R454B, R502, R507A, R513A, R515B, **R744 (CO2)**, R1233zd, R1234ze
---
## 🏗️ Architecture du système
```mermaid
graph TB
subgraph "Client Layer"
A[Jupyter Notebook]
B[React Application]
C[Mobile App]
D[CLI Tools]
end
subgraph "AWS Cloud"
E[Route 53 DNS]
F[CloudFront CDN]
G[Application Load Balancer]
subgraph "Elastic Beanstalk Environment"
H1[API Server 1<br/>Docker Container]
H2[API Server 2<br/>Docker Container]
H3[API Server N<br/>Docker Container]
end
I[CloudWatch<br/>Logs & Metrics]
J[S3 Bucket<br/>Static Assets]
end
subgraph "API Container"
K[FastAPI Application]
L[RefrigerantEngine<br/>DLL/SO Wrapper]
M[DiagramGenerator<br/>Matplotlib/Plotly]
N[CycleCalculator<br/>Thermodynamics]
O[Cache Layer<br/>LRU + TTL]
end
subgraph "Native Libraries"
P[R134a.so]
Q[R410A.so]
R[refifc.so]
S[Other refrigerants...]
end
A & B & C & D --> E
E --> F
F --> G
G --> H1 & H2 & H3
H1 & H2 & H3 --> I
H1 & H2 & H3 -.-> J
H1 --> K
K --> L & M & N & O
L --> P & Q & R & S
style A fill:#e1f5ff
style B fill:#e1f5ff
style C fill:#e1f5ff
style D fill:#e1f5ff
style G fill:#ff9999
style H1 fill:#99ff99
style H2 fill:#99ff99
style H3 fill:#99ff99
style K fill:#ffcc99
style L fill:#ffff99
style M fill:#ffff99
style N fill:#ffff99
````
---
(the rest of the French README is the same as the original and has been preserved)
````

138
app/ipm/README.md Normal file
View File

@@ -0,0 +1,138 @@
# IPM native integration (app.ipm)
This folder contains the Python wrapper that calls the native refifc libraries.
Quick summary
- Wrapper import path: `app.ipm.simple_refrig_api`.
- Windows DLLs: place under `app/ipm/lib/windows/`.
- Linux shared objects (.so): place under `app/ipm/lib/linux/`.
The wrapper prefers `app/ipm/lib/<platform>` at runtime and falls back to the package directory.
Important: native binaries are large and often licensed. Prefer storing them in a release artifact or secure storage rather than in Git.
--------------------------------
Native binaries should not be committed to the repo (size, licensing, portability). The repo contains a `.gitignore` rule excluding `app/ipm/lib/windows/*.dll`.
CI/CD
- Store binaries in a secure artifact repository (releases, internal storage, S3, etc.).
- During CI, download them and copy into `app/ipm/lib/<platform>` before building the image or deploying.
Quick local test
1. Copy the binaries into the correct folder (e.g. `app/ipm/lib/windows/refifc.dll`).
2. Test locally:
```powershell
.venv\Scripts\python -c "import app.ipm.simple_refrig_api as s; r=s.Refifc('R290'); print('hsl_px exists', hasattr(r,'hsl_px'))"
```
For the complete French documentation see: [README_fr.md](README_fr.md)
````markdown
# IPM native integration (app.ipm)
This folder contains the Python wrapper that calls the native refifc libraries.
Goals
- Centralize the Python wrapper under `app/ipm` so application code can import `app.ipm.simple_refrig_api`.
- Provide a clear location for native binaries (DLLs for Windows, .so for Linux).
Where to place native binaries
- Windows (local/dev): place DLL files in `app/ipm/lib/windows/`.
- Linux (container/production): place .so files in `app/ipm/lib/linux/`.
The wrapper `app/ipm/simple_refrig_api.py` will look first in `app/ipm/lib/<platform>` (`windows` or `linux`) and fall back to the package directory if nothing is found.
Do NOT commit native binaries
--------------------------------
Native binaries should not be committed to the repo (size, licensing, portability). The repo contains a `.gitignore` rule excluding `app/ipm/lib/windows/*.dll` and `app/ipm/lib/linux/*.so`.
CI/CD
- Store binaries in a secure artifact repository (releases, internal storage, S3, etc.).
- During CI, download them and copy into `app/ipm/lib/<platform>` before building the image or deploying.
Quick local test
1. Copy the binaries into the correct folder (e.g. `app/ipm/lib/windows/refifc.dll`).
2. Test locally:
```powershell
.venv\Scripts\python -c "import app.ipm.simple_refrig_api as s; r=s.Refifc('R290'); print('hsl_px exists', hasattr(r,'hsl_px'))"
```
Best practices
- Avoid committing binaries in Git.
- Record the exact origin and version of native binaries in release notes.
- Provide small helper scripts (`scripts/copy-ipm-libs.*`) to automate copying binaries into build environments.
For French documentation see: [README_fr.md](README_fr.md)
````
# IPM native integration (app.ipm) — English (default)
This is the default README for the `app/ipm` package. It is the English version.
For the French version, see: [README_fr.md](README_fr.md)
Short summary
- The `app/ipm` package contains the Python wrapper for the native `refifc` libraries.
- Place Windows DLLs in `app/ipm/lib/windows/` and Linux `.so` files in `app/ipm/lib/linux/`.
See `README_en.md` for the full English documentation and `README_fr.md` for the French translation.
# IPM native integration (app.ipm)
Ce dossier contient l'enveloppe Python qui appelle les bibliothèques natives (refifc).
But
- centraliser le wrapper Python dans `app/ipm` pour que le code applicatif importe depuis `app.ipm.simple_refrig_api`.
- fournir un emplacement clair pour les binaires natifs (DLL pour Windows, .so pour Linux).
Où placer les binaires
---------------------
- Windows (local/dev): placez vos DLL dans `app/ipm/lib/windows/`.
- Linux (container/production): placez vos .so dans `app/ipm/lib/linux/`.
Le wrapper `app/ipm/simple_refrig_api.py` recherche automatiquement, en priorité, le répertoire `app/ipm/lib/<platform>` (`windows` ou `linux`) puis retombe sur le répertoire du package si rien n'est trouvé.
Ne pas committer les binaires
----------------------------
Les fichiers natifs ne doivent pas être committés dans Git (poids, licence, portabilité). Le dépôt contient une règle `.gitignore` qui exclut `app/ipm/lib/windows/*.dll` et `app/ipm/lib/linux/*.so`.
Déploiement / Docker
---------------------
Le Dockerfile doit copier les binaires appropriés dans le répertoire `app/ipm/lib/<platform>` au moment du build. Exemple (Linux image):
```Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY . /app
# Copier les libs natives Linux dans le bon dossier
COPY path/to/linlibs/*.so /app/app/ipm/lib/linux/
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
```
Pour Windows-based artifacts (si vous buildissez une image Windows ou déployez sur Windows), copiez les DLL dans `app/ipm/lib/windows/`.
CI/CD
-----
- Stockez les binaires dans un artefact sécurisé (release, storage interne, S3, etc.).
- Lors du pipeline, téléchargez-les et copiez-les dans `app/ipm/lib/<platform>` avant l'étape d'image ou de déploiement.
Test rapide local
-----------------
1. Copier les binaires dans le bon dossier (ex: `app/ipm/lib/windows/refifc.dll`).
2. Lancer un shell Python depuis la racine du projet et tester :
```powershell
.venv\Scripts\python -c "import app.ipm.simple_refrig_api as s; r=s.Refifc('R290'); print('hsl_px exists', hasattr(r,'hsl_px'))"
```
Bonnes pratiques
----------------
- Ne stockez pas les binaires dans Git.
- Documentez dans votre release notes la provenance et la version exacte des fichiers natifs.
- Préparez un script `scripts/fetch-ipm-libs.sh` (ou équivalent PowerShell) pour automatiser la récupération des binaires dans vos environnements de build.
Si tu veux, j'ajoute un petit `scripts/` helper pour télécharger/copy automatiquement les binaires depuis un dossier central ou un storage.

View File

@@ -1,83 +0,0 @@
# IPM native integration (app.ipm)
This folder contains the Python wrapper that calls the native refifc libraries.
Goals
- Centralize the Python wrapper under `app/ipm` so application code can import `app.ipm.simple_refrig_api`.
- Provide a clear location for native binaries (DLLs for Windows, .so for Linux).
Where to place native binaries
- Windows (local/dev): place DLL files in `app/ipm/lib/windows/`.
- Linux (container/production): place .so files in `app/ipm/lib/linux/`.
The wrapper `app/ipm/simple_refrig_api.py` will look first in `app/ipm/lib/<platform>` (`windows` or `linux`) and fall back to the package directory if nothing is found.
Do NOT commit native binaries
--------------------------------
Native binaries should not be committed to the repo (size, licensing, portability). The repo contains a `.gitignore` rule excluding `app/ipm/lib/windows/*.dll` and `app/ipm/lib/linux/*.so`.
CI/CD
- Store binaries in a secure artifact repository (releases, internal storage, S3, etc.).
- During CI, download them and copy into `app/ipm/lib/<platform>` before building the image or deploying.
Quick local test
1. Copy the binaries into the correct folder (e.g. `app/ipm/lib/windows/refifc.dll`).
2. Test locally:
```powershell
.venv\Scripts\python -c "import app.ipm.simple_refrig_api as s; r=s.Refifc('R290'); print('hsl_px exists', hasattr(r,'hsl_px'))"
```
Best practices
- Avoid committing binaries in Git.
- Record the exact origin and version of native binaries in release notes.
- Provide small helper scripts (`scripts/copy-ipm-libs.*`) to automate copying binaries into build environments.
# IPM native integration (app.ipm)
This folder contains the Python wrapper that calls the native refifc libraries.
Goals
- Centralize the Python wrapper under `app/ipm` so application code can import `app.ipm.simple_refrig_api`.
- Provide a clear location for native binaries (DLLs for Windows, .so for Linux).
Where to place native binaries
- Windows (local/dev): place DLL files in `app/ipm/lib/windows/`.
- Linux (container/production): place .so files in `app/ipm/lib/linux/`.
The wrapper `app/ipm/simple_refrig_api.py` will look first in `app/ipm/lib/<platform>` (`windows` or `linux`) and fall back to the package directory if nothing is found.
Do NOT commit native binaries
--------------------------------
Native binaries should not be committed to the repo (size, licensing, portability). The repo contains a `.gitignore` rule excluding `app/ipm/lib/windows/*.dll` and `app/ipm/lib/linux/*.so`.
Deployment / Docker
- The Dockerfile should copy the appropriate native binaries into `app/ipm/lib/<platform>` during the build. Example (Linux image):
```Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY . /app
# Copy native linux libs into the package
COPY path/to/linlibs/*.so /app/app/ipm/lib/linux/
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
```
CI/CD
- Store binaries in a secure artifact repository (releases, internal storage, S3, etc.).
- During CI, download them and copy into `app/ipm/lib/<platform>` before building the image or deploying.
Quick local test
1. Copy the binaries into the correct folder (e.g. `app/ipm/lib/windows/refifc.dll`).
2. Test locally:
```powershell
.venv\Scripts\python -c "import app.ipm.simple_refrig_api as s; r=s.Refifc('R290'); print('hsl_px exists', hasattr(r,'hsl_px'))"
```
Best practices
- Avoid committing binaries in Git.
- Record the exact origin and version of native binaries in release notes.
- Provide small helper scripts (`scripts/copy-ipm-libs.*`) to automate copying binaries into build environments.

View File

@@ -32,3 +32,5 @@ Bonnes pratiques
- Ne stockez pas les binaires dans Git. - Ne stockez pas les binaires dans Git.
- Documentez la provenance et la version des fichiers natifs dans vos notes de release. - Documentez la provenance et la version des fichiers natifs dans vos notes de release.
- Préparez un script `scripts/copy-ipm-libs.*` pour automatiser la copie des binaires dans les environnements de build. - Préparez un script `scripts/copy-ipm-libs.*` pour automatiser la copie des binaires dans les environnements de build.
Pour la documentation en anglais, voir : [README_en.md](README_en.md)

0
docker-compose.dev.yml Normal file
View File

59
docker-compose.yml Normal file
View 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

Binary file not shown.

BIN
libs/so/libR1233zd.so Normal file

Binary file not shown.

BIN
libs/so/libR1234ze.so Normal file

Binary file not shown.

BIN
libs/so/libR134a.so Normal file

Binary file not shown.

BIN
libs/so/libR22.so Normal file

Binary file not shown.

BIN
libs/so/libR290.so Normal file

Binary file not shown.

BIN
libs/so/libR32.so Normal file

Binary file not shown.

BIN
libs/so/libR404A.so Normal file

Binary file not shown.

BIN
libs/so/libR410A.so Normal file

Binary file not shown.

BIN
libs/so/libR502.so Normal file

Binary file not shown.

BIN
libs/so/libR507A.so Normal file

Binary file not shown.

BIN
libs/so/libR717.so Normal file

Binary file not shown.

BIN
libs/so/libR744.so Normal file

Binary file not shown.

5
requirements-dev.txt Normal file
View File

@@ -0,0 +1,5 @@
pytest
httpx
requests
fastapi
starlette

11
requirements.txt Normal file
View 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