Claude
Skills
Sign in
Back

api-integration

Included with Lifetime
$97 forever

# API Integration Skill

Backend & APIs

What this skill does

# API Integration Skill

```yaml
name: api-integration
version: 1.0.0
category: programming
tags: [api, integration, orcaflex, aqwa, wamit, mock-testing, automation, offshore-software]
created: 2026-01-06
updated: 2026-01-06
author: Claude
description: |
  Expert API integration for offshore engineering software (OrcaFlex, AQWA, WAMIT)
  with mock testing strategies, error handling, and automation workflows. Enables
  development and testing without requiring the actual commercial software licenses.
```

## When to Use This Skill

Use this skill when you need to:
- Integrate with OrcaFlex Python API
- Integrate with ANSYS AQWA or WAMIT
- Create mock APIs for testing without software licenses
- Build automation workflows for marine analysis software
- Develop robust error handling for API calls
- Implement batch processing with external software APIs
- Create abstraction layers over multiple analysis tools

## Core Knowledge Areas

### 1. OrcaFlex API Integration

Working with OrcaFlex Python API:

```python
import os
from pathlib import Path
from typing import Optional, Dict, List, Any
from dataclasses import dataclass
from abc import ABC, abstractmethod

# Mock OrcaFlex API for testing without license
class MockOrcFxAPI:
    """Mock OrcaFlex API for development without license."""

    class Model:
        """Mock OrcaFlex Model class."""

        def __init__(self, file_path: str = None):
            self.file_path = file_path
            self._general_data = {}
            self._objects = []
            self._is_calculated = False

        def SaveData(self, path: str):
            """Mock save data file."""
            print(f"[MOCK] Saving data to: {path}")
            self.file_path = path

        def LoadData(self, path: str):
            """Mock load data file."""
            print(f"[MOCK] Loading data from: {path}")
            self.file_path = path

        def CalculateStatics(self):
            """Mock static calculation."""
            print("[MOCK] Calculating statics...")
            self._is_calculated = True

        def RunSimulation(self):
            """Mock simulation run."""
            print("[MOCK] Running simulation...")
            self._is_calculated = True

        def SaveSimulation(self, path: str):
            """Mock save simulation."""
            print(f"[MOCK] Saving simulation to: {path}")

    @staticmethod
    def otVessel():
        return "Vessel"

    @staticmethod
    def otLine():
        return "Line"

    @staticmethod
    def ot6DBuoy():
        return "6D Buoy"

# Try to import real OrcaFlex API, fall back to mock
try:
    import OrcFxAPI
    USING_MOCK_ORCAFLEX = False
except ImportError:
    OrcFxAPI = MockOrcFxAPI
    USING_MOCK_ORCAFLEX = True
    print("Warning: OrcaFlex not available, using mock API")

@dataclass
class OrcaFlexConfig:
    """Configuration for OrcaFlex analysis."""
    model_file: Path
    output_dir: Path
    simulation_duration: float
    time_step: float
    use_variable_timestep: bool = True
    thread_count: int = 4

class OrcaFlexWrapper:
    """
    Wrapper class for OrcaFlex API with error handling and utilities.

    Example:
        >>> config = OrcaFlexConfig(
        ...     model_file=Path('mooring.dat'),
        ...     output_dir=Path('results'),
        ...     simulation_duration=3600,
        ...     time_step=0.01
        ... )
        >>> wrapper = OrcaFlexWrapper(config)
        >>> wrapper.run_analysis()
    """

    def __init__(self, config: OrcaFlexConfig):
        self.config = config
        self.model: Optional[OrcFxAPI.Model] = None
        self.is_mock = USING_MOCK_ORCAFLEX

    def load_model(self) -> None:
        """Load OrcaFlex model from file."""
        if not self.config.model_file.exists():
            raise FileNotFoundError(f"Model file not found: {self.config.model_file}")

        try:
            self.model = OrcFxAPI.Model(str(self.config.model_file))
            print(f"Loaded model: {self.config.model_file}")
        except Exception as e:
            raise RuntimeError(f"Failed to load model: {e}")

    def configure_simulation(self) -> None:
        """Configure simulation parameters."""
        if self.model is None:
            raise ValueError("Model not loaded")

        if not self.is_mock:
            # Configure real model
            general = self.model.general
            general.ImplicitUseVariableTimeStep = 'Yes' if self.config.use_variable_timestep else 'No'
            general.TargetLogSampleInterval = self.config.time_step
            general.ThreadCount = self.config.thread_count

            # Set simulation stages
            general.StageCount = 2
            general.StageDuration[0] = 100  # Build-up
            general.StageDuration[1] = self.config.simulation_duration
        else:
            print(f"[MOCK] Configured simulation: duration={self.config.simulation_duration}s")

    def run_static_analysis(self) -> bool:
        """
        Run static analysis.

        Returns:
            True if successful, False otherwise
        """
        if self.model is None:
            raise ValueError("Model not loaded")

        try:
            self.model.CalculateStatics()
            print("Static analysis complete")
            return True
        except Exception as e:
            print(f"Static analysis failed: {e}")
            return False

    def run_dynamic_analysis(self, save_results: bool = True) -> Optional[Path]:
        """
        Run dynamic analysis.

        Args:
            save_results: Whether to save simulation results

        Returns:
            Path to saved simulation file if save_results=True, else None
        """
        if self.model is None:
            raise ValueError("Model not loaded")

        try:
            self.model.RunSimulation()
            print("Dynamic analysis complete")

            if save_results:
                self.config.output_dir.mkdir(parents=True, exist_ok=True)
                sim_file = self.config.output_dir / f"{self.config.model_file.stem}.sim"
                self.model.SaveSimulation(str(sim_file))
                print(f"Results saved: {sim_file}")
                return sim_file

            return None

        except Exception as e:
            print(f"Dynamic analysis failed: {e}")
            raise

    def extract_time_series(
        self,
        object_name: str,
        variable_name: str,
        object_extra: str = 'EndA'
    ) -> tuple:
        """
        Extract time series from results.

        Args:
            object_name: Name of object
            variable_name: Variable name
            object_extra: Object extra specification

        Returns:
            Tuple of (time, values) as numpy arrays
        """
        if self.model is None:
            raise ValueError("Model not loaded")

        if self.is_mock:
            # Return mock data
            import numpy as np
            time = np.linspace(0, self.config.simulation_duration, 1000)
            values = np.random.randn(1000) * 100 + 1000  # Mock tension data
            print(f"[MOCK] Extracted time series for {object_name}.{variable_name}")
            return time, values

        # Extract from real model
        import numpy as np
        obj = self.model[object_name]

        # Handle object extra parameter
        if not self.is_mock:
            # Map string to OrcaFlex enum
            if object_extra == 'EndA':
                oe = OrcFxAPI.oeEndA
            elif object_extra == 'EndB':
                oe = OrcFxAPI.oeEndB
            else:
                oe = OrcFxAPI.oeEndA  # Default

            time = np.array(obj.TimeHistory('Time', objectExtra=oe))
            values = np.array(obj.TimeHistory(variable_name, objectExtra=oe))
        else:
            time = np.linspace(0, 3600, 1000)
            values = np.random.randn(1000) * 100 + 1000

        return time, values

    def run_analysis(self) -> Dict[str, Any]:
        """
        Complete anal

Related in Backend & APIs