# Working with Parametric Attributes

Product parts in the Renesas Web Data API contain rich parametric data through the `parametricAttributes` array. This guide shows how to iterate through product parts and extract specific attribute information, using country of wafer fabrication as a practical example.

## Overview

Each product part includes detailed parametric attributes that describe technical specifications, manufacturing details, and other properties. These attributes are structured as an array of objects, each containing:

- `productPartAttributeId`: Unique identifier for the attribute type
- `attributeName`: Human-readable name of the attribute
- `attributeValues`: Array of values (can be strings, numbers, or objects)
- `href`: API endpoint for more details about this attribute type


## Understanding Parametric Attributes Structure

```json
{
  "parametricAttributes": [
    {
      "productPartAttributeId": "field__country_of_wafer_fabrication",
      "attributeName": "Country of Wafer Fabrication",
      "attributeValues": ["JAPAN"],
      "href": "/product-part-attributes/field__country_of_wafer_fabrication"
    },
    {
      "productPartAttributeId": "field__supply_voltage_v",
      "attributeName": "Supply Voltage",
      "attributeValues": [{"from": "1.6", "to": "5.5"}],
      "href": "/product-part-attributes/field__supply_voltage_v"
    }
  ]
}
```

## Retrieving Product Parts with Attributes

### Single Product Part Retrieval

Get a specific product part with all its parametric attributes using the canonical endpoint:

```bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.renesas.com/web-data/v1/product-parts/R5F52617BDNE%2310"
```

Note: The `#` character in part numbers must be URL encoded as `%23`.

### Basic List Request

Get multiple product parts with their complete parametric attributes:

```bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.renesas.com/web-data/v1/product-parts?limit=50"
```

### Filter by Product Family

Focus on specific product families for attribute analysis:

```bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.renesas.com/web-data/v1/product-parts?product_family=RX&limit=100"
```

## Extracting Specific Attributes

### Python Example: Country of Wafer Fabrication

```python
import requests
from urllib.parse import quote
from collections import Counter

def get_single_part_attributes(api_key, part_number):
    """Retrieve a single product part and its parametric attributes"""
    
    # URL encode the part number (# becomes %23)
    encoded_part = quote(part_number, safe='')
    url = f"https://api.renesas.com/web-data/v1/product-parts/{encoded_part}"
    headers = {"x-api-key": api_key}
    
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        return response.json()
    else:
        response.raise_for_status()

def extract_attribute_value(part, attribute_id):
    """Extract a specific attribute value from a product part"""
    
    for attr in part.get('parametricAttributes', []):
        if attr['productPartAttributeId'] == attribute_id:
            values = attr['attributeValues']
            if values and len(values) > 0:
                # Return the first value (most attributes have single values)
                return values[0]
    return None

def analyze_single_part_example():
    """Analyze the specific RX261 part for wafer fabrication country"""
    
    api_key = "your-api-key"
    part_number = "R5F52617BDNE#10"
    
    try:
        part_data = get_single_part_attributes(api_key, part_number)
        
        print(f"Analyzing part: {part_data['orderableId']}")
        print(f"Product Family: {part_data['productFamily']}")
        print(f"Generic ID: {part_data['genericId']}")
        print()
        
        # Extract wafer fabrication country
        country = extract_attribute_value(part_data, 'field__country_of_wafer_fabrication')
        if country:
            print(f"Wafer Fabrication Country: {country}")
        else:
            print("Wafer fabrication country not available")
        
        # Show all available attributes for this part
        print(f"\nTotal Parametric Attributes: {len(part_data.get('parametricAttributes', []))}")
        
        # Extract other interesting attributes
        key_attributes = {
            'field__operating_freq_max_': 'Operating Frequency (MHz)',
            'field__ram_size_kb': 'RAM Size (KB)', 
            'field__program_memory': 'Program Memory (KB)',
            'field__supply_voltage_v': 'Supply Voltage Range',
            'temperature_range': 'Temperature Range'
        }
        
        print("\nKey Technical Specifications:")
        for attr_id, display_name in key_attributes.items():
            value = extract_attribute_value(part_data, attr_id)
            if value:
                print(f"  {display_name}: {value}")
        
        return part_data
        
    except requests.exceptions.RequestException as e:
        print(f"Error retrieving part data: {e}")
        return None

def get_wafer_fabrication_countries(api_key, limit=1000):
    """Retrieve all product parts and extract wafer fabrication countries"""
    
    url = "https://api.renesas.com/web-data/v1/product-parts"
    headers = {"x-api-key": api_key}
    countries = []
    offset = 0
    
    while True:
        params = {"limit": 100, "offset": offset}
        response = requests.get(url, headers=headers, params=params)
        
        if response.status_code != 200:
            response.raise_for_status()
            
        data = response.json()
        
        # Process each product part
        for part in data.get('data', []):
            country = extract_attribute_value(
                part, 
                'field__country_of_wafer_fabrication'
            )
            if country:
                countries.append({
                    'part_id': part['orderableId'],
                    'product_family': part['productFamily'],
                    'country': country
                })
        
        # Check if we have more data to fetch
        pagination = data.get('pagination', {})
        if not pagination.get('has_more', False) or len(countries) >= limit:
            break
            
        offset += 1
    
    return countries

def analyze_fabrication_countries(api_key):
    """Analyze distribution of wafer fabrication countries"""
    
    countries_data = get_wafer_fabrication_countries(api_key)
    
    # Count by country
    country_counts = Counter([item['country'] for item in countries_data])
    
    # Count by product family and country
    family_country_counts = Counter([
        f"{item['product_family']}-{item['country']}" 
        for item in countries_data
    ])
    
    print("Wafer Fabrication Countries Distribution:")
    for country, count in country_counts.most_common():
        print(f"  {country}: {count} parts")
    
    print("\nTop Family-Country Combinations:")
    for combo, count in family_country_counts.most_common(10):
        family, country = combo.split('-', 1)
        print(f"  {family} from {country}: {count} parts")
    
    return countries_data

# Usage Examples:

# 1. Analyze the specific RX261 part
part_analysis = analyze_single_part_example()

# 2. Get broader fabrication data across all parts
fabrication_data = analyze_fabrication_countries("your-api-key")
```

### JavaScript Example: Single Part Attribute Extraction

```javascript
async function getSinglePartAttributes(apiKey, partNumber) {
    // URL encode the part number (# becomes %23)
    const encodedPart = encodeURIComponent(partNumber);
    const url = `https://api.renesas.com/web-data/v1/product-parts/${encodedPart}`;
    
    const response = await fetch(url, {
        headers: {
            'x-api-key': apiKey,
            'Accept': 'application/json'
        }
    });
    
    if (!response.ok) {
        throw new Error(`API error: ${response.status}`);
    }
    
    return await response.json();
}

function extractAttributeValue(part, attributeId) {
    const attribute = part.parametricAttributes?.find(
        attr => attr.productPartAttributeId === attributeId
    );
    
    if (attribute && attribute.attributeValues?.length > 0) {
        return attribute.attributeValues[0];
    }
    
    return null;
}

async function analyzeSinglePartExample(apiKey) {
    const partNumber = 'R5F52617BDNE#10';
    
    try {
        const partData = await getSinglePartAttributes(apiKey, partNumber);
        
        console.log(`Analyzing part: ${partData.orderableId}`);
        console.log(`Product Family: ${partData.productFamily}`);
        console.log(`Generic ID: ${partData.genericId}`);
        console.log('');
        
        // Extract wafer fabrication country
        const country = extractAttributeValue(partData, 'field__country_of_wafer_fabrication');
        if (country) {
            console.log(`Wafer Fabrication Country: ${country}`);
        }
        
        // Extract key technical specifications
        const keyAttributes = {
            'field__operating_freq_max_': 'Operating Frequency (MHz)',
            'field__ram_size_kb': 'RAM Size (KB)', 
            'field__program_memory': 'Program Memory (KB)',
            'field__supply_voltage_v': 'Supply Voltage Range',
            'field__bit_length': 'Bit Length',
            'field__main_cpu': 'CPU Architecture',
            'temperature_range': 'Temperature Range'
        };
        
        console.log('\nKey Technical Specifications:');
        Object.entries(keyAttributes).forEach(([attrId, displayName]) => {
            const value = extractAttributeValue(partData, attrId);
            if (value !== null) {
                // Handle complex values like voltage ranges
                const displayValue = typeof value === 'object' ? 
                    `${value.from}V to ${value.to}V` : value;
                console.log(`  ${displayName}: ${displayValue}`);
            }
        });
        
        // Show total attributes available
        console.log(`\nTotal Parametric Attributes: ${partData.parametricAttributes?.length || 0}`);
        
        return partData;
        
    } catch (error) {
        console.error(`Error retrieving part data: ${error.message}`);
        return null;
    }
}

async function getProductPartsWithAttribute(apiKey, attributeId, maxParts = 500) {
    const baseUrl = 'https://api.renesas.com/web-data/v1/product-parts';
    const results = [];
    let offset = 0;
    
    while (results.length < maxParts) {
        const url = new URL(baseUrl);
        url.searchParams.append('limit', '100');
        url.searchParams.append('offset', offset.toString());
        
        const response = await fetch(url, {
            headers: {
                'x-api-key': apiKey,
                'Accept': 'application/json'
            }
        });
        
        if (!response.ok) {
            throw new Error(`API error: ${response.status}`);
        }
        
        const data = await response.json();
        
        // Extract parts with the specified attribute
        for (const part of data.data) {
            const attributeValue = extractAttributeValue(part, attributeId);
            if (attributeValue !== null) {
                results.push({
                    orderableId: part.orderableId,
                    productFamily: part.productFamily,
                    genericId: part.genericId,
                    attributeValue: attributeValue
                });
            }
        }
        
        // Check if more data is available
        if (!data.pagination?.has_more) break;
        offset++;
    }
    
    return results;
}

// Usage examples
async function runExamples(apiKey) {
    // 1. Analyze the specific RX261 part
    console.log('=== Single Part Analysis ===');
    await analyzeSinglePartExample(apiKey);
    
    console.log('\n=== Wafer Fabrication Analysis ===');
    // 2. Find parts fabricated in specific country
    const allParts = await getProductPartsWithAttribute(
        apiKey, 
        'field__country_of_wafer_fabrication'
    );
    
    // Group by country
    const countryGroups = allParts.reduce((acc, part) => {
        const country = part.attributeValue;
        if (!acc[country]) acc[country] = [];
        acc[country].push(part);
        return acc;
    }, {});
    
    console.log('Wafer Fabrication Analysis:');
    Object.entries(countryGroups).forEach(([country, parts]) => {
        console.log(`${country}: ${parts.length} parts`);
        
        // Show product families for each country
        const families = [...new Set(parts.map(p => p.productFamily))];
        console.log(`  Families: ${families.join(', ')}`);
    });
}

// Find parts fabricated in specific country
async function findPartsFromCountry(apiKey, country) {
    const allParts = await getProductPartsWithAttribute(
        apiKey, 
        'field__country_of_wafer_fabrication'
    );
    
    return allParts.filter(part => 
        part.attributeValue.toUpperCase() === country.toUpperCase()
    );
}

// Usage
// const partAnalysis = await analyzeSinglePartExample('your-api-key');
// const japanParts = await findPartsFromCountry('your-api-key', 'JAPAN');
// console.log(`Found ${japanParts.length} parts fabricated in Japan`);
```

## Common Attribute Patterns

### Supply Voltage Ranges

Many attributes contain range values with `from` and `to` properties:

```python
def extract_voltage_range(part):
    """Extract supply voltage range from a product part"""
    
    for attr in part.get('parametricAttributes', []):
        if attr['productPartAttributeId'] == 'field__supply_voltage_v':
            values = attr['attributeValues']
            if values and isinstance(values[0], dict):
                voltage_range = values[0]
                return {
                    'min_voltage': float(voltage_range.get('from', 0)),
                    'max_voltage': float(voltage_range.get('to', 0))
                }
    return None

# Filter parts by voltage range
def find_parts_by_voltage(parts, min_voltage, max_voltage):
    """Find parts that operate within specified voltage range"""
    
    matching_parts = []
    
    for part in parts:
        voltage_info = extract_voltage_range(part)
        if voltage_info:
            if (voltage_info['min_voltage'] >= min_voltage and 
                voltage_info['max_voltage'] <= max_voltage):
                matching_parts.append({
                    'part_id': part['orderableId'],
                    'voltage_range': voltage_info,
                    'family': part['productFamily']
                })
    
    return matching_parts
```

### Multiple Value Attributes

Some attributes have multiple values in the array:

```python
def extract_security_features(part):
    """Extract security and encryption features"""
    
    for attr in part.get('parametricAttributes', []):
        if attr['productPartAttributeId'] == 'field__security_encryption':
            return attr['attributeValues']  # Returns array of features
    return []

# Example: Find parts with specific security features
def find_parts_with_encryption(parts, required_feature):
    matching_parts = []
    
    for part in parts:
        security_features = extract_security_features(part)
        if any(required_feature.lower() in feature.lower() 
               for feature in security_features):
            matching_parts.append({
                'part_id': part['orderableId'],
                'security_features': security_features
            })
    
    return matching_parts
```

## Advanced Filtering Techniques

### Multi-Attribute Analysis

```python
def analyze_multiple_attributes(api_key, attribute_ids):
    """Analyze multiple attributes across product parts"""
    
    url = "https://api.renesas.com/web-data/v1/product-parts"
    headers = {"x-api-key": api_key}
    results = []
    offset = 0
    
    while offset < 10:  # Limit for example
        params = {"limit": 100, "offset": offset}
        response = requests.get(url, headers=headers, params=params)
        data = response.json()
        
        for part in data.get('data', []):
            part_attributes = {}
            
            # Extract all requested attributes
            for attr_id in attribute_ids:
                value = extract_attribute_value(part, attr_id)
                if value:
                    part_attributes[attr_id] = value
            
            # Only include parts that have all requested attributes
            if len(part_attributes) == len(attribute_ids):
                results.append({
                    'orderableId': part['orderableId'],
                    'productFamily': part['productFamily'],
                    'attributes': part_attributes
                })
        
        if not data.get('pagination', {}).get('has_more', False):
            break
        offset += 1
    
    return results

# Example: Find parts with both wafer fabrication country and temperature range
attributes_to_analyze = [
    'field__country_of_wafer_fabrication',
    'temperature_range'
]

parts_with_attributes = analyze_multiple_attributes(
    "your-api-key", 
    attributes_to_analyze
)

for part in parts_with_attributes[:10]:
    print(f"Part: {part['orderableId']}")
    print(f"  Family: {part['productFamily']}")
    print(f"  Fabricated in: {part['attributes']['field__country_of_wafer_fabrication']}")
    print(f"  Temperature Range: {part['attributes']['temperature_range']}")
    print()
```

### Building Attribute Indexes

```python
def build_attribute_index(parts, attribute_id):
    """Build an index of attribute values to parts for fast lookup"""
    
    index = {}
    
    for part in parts:
        value = extract_attribute_value(part, attribute_id)
        if value:
            if value not in index:
                index[value] = []
            index[value].append(part['orderableId'])
    
    return index

# Usage
parts_data = get_wafer_fabrication_countries("your-api-key", limit=1000)
fabrication_index = build_attribute_index(
    parts_data, 
    'field__country_of_wafer_fabrication'
)

print("Parts by fabrication country:")
for country, part_ids in fabrication_index.items():
    print(f"{country}: {len(part_ids)} parts")
```

## Performance Considerations

### Efficient Pagination

```python
def efficient_attribute_extraction(api_key, attribute_id, max_parts=None):
    """Efficiently extract attributes with proper pagination"""
    
    url = "https://api.renesas.com/web-data/v1/product-parts"
    headers = {"x-api-key": api_key}
    
    all_attributes = []
    offset = 0
    
    while True:
        params = {
            "limit": 100,  # Maximum efficient batch size
            "offset": offset,
            "order": "last_updated",
            "orderDirection": "desc"
        }
        
        try:
            response = requests.get(url, headers=headers, params=params)
            response.raise_for_status()
            data = response.json()
            
            batch_attributes = []
            for part in data.get('data', []):
                value = extract_attribute_value(part, attribute_id)
                if value:
                    batch_attributes.append({
                        'orderableId': part['orderableId'],
                        'value': value
                    })
            
            all_attributes.extend(batch_attributes)
            
            # Check stopping conditions
            if (not data.get('pagination', {}).get('has_more', False) or
                (max_parts and len(all_attributes) >= max_parts)):
                break
                
            offset += 1
            
        except requests.exceptions.RequestException as e:
            print(f"Error fetching data: {e}")
            break
    
    return all_attributes[:max_parts] if max_parts else all_attributes
```

## Common Use Cases

### Supply Chain Analysis

```bash
# Get specific part details with all attributes
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.renesas.com/web-data/v1/product-parts/R5F52617BDNE%2310" \
  | jq '{orderableId, productFamily, fabrication: (.parametricAttributes[] | select(.productPartAttributeId == "field__country_of_wafer_fabrication") | .attributeValues[0])}'

# Find all parts and their fabrication countries
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.renesas.com/web-data/v1/product-parts?limit=100&product_family=RX" \
  | jq '.data[] | {orderableId, productFamily, fabrication: (.parametricAttributes[] | select(.productPartAttributeId == "field__country_of_wafer_fabrication") | .attributeValues[0])}'
```

### Technology Roadmap Planning

Use parametric attributes to analyze technology trends:

```python
def analyze_technology_trends(api_key):
    """Analyze technology attributes across product families"""
    
    # Get recent parts
    params = {
        "limit": 500,
        "order": "last_updated",
        "orderDirection": "desc"
    }
    
    # Analyze key technology attributes
    tech_attributes = [
        'field__bit_length',
        'field__operating_freq_max_',
        'field__security_encryption',
        'field__country_of_wafer_fabrication'
    ]
    
    results = analyze_multiple_attributes(api_key, tech_attributes)
    
    # Group by product family
    family_analysis = {}
    for part in results:
        family = part['productFamily']
        if family not in family_analysis:
            family_analysis[family] = []
        family_analysis[family].append(part)
    
    return family_analysis
```

## Error Handling

### Robust Attribute Extraction

```python
def safe_extract_attribute(part, attribute_id, default=None):
    """Safely extract attribute with error handling"""
    
    try:
        parametric_attrs = part.get('parametricAttributes', [])
        if not isinstance(parametric_attrs, list):
            return default
            
        for attr in parametric_attrs:
            if not isinstance(attr, dict):
                continue
                
            if attr.get('productPartAttributeId') == attribute_id:
                values = attr.get('attributeValues', [])
                if values and len(values) > 0:
                    return values[0]
                    
        return default
        
    except (KeyError, TypeError, IndexError) as e:
        print(f"Error extracting attribute {attribute_id}: {e}")
        return default
```

## Best Practices

1. **Use Pagination**: Always implement proper pagination for large datasets
2. **Cache Results**: Cache attribute extractions to avoid repeated API calls
3. **Handle Missing Data**: Not all parts have all attributes - handle gracefully
4. **Batch Processing**: Process parts in batches for better performance
5. **Filter Early**: Use API filters to reduce data transfer when possible


## Next Steps

- Learn about [Product Parts filtering](/guides/product-parts) for more targeted queries
- Explore the [Documents API](/guides/documents) for related technical documentation
- Review [Authentication](/guides/authentication) for API security best practices