Compare commits
3 Commits
c0c0e6e3ea
...
snapshot/2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d5005ce4e | ||
|
|
d22184cf70 | ||
|
|
24db8ad426 |
13
Dockerfile
13
Dockerfile
@@ -30,14 +30,15 @@ COPY requirements.txt /app/requirements.txt
|
|||||||
RUN python -m pip install --upgrade pip setuptools wheel && \
|
RUN python -m pip install --upgrade pip setuptools wheel && \
|
||||||
python -m pip install -r /app/requirements.txt
|
python -m pip install -r /app/requirements.txt
|
||||||
|
|
||||||
# Copy project
|
# Copy only app directory and libs/so (native .so libraries for Linux)
|
||||||
COPY . /app
|
COPY app /app/app
|
||||||
|
COPY libs/so /app/libs/so
|
||||||
|
|
||||||
# Ensure Python and dynamic linker will find the native libs if mounted
|
# Set environment variables to use libs/so for native libraries
|
||||||
ENV PYTHONPATH="/app:/app/IPM_SO:/app/IPM_DLL"
|
ENV PYTHONPATH="/app"
|
||||||
ENV LD_LIBRARY_PATH="/app/IPM_SO:/app/IPM_DLL"
|
ENV LD_LIBRARY_PATH="/app/libs/so"
|
||||||
|
|
||||||
EXPOSE 8001
|
EXPOSE 8001
|
||||||
|
|
||||||
# Default command runs uvicorn (use docker-compose override for development)
|
# Default command runs uvicorn
|
||||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Frontend .dockerignore
|
||||||
|
node_modules
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
build
|
||||||
|
.turbo
|
||||||
|
dist
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Frontend Dockerfile
|
||||||
|
FROM node:20-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package.json package-lock.json* ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the Next.js app
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
ENV HOSTNAME "0.0.0.0"
|
||||||
|
|
||||||
|
CMD ["node", "server.js"]
|
||||||
|
|||||||
179
README-DOCKER.md
179
README-DOCKER.md
@@ -0,0 +1,179 @@
|
|||||||
|
# DiagramPH - Docker Deployment Guide
|
||||||
|
|
||||||
|
## 🐳 Docker Compose Setup
|
||||||
|
|
||||||
|
Ce projet utilise Docker Compose pour déployer le backend (FastAPI) et le frontend (Next.js) ensemble.
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐ ┌──────────────────┐
|
||||||
|
│ Frontend │─────▶│ Backend │
|
||||||
|
│ (Next.js) │ │ (FastAPI) │
|
||||||
|
│ Port: 3000 │ │ Port: 8001 │
|
||||||
|
└─────────────────┘ └──────────────────┘
|
||||||
|
│ │
|
||||||
|
└────────────────────────┘
|
||||||
|
Docker Network
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Démarrage Rapide
|
||||||
|
|
||||||
|
### Production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build et démarrer tous les services
|
||||||
|
docker-compose up --build
|
||||||
|
|
||||||
|
# En mode détaché (background)
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Arrêter les services
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Arrêter et supprimer les volumes
|
||||||
|
docker-compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Accès:
|
||||||
|
- **Frontend**: http://localhost:3000
|
||||||
|
- **Backend API**: http://localhost:8001
|
||||||
|
- **API Docs**: http://localhost:8001/docs
|
||||||
|
|
||||||
|
### Développement
|
||||||
|
|
||||||
|
Pour le développement avec hot-reload:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrer en mode développement
|
||||||
|
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
|
||||||
|
|
||||||
|
# Rebuild si nécessaire
|
||||||
|
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📦 Services
|
||||||
|
|
||||||
|
### Backend (Python FastAPI)
|
||||||
|
|
||||||
|
- **Port**: 8001
|
||||||
|
- **Base Image**: python:3.12-slim
|
||||||
|
- **Hot Reload**: Activé avec `--reload` en dev
|
||||||
|
- **Healthcheck**: GET /api/v1/refrigerants/
|
||||||
|
|
||||||
|
### Frontend (Next.js)
|
||||||
|
|
||||||
|
- **Port**: 3000
|
||||||
|
- **Base Image**: node:20-alpine
|
||||||
|
- **Build**: Standalone output optimisé
|
||||||
|
- **Healthcheck**: HTTP GET sur port 3000
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Variables d'Environnement
|
||||||
|
|
||||||
|
#### Backend
|
||||||
|
```env
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
PYTHONPATH=/app:/app/IPM_SO:/app/IPM_DLL
|
||||||
|
LD_LIBRARY_PATH=/app/IPM_SO:/app/IPM_DLL
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Frontend
|
||||||
|
```env
|
||||||
|
NODE_ENV=production
|
||||||
|
NEXT_PUBLIC_API_URL=http://backend:8001/api/v1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Volumes
|
||||||
|
|
||||||
|
Les volumes sont montés pour permettre le hot-reload en développement:
|
||||||
|
- `./app` → Backend code
|
||||||
|
- `./Frontend` → Frontend code
|
||||||
|
- `./IPM_SO` et `./IPM_DLL` → Native libraries
|
||||||
|
|
||||||
|
## 📝 Commandes Utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Voir les logs
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Logs d'un service spécifique
|
||||||
|
docker-compose logs -f backend
|
||||||
|
docker-compose logs -f frontend
|
||||||
|
|
||||||
|
# Reconstruire un service
|
||||||
|
docker-compose build backend
|
||||||
|
docker-compose build frontend
|
||||||
|
|
||||||
|
# Exécuter une commande dans un conteneur
|
||||||
|
docker-compose exec backend python -m pytest
|
||||||
|
docker-compose exec frontend npm test
|
||||||
|
|
||||||
|
# Voir l'état des services
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
# Redémarrer un service
|
||||||
|
docker-compose restart backend
|
||||||
|
docker-compose restart frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
|
### Le frontend ne peut pas se connecter au backend
|
||||||
|
|
||||||
|
Vérifiez que:
|
||||||
|
1. Le backend est en cours d'exécution: `docker-compose ps`
|
||||||
|
2. Le healthcheck du backend est OK: `docker-compose logs backend`
|
||||||
|
3. Les deux services sont sur le même réseau Docker
|
||||||
|
|
||||||
|
### Erreur de build frontend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Nettoyer le cache et rebuild
|
||||||
|
docker-compose build --no-cache frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Erreur de permissions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sur Linux/Mac, ajuster les permissions
|
||||||
|
sudo chown -R $USER:$USER Frontend/.next
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Structure des Fichiers
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── docker-compose.yml # Configuration production
|
||||||
|
├── docker-compose.dev.yml # Override pour développement
|
||||||
|
├── Dockerfile # Backend Dockerfile
|
||||||
|
├── Frontend/
|
||||||
|
│ ├── Dockerfile # Frontend Dockerfile
|
||||||
|
│ ├── .dockerignore
|
||||||
|
│ └── next.config.js
|
||||||
|
├── app/ # Code backend
|
||||||
|
└── README-DOCKER.md # Ce fichier
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 Production Deployment
|
||||||
|
|
||||||
|
Pour un déploiement en production:
|
||||||
|
|
||||||
|
1. **Désactiver le mode debug**:
|
||||||
|
- Retirer `--reload` du backend
|
||||||
|
- Utiliser `NODE_ENV=production`
|
||||||
|
|
||||||
|
2. **Utiliser des secrets**:
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=${DATABASE_URL}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Configurer un reverse proxy** (Nginx/Traefik)
|
||||||
|
|
||||||
|
4. **Ajouter SSL/TLS** avec Let's Encrypt
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|||||||
116
README.md
116
README.md
@@ -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]
|
This repository contains a FastAPI-based REST API for generating Pressure-Enthalpy (PH) diagrams
|
||||||
J[S3 Bucket<br/>Static Assets]
|
and performing advanced refrigeration thermodynamic calculations.
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "API Container"
|
For the full French documentation, see: `README_fr.md` (converted from the original README).
|
||||||
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"
|
Badges
|
||||||
P[R134a.so]
|
- Python 3.12+
|
||||||
Q[R410A.so]
|
- FastAPI
|
||||||
R[refifc.so]
|
- Docker-ready
|
||||||
S[Other refrigerants...]
|
|
||||||
end
|
|
||||||
|
|
||||||
A & B & C & D --> E
|
Quick start
|
||||||
E --> F
|
- Install dependencies and run with uvicorn (see documentation in the `docs/` folder).
|
||||||
F --> G
|
|
||||||
G --> H1 & H2 & H3
|
|
||||||
H1 & H2 & H3 --> I
|
|
||||||
H1 & H2 & H3 -.-> J
|
|
||||||
|
|
||||||
H1 --> K
|
Repository structure (short)
|
||||||
K --> L & M & N & O
|
- `app/` : application code
|
||||||
L --> P & Q & R & S
|
- `libs/` : native libraries (dll/ and so/)
|
||||||
|
- `scripts/` : helper scripts
|
||||||
|
- `docs/` : extra documentation
|
||||||
|
|
||||||
style A fill:#e1f5ff
|
If you need the original French README, open `README_fr.md`.
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Structure du projet
|
|
||||||
|
|
||||||
```
|
|
||||||
diagram-ph-api/
|
|
||||||
├── 📄 API_SPECIFICATION.md # Spécifications complètes des endpoints
|
|
||||||
├── 📄 ARCHITECTURE.md # Architecture technique détaillée
|
|
||||||
├── 📄 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
|
|
||||||
|
|
||||||
### Prérequis
|
|
||||||
|
|
||||||
- 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
99
README_fr.md
Normal 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
|
||||||
|
|
||||||
|
[](https://www.python.org/)
|
||||||
|
[](https://fastapi.tiangolo.com/)
|
||||||
|
[](https://www.docker.com/)
|
||||||
|
[](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)
|
||||||
|
|
||||||
|
````
|
||||||
@@ -7,13 +7,18 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional, List
|
from typing import Dict, Optional, List
|
||||||
|
|
||||||
# Prefer the packaged app.ipm module, but keep a fallback to the legacy
|
# Prefer the packaged app.ipm module, but fall back to the legacy IPM_DLL
|
||||||
# IPM_DLL folder for development compatibility.
|
# folder only if the packaged module cannot be imported. Import the module
|
||||||
|
# object and use getattr to avoid ImportError when optional symbols like
|
||||||
|
# `MockRefifc` are missing.
|
||||||
try:
|
try:
|
||||||
from app.ipm.simple_refrig_api import Refifc, MockRefifc # type: ignore
|
import importlib
|
||||||
|
_sr = importlib.import_module('app.ipm.simple_refrig_api')
|
||||||
|
Refifc = getattr(_sr, 'Refifc')
|
||||||
|
MockRefifc = getattr(_sr, 'MockRefifc', None)
|
||||||
except Exception:
|
except Exception:
|
||||||
# Fall back to loading from IPM_DLL directory as before. Import the
|
# Fall back to loading from IPM_DLL directory as before. Import the
|
||||||
# module and pick attributes if present; older legacy wrappers may not
|
# legacy module and pick attributes if present; older wrappers may not
|
||||||
# define MockRefifc.
|
# define MockRefifc.
|
||||||
_current_dir = Path(__file__).parent.parent.parent
|
_current_dir = Path(__file__).parent.parent.parent
|
||||||
_ipm_dll_dir = _current_dir / "IPM_DLL"
|
_ipm_dll_dir = _current_dir / "IPM_DLL"
|
||||||
|
|||||||
@@ -112,28 +112,55 @@ class Refifc(object):
|
|||||||
|
|
||||||
# Sauvegardez le répertoire courant pour pouvoir y revenir plus tard
|
# Sauvegardez le répertoire courant pour pouvoir y revenir plus tard
|
||||||
self.original_directory = os.getcwd()
|
self.original_directory = os.getcwd()
|
||||||
# Determine candidate directories for the native library. Prefer
|
# Determine candidate directories for the native library.
|
||||||
# app/ipm/lib/<platform> if present, otherwise fall back to the
|
# Prefer central repo-level folders:
|
||||||
# package directory (for compatibility with older layouts).
|
# <repo_root>/libs/dll (Windows)
|
||||||
|
# <repo_root>/libs/so (Linux)
|
||||||
|
# Fall back to package-local `app/ipm/lib/<platform>` or the package dir.
|
||||||
package_dir = os.path.dirname(os.path.abspath(__file__))
|
package_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
platform_dir = os.path.join(package_dir, 'lib', 'windows' if os.name == 'nt' else 'linux')
|
# repo root is two levels above app/ipm
|
||||||
dll_directory = platform_dir if os.path.isdir(platform_dir) else package_dir
|
repo_root = os.path.abspath(os.path.join(package_dir, '..', '..'))
|
||||||
|
preferred_windows = os.path.join(repo_root, 'libs', 'dll')
|
||||||
|
preferred_linux = os.path.join(repo_root, 'libs', 'so')
|
||||||
|
|
||||||
# Change working directory to the chosen directory while loading
|
if os.name == 'nt':
|
||||||
os.chdir(dll_directory)
|
candidate_dirs = [preferred_windows]
|
||||||
|
else:
|
||||||
|
candidate_dirs = [preferred_linux]
|
||||||
|
|
||||||
# Try to load the native library from the chosen directory; if that
|
# also consider the package-local lib/<platform> layout as fallback
|
||||||
# fails, attempt to load by name (for system-installed libs) and
|
candidate_dirs.append(os.path.join(package_dir, 'lib', 'windows' if os.name == 'nt' else 'linux'))
|
||||||
# otherwise raise the original exception.
|
candidate_dirs.append(package_dir)
|
||||||
|
|
||||||
|
# Try each candidate directory in order until we can load the library.
|
||||||
|
load_exc = None
|
||||||
|
for dll_directory in candidate_dirs:
|
||||||
|
if not dll_directory:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
|
if os.path.isdir(dll_directory):
|
||||||
|
# temporarily change cwd to help some LoadLibrary behaviors
|
||||||
|
os.chdir(dll_directory)
|
||||||
self.lib = ctypes.cdll.LoadLibrary(os.path.join(dll_directory, REFIFC_LIB_NAME))
|
self.lib = ctypes.cdll.LoadLibrary(os.path.join(dll_directory, REFIFC_LIB_NAME))
|
||||||
except OSError:
|
else:
|
||||||
|
# attempt to load directly by path anyway
|
||||||
|
self.lib = ctypes.cdll.LoadLibrary(os.path.join(dll_directory, REFIFC_LIB_NAME))
|
||||||
|
load_exc = None
|
||||||
|
break
|
||||||
|
except OSError as e:
|
||||||
|
load_exc = e
|
||||||
|
# try next candidate
|
||||||
|
continue
|
||||||
|
|
||||||
|
# if we failed to load from candidates, try loading by name (system path)
|
||||||
|
if load_exc is not None:
|
||||||
try:
|
try:
|
||||||
self.lib = ctypes.cdll.LoadLibrary(REFIFC_LIB_NAME)
|
self.lib = ctypes.cdll.LoadLibrary(REFIFC_LIB_NAME)
|
||||||
except Exception as e:
|
load_exc = None
|
||||||
# Restore cwd before raising
|
except Exception:
|
||||||
|
# restore cwd before raising
|
||||||
os.chdir(self.original_directory)
|
os.chdir(self.original_directory)
|
||||||
raise
|
raise load_exc
|
||||||
|
|
||||||
ctypes_refrig_name = refrig_name
|
ctypes_refrig_name = refrig_name
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
@@ -145,7 +172,8 @@ class Refifc(object):
|
|||||||
try:
|
try:
|
||||||
ctypes.CDLL(os.path.join(dll_directory, REFIFC_LIB_NAME))
|
ctypes.CDLL(os.path.join(dll_directory, REFIFC_LIB_NAME))
|
||||||
except OSError:
|
except OSError:
|
||||||
print(f"Refrig {refrig_name} not found, please check!")
|
# don't raise here; letting the subsequent load/check handle missing refrigerant libs
|
||||||
|
print(f"Refrig {refrig_name} not found in {dll_directory}, please check!")
|
||||||
|
|
||||||
func = self.lib.refdll_load
|
func = self.lib.refdll_load
|
||||||
func.restype = POINTER(c_void_p)
|
func.restype = POINTER(c_void_p)
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
# Development override for docker-compose.yml
|
||||||
|
# Usage: docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
|
||||||
|
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
volumes:
|
||||||
|
- ./app:/app/app:cached
|
||||||
|
- ./IPM_SO:/app/IPM_SO:cached
|
||||||
|
- ./IPM_DLL:/app/IPM_DLL:cached
|
||||||
|
- ./tests:/app/tests:cached
|
||||||
|
command: uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload
|
||||||
|
environment:
|
||||||
|
- DEBUG=1
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./Frontend
|
||||||
|
target: deps
|
||||||
|
volumes:
|
||||||
|
- ./Frontend:/app:cached
|
||||||
|
- /app/node_modules
|
||||||
|
- /app/.next
|
||||||
|
command: npm run dev
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- NEXT_PUBLIC_API_URL=http://localhost:8001/api/v1
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# Backend API Service
|
# Backend API Service
|
||||||
backend:
|
backend:
|
||||||
@@ -11,12 +9,11 @@ services:
|
|||||||
- "8001:8001"
|
- "8001:8001"
|
||||||
volumes:
|
volumes:
|
||||||
- ./app:/app/app:cached
|
- ./app:/app/app:cached
|
||||||
- ./IPM_SO:/app/IPM_SO:cached
|
- ./libs/so:/app/libs/so:cached
|
||||||
- ./IPM_DLL:/app/IPM_DLL:cached
|
|
||||||
environment:
|
environment:
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
- PYTHONPATH=/app:/app/IPM_SO:/app/IPM_DLL
|
- PYTHONPATH=/app
|
||||||
- LD_LIBRARY_PATH=/app/IPM_SO:/app/IPM_DLL
|
- LD_LIBRARY_PATH=/app/libs/so
|
||||||
command: uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload
|
command: uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload
|
||||||
networks:
|
networks:
|
||||||
- diagramph-network
|
- diagramph-network
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user