A Python-based structural calculation engine for steel beam analysis using NumPy, Pandas, and SciPy. This service communicates with the Form & Function Go API exclusively via gRPC for optimal performance and type safety.
- Steel Beam Analysis: Comprehensive structural analysis including:
- Bending moment calculations
- Shear force analysis
- Deflection calculations
- Stress utilization checks
- Eurocode 3 compliance
- Load Types: Support for uniform distributed loads and point loads
- Material Grades: S235, S275, S355, S460 steel grades
- Optimal Beam Selection: Automatically find the most economical beam for given loads
- Safety Checks: Configurable safety factors and serviceability limits
- RESTful API: FastAPI-based web service with automatic OpenAPI documentation
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ React Web │───▶│ Go gRPC │───▶│ Steel Beam │
│ Frontend │ │ Server │ │ Data │
│ (Vercel) │ │ (Port 9090) │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ ▲
│ │ gRPC
│ ┌─────────────────┐
└─────────────▶│ Python Calc │
│ Engine │
│ (Port 8081) │
│ gRPC Client │
└─────────────────┘
- Python 3.8 or higher
- Go gRPC server running (port 9090)
- Virtual environment support
- Docker (for containerization)
- gRPC dependencies (protobuf, grpcio)
# From itsformandfunction directory
docker-compose up --buildThis starts both the Go gRPC server (port 9090) and Python calc engine (port 8081).
-
Start the Go gRPC server first:
cd ../formandfunction-api export GRPC_PORT=9090 go run .
-
Start the calc engine:
./start.sh
-
Access the API documentation: Open http://localhost:8081/docs in your browser
-
Run tests:
python test_calc.py
-
Deploy to Railway:
railway up # or via Railway Dashboard - connect GitHub repository -
Access production API:
- Production URL: https://engine.itsformfunction.com
- API docs: https://engine.itsformfunction.com/docs
- Health check: https://engine.itsformfunction.com/health
-
Docker deployment:
docker build -t calc-engine . docker run -p 8081:8081 calc-engine
If you prefer to set up manually:
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set environment variables (optional)
export API_BASE_URL="http://localhost:8080"
export PORT="8081"
# Start the service
python main.py- Base URL:
http://localhost:8081 - API Docs:
http://localhost:8081/docs
- Base URL:
https://engine.itsformfunction.com - API Docs:
https://engine.itsformfunction.com/docs
GET /- Service informationGET /health- Detailed health check including API connectivityGET /beams- Get all available steel beams from the Go APIGET /beams/{designation}- Get specific beam information
POST /analyze- Perform comprehensive beam analysis
{
"beam_designation": "UB406x178x74", // Optional - if not provided, optimal beam is selected
"applied_load": 15.0, // kN or kN/m depending on load_type
"span_length": 6.0, // meters
"load_type": "uniform", // "uniform" or "point"
"safety_factor": 1.6, // Safety factor for design
"material_grade": "S355" // Steel grade: S235, S275, S355, S460
}{
"beam": {
"section_designation": "UB406x178x74",
"mass_per_metre": 74.6,
// ... full beam properties
},
"applied_load": 15.0,
"span_length": 6.0,
"max_moment": 67.5, // kNm
"max_shear": 45.0, // kN
"max_deflection": 12.34, // mm
"stress_utilization": 0.756, // Ratio (should be ≤ 1.0)
"deflection_limit_check": true, // Passes L/250 limit
"is_adequate": true, // Overall adequacy
"safety_margin": 24.4, // Percentage
"recommendations": [
"PASS: Beam is adequate for the applied loading."
]
}- Uniform Load: M = wL²/8
- Point Load (center): M = PL/4
- Uniform Load: δ = 5wL⁴/(384EI)
- Point Load (center): δ = PL³/(48EI)
- Utilization = (Actual Stress) / (Allowable Stress)
- Allowable Stress = fy / Safety Factor
- Actual Stress = M / W (elastic section modulus)
- Deflection limit: L/250 (general construction)
- Can be customized for specific applications
import requests
# Analyze a specific beam
response = requests.post("http://localhost:8081/analyze", json={
"beam_designation": "UB406x178x74",
"applied_load": 12.0,
"span_length": 8.0,
"load_type": "uniform",
"material_grade": "S355"
})
result = response.json()
print(f"Beam adequate: {result['is_adequate']}")
print(f"Stress utilization: {result['stress_utilization']}")curl -X POST "http://localhost:8081/analyze" \
-H "Content-Type: application/json" \
-d '{
"applied_load": 20.0,
"span_length": 6.0,
"load_type": "uniform",
"material_grade": "S355"
}'The calc engine is designed to be called from the React frontend with automatic environment switching:
const analyzeBeam = async (loadData: CalculationRequest) => {
const calcEngineUrl = process.env.NODE_ENV === 'development'
? 'http://localhost:8081'
: 'https://engine.itsformfunction.com';
const response = await fetch(`${calcEngineUrl}/analyze`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(loadData)
});
return response.json();
};Local Development:
API_BASE_URL: Go API base URL (default: http://localhost:8080)PORT: Port for calc engine (default: 8081)
Production (Railway):
API_BASE_URL: Production Go API URL (set in Railway dashboard)PORT: Automatically set by Railway- Container-based deployment with auto-scaling
- Custom domain:
engine.itsformfunction.com
The railway.json and Dockerfile configure containerized deployment:
- Python 3.11 slim image
- FastAPI with Uvicorn server
- Health checks and auto-restart
- Environment variable support
Local Testing:
# Run all tests (includes gRPC tests)
python test_calc.py
# Test gRPC-only setup
python ../test_grpc_only.py
# Test specific functionality
python -c "from main import BeamAnalysis; analyzer = BeamAnalysis(); print(analyzer.fetch_beams_from_api())"
# Test health check
curl http://localhost:8081/healthProduction Testing:
# Test production health
curl https://engine.itsformfunction.com/health
# Test production calculation
curl -X POST https://engine.itsformfunction.com/analyze \
-H "Content-Type: application/json" \
-d '{"applied_load": 10.0, "span_length": 6.0, "load_type": "uniform", "material_grade": "S355"}'# Local development
./start.sh
# Build and test Docker image
docker build -t calc-engine .
docker run -p 8081:8081 calc-engine
# Deploy to Railway
railway up
# Check deployment logs
railway logs- Add calculation method to
BeamAnalysisclass inmain.py - Update the analysis workflow in
perform_analysis() - Add corresponding tests in
test_calc.py - Test locally with Docker
- Deploy to Railway for production
# Format code
black main.py test_calc.py
# Lint code
flake8 main.py test_calc.py
# Run with type checking
mypy main.py-
"Unable to fetch beam data from API"
- Ensure Go API is running on port 8080
- Check network connectivity
- Verify API endpoint responds:
curl http://localhost:8080/beams
-
Import errors
- Activate virtual environment:
source venv/bin/activate - Install dependencies:
pip install -r requirements.txt
- Activate virtual environment:
-
Port already in use
- Change port:
export CALC_ENGINE_PORT=8082 - Kill existing process:
lsof -ti:8081 | xargs kill
- Change port:
-
Deployment failures
- Check
Dockerfileandrailway.jsonconfiguration - Verify
requirements.txthas correct dependencies - Check build logs in Railway dashboard
- Check
-
Runtime errors
- Check Railway logs:
railway logs - Verify environment variables are set
- Test API connectivity from container environment
- Check Railway logs:
-
Performance issues
- Monitor resource usage in Railway dashboard
- Optimize calculation algorithms
- Consider upgrading to Railway Pro plan
Local debugging:
export LOG_LEVEL=DEBUG
python main.pyProduction debugging:
# View deployment logs
railway logs
# Check deployment status
railway status
# Test container locally
docker run -it calc-engine /bin/bash- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is part of the Form & Function engineering platform.
For detailed Railway deployment instructions, see RAILWAY_DEPLOYMENT.md.
-
Create Railway project:
- Connect GitHub repository
- Set
API_BASE_URLenvironment variable - Deploy automatically triggers
-
Local Docker testing:
docker build -t calc-engine . docker run -p 8081:8081 -e API_BASE_URL=http://host.docker.internal:8080 calc-engine -
Production monitoring:
- Health checks: Built into Docker container
- Logs: Available in Railway dashboard
- Metrics: CPU, memory, and response times# formandfunction-calcengine