Skill: sdk-team/alibabacloud-icpba-sucessdata-query (version 0.0.1)

--- name: alibabacloud-icpba-sucessdata-query description: | Alibaba Cloud ICP Filing Success Data Query Skill. Use for querying ICP filing success information including entity, website, app details and risk alerts after successful filing. Triggers: "ICP filing query", "beian query", "filing information", "filing risk", "query filing success", "备案查询", "备案信息", "备案风险". --- # Alibaba Cloud ICP Filing Success Data Query ## Scenario Description After successfully completing ICP filing (beian) on Alibaba Cloud, customers need to: 1. Login to the filing system to view their filing success information 2. Query filing details including entity information, website information, and APP information 3. Check if there are any risks associated with their filing that need attention This skill enables automated querying of ICP filing success data and associated risk information through Alibaba Cloud APIs. **Architecture**: Alibaba Cloud Beian Service → QuerySuccessIcpData API → Filing Information (Entity + Websites + APPs + Risks) --- ## Installation ### Alibaba Cloud CLI This skill requires Aliyun CLI version >= 3.3.3. **Pre-check: Aliyun CLI >= 3.3.3 required** > Run `aliyun version` to verify >= 3.3.3. If not installed or version too low, > run `curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash` to install/update, > or see `references/cli-installation-guide.md` for installation instructions. **Pre-check: Aliyun CLI plugin update required** > [MUST] run `aliyun configure set --auto-plugin-install true` to enable automatic plugin installation. > [MUST] run `aliyun plugin update` to ensure that any existing plugins are always up-to-date. ### Python Dependencies Since the CLI command is not yet available in the current plugin version, this skill uses the Python Common SDK: ```bash pip install -r scripts/requirements.txt ``` --- ## Authentication > **Pre-check: Alibaba Cloud Credentials Required** > > **Security Rules:** > - **NEVER** read, echo, or print AK/SK values (e.g., `echo $ALIBABA_CLOUD_ACCESS_KEY_ID` is FORBIDDEN) > - **NEVER** ask the user to input AK/SK directly in the conversation or command line > - **NEVER** use `aliyun configure set` with literal credential values > - **ONLY** use `aliyun configure list` to check credential status > > ```bash > aliyun configure list > ``` > Check the output for a valid profile (AK, STS, or OAuth identity). > > **If no valid profile exists, STOP here.** > 1. Obtain credentials from [Alibaba Cloud Console](https://ram.console.aliyun.com/manage/ak) > 2. Configure credentials **outside of this session** (via `aliyun configure` in terminal or environment variables in shell profile) > 3. Return and re-run after `aliyun configure list` shows a valid profile --- ## RAM Policy This skill requires the `beian:QuerySuccessIcpData` permission. For the complete RAM policy JSON and configuration instructions, see [references/ram-policies.md](references/ram-policies.md). > **[MUST] Permission Failure Handling:** When any command or API call fails due to permission errors at any point during execution, follow this process: > 1. Read `references/ram-policies.md` to get the full list of permissions required by this SKILL > 2. Use `ram-permission-diagnose` skill to guide the user through requesting the necessary permissions > 3. Pause and wait until the user confirms that the required permissions have been granted --- ## Parameter Confirmation > **IMPORTANT: Parameter Confirmation** — Before executing any command or API call, > ALL user-customizable parameters (e.g., RegionId, instance names, CIDR blocks, > passwords, domain names, resource specifications, etc.) MUST be confirmed with the > user. Do NOT assume or use default values without explicit user approval. | Parameter Name | Required/Optional | Description | Default Value | |----------------|-------------------|-------------|---------------| | Caller | Required | Caller identifier for API request | `skill` (fixed value) | | Region | Optional | Alibaba Cloud region | `cn-hangzhou` | --- ## Core Workflow > At the **start** of the Core Workflow (before any CLI invocation): > **[MUST] Enable AI-Mode** — AI-mode is required for Agent Skill execution. > Run the following commands before any CLI invocation: > ```bash > aliyun configure ai-mode enable > aliyun configure ai-mode set-user-agent --user-agent [REDACTED_SECRET] > ``` ### Step 1: Query ICP Filing Success Data Since the CLI command `aliyun companyreg query-success-icp-data` is not yet available in the current plugin version, we'll use the Python Common SDK to call the API directly. Create a Python script to query the filing data: ```python #!/usr/bin/env python3 # -*- coding: utf-8 -*- from alibabacloud_credentials.client import Client as CredentialClient from alibabacloud_tea_openapi.client import Client as OpenApiClient from alibabacloud_tea_openapi import models as open_api_models from alibabacloud_tea_util import models as util_models import json def create_client() -> OpenApiClient: """ Create an OpenAPI client with credential authentication. """ credential = CredentialClient() config = open_api_models.Config( credential=credential, endpoint='companyreg.aliyuncs.com', region_id='cn-hangzhou', user_agent=[REDACTED_SECRET] ) return OpenApiClient(config) def query_success_icp_data(caller: str = 'skill') -> dict: """ Query ICP filing success data including entity, website, app, and risk information. Args: caller: Caller identifier (fixed value: 'skill') Returns: dict: Filing success data response """ client = create_client() params = open_api_models.Params( action='QuerySuccessIcpData', version='2026-04-23', protocol='HTTPS', method='POST', auth_type='AK', style='RPC', pathname='/', req_body_type='formData', body_type='json' ) queries = { 'Caller': caller } request = open_api_models.OpenApiRequest( query=queries ) runtime = util_models.RuntimeOptions( connect_timeout=5000, read_timeout=10000 ) try: response = client.call_api(params, request, runtime) return response.get('body', {}) except Exception as e: print(f"Error querying ICP filing data: {str(e)}") raise def main(): print("Querying ICP Filing Success Data...") print("=" * 60) # Query filing data result = query_success_icp_data(caller='skill') # Print formatted result print(json.dumps(result, indent=2, ensure_ascii=False)) # Parse and display summary if result.get('Success'): ba_list = result.get('BaSuccessDataWithRiskList', []) print("\n" + "=" * 60) print(f"Total Filing Records: {len(ba_list)}") for idx, ba_data in enumerate(ba_list, 1): print(f"\n--- Filing Record {idx} ---") print(f"ICP Number: {ba_data.get('IcpNumber')}") print(f"Entity Name: {ba_data.get('OrganizersName')}") print(f"Entity Type: {ba_data.get('OrganizersNature')}") print(f"Responsible Person: {ba_data.get('ResponsiblePersonName')}") # Website information websites = ba_data.get('WebsiteList', []) print(f"\nWebsites: {len(websites)}") for site in websites: print(f" - {site.get('SiteName')} ({site.get('SiteRecordNum')})") print(f" Domains: {', '.join(site.get('DomainList', []))}") # APP information apps = ba_data.get('AppList', []) if apps: print(f"\nAPPs: {len(apps)}") for app in apps: print(f" - {app.get('AppName')} ({app.get('AppRecordNum')})") print(f" Domains: {', '.join(app.get('DomainList', []))}") # Risk information risks = ba_data.get('RiskList', []) if risks: print(f"\n⚠️ Risks: {len(risks)}") for risk in risks: print(f" Deadline: {risk.get('DeadLine')}") for detail in risk.get('RiskDetailList', []): print(f" Source: {detail.get('RiskSource')}") for suggest in detail.get('rectifySuggest', []): print(f" Suggestion: {suggest}") else: print("Query failed or returned no data.") if __name__ == '__main__': main() ``` Save this script as `query_icp_filing.py` and run: ```bash python3 query_icp_filing.py ``` ### Step 2: Analyze Results The API returns the following information structure: 1. **Entity Information (主体信息)**: - ICP Number (备案号) - Entity Name (主体名称) - Entity Type (主体性质: 企业/个人) - Responsible Person (负责人) 2. **Website Information (网站信息)**: - Site Record Number (网站备案号) - Site Name (网站名称) - Domain List (域名列表) - Responsible Person (网站负责人) 3. **APP Information (APP信息)**: - APP Record Number (APP备案号) - APP Name (APP名称) - Domain List (域名列表) - Responsible Person (APP负责人) 4. **Risk Information (风险信息)**: - Deadline (处理截止日期) - Risk Source (风险来源) - Rectify Suggestions (整改建议) ### Example Response Data **Example 1: Filing with Entity, Websites, and Risks** ```json { "RequestId": [REDACTED_SECRET], "Success": true, "BaSuccessDataWithRiskList": [ { "IcpNumber": "粤ICP测50000001号", "OrganizersName": "深圳市星澜美容有限公司变更", "OrganizersNature": "企业", "ResponsiblePersonName": "于婷", "WebsiteList": [ { "SiteRecordNum": "粤ICP测50000001号-1", "DomainList": ["13011160846019.com"], "SiteName": "于婷广东", "ResponsiblePersonName": "于婷" }, { "SiteRecordNum": "津ICP备2023010907号-1", "DomainList": ["uijikoxjsu.com"], "SiteName": "920企业变更网站001", "ResponsiblePersonName": "于婷" } ], "AppList": [], "RiskList": [ { "DeadLine": "2026年04月28日0点", "RiskDetailList": [ { "RiskSource": "网站/APP信息 - 津ICP备2023010907号-1 - 网站域名 - uijikoxjsu.com", "rectifySuggest": [ "<span style=\"font-weight:bold;\">网站内容涉及金融业务</span>,请提交<span style=\"font-weight:bold; color: red;\">变更备案</span>上传有效期内的金融前置文件许可,牌照或批文,传到备案系统,或者修改网站内容,与备案主体一致,符合最新备案规则。" ] } ] } ] } ] } ``` **Example 2: Filing with Entity, Websites, and APPs** ```json { "RequestId": [REDACTED_SECRET], "Success": true, "BaSuccessDataWithRiskList": [ { "IcpNumber": "测BA20251231094500051号", "OrganizersName": "LXtest001变更测试", "OrganizersNature": "企业", "ResponsiblePersonName": "李四", "WebsiteList": [ { "SiteRecordNum": "测BA20251231094500051号-1", "DomainList": ["lxtest001.com"], "SiteName": "测试迁移使用11111111111111111111", "ResponsiblePersonName": "张三" }, { "SiteRecordNum": "测BA20251230112600098号-2", "DomainList": ["test89876868.com"], "SiteName": "测试test111", "ResponsiblePersonName": "张三" } ], "AppList": [ { "AppRecordNum": "测BA20251231094500051号-2", "DomainList": ["lxtest002.com"], "AppName": "测试测试11", "ResponsiblePersonName": "李四" } ], "RiskList": [] } ] } ``` > **[MUST] Disable AI-Mode at EVERY exit point** — Before delivering the final response for ANY reason, always disable AI-mode first. This applies to ALL exit paths: workflow success, workflow failure, error/exception, user cancellation, session end, or any other scenario where no further CLI commands will be executed. > AI-mode is only used for Agent Skill invocation scenarios and MUST NOT remain enabled after the skill stops running. > ```bash > aliyun configure ai-mode disable > ``` --- ## Success Verification Method To verify the query was successful: 1. Check the `Success` field in the response is `true` 2. Verify `BaSuccessDataWithRiskList` contains filing records 3. Confirm each record has: - Valid `IcpNumber` - Entity information (`OrganizersName`, `OrganizersNature`) - At least one website in `WebsiteList` or one app in `AppList` For detailed verification steps, see [references/verification-method.md](references/verification-method.md). --- ## Cleanup This is a read-only query operation with no resources to clean up. --- ## Best Practices 1. **Regular Monitoring**: Query filing data regularly to stay informed of any new risks 2. **Risk Response**: When risks are identified, respond before the deadline to avoid filing cancellation 3. **Data Consistency**: Ensure website/APP content matches the filed information to prevent risks 4. **Permission Management**: Use RAM policies to grant minimal required permissions 5. **Error Handling**: Implement proper error handling and retry logic for API calls 6. **Credential Security**: Never hardcode credentials; always use environment variables or credential files 7. **Response Parsing**: Handle both scenarios where AppList or RiskList may be empty arrays 8. **HTML Content**: Be aware that risk suggestions may contain HTML tags for formatting --- ## Reference Links | Reference | Description | |-----------|-------------| | [references/ram-policies.md](references/ram-policies.md) | Detailed RAM permission requirements | | [references/related-commands.md](references/related-commands.md) | All related CLI commands and SDK methods | | [references/verification-method.md](references/verification-method.md) | Detailed verification steps | | [references/cli-installation-guide.md](references/cli-installation-guide.md) | Alibaba Cloud CLI installation guide | | [references/common-sdk-usage.md](references/common-sdk-usage.md) | Python Common SDK usage patterns | | [references/error-handling.md](references/error-handling.md) | Common errors and solutions |

path: references/acceptance-criteria.md
content: # Acceptance Criteria: alibabacloud-icpba-sucessdata-query

**Scenario**: ICP Filing Success Data Query
**Purpose**: Skill testing acceptance criteria

---

## Correct Python Common SDK Code Patterns

Since the CLI command is not yet available, this skill uses Python Common SDK exclusively.

### 1. Import Patterns

#### ✅ CORRECT

```python
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi.client import Client as OpenApiClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models
```

**Why**: These are the correct import paths for Alibaba Cloud Python Common SDK.

#### ❌ INCORRECT

```python
# Don't use old SDK imports
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest

# Don't use wrong module names
from alibabacloud_openapi import Client
from tea_openapi import models
```

**Why**:
- Old SDK (`aliyunsdkcore`) is deprecated
- Wrong module names will cause ImportError

---

### 2. Authentication — Must Use CredentialClient

#### ✅ CORRECT

```python
from alibabacloud_credentials.client import Client as CredentialClient

credential = CredentialClient()
config = open_api_models.Config(
    credential=credential,
    endpoint='companyreg.aliyuncs.com'
)
```

**Why**: `CredentialClient` automatically discovers credentials from multiple sources (env vars, config file, ECS role).

#### ❌ INCORRECT

```python
# Never hardcode credentials
config = open_api_models.Config(
    [REDACTED_SECRET]',
    [REDACTED_SECRET]'
)

# Don't manually construct credentials
credential = {
    'accessKeyId': 'LTAI...',
    'accessKeySecret': 'xxxxx...'
}
```

**Why**:
- Security risk (credentials in code)
- Violates best practices
- Will fail skill validation

---

### 3. Client Configuration — Correct Endpoint

#### ✅ CORRECT

```python
config = open_api_models.Config(
    credential=credential,
    endpoint='companyreg.aliyuncs.com',  # Correct endpoint
    region_id='cn-hangzhou'               # Valid region
)

client = OpenApiClient(config)
```

**Why**: This is the correct endpoint for the Beian API operations.

#### ❌ INCORRECT

```python
# Wrong endpoint
config = open_api_models.Config(
    credential=credential,
    endpoint='beian.aliyuncs.com',  # Wrong endpoint
)

# Missing endpoint
config = open_api_models.Config(
    credential=credential,
    region_id='cn-hangzhou'
)
```

**Why**:
- `beian.aliyuncs.com` doesn't exist
- Endpoint must be explicitly set to `companyreg.aliyuncs.com`

---

### 4. API Parameters — Correct Structure

#### ✅ CORRECT

```python
params = open_api_models.Params(
    action='QuerySuccessIcpData',  # Correct action name
    version='2026-04-23',           # Correct API version
    protocol='HTTPS',
    method='POST',
    auth_type='AK',
    style='RPC',
    pathname='/',
    req_body_type='formData',
    body_type='json'
)
```

**Why**: All fields are correctly set according to API specification.

#### ❌ INCORRECT

```python
# Wrong action name
params = open_api_models.Params(
    action='QueryIcpData',  # Missing 'Success' in name
    version='2026-04-23',
)

# Wrong version
params = open_api_models.Params(
    action='QuerySuccessIcpData',
    version='2021-01-01',  # Wrong version
)

# Wrong protocol/method
params = open_api_models.Params(
    action='QuerySuccessIcpData',
    version='2026-04-23',
    protocol='HTTP',   # Should be HTTPS
    method='GET',      # Should be POST
)
```

**Why**:
- Wrong action name will return "API not found"
- Wrong version will fail
- Wrong protocol/method won't match API specification

---

### 5. Request Parameters — Required Fields

#### ✅ CORRECT

```python
queries = {
    'Caller': 'skill'  # Required parameter with correct value
}

request = open_api_models.OpenApiRequest(
    query=queries
)
```

**Why**: `Caller` is a required parameter and must be set to 'skill'.

#### ❌ INCORRECT

```python
# Missing required parameter
queries = {}
request = open_api_models.OpenApiRequest(
    query=queries
)

# Wrong parameter name
queries = {
    'CallerId': 'skill'  # Wrong field name
}

# Wrong parameter value
queries = {
    'Caller': 'user'  # Should be 'skill'
}

# Wrong parameter type
queries = {
    'Caller': None  # Should be string 'skill'
}
```

**Why**:
- API will return "MissingParameter" error
- Wrong field name won't be recognized
- Parameter must be exactly 'skill'

---

### 6. Runtime Options — Proper Configuration

#### ✅ CORRECT

```python
runtime = util_models.RuntimeOptions()
response = client.call_api(params, request, runtime)
```

**Why**: `RuntimeOptions` from `util_models` is the correct class.

#### ❌ INCORRECT

```python
# Wrong import
from alibabacloud_tea_openapi import models as util_models
runtime = util_models.RuntimeOptions()

# Missing runtime parameter
response = client.call_api(params, request)

# Wrong runtime type
runtime = {}
response = client.call_api(params, request, runtime)
```

**Why**:
- Wrong import will cause AttributeError
- API call requires runtime parameter
- Runtime must be RuntimeOptions instance

---

### 7. Response Handling — Proper Access

#### ✅ CORRECT

```python
response = client.call_api(params, request, runtime)
body = response.get('body', {})

if body.get('Success'):
    ba_list = body.get('BaSuccessDataWithRiskList', [])
    for ba_data in ba_list:
        icp_number = ba_data.get('IcpNumber')
```

**Why**: Safe access with `.get()` method prevents KeyError.

#### ❌ INCORRECT

```python
# Direct access without checking
response = client.call_api(params, request, runtime)
body = response['body']  # May raise KeyError
ba_list = body['BaSuccessDataWithRiskList']

# Not checking Success field
ba_list = body.get('BaSuccessDataWithRiskList', [])
for ba_data in ba_list:  # May iterate over empty/invalid data
    icp_number = ba_data['IcpNumber']  # May raise KeyError
```

**Why**:
- Response might not have 'body' if error occurs
- Should check 'Success' field before processing
- Direct dictionary access can raise KeyError

---

### 8. Error Handling — Comprehensive Patterns

#### ✅ CORRECT

```python
from Tea.exceptions import TeaException

try:
    response = client.call_api(params, request, runtime)
    body = response.get('body', {})
    return body
except TeaException as e:
    print(f"API Error: {e.code} - {e.message}")
    raise
except Exception as e:
    print(f"Unexpected error: {str(e)}")
    raise
```

**Why**: Proper exception handling with specific error types.

#### ❌ INCORRECT

```python
# Bare except clause
try:
    response = client.call_api(params, request, runtime)
    return response['body']
except:  # Too broad
    print("Error occurred")
    return None

# Ignoring errors
try:
    response = client.call_api(params, request, runtime)
    return response['body']
except Exception:
    pass  # Silent failure
```

**Why**:
- Bare except catches everything including system exits
- Silent failures hide important errors
- Should distinguish between API errors and other errors

---

### 9. Response Structure Validation

#### ✅ CORRECT

```python
result = query_success_icp_data(caller='skill')

# Validate top-level structure
assert 'Success' in result
assert 'BaSuccessDataWithRiskList' in result

if result['Success']:
    # Validate data structure
    for ba_data in result.get('BaSuccessDataWithRiskList', []):
        assert 'IcpNumber' in ba_data
        assert 'OrganizersName' in ba_data
        assert 'WebsiteList' in ba_data
        assert 'AppList' in ba_data
        assert 'RiskList' in ba_data
```

**Why**: Validates response structure before processing.

#### ❌ INCORRECT

```python
result = query_success_icp_data(caller='skill')

# No validation
ba_list = result['BaSuccessDataWithRiskList']
first_icp = ba_list[0]['IcpNumber']  # May fail if empty or missing

# Incorrect field names
for ba_data in ba_list:
    icp = ba_data['ICP_Number']  # Wrong field name (should be IcpNumber)
    websites = ba_data['Websites']  # Wrong field name (should be WebsiteList)
```

**Why**:
- No validation can lead to runtime errors
- Field names are case-sensitive and must match exactly

---

### 10. Data Extraction Patterns

#### ✅ CORRECT

```python
# Safe extraction with defaults
def extract_website_info(response: dict) -> list:
    websites = []

    if not response.get('Success'):
        return websites

    for ba_data in response.get('BaSuccessDataWithRiskList', []):
        for site in ba_data.get('WebsiteList', []):
            website = {
                'site_name': site.get('SiteName', ''),
                'domains': site.get('DomainList', []),
                'responsible_person': site.get('ResponsiblePersonName', '')
            }
            websites.append(website)

    return websites
```

**Why**: Safe extraction with default values prevents errors.

#### ❌ INCORRECT

```python
# Unsafe extraction
def extract_website_info(response):
    websites = []

    for ba_data in response['BaSuccessDataWithRiskList']:
        for site in ba_data['WebsiteList']:
            website = {
                'site_name': site['SiteName'],
                'domains': site['DomainList'],
            }
            websites.append(website)

    return websites
```

**Why**:
- No check for Success field
- Direct dictionary access can raise KeyError
- No default values for missing fields

---

## API Response Field Names

### ✅ CORRECT Field Names

```python
# Top-level fields
response['Success']
response['RequestId']
response['BaSuccessDataWithRiskList']

# Entity fields
ba_data['IcpNumber']
ba_data['OrganizersName']
ba_data['OrganizersNature']
ba_data['ResponsiblePersonName']

# Website fields
site['SiteRecordNum']
site['SiteName']
site['DomainList']
site['ResponsiblePersonName']

# APP fields
app['AppRecordNum']
app['AppName']
app['DomainList']
app['ResponsiblePersonName']

# Risk fields
risk['DeadLine']
risk['RiskDetailList']
detail['RiskSource']
detail['rectifySuggest']  # Note: lowercase 'rectify'
```

### ❌ INCORRECT Field Names

```python
# Wrong capitalization or spelling
response['success']              # Should be 'Success'
response['request_id']           # Should be 'RequestId'
ba_data['ICP_Number']           # Should be 'IcpNumber'
ba_data['OrganizationName']     # Should be 'OrganizersName'
site['SiteRecord']              # Should be 'SiteRecordNum'
site['Domains']                 # Should be 'DomainList'
risk['Deadline']                # Should be 'DeadLine'
detail['RectifySuggest']        # Should be 'rectifySuggest'
```

---

## Common Anti-Patterns to Avoid

### ❌ 1. Hardcoding Credentials

```python
# NEVER do this
[REDACTED_SECRET]'
[REDACTED_SECRET]'
```

### ❌ 2. Using Synchronous Code in Async Context

```python
# If using async, use proper async patterns
async def query():
    result = query_success_icp_data()  # Blocking call in async function
```

### ❌ 3. Not Handling Empty Arrays

```python
# Assuming arrays are not empty
websites = ba_data['WebsiteList']
first_website = websites[0]  # May fail if empty
```

### ❌ 4. Ignoring Risk Information

```python
# Not checking for risks
for ba_data in result['BaSuccessDataWithRiskList']:
    print(ba_data['IcpNumber'])
    # Missing: Check ba_data['RiskList']
```

### ❌ 5. Not Setting User-Agent

```python
# Missing user-agent for tracking
config = open_api_models.Config(
    credential=credential,
    endpoint='companyreg.aliyuncs.com'
    # Missing: user_agent='ICP-Filing-Query-Skill/1.0'
)
```

---

## Testing Checklist

- [ ] Can import all required modules
- [ ] CredentialClient initializes without error
- [ ] OpenApiClient configuration is correct
- [ ] API parameters match specification
- [ ] Request parameters include 'Caller': 'skill'
- [ ] Response has 'Success' field
- [ ] Response has 'BaSuccessDataWithRiskList' field
- [ ] Can extract entity information
- [ ] Can extract website information
- [ ] Can extract APP information (if present)
- [ ] Can extract risk information (if present)
- [ ] Error handling works for authentication errors
- [ ] Error handling works for permission errors
- [ ] Error handling works for network errors
- [ ] No hardcoded credentials in code
- [ ] All field names match API specification exactly

---

## Example Test Script

```python
#!/usr/bin/env python3
"""
Acceptance test for ICP Filing Success Query skill
"""

def test_imports():
    """Test all imports work correctly"""
    try:
        from alibabacloud_credentials.client import Client as CredentialClient
        from alibabacloud_tea_openapi.client import Client as OpenApiClient
        from alibabacloud_tea_openapi import models as open_api_models
        from alibabacloud_tea_util import models as util_models
        print("✓ All imports successful")
        return True
    except ImportError as e:
        print(f"✗ Import failed: {e}")
        return False

def test_client_creation():
    """Test client can be created"""
    try:
        from alibabacloud_credentials.client import Client as CredentialClient
        from alibabacloud_tea_openapi.client import Client as OpenApiClient
        from alibabacloud_tea_openapi import models as open_api_models

        credential = CredentialClient()
        config = open_api_models.Config(
            credential=credential,
            endpoint='companyreg.aliyuncs.com',
            region_id='cn-hangzhou'
        )
        client = OpenApiClient(config)
        print("✓ Client created successfully")
        return True
    except Exception as e:
        print(f"✗ Client creation failed: {e}")
        return False

def test_response_structure():
    """Test response has correct structure"""
    # Mock response for testing
    mock_response = {
        'Success': True,
        'RequestId': 'test-request-id',
        'BaSuccessDataWithRiskList': [
            {
                'IcpNumber': '测ICP备12345678号',
                'OrganizersName': '测试公司',
                'OrganizersNature': '企业',
                'ResponsiblePersonName': '张三',
                'WebsiteList': [],
                'AppList': [],
                'RiskList': []
            }
        ]
    }

    try:
        assert 'Success' in mock_response
        assert 'BaSuccessDataWithRiskList' in mock_response
        ba_list = mock_response['BaSuccessDataWithRiskList']
        assert len(ba_list) > 0
        ba_data = ba_list[0]
        assert 'IcpNumber' in ba_data
        assert 'OrganizersName' in ba_data
        assert 'WebsiteList' in ba_data
        assert 'AppList' in ba_data
        assert 'RiskList' in ba_data
        print("✓ Response structure validation passed")
        return True
    except AssertionError as e:
        print(f"✗ Response structure validation failed: {e}")
        return False

if __name__ == '__main__':
    print("Running Acceptance Tests...\n")

    tests = [
        test_imports,
        test_client_creation,
        test_response_structure
    ]

    results = [test() for test in tests]

    print(f"\nResults: {sum(results)}/{len(results)} tests passed")
```

---

## Related Documentation

- Common SDK Usage: references/common-sdk-usage.md
- Error Handling: references/error-handling.md
- Verification Method: references/verification-method.md


path: references/cli-installation-guide.md
content: # Aliyun CLI Installation & Configuration Guide

Complete guide for installing and configuring Aliyun CLI.

> **Aliyun CLI 3.3.3+**: Supports installing and using all published Alibaba Cloud product plugins. Make sure to upgrade to 3.3.3 or later for full plugin ecosystem coverage.

## Installation

### macOS

**Using Homebrew (Recommended)**
```bash
brew install aliyun-cli
# Upgrade to latest
brew upgrade aliyun-cli

# Verify version (>= 3.3.3)
aliyun version
```

**Using Binary**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-macosx-latest-amd64.tgz

# Extract
tar -xzf aliyun-cli-macosx-latest-amd64.tgz

# Move to PATH
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

### Linux

**Debian/Ubuntu**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

**CentOS/RHEL**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

**ARM64 Architecture**
```bash
# Download ARM64 version
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-arm64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-arm64.tgz
sudo mv aliyun /usr/local/bin/
```

### Windows

**Using Binary**
1. Download from: https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip
2. Extract the ZIP file
3. Add the directory to your PATH environment variable
4. Open new Command Prompt or PowerShell
5. Verify: `aliyun version`

**Using PowerShell**
```powershell
# Download
Invoke-WebRequest -Uri "https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip" -OutFile "aliyun-cli.zip"

# Extract
Expand-Archive -Path aliyun-cli.zip -DestinationPath C:\aliyun-cli

# Add to PATH (requires admin privileges)
$env:Path += ";C:\aliyun-cli"
[Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

# Verify
aliyun version
```

## Configuration

### Quick Start

```bash
aliyun configure set \
  --mode AK \
  --access-key-id <your-access-key-id> \
  --access-key-secret <your-access-key-secret> \
  --region cn-hangzhou
```

All `aliyun configure` commands support non-interactive flags, which is the recommended approach —
it works in scripts, CI/CD pipelines, and agent-driven automation without hanging on stdin prompts.

**Where to Get Access Keys**

1. Log in to Aliyun Console: https://ram.console.aliyun.com/
2. Navigate to: AccessKey Management
3. Create a new AccessKey pair
4. Save the secret immediately — it's only shown once

### Configuration Modes

Aliyun CLI supports 6 authentication modes. All examples below use non-interactive flags.

#### 1. AK Mode (Access Key)

Most common mode for personal accounts and scripts.

```bash
aliyun configure set \
  --mode AK \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --region cn-hangzhou
```

Configuration is stored in `~/.aliyun/config.json`:

```json
{
  "current": "default",
  "profiles": [
    {
      "name": "default",
      "mode": "AK",
      "access_key_id": "LTAI5tXXXXXXXX",
      "access_key_secret": "8dXXXXXXXXXXXXXXXXXXXXXXXX",
      "region_id": "cn-hangzhou",
      "output_format": "json",
      "language": "en"
    }
  ]
}
```

#### 2. StsToken Mode (Temporary Credentials)

For short-lived access (tokens expire in 1-12 hours).

```bash
aliyun configure set \
  --mode StsToken \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --sts-token v1.0:XXXXXXXXXXXXXXXX \
  --region cn-hangzhou
```

Use cases: CI/CD pipelines, temporary access for external contractors, cross-account access.

#### 3. RamRoleArn Mode (Assume RAM Role)

Assume a RAM role for elevated or cross-account access.

```bash
aliyun configure set \
  --mode RamRoleArn \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --ram-role-arn acs:ram::123456789012:role/AdminRole \
  --role-session-name my-session \
  --region cn-hangzhou
```

Use cases: cross-account resource access, temporary elevated privileges, role-based access control.

#### 4. EcsRamRole Mode (ECS Instance RAM Role)

Use the RAM role attached to an ECS instance — no credentials needed.

```bash
aliyun configure set \
  --mode EcsRamRole \
  --ram-role-name MyEcsRole \
  --region cn-hangzhou
```

Requirements: must be running on an ECS instance with a RAM role attached.

Use cases: scripts and automation running on ECS instances.

#### 5. RsaKeyPair Mode (RSA Key Pair)

Use RSA key pair for authentication (generate key pair in Aliyun Console first).

```bash
aliyun configure set \
  --mode RsaKeyPair \
  --private-key /path/to/private-key.pem \
  --key-pair-name my-key-pair \
  --region cn-hangzhou
```

#### 6. RamRoleArnWithEcs Mode (ECS + RAM Role)

Combine ECS instance role with RAM role assumption for cross-account access from ECS.

```bash
aliyun configure set \
  --mode RamRoleArnWithEcs \
  --ram-role-name MyEcsRole \
  --ram-role-arn acs:ram::123456789012:role/TargetRole \
  --role-session-name my-session \
  --region cn-hangzhou
```

### Environment Variables

**Highest priority** - overrides config file

**Access Key Mode**
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou
```

**STS Token Mode**
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_SECURITY_TOKEN=your_sts_token
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou
```

**ECS RAM Role Mode**
```bash
export ALIBABA_CLOUD_ECS_METADATA=role_name
```

**Use Case**:
- CI/CD pipelines
- Docker containers
- Temporary credential override

### Managing Multiple Profiles

**Create Named Profiles**

```bash
aliyun configure set --profile projectA \
  --mode AK \
  --access-key-id LTAI5tAAAAAAAA \
  --access-key-secret 8dAAAAAAAAAAAAAAAAAAAAAAAA \
  --region cn-hangzhou

aliyun configure set --profile projectB \
  --mode AK \
  --access-key-id LTAI5tBBBBBBBB \
  --access-key-secret 8dBBBBBBBBBBBBBBBBBBBBBBBB \
  --region cn-shanghai
```

**Use Specific Profile**

```bash
aliyun ecs describe-instances --profile projectA

export ALIBABA_CLOUD_PROFILE=projectA
aliyun ecs describe-instances   # Uses projectA
```

**List and Switch Profiles**

```bash
aliyun configure list                      # List all profiles
aliyun configure set --current projectA    # Switch default profile
```

### Credential Priority

Credentials are loaded in this order (first found wins):

1. **Command-line flag**: `--profile <name>`
2. **Environment variable**: `ALIBABA_CLOUD_PROFILE`
3. **Environment credentials**: `ALIBABA_CLOUD_ACCESS_KEY_ID`, etc.
4. **Configuration file**: `~/.aliyun/config.json` (current profile)
5. **ECS Instance RAM Role**: If running on ECS with attached role

## Verification

### Test Authentication

```bash
# Basic test - list regions
aliyun ecs describe-regions

# Expected output: JSON array of regions
```

**If successful**, you'll see:
```json
{
  "Regions": {
    "Region": [
      {
        "RegionId": "cn-hangzhou",
        "RegionEndpoint": "ecs.cn-hangzhou.aliyuncs.com",
        "LocalName": "华东 1（杭州）"
      },
      ...
    ]
  },
  "RequestId": "..."
}
```

**If failed**, you'll see error messages:
- `InvalidAccessKeyId.NotFound` - Wrong Access Key ID
- `SignatureDoesNotMatch` - Wrong Access Key Secret
- `InvalidSecurityToken.Expired` - STS token expired (for StsToken mode)
- `Forbidden.RAM` - Insufficient permissions

### Debug Configuration

```bash
# Show current configuration
aliyun configure get

# Test with debug logging
aliyun ecs describe-regions --log-level=debug

# Check credential provider
aliyun configure get mode
```

## Security Best Practices

### 1. Use RAM Users (Not Root Account)

❌ **Don't**: Use Aliyun root account credentials
✅ **Do**: Create RAM users with specific permissions

```bash
# Create RAM user in console
# Attach only necessary policies
# Use RAM user's access keys
```

### 2. Principle of Least Privilege

Grant only the minimum permissions needed:

```bash
# Example: Read-only ECS access
# Attach policy: AliyunECSReadOnlyAccess
```

### 3. Rotate Access Keys Regularly

```bash
# Create new access key in RAM Console, then update configuration
aliyun configure set --access-key-id NEW_KEY --access-key-secret NEW_SECRET
# Delete old access key from console
```

### 4. Use STS Tokens for Temporary Access

```bash
aliyun configure set --mode StsToken \
  --access-key-id XXXX --access-key-secret XXXX \
  --sts-token XXXX --region cn-hangzhou
```

### 5. Use ECS RAM Roles When Possible

```bash
aliyun configure set --mode EcsRamRole --ram-role-name MyRole --region cn-hangzhou
```

### 6. Never Commit Credentials

```bash
# Add to .gitignore
echo "~/.aliyun/config.json" >> .gitignore

# Use environment variables in CI/CD instead
```

### 7. Secure Config File

```bash
# Restrict permissions
chmod 600 ~/.aliyun/config.json
```

## Troubleshooting

### Issue: Command Not Found

```bash
# Check installation
which aliyun

# Check PATH
echo $PATH

# Reinstall or add to PATH
```

### Issue: Authentication Failed

```bash
# Verify configuration
aliyun configure get

# Test with debug
aliyun ecs describe-regions --log-level=debug

# Check credentials in console
# Verify access key is active
```

### Issue: Permission Denied

```bash
# Error: Forbidden.RAM

# Check RAM user permissions
# Attach necessary policies in RAM console
# Example: AliyunECSFullAccess for ECS operations
```

### Issue: STS Token Expired

```bash
# Error: InvalidSecurityToken.Expired

# Reconfigure with new token
aliyun configure set --mode StsToken \
  --access-key-id XXXX --access-key-secret XXXX \
  --sts-token NEW_TOKEN --region cn-hangzhou
```

### Issue: Wrong Region

```bash
# Some resources may not exist in the specified region

# Check available regions
aliyun ecs describe-regions

# Update default region
aliyun configure set region cn-shanghai
```

## Advanced Configuration

### Custom Endpoint

```bash
# Use custom or private endpoint
export ALIBABA_CLOUD_ECS_ENDPOINT=ecs-vpc.cn-hangzhou.aliyuncs.com
```

### Proxy Settings

```bash
# HTTP proxy
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

# No proxy for specific domains
export NO_PROXY=localhost,127.0.0.1,.aliyuncs.com
```

### Timeout Settings

```bash
# Connection timeout (default: 10s)
export ALIBABA_CLOUD_CONNECT_TIMEOUT=30

# Read timeout (default: 10s)
export ALIBABA_CLOUD_READ_TIMEOUT=30
```

## Next Steps

After installation and configuration:

1. **Install plugins** for services you need (v3.3.3+ supports all published product plugins):
   ```bash
   aliyun plugin install --names ecs vpc rds

   # List all available plugins
   aliyun plugin list-remote
   ```

2. **Explore commands**:
   ```bash
   aliyun ecs --help
   aliyun fc --help
   ```

3. **Read documentation**:
   - [Command Syntax Guide](./command-syntax.md)
   - [Global Flags Reference](./global-flags.md)
   - [Common Scenarios](./common-scenarios.md)

## References

- Official Documentation: https://help.aliyun.com/zh/cli/
- RAM Console: https://ram.console.aliyun.com/
- Access Key Management: https://ram.console.aliyun.com/manage/ak
- Plugin Repository: https://github.com/aliyun/aliyun-cli


path: references/common-sdk-usage.md
content: # Python Common SDK Usage for ICP Filing Query

## Overview

This document provides detailed guidance on using the Alibaba Cloud Python Common SDK to query ICP filing success data.

## Prerequisites

### Install Dependencies

```bash
pip install -r scripts/requirements.txt
```

### Verify Installation

```python
import alibabacloud_credentials
import alibabacloud_tea_openapi

print(f"Credentials SDK version: {alibabacloud_credentials.__version__}")
print(f"OpenAPI SDK version: {alibabacloud_tea_openapi.__version__}")
```

## Authentication

### Using CredentialClient (Recommended)

The `CredentialClient` automatically discovers credentials from multiple sources:

1. Environment variables (`ALIBABA_CLOUD_ACCESS_KEY_ID`, `ALIBABA_CLOUD_ACCESS_KEY_SECRET`)
2. Credentials file (`~/.alibabacloud/credentials`)
3. ECS RAM role
4. STS token

```python
from alibabacloud_credentials.client import Client as CredentialClient

# Automatic credential discovery
credential = CredentialClient()
```

### Credential Priority Chain

The credential client searches in this order:

1. **Environment Variables**:
   ```bash
   export ALIBABA_CLOUD_ACCESS_KEY_ID="your-access-key-id"
   export ALIBABA_CLOUD_ACCESS_KEY_SECRET="your-access-key-secret"
   ```

2. **Credentials File** (`~/.alibabacloud/credentials`):
   ```ini
   [default]
   type = access_key
   [REDACTED_SECRET]
   [REDACTED_SECRET]
   ```

3. **ECS RAM Role** (when running on ECS):
   - No configuration needed
   - Automatically fetches temporary credentials from instance metadata

4. **STS Token**:
   ```bash
   export ALIBABA_CLOUD_ACCESS_KEY_ID="your-access-key-id"
   export ALIBABA_CLOUD_ACCESS_KEY_SECRET="your-access-key-secret"
   export ALIBABA_CLOUD_SECURITY_TOKEN="your-security-token"
   ```

## Creating OpenAPI Client

### Basic Client Configuration

```python
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi.client import Client as OpenApiClient
from alibabacloud_tea_openapi import models as open_api_models

def create_client(endpoint: str = 'companyreg.aliyuncs.com',
                  region_id: str = 'cn-hangzhou') -> OpenApiClient:
    """
    Create an OpenAPI client with automatic credential discovery.

    Args:
        endpoint: API endpoint (default: companyreg.aliyuncs.com)
        region_id: Region ID (default: cn-hangzhou)

    Returns:
        OpenApiClient: Configured API client
    """
    # Automatic credential discovery
    credential = CredentialClient()

    # Configure client
    config = open_api_models.Config(
        credential=credential,
        endpoint=endpoint,
        region_id=region_id
    )

    return OpenApiClient(config)
```

### Advanced Client Configuration

For more control over client behavior:

```python
def create_advanced_client(
    endpoint: str = 'companyreg.aliyuncs.com',
    region_id: str = 'cn-hangzhou',
    connect_timeout: int = 5000,
    read_timeout: int = 10000,
    max_idle_conns: int = 50
) -> OpenApiClient:
    """
    Create an OpenAPI client with advanced configuration.
    """
    credential = CredentialClient()

    config = open_api_models.Config(
        credential=credential,
        endpoint=endpoint,
        region_id=region_id,
        connect_timeout=connect_timeout,  # Connection timeout in milliseconds
        read_timeout=read_timeout,        # Read timeout in milliseconds
        max_idle_conns=max_idle_conns,    # Maximum idle connections
        protocol='HTTPS',                 # Force HTTPS
        user_agent='ICP-Filing-Query-Skill/1.0'
    )

    return OpenApiClient(config)
```

## Making API Calls

### Basic API Call Pattern

```python
from alibabacloud_tea_util import models as util_models

def call_api(client: OpenApiClient, action: str, queries: dict) -> dict:
    """
    Generic API call pattern.

    Args:
        client: OpenAPI client
        action: API action name
        queries: Query parameters

    Returns:
        dict: API response body
    """
    # Define API parameters
    params = open_api_models.Params(
        action=action,
        version='2026-04-23',
        protocol='HTTPS',
        method='POST',
        auth_type='AK',
        style='RPC',
        pathname='/',
        req_body_type='formData',
        body_type='json'
    )

    # Create request
    request = open_api_models.OpenApiRequest(
        query=queries
    )

    # Runtime options
    runtime = util_models.RuntimeOptions()

    # Call API
    response = client.call_api(params, request, runtime)

    return response.get('body', {})
```

### QuerySuccessIcpData Implementation

See the complete implementation in `scripts/query_icp_filing.py` and the Core Workflow section of `SKILL.md`.

## Error Handling

### Basic Error Handling

```python
from Tea.exceptions import TeaException

def query_with_error_handling(caller: str = 'skill') -> dict:
    """
    Query with comprehensive error handling.
    """
    try:
        result = query_success_icp_data(caller)
        return result
    except TeaException as e:
        print(f"API Error:")
        print(f"  Code: {e.code}")
        print(f"  Message: {e.message}")
        print(f"  Data: {e.data}")
        raise
    except Exception as e:
        print(f"Unexpected error: {str(e)}")
        raise
```

### Retry Logic

```python
import time

def query_with_retry(caller: str = 'skill', max_retries: int = 3) -> dict:
    """
    Query with automatic retry on failure.

    Args:
        caller: Caller identifier
        max_retries: Maximum number of retry attempts

    Returns:
        dict: API response
    """
    for attempt in range(max_retries):
        try:
            result = query_success_icp_data(caller)
            return result
        except Exception as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Attempt {attempt + 1} failed, retrying in {wait_time}s...")
                time.sleep(wait_time)
            else:
                print(f"All {max_retries} attempts failed")
                raise
```

## Response Processing

### Parse Entity Information

```python
def extract_entity_info(response: dict) -> list:
    """
    Extract entity information from API response.

    Args:
        response: API response dict

    Returns:
        list: List of entity information dicts
    """
    entities = []

    if not response.get('Success'):
        return entities

    for ba_data in response.get('BaSuccessDataWithRiskList', []):
        entity = {
            'icp_number': ba_data.get('IcpNumber'),
            'name': ba_data.get('OrganizersName'),
            'type': ba_data.get('OrganizersNature'),
            'responsible_person': ba_data.get('ResponsiblePersonName')
        }
        entities.append(entity)

    return entities
```

### Parse Website Information

```python
def extract_website_info(response: dict) -> list:
    """
    Extract website information from API response.

    Args:
        response: API response dict

    Returns:
        list: List of website information dicts
    """
    websites = []

    if not response.get('Success'):
        return websites

    for ba_data in response.get('BaSuccessDataWithRiskList', []):
        icp_number = ba_data.get('IcpNumber')

        for site in ba_data.get('WebsiteList', []):
            website = {
                'icp_number': icp_number,
                'site_record_num': site.get('SiteRecordNum'),
                'site_name': site.get('SiteName'),
                'domains': site.get('DomainList', []),
                'responsible_person': site.get('ResponsiblePersonName')
            }
            websites.append(website)

    return websites
```

### Parse APP Information

```python
def extract_app_info(response: dict) -> list:
    """
    Extract APP information from API response.

    Args:
        response: API response dict

    Returns:
        list: List of APP information dicts
    """
    apps = []

    if not response.get('Success'):
        return apps

    for ba_data in response.get('BaSuccessDataWithRiskList', []):
        icp_number = ba_data.get('IcpNumber')

        for app in ba_data.get('AppList', []):
            app_info = {
                'icp_number': icp_number,
                'app_record_num': app.get('AppRecordNum'),
                'app_name': app.get('AppName'),
                'domains': app.get('DomainList', []),
                'responsible_person': app.get('ResponsiblePersonName')
            }
            apps.append(app_info)

    return apps
```

### Parse Risk Information

```python
def extract_risk_info(response: dict) -> list:
    """
    Extract risk information from API response.

    Args:
        response: API response dict

    Returns:
        list: List of risk information dicts
    """
    risks = []

    if not response.get('Success'):
        return risks

    for ba_data in response.get('BaSuccessDataWithRiskList', []):
        icp_number = ba_data.get('IcpNumber')

        for risk in ba_data.get('RiskList', []):
            for detail in risk.get('RiskDetailList', []):
                risk_info = {
                    'icp_number': icp_number,
                    'deadline': risk.get('DeadLine'),
                    'source': detail.get('RiskSource'),
                    'suggestions': detail.get('rectifySuggest', [])
                }
                risks.append(risk_info)

    return risks
```

## Complete Usage Example

See `scripts/query_icp_filing.py` for a complete working example that includes querying, parsing, and displaying ICP filing data.

## Best Practices

1. **Use CredentialClient**: Always use automatic credential discovery instead of hardcoding
2. **Handle Errors**: Implement comprehensive error handling and retry logic
3. **Parse Responses**: Use helper functions to extract structured data
4. **Timeout Configuration**: Set appropriate timeouts for your use case
5. **Connection Pooling**: Reuse clients when making multiple API calls
6. **Logging**: Add proper logging for debugging and monitoring
7. **Validation**: Validate response structure before accessing nested fields

## Common Issues

### Issue 1: Credential Not Found

**Error**: `No credentials found`

**Solution**: Set credentials using one of the supported methods (environment variables, credentials file, etc.)

### Issue 2: Permission Denied

**Error**: `Forbidden.RAM`

**Solution**: Check RAM policies and ensure the user has `beian:QuerySuccessIcpData` permission

### Issue 3: Endpoint Not Found

**Error**: `Cannot resolve endpoint`

**Solution**: Verify the endpoint URL is correct: `companyreg.aliyuncs.com`

### Issue 4: Timeout

**Error**: `Request timeout`

**Solution**: Increase timeout values or check network connectivity

## Related Documentation

- [Alibaba Cloud Credentials SDK](https://github.com/aliyun/credentials-python)
- [Alibaba Cloud OpenAPI SDK](https://github.com/aliyun/alibabacloud-sdk)
- [API Reference](https://next.api.aliyun.com/)


path: references/error-handling.md
content: # Error Handling for ICP Filing Success Query

## Overview

This document describes common errors that may occur when querying ICP filing success data and their solutions.

## Common Error Categories

### 1. Authentication Errors
### 2. Permission Errors
### 3. Parameter Errors
### 4. Network Errors
### 5. Service Errors

---

## 1. Authentication Errors

### Error: InvalidAccessKeyId.NotFound

**Full Error Message**:
```
InvalidAccessKeyId.NotFound: Specified access key is not found.
```

**Cause**: The Access Key ID does not exist or is incorrect.

**Solution**:
1. Verify your Access Key ID is correct
2. Check if the Access Key has been deleted
3. Ensure you're using the correct environment/account
4. Generate a new Access Key if necessary

```bash
# Check current credentials
aliyun configure list

# Reconfigure with correct credentials
aliyun configure
```

---

### Error: InvalidAccessKeySecret

**Full Error Message**:
```
InvalidAccessKeySecret: Specified access key secret is not valid.
```

**Cause**: The Access Key Secret is incorrect.

**Solution**:
1. Verify the Access Key Secret matches the Access Key ID
2. Check for extra spaces or hidden characters
3. Regenerate the Access Key pair if necessary

```python
# Verify credentials programmatically
from alibabacloud_credentials.client import Client as CredentialClient

try:
    credential = CredentialClient()
    # If this succeeds, credentials are found
    print("Credentials loaded successfully")
except Exception as e:
    print(f"Credential error: {e}")
```

---

### Error: SecurityToken.Expired

**Full Error Message**:
```
SecurityToken.Expired: The security token you provided has expired.
```

**Cause**: STS token has expired (common when using temporary credentials).

**Solution**:
1. Refresh your STS token
2. Use long-term Access Keys for development
3. Implement automatic token refresh logic

```python
# For STS token refresh
from alibabacloud_sts20150401.client import Client as StsClient
from alibabacloud_sts20150401 import models as sts_models

def refresh_sts_token():
    # Implement STS token refresh logic
    pass
```

---

## 2. Permission Errors

### Error: Forbidden.RAM

**Full Error Message**:
```
Forbidden.RAM: User not authorized to operate on the specified resource.
```

**Cause**: The current user/role lacks the required RAM permission `beian:QuerySuccessIcpData`.

**Solution**:
1. Check current user's permissions:
   ```bash
   aliyun ram list-policies-for-user --user-name <username>
   ```

2. Grant the required permission (see references/ram-policies.md)

3. Verify the policy is attached:
   ```bash
   aliyun ram get-user-policy \
     --user-name <username> \
     --policy-name IcpFilingQueryPolicy \
     --policy-type Custom
   ```

4. Wait a few minutes for permission changes to propagate

**Prevention**:
- Always verify permissions before deploying to production
- Use RAM policy simulator to test permissions
- Follow principle of least privilege

---

### Error: Forbidden.NoPermission

**Full Error Message**:
```
Forbidden.NoPermission: You are not authorized to do this action.
```

**Cause**: Similar to Forbidden.RAM, indicates missing permissions.

**Solution**:
1. Review required permissions in references/ram-policies.md
2. Use `ram-permission-diagnose` skill for detailed analysis
3. Contact account administrator to grant permissions

---

## 3. Parameter Errors

### Error: InvalidParameter

**Full Error Message**:
```
InvalidParameter: The specified parameter is invalid.
```

**Cause**: One or more parameters have invalid values.

**Solution**:
1. Verify all parameters match the API specification
2. Check parameter types (string, integer, boolean)
3. Ensure required parameters are provided

```python
# Correct parameter usage
def query_success_icp_data(caller: str = 'skill') -> dict:
    # Validate parameter
    if not caller or not isinstance(caller, str):
        raise ValueError("Caller must be a non-empty string")

    queries = {
        'Caller': caller  # Must be 'skill' for this API
    }
    # ... rest of the code
```

**Common Parameter Issues**:
| Parameter | Issue | Solution |
|-----------|-------|----------|
| Caller | Empty or wrong value | Must be 'skill' |
| Caller | Wrong type | Must be string, not int/bool |

---

### Error: MissingParameter

**Full Error Message**:
```
MissingParameter: The required parameter is missing.
```

**Cause**: A required parameter was not provided.

**Solution**:
1. Check API documentation for required parameters
2. Ensure all required parameters are included in the request

```python
# Always include required parameters
queries = {
    'Caller': 'skill'  # Required parameter
}
```

---

## 4. Network Errors

### Error: Connection Timeout

**Full Error Message**:
```
RequestTimeout: Request timeout.
```

**Cause**: Network request took too long to complete.

**Solution**:
1. Check network connectivity
2. Increase timeout values
3. Implement retry logic

```python
from alibabacloud_tea_util import models as util_models

# Increase timeout
runtime = util_models.RuntimeOptions(
    connect_timeout=10000,  # 10 seconds
    read_timeout=30000      # 30 seconds
)

response = client.call_api(params, request, runtime)
```

---

### Error: Connection Refused

**Full Error Message**:
```
ConnectionError: Connection refused.
```

**Cause**: Cannot connect to the API endpoint.

**Solution**:
1. Verify endpoint URL is correct: `companyreg.aliyuncs.com`
2. Check firewall settings
3. Verify network connectivity
4. Ensure you're not blocked by security policies

```python
# Verify endpoint
config = open_api_models.Config(
    credential=credential,
    endpoint='companyreg.aliyuncs.com',  # Verify this
    region_id='cn-hangzhou'
)
```

---

### Error: SSL Certificate Verification Failed

**Full Error Message**:
```
SSLError: Certificate verification failed.
```

**Cause**: SSL certificate cannot be verified.

**Solution**:
1. Update CA certificates on your system
2. Check system time is correct (affects certificate validation)
3. If behind corporate proxy, configure proxy settings

```bash
# Update CA certificates (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install ca-certificates

# macOS
brew install openssl
```

---

## 5. Service Errors

### Error: InternalError

**Full Error Message**:
```
InternalError: An internal error occurred.
```

**Cause**: Server-side error in the Alibaba Cloud service.

**Solution**:
1. Retry the request (often transient errors)
2. Implement exponential backoff
3. Check [Alibaba Cloud Service Status](https://status.alibabacloud.com/)
4. Contact support if error persists

```python
import time

def query_with_exponential_backoff(max_retries=3):
    for attempt in range(max_retries):
        try:
            return query_success_icp_data(caller='skill')
        except Exception as e:
            if 'InternalError' in str(e) and attempt < max_retries - 1:
                wait_time = 2 ** attempt
                print(f"Internal error, retrying in {wait_time}s...")
                time.sleep(wait_time)
            else:
                raise
```

---

### Error: ServiceUnavailable

**Full Error Message**:
```
ServiceUnavailable: The service is temporarily unavailable.
```

**Cause**: The API service is temporarily unavailable (maintenance, overload, etc.).

**Solution**:
1. Wait and retry after a few minutes
2. Check service status page
3. Implement circuit breaker pattern

```python
import time
from datetime import datetime, timedelta

class CircuitBreaker:
    def __init__(self, failure_threshold=5, timeout=60):
        self.failure_count = 0
        self.failure_threshold = failure_threshold
        self.timeout = timeout
        self.last_failure_time = None
        self.state = 'closed'  # closed, open, half-open

    def call(self, func, *args, **kwargs):
        if self.state == 'open':
            if datetime.now() - self.last_failure_time > timedelta(seconds=self.timeout):
                self.state = 'half-open'
            else:
                raise Exception("Circuit breaker is open")

        try:
            result = func(*args, **kwargs)
            self.on_success()
            return result
        except Exception as e:
            self.on_failure()
            raise

    def on_success(self):
        self.failure_count = 0
        self.state = 'closed'

    def on_failure(self):
        self.failure_count += 1
        self.last_failure_time = datetime.now()
        if self.failure_count >= self.failure_threshold:
            self.state = 'open'
```

---

### Error: Throttling.User

**Full Error Message**:
```
Throttling.User: Request was denied due to user flow control.
```

**Cause**: Too many requests from your account in a short time period.

**Solution**:
1. Implement rate limiting in your application
2. Add delays between requests
3. Request quota increase if needed

```python
import time
from datetime import datetime

class RateLimiter:
    def __init__(self, max_calls_per_minute=60):
        self.max_calls = max_calls_per_minute
        self.calls = []

    def wait_if_needed(self):
        now = datetime.now()
        # Remove calls older than 1 minute
        self.calls = [call_time for call_time in self.calls
                      if (now - call_time).seconds < 60]

        if len(self.calls) >= self.max_calls:
            # Wait until oldest call is more than 1 minute old
            sleep_time = 60 - (now - self.calls[0]).seconds
            if sleep_time > 0:
                time.sleep(sleep_time)

        self.calls.append(now)

# Usage
rate_limiter = RateLimiter(max_calls_per_minute=60)

def query_with_rate_limit():
    rate_limiter.wait_if_needed()
    return query_success_icp_data(caller='skill')
```

---

## Error Handling Best Practices

### 1. Comprehensive Try-Catch

```python
from Tea.exceptions import TeaException

def robust_query(caller: str = 'skill') -> dict:
    """
    Query with comprehensive error handling.
    """
    try:
        result = query_success_icp_data(caller)
        return result

    except TeaException as e:
        # Handle API-specific errors
        error_code = getattr(e, 'code', 'Unknown')

        if error_code in ['InvalidAccessKeyId.NotFound', 'InvalidAccessKeySecret']:
            print("Authentication error: Check your credentials")
        elif error_code in ['Forbidden.RAM', 'Forbidden.NoPermission']:
            print("Permission error: Check RAM policies")
        elif error_code == 'InvalidParameter':
            print("Parameter error: Check parameter values")
        elif error_code in ['InternalError', 'ServiceUnavailable']:
            print("Service error: Retry after a few minutes")
        else:
            print(f"API error [{error_code}]: {e.message}")

        raise

    except ConnectionError as e:
        print(f"Network error: {e}")
        raise

    except Exception as e:
        print(f"Unexpected error: {e}")
        raise
```

### 2. Logging

```python
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

def query_with_logging(caller: str = 'skill') -> dict:
    """
    Query with detailed logging.
    """
    logger.info(f"Starting ICP filing query with caller: {caller}")

    try:
        result = query_success_icp_data(caller)
        logger.info(f"Query successful, RequestId: {result.get('RequestId')}")
        return result

    except Exception as e:
        logger.error(f"Query failed: {str(e)}", exc_info=True)
        raise
```

### 3. Custom Exception Classes

```python
class ICPFilingQueryError(Exception):
    """Base exception for ICP filing query errors."""
    pass

class AuthenticationError(ICPFilingQueryError):
    """Authentication-related errors."""
    pass

class PermissionError(ICPFilingQueryError):
    """Permission-related errors."""
    pass

class ParameterError(ICPFilingQueryError):
    """Parameter validation errors."""
    pass

def query_with_custom_exceptions(caller: str = 'skill') -> dict:
    """
    Query with custom exception handling.
    """
    try:
        result = query_success_icp_data(caller)
        return result

    except TeaException as e:
        error_code = getattr(e, 'code', 'Unknown')

        if error_code in ['InvalidAccessKeyId.NotFound', 'InvalidAccessKeySecret']:
            raise AuthenticationError(f"Authentication failed: {e.message}")
        elif error_code in ['Forbidden.RAM', 'Forbidden.NoPermission']:
            raise PermissionError(f"Permission denied: {e.message}")
        elif error_code == 'InvalidParameter':
            raise ParameterError(f"Invalid parameter: {e.message}")
        else:
            raise ICPFilingQueryError(f"Query failed: {e.message}")
```

## Error Response Structure

API errors typically have this structure:

```json
{
  "Code": "Forbidden.RAM",
  "Message": "User not authorized to operate on the specified resource.",
  "RequestId": "ABC123-DEF456-GHI789",
  "HostId": "companyreg.aliyuncs.com"
}
```

## Debugging Tips

1. **Enable Debug Logging**:
   ```python
   import logging
   logging.basicConfig(level=logging.DEBUG)
   ```

2. **Print Request Details**:
   ```python
   print(f"Endpoint: {config.endpoint}")
   print(f"Region: {config.region_id}")
   print(f"Parameters: {queries}")
   ```

3. **Check Request ID**:
   Every API response includes a RequestId. Use it when contacting support.

4. **Use API Explorer**:
   Test API calls in [OpenAPI Explorer](https://next.api.aliyun.com/) to isolate issues.

## Related Documentation

- [API Error Codes Reference](https://www.alibabacloud.com/help/doc-detail/error-codes)
- RAM Permission Troubleshooting: references/ram-policies.md
- Common SDK Usage: references/common-sdk-usage.md


path: references/ram-policies.md
content: # RAM Policies for ICP Filing Success Query

## Required Permissions

This skill requires the following RAM permissions to function properly:

```json
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "beian:QuerySuccessIcpData"
      ],
      "Resource": "*"
    }
  ]
}
```

## Permission Details

### beian:QuerySuccessIcpData

**Action**: `beian:QuerySuccessIcpData`

**Description**: Query ICP filing success data including entity information, website information, APP information, and risk information.

**Resource**: `*` (applies to all resources under the account)

**Usage Scenario**:
- Query filing success information after successful filing
- Retrieve entity, website, and APP details
- Check filing risks and rectification requirements

## How to Grant Permissions

### Option 1: Through RAM Console

1. Login to [RAM Console](https://ram.console.aliyun.com/)
2. Navigate to **Identities** > **Users** or **Roles**
3. Select the target user or role
4. Click **Add Permissions**
5. Select **Custom Policy** and create a new policy with the JSON above
6. Or select **System Policy** if available (search for "Beian")
7. Click **OK** to grant permissions

### Option 2: Using CLI

Create a custom policy file `icp-filing-query-policy.json`:

```json
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "beian:QuerySuccessIcpData"
      ],
      "Resource": "*"
    }
  ]
}
```

Create the policy:

```bash
aliyun ram create-policy \
  --policy-name IcpFilingQueryPolicy \
  --policy-document "$(cat icp-filing-query-policy.json)"
```

Attach the policy to a user:

```bash
aliyun ram attach-policy-to-user \
  --policy-type Custom \
  --policy-name IcpFilingQueryPolicy \
  --user-name <your-username>
```

### Option 3: Using Python SDK

```python
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi.client import Client as OpenApiClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models
import json

def create_ram_client() -> OpenApiClient:
    credential = CredentialClient()
    config = open_api_models.Config(
        credential=credential,
        endpoint='ram.aliyuncs.com'
    )
    return OpenApiClient(config)

def create_policy():
    client = create_ram_client()

    policy_document = {
        "Version": "1",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": ["beian:QuerySuccessIcpData"],
                "Resource": "*"
            }
        ]
    }

    params = open_api_models.Params(
        action='CreatePolicy',
        version='2015-05-01',
        protocol='HTTPS',
        method='POST',
        auth_type='AK',
        style='RPC',
        pathname='/',
        req_body_type='formData',
        body_type='json'
    )

    request = open_api_models.OpenApiRequest(
        query={
            'PolicyName': 'IcpFilingQueryPolicy',
            'PolicyDocument': json.dumps(policy_document)
        }
    )

    runtime = util_models.RuntimeOptions()
    response = client.call_api(params, request, runtime)
    return response

# Create policy
result = create_policy()
print(json.dumps(result, indent=2))
```

## Permission Verification

To verify that permissions are correctly configured:

1. **Check User Policies**:
   ```bash
   aliyun ram list-policies-for-user --user-name <your-username>
   ```

2. **Test API Call**:
   Try running the query operation. If you receive a permission error, the permissions are not correctly configured.

   Common permission error messages:
   - `You are not authorized to do this action.`
   - `User not authorized to operate on the specified resource.`
   - `Forbidden.RAM`

## Minimum Privilege Principle

This skill follows the principle of least privilege by only requesting:
- Read-only access to ICP filing data
- No write or delete permissions
- No access to other Alibaba Cloud services

## Security Recommendations

1. **Use RAM Roles**: When possible, use RAM roles instead of RAM users for better security
2. **Regular Audits**: Regularly review and audit permissions granted to users
3. **Temporary Credentials**: Use STS temporary credentials for short-term access
4. **Avoid Root Account**: Never use the root account for daily operations
5. **Enable MFA**: Enable multi-factor authentication for sensitive operations

## Troubleshooting Permission Issues

If you encounter permission errors:

1. **Verify the policy is attached**: Check that the policy is actually attached to your user/role
2. **Check policy content**: Ensure the policy JSON is correctly formatted
3. **Verify resource scope**: Confirm that `Resource: "*"` is set correctly
4. **Check API action name**: Ensure the action name is exactly `beian:QuerySuccessIcpData`
5. **Review account status**: Verify your account is in good standing and not suspended
6. **Use RAM permission diagnosis**: Use the `ram-permission-diagnose` skill for detailed analysis

## Related Documentation

- [RAM Policy Language](https://www.alibabacloud.com/help/ram/developer-reference/ram-policy-language)
- [RAM Policy Best Practices](https://www.alibabacloud.com/help/ram/user-guide/best-practices-for-ram-policies)
- [Beian Service Documentation](https://www.alibabacloud.com/help/beian)


path: references/related-commands.md
content: # Related Commands for ICP Filing Success Query

## CLI Commands

Currently, the direct CLI command for querying ICP filing success data is not available in the standard Aliyun CLI plugin. This skill uses the Python Common SDK as an alternative.

### Future CLI Command (when available)

```bash
aliyun beian query-success-icp-data --caller skill
```

**Expected Parameters**:
- `--caller`: Caller identifier (fixed value: "skill")

**Expected Output**: JSON response containing filing success data

## Python Common SDK Methods

### Import Statements

```python
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi.client import Client as OpenApiClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models
import json
```

### Create OpenAPI Client

```python
def create_client() -> OpenApiClient:
    """
    Create an OpenAPI client with credential authentication.
    """
    credential = CredentialClient()

    config = open_api_models.Config(
        credential=credential,
        endpoint='companyreg.aliyuncs.com',
        region_id='cn-hangzhou'
    )

    return OpenApiClient(config)
```

### Query ICP Filing Success Data

```python
def query_success_icp_data(caller: str = 'skill') -> dict:
    """
    Query ICP filing success data.

    Args:
        caller: Caller identifier (fixed value: 'skill')

    Returns:
        dict: Filing success data response
    """
    client = create_client()

    params = open_api_models.Params(
        action='QuerySuccessIcpData',
        version='2026-04-23',
        protocol='HTTPS',
        method='POST',
        auth_type='AK',
        style='RPC',
        pathname='/',
        req_body_type='formData',
        body_type='json'
    )

    queries = {
        'Caller': caller
    }

    request = open_api_models.OpenApiRequest(
        query=queries
    )

    runtime = util_models.RuntimeOptions()

    response = client.call_api(params, request, runtime)
    return response.get('body', {})
```

## API Information

| Field | Value |
|-------|-------|
| **Product** | Companyreg (Beian operations) |
| **API Action** | QuerySuccessIcpData |
| **API Version** | 2026-04-23 |
| **Protocol** | HTTPS |
| **Method** | POST |
| **Style** | RPC |
| **Endpoint** | companyreg.aliyuncs.com |

## Request Parameters

| Parameter | Type | Required | Description | Default |
|-----------|------|----------|-------------|---------|
| Caller | String | Yes | Caller identifier | `skill` |

## Response Structure

```json
{
  "RequestId": "string",
  "Success": boolean,
  "BaSuccessDataWithRiskList": [
    {
      "IcpNumber": "string",
      "OrganizersName": "string",
      "OrganizersNature": "string",
      "ResponsiblePersonName": "string",
      "WebsiteList": [
        {
          "SiteRecordNum": "string",
          "DomainList": ["string"],
          "SiteName": "string",
          "ResponsiblePersonName": "string"
        }
      ],
      "AppList": [
        {
          "AppRecordNum": "string",
          "DomainList": ["string"],
          "AppName": "string",
          "ResponsiblePersonName": "string"
        }
      ],
      "RiskList": [
        {
          "DeadLine": "string",
          "RiskDetailList": [
            {
              "RiskSource": "string",
              "rectifySuggest": ["string"]
            }
          ]
        }
      ]
    }
  ]
}
```

## Response Fields

### Top-Level Fields

| Field | Type | Description |
|-------|------|-------------|
| RequestId | String | Unique request identifier |
| Success | Boolean | Whether the request was successful |
| BaSuccessDataWithRiskList | Array | List of filing success data records |

### BaSuccessDataWithRiskList Object

| Field | Type | Description |
|-------|------|-------------|
| IcpNumber | String | ICP filing number (备案号) |
| OrganizersName | String | Entity name (主体名称) |
| OrganizersNature | String | Entity type (主体性质): 企业/个人 |
| ResponsiblePersonName | String | Responsible person name (负责人) |
| WebsiteList | Array | List of websites under this filing |
| AppList | Array | List of APPs under this filing |
| RiskList | Array | List of risks associated with this filing |

### WebsiteList Object

| Field | Type | Description |
|-------|------|-------------|
| SiteRecordNum | String | Website filing number (网站备案号) |
| DomainList | Array[String] | List of domain names |
| SiteName | String | Website name |
| ResponsiblePersonName | String | Website responsible person |

### AppList Object

| Field | Type | Description |
|-------|------|-------------|
| AppRecordNum | String | APP filing number (APP备案号) |
| DomainList | Array[String] | List of domain names |
| AppName | String | APP name |
| ResponsiblePersonName | String | APP responsible person |

### RiskList Object

| Field | Type | Description |
|-------|------|-------------|
| DeadLine | String | Risk rectification deadline |
| RiskDetailList | Array | List of risk details |

### RiskDetailList Object

| Field | Type | Description |
|-------|------|-------------|
| RiskSource | String | Source of the risk |
| rectifySuggest | Array[String] | List of rectification suggestions (may contain HTML) |

## Related RAM Commands

### List User Policies

```bash
aliyun ram list-policies-for-user --user-name <username>
```

### Create Custom Policy

```bash
aliyun ram create-policy \
  --policy-name IcpFilingQueryPolicy \
  --policy-document file://policy.json
```

### Attach Policy to User

```bash
aliyun ram attach-policy-to-user \
  --policy-type Custom \
  --policy-name IcpFilingQueryPolicy \
  --user-name <username>
```

## Usage Examples

### Basic Query

```python
from query_icp_filing import query_success_icp_data
import json

# Query filing data
result = query_success_icp_data(caller='skill')

# Print formatted result
print(json.dumps(result, indent=2, ensure_ascii=False))
```

### Query and Filter Risks

```python
result = query_success_icp_data(caller='skill')

if result.get('Success'):
    for ba_data in result.get('BaSuccessDataWithRiskList', []):
        risks = ba_data.get('RiskList', [])
        if risks:
            print(f"⚠️ Filing {ba_data.get('IcpNumber')} has {len(risks)} risks:")
            for risk in risks:
                print(f"  Deadline: {risk.get('DeadLine')}")
```

### Extract All Domains

```python
result = query_success_icp_data(caller='skill')

all_domains = []
if result.get('Success'):
    for ba_data in result.get('BaSuccessDataWithRiskList', []):
        # Website domains
        for site in ba_data.get('WebsiteList', []):
            all_domains.extend(site.get('DomainList', []))
        # APP domains
        for app in ba_data.get('AppList', []):
            all_domains.extend(app.get('DomainList', []))

print(f"Total domains: {len(all_domains)}")
print(all_domains)
```

## Error Handling

### Common Errors

| Error Code | Description | Solution |
|------------|-------------|----------|
| InvalidAccessKeyId.NotFound | Access Key ID not found | Verify credentials configuration |
| Forbidden.RAM | Insufficient permissions | Check RAM policies |
| InvalidParameter | Invalid parameter value | Verify parameter format |
| InternalError | Internal service error | Retry or contact support |

### Error Handling Pattern

```python
try:
    result = query_success_icp_data(caller='skill')
    if not result.get('Success'):
        print("Query failed")
except Exception as e:
    error_msg = str(e)
    if 'InvalidAccessKeyId' in error_msg:
        print("Credential error: Check your Access Key configuration")
    elif 'Forbidden' in error_msg:
        print("Permission error: Check RAM policies")
    else:
        print(f"Error: {error_msg}")
```

## Additional Resources

- [Alibaba Cloud OpenAPI Portal](https://next.api.aliyun.com/)
- [Python Common SDK Documentation](https://www.alibabacloud.com/help/sdk/python-sdk)
- [API Error Codes](https://www.alibabacloud.com/help/doc-detail/error-codes)


path: references/verification-method.md
content: # Verification Method for ICP Filing Success Query

## Overview

This document describes the methods to verify that the ICP filing success data query operation completed successfully.

## Verification Steps

### Step 1: Check API Response Status

Verify the API call returned successfully:

```python
result = query_success_icp_data(caller='skill')

# Check if Success field is true
assert result.get('Success') == True, "Query failed: Success is not True"
print("✓ API call successful")
```

### Step 2: Verify Response Structure

Check that the response contains the expected data structure:

```python
# Check RequestId exists
assert 'RequestId' in result, "Missing RequestId in response"
print(f"✓ Request ID: {result['RequestId']}")

# Check BaSuccessDataWithRiskList exists
assert 'BaSuccessDataWithRiskList' in result, "Missing BaSuccessDataWithRiskList"
ba_list = result['BaSuccessDataWithRiskList']
print(f"✓ Found {len(ba_list)} filing record(s)")
```

### Step 3: Validate Filing Record Data

For each filing record, verify the required fields:

```python
for idx, ba_data in enumerate(ba_list, 1):
    print(f"\nVerifying Filing Record {idx}...")

    # Check ICP Number
    assert 'IcpNumber' in ba_data and ba_data['IcpNumber'], \
        f"Missing or empty IcpNumber in record {idx}"
    print(f"  ✓ ICP Number: {ba_data['IcpNumber']}")

    # Check Entity Name
    assert 'OrganizersName' in ba_data and ba_data['OrganizersName'], \
        f"Missing or empty OrganizersName in record {idx}"
    print(f"  ✓ Entity Name: {ba_data['OrganizersName']}")

    # Check Entity Type
    assert 'OrganizersNature' in ba_data and ba_data['OrganizersNature'], \
        f"Missing or empty OrganizersNature in record {idx}"
    print(f"  ✓ Entity Type: {ba_data['OrganizersNature']}")

    # Check Responsible Person
    assert 'ResponsiblePersonName' in ba_data and ba_data['ResponsiblePersonName'], \
        f"Missing or empty ResponsiblePersonName in record {idx}"
    print(f"  ✓ Responsible Person: {ba_data['ResponsiblePersonName']}")
```

### Step 4: Validate Website Data

Verify website information is present and valid:

```python
    # Check WebsiteList exists
    assert 'WebsiteList' in ba_data, f"Missing WebsiteList in record {idx}"
    websites = ba_data['WebsiteList']
    print(f"  ✓ Websites: {len(websites)}")

    for site_idx, site in enumerate(websites, 1):
        # Check required website fields
        assert 'SiteRecordNum' in site, f"Missing SiteRecordNum in website {site_idx}"
        assert 'SiteName' in site, f"Missing SiteName in website {site_idx}"
        assert 'DomainList' in site, f"Missing DomainList in website {site_idx}"
        assert 'ResponsiblePersonName' in site, f"Missing ResponsiblePersonName in website {site_idx}"

        # Verify DomainList is not empty
        assert len(site['DomainList']) > 0, f"Empty DomainList in website {site_idx}"

        print(f"    ✓ Website {site_idx}: {site['SiteName']} ({site['SiteRecordNum']})")
        print(f"      Domains: {', '.join(site['DomainList'])}")
```

### Step 5: Validate APP Data (if present)

Check APP information if available:

```python
    # Check AppList exists
    assert 'AppList' in ba_data, f"Missing AppList in record {idx}"
    apps = ba_data['AppList']

    if len(apps) > 0:
        print(f"  ✓ APPs: {len(apps)}")

        for app_idx, app in enumerate(apps, 1):
            # Check required app fields
            assert 'AppRecordNum' in app, f"Missing AppRecordNum in app {app_idx}"
            assert 'AppName' in app, f"Missing AppName in app {app_idx}"
            assert 'DomainList' in app, f"Missing DomainList in app {app_idx}"
            assert 'ResponsiblePersonName' in app, f"Missing ResponsiblePersonName in app {app_idx}"

            print(f"    ✓ APP {app_idx}: {app['AppName']} ({app['AppRecordNum']})")
            print(f"      Domains: {', '.join(app['DomainList'])}")
    else:
        print(f"  ℹ No APPs in this filing record")
```

### Step 6: Validate Risk Data (if present)

Check risk information and warnings:

```python
    # Check RiskList exists
    assert 'RiskList' in ba_data, f"Missing RiskList in record {idx}"
    risks = ba_data['RiskList']

    if len(risks) > 0:
        print(f"  ⚠️ Risks: {len(risks)}")

        for risk_idx, risk in enumerate(risks, 1):
            # Check required risk fields
            assert 'DeadLine' in risk, f"Missing DeadLine in risk {risk_idx}"
            assert 'RiskDetailList' in risk, f"Missing RiskDetailList in risk {risk_idx}"

            print(f"    ⚠️ Risk {risk_idx}:")
            print(f"      Deadline: {risk['DeadLine']}")

            for detail_idx, detail in enumerate(risk['RiskDetailList'], 1):
                assert 'RiskSource' in detail, f"Missing RiskSource in risk detail {detail_idx}"
                assert 'rectifySuggest' in detail, f"Missing rectifySuggest in risk detail {detail_idx}"

                print(f"      Source: {detail['RiskSource']}")
                print(f"      Suggestions: {len(detail['rectifySuggest'])} item(s)")
    else:
        print(f"  ✓ No risks detected")
```

## Complete Verification Script

Here's a complete verification script you can use:

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
from query_icp_filing import query_success_icp_data

def verify_filing_query():
    """
    Comprehensive verification of ICP filing query results.
    """
    print("Starting ICP Filing Query Verification...")
    print("=" * 60)

    try:
        # Step 1: Execute query
        print("\n[Step 1] Executing query...")
        result = query_success_icp_data(caller='skill')

        # Step 2: Check API response status
        print("\n[Step 2] Verifying API response status...")
        assert result.get('Success') == True, "Query failed: Success is not True"
        print("✓ API call successful")

        # Step 3: Verify response structure
        print("\n[Step 3] Verifying response structure...")
        assert 'RequestId' in result, "Missing RequestId in response"
        print(f"✓ Request ID: {result['RequestId']}")

        assert 'BaSuccessDataWithRiskList' in result, "Missing BaSuccessDataWithRiskList"
        ba_list = result['BaSuccessDataWithRiskList']
        print(f"✓ Found {len(ba_list)} filing record(s)")

        # Step 4-6: Validate each filing record
        for idx, ba_data in enumerate(ba_list, 1):
            print(f"\n[Step 4-6] Verifying Filing Record {idx}...")

            # Validate entity information
            assert 'IcpNumber' in ba_data and ba_data['IcpNumber'], \
                f"Missing or empty IcpNumber in record {idx}"
            print(f"  ✓ ICP Number: {ba_data['IcpNumber']}")

            assert 'OrganizersName' in ba_data and ba_data['OrganizersName'], \
                f"Missing or empty OrganizersName in record {idx}"
            print(f"  ✓ Entity Name: {ba_data['OrganizersName']}")

            assert 'OrganizersNature' in ba_data and ba_data['OrganizersNature'], \
                f"Missing or empty OrganizersNature in record {idx}"
            print(f"  ✓ Entity Type: {ba_data['OrganizersNature']}")

            assert 'ResponsiblePersonName' in ba_data and ba_data['ResponsiblePersonName'], \
                f"Missing or empty ResponsiblePersonName in record {idx}"
            print(f"  ✓ Responsible Person: {ba_data['ResponsiblePersonName']}")

            # Validate website data
            assert 'WebsiteList' in ba_data, f"Missing WebsiteList in record {idx}"
            websites = ba_data['WebsiteList']
            print(f"  ✓ Websites: {len(websites)}")

            for site_idx, site in enumerate(websites, 1):
                assert all(k in site for k in ['SiteRecordNum', 'SiteName', 'DomainList', 'ResponsiblePersonName']), \
                    f"Missing required fields in website {site_idx}"
                assert len(site['DomainList']) > 0, f"Empty DomainList in website {site_idx}"
                print(f"    ✓ Website {site_idx}: {site['SiteName']} ({site['SiteRecordNum']})")

            # Validate APP data
            assert 'AppList' in ba_data, f"Missing AppList in record {idx}"
            apps = ba_data['AppList']

            if len(apps) > 0:
                print(f"  ✓ APPs: {len(apps)}")
                for app_idx, app in enumerate(apps, 1):
                    assert all(k in app for k in ['AppRecordNum', 'AppName', 'DomainList', 'ResponsiblePersonName']), \
                        f"Missing required fields in app {app_idx}"
                    print(f"    ✓ APP {app_idx}: {app['AppName']} ({app['AppRecordNum']})")
            else:
                print(f"  ℹ No APPs in this filing record")

            # Validate risk data
            assert 'RiskList' in ba_data, f"Missing RiskList in record {idx}"
            risks = ba_data['RiskList']

            if len(risks) > 0:
                print(f"  ⚠️ Risks: {len(risks)}")
                for risk_idx, risk in enumerate(risks, 1):
                    assert all(k in risk for k in ['DeadLine', 'RiskDetailList']), \
                        f"Missing required fields in risk {risk_idx}"
                    print(f"    ⚠️ Risk {risk_idx}: Deadline {risk['DeadLine']}")
            else:
                print(f"  ✓ No risks detected")

        print("\n" + "=" * 60)
        print("✓ All verification checks passed!")
        return True

    except AssertionError as e:
        print(f"\n✗ Verification failed: {e}")
        return False
    except Exception as e:
        print(f"\n✗ Error during verification: {e}")
        return False

if __name__ == '__main__':
    success = verify_filing_query()
    sys.exit(0 if success else 1)
```

## Expected Output

A successful verification should produce output similar to:

```
Starting ICP Filing Query Verification...
============================================================

[Step 1] Executing query...

[Step 2] Verifying API response status...
✓ API call successful

[Step 3] Verifying response structure...
✓ Request ID: 79732597-AB14-1341-9131-D94F48D1AFD7
✓ Found 1 filing record(s)

[Step 4-6] Verifying Filing Record 1...
  ✓ ICP Number: 粤ICP测50000001号
  ✓ Entity Name: 深圳市星澜美容有限公司变更
  ✓ Entity Type: 企业
  ✓ Responsible Person: 于婷
  ✓ Websites: 2
    ✓ Website 1: 于婷广东 (粤ICP测50000001号-1)
    ✓ Website 2: 920企业变更网站001 (津ICP备2023010907号-1)
  ℹ No APPs in this filing record
  ⚠️ Risks: 1
    ⚠️ Risk 1: Deadline 2026年04月28日0点

============================================================
✓ All verification checks passed!
```

## Common Verification Failures

### Failure 1: Success is False

**Symptom**: `Success` field in response is `false`

**Possible Causes**:
- Invalid caller parameter
- API service error
- Account issues

**Solution**: Check the error message in the response and verify account status

### Failure 2: Empty BaSuccessDataWithRiskList

**Symptom**: `BaSuccessDataWithRiskList` is empty array

**Possible Causes**:
- No filing records exist for this account
- Filings are not in "success" state

**Solution**: Verify filing status in Beian console

### Failure 3: Missing Required Fields

**Symptom**: AssertionError about missing fields

**Possible Causes**:
- API response format changed
- Partial data in response

**Solution**: Review the API documentation and update verification logic

### Failure 4: Permission Error

**Symptom**: Exception about unauthorized access

**Possible Causes**:
- Missing RAM permissions
- Invalid credentials

**Solution**: Check RAM policies and credential configuration

## Automated Testing

You can integrate this verification into your CI/CD pipeline:

```bash
#!/bin/bash
# run_verification.sh

echo "Running ICP Filing Query Verification..."

python3 verify_filing_query.py

if [ $? -eq 0 ]; then
    echo "Verification PASSED"
    exit 0
else
    echo "Verification FAILED"
    exit 1
fi
```

## Monitoring and Alerts

For production systems, consider setting up monitoring:

1. **Success Rate Monitoring**: Track the percentage of successful queries
2. **Response Time**: Monitor API response latency
3. **Risk Alerts**: Set up alerts when new risks are detected
4. **Data Completeness**: Verify all expected fields are present

## Related Documentation

- [API Response Codes](https://www.alibabacloud.com/help/doc-detail/error-codes)
- [Beian Service Status](https://status.alibabacloud.com/)
- RAM Permission Troubleshooting: references/ram-policies.md


path: scripts/requirements.txt
content: alibabacloud-credentials==1.0.3
alibabacloud-tea-openapi==0.4.1
alibabacloud-tea-util==0.3.13


path: scripts/validate_skill.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Skill Validation Script

This script validates that the ICP Filing Success Query skill is properly configured.
"""

import os
import sys


def check_file_exists(filepath: str) -> bool:
    """Check if a file exists."""
    exists = os.path.exists(filepath)
    status = "✓" if exists else "✗"
    print(f"  {status} {filepath}")
    return exists


def validate_skill_structure():
    """Validate the skill directory structure."""
    print("\n" + "=" * 60)
    print("Validating Skill Structure")
    print("=" * 60)

    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    required_files = [
        'SKILL.md',
        'scripts/query_icp_filing.py',
        'references/ram-policies.md',
        'references/related-commands.md',
        'references/verification-method.md',
        'references/cli-installation-guide.md',
        'references/common-sdk-usage.md',
        'references/error-handling.md',
        'references/acceptance-criteria.md'
    ]

    all_exist = True
    for file in required_files:
        filepath = os.path.join(base_dir, file)
        if not check_file_exists(filepath):
            all_exist = False

    return all_exist


def validate_imports():
    """Validate that required Python modules can be imported."""
    print("\n" + "=" * 60)
    print("Validating Python Dependencies")
    print("=" * 60)

    required_modules = [
        'alibabacloud_credentials',
        'alibabacloud_tea_openapi',
        'alibabacloud_tea_util'
    ]

    all_imported = True
    for module in required_modules:
        try:
            __import__(module)
            print(f"  ✓ {module}")
        except ImportError:
            print(f"  ✗ {module} (not installed)")
            all_imported = False

    if not all_imported:
        print("\nTo install missing dependencies:")
        print("  pip install -r scripts/requirements.txt")

    return all_imported


def validate_skill_metadata():
    """Validate SKILL.md metadata."""
    print("\n" + "=" * 60)
    print("Validating SKILL.md Metadata")
    print("=" * 60)

    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    skill_file = os.path.join(base_dir, 'SKILL.md')

    try:
        with open(skill_file, 'r', encoding='utf-8') as f:
            content = f.read()

        # Check for frontmatter
        if content.startswith('---'):
            print("  ✓ YAML frontmatter present")

            # Check for required fields
            has_name = 'name:' in content[:500]
            has_description = 'description:' in content[:500]

            print(f"  {'✓' if has_name else '✗'} name field")
            print(f"  {'✓' if has_description else '✗'} description field")

            return has_name and has_description
        else:
            print("  ✗ Missing YAML frontmatter")
            return False

    except Exception as e:
        print(f"  ✗ Error reading SKILL.md: {e}")
        return False


def validate_credentials():
    """Validate that credentials can be loaded."""
    print("\n" + "=" * 60)
    print("Validating Credentials Configuration")
    print("=" * 60)

    try:
        from alibabacloud_credentials.client import Client as CredentialClient

        # Try to create credential client
        credential = CredentialClient()
        print("  ✓ CredentialClient created successfully")
        print("  ✓ Credentials are configured")
        return True

    except ImportError:
        print("  ✗ Cannot import CredentialClient")
        print("    Install: pip install -r scripts/requirements.txt")
        return False

    except Exception as e:
        print("  ⚠ Credentials may not be configured")
        print(f"    Error: {str(e)}")
        print("\n  Configure credentials using one of these methods:")
        print("    1. Environment variables: ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET")
        print("    2. Credentials file: ~/.alibabacloud/credentials")
        print("    3. ECS RAM role (when running on ECS)")
        return False


def main():
    """Main validation function."""
    print("=" * 60)
    print("ICP Filing Success Query Skill Validation")
    print("=" * 60)

    results = []

    # Validate skill structure
    results.append(("Skill Structure", validate_skill_structure()))

    # Validate Python dependencies
    results.append(("Python Dependencies", validate_imports()))

    # Validate SKILL.md metadata
    results.append(("SKILL.md Metadata", validate_skill_metadata()))

    # Validate credentials (optional, may not be configured in dev)
    results.append(("Credentials", validate_credentials()))

    # Print summary
    print("\n" + "=" * 60)
    print("Validation Summary")
    print("=" * 60)

    passed = 0
    total = len(results)

    for name, result in results:
        status = "PASS" if result else "FAIL"
        symbol = "✓" if result else "✗"
        print(f"  {symbol} {name}: {status}")
        if result:
            passed += 1

    print("\n" + "=" * 60)
    print(f"Results: {passed}/{total} checks passed")
    print("=" * 60)

    if passed == total:
        print("\n✓ All validation checks passed!")
        print("  The skill is ready to use.")
        return 0
    else:
        print("\n⚠ Some validation checks failed.")
        print("  Please address the issues above before using the skill.")
        return 1


if __name__ == '__main__':
    sys.exit(main())


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)