Skip to main content

ASFConnector API

ASFConnector is an asynchronous Python client for interacting with the ArchiSteamFarm (ASF) IPC API. It features a modular architecture with connection pool reuse, providing high-performance API call experience.

license python asyncio ASF ruff pre-commit

Chinese | 中文文档

API Implementation Details

Architecture Design

Core Components

  1. ASFConnector (__init__.py)

    • Main entry class managing connection lifecycle
    • Unified management of all Controller instances
    • Supports async with context manager for connection pool reuse
  2. IPCProtocolHandler (IPCProtocol.py)

    • Low-level HTTP client wrapper
    • Implements asynchronous requests using httpx.AsyncClient
    • Supports connection pool reuse for improved performance
  3. BaseController (BaseController.py)

    • Base class for all Controllers
    • Provides common GET/POST/DELETE request methods
    • Unified logging
  4. ASFConfig (config.py)

    • Pydantic-based configuration management
    • Supports loading configuration from .env files
    • Automatic parameter validation
  5. Controller Modules

    • ASFController: ASF global operations (get info, update config, restart, etc.)
    • BotController: Bot-related operations (start, stop, redeem, etc.)
    • NLogController: Logging operations (retrieve log files)
    • TypeController: Type information queries
    • StructureController: Structure information queries
    • CommandController: Command execution (marked as legacy)

Quick Start

⚠️ IMPORTANT: Configure Default Bot in ASF

Before using any Bot-related operations with this library, you MUST configure a DefaultBot in your ASF global configuration. Without this setting, all Bot-related operations may exhibit random behavior and produce unexpected results.

Add the following to your ASF ASF.json configuration file:

{
  "DefaultBot": "your_primary_bot_name"
}

For more details, see: ASF Configuration - DefaultBot

Configuration Setup

  1. Copy .env.example to .env:
cp .env.example .env
  1. Edit the .env file:
ASF_HOST=127.0.0.1
ASF_PORT=1242
ASF_PASSWORD=your_ipc_password
ENABLE_RICH_TRACEBACK=False

Basic Usage (Recommended)

Use .env configuration file with automatic loading:

import asyncio
from ASFConnector import ASFConnector

async def main():
    # Auto-load configuration from .env file
    async with ASFConnector.from_config() as connector:
        # Get ASF info
        asf_info = await connector.asf.get_info()
        print(f"ASF Version: {asf_info['Result']['Version']}")
        
        # Get Bot info
        bot_info = await connector.bot.get_info('bot_name')
        print(bot_info)

asyncio.run(main())

Using Custom Configuration

import asyncio
from ASFConnector import ASFConnector
from ASFConnector.config import ASFConfig

async def main():
    # Create custom configuration
    config = ASFConfig(
        asf_host='192.168.1.100',
        asf_port='8080',
        asf_password='my_password'
    )
    
    async with ASFConnector.from_config(config) as connector:
        info = await connector.asf.get_info()
        print(info)

asyncio.run(main())

Direct Parameters (Backward Compatible)

import asyncio
from ASFConnector import ASFConnector

async def main():
    # Create connection with direct parameters
    async with ASFConnector(
        host='127.0.0.1',
        port='1242',
        password='your_ipc_password'
    ) as connector:
        info = await connector.asf.get_info()
        print(f"Request: {info['Success']}")

asyncio.run(main())

API Reference

ASFController

get_info()

Get ASF global information.

info = await connector.asf.get_info()

Response Example:

{
    "Success": true,
    "Result": {
        "Version": "5.4.0.3",
        "BuildVariant": "generic",
        ...
    }
}

update_config(config: dict)

Update ASF global configuration.

config = {
    "AutoRestart": True,
    "UpdatePeriod": 24
}
result = await connector.asf.update_config(config)

exit()

Shut down ASF.

result = await connector.asf.exit()

restart()

Restart ASF.

result = await connector.asf.restart()

update()

Update ASF to the latest stable version.

result = await connector.asf.update()

encrypt(data: dict)

Encrypt data using ASF encryption mechanisms.

data = {
    "CryptoMethod": 0,  # Encryption method (0 = AES)
    "StringToEncrypt": "my_sensitive_data"
}
result = await connector.asf.encrypt(data)

hash(data: dict)

Hash data using ASF hashing mechanisms.

data = {
    "HashMethod": 0,  # Hashing method (0 = SHA256)
    "StringToHash": "my_string_to_hash"
}
result = await connector.asf.hash(data)

BotController

get_info(bot_names: str)

Get information for specified Bot(s).

# Single Bot
info = await connector.bot.get_info('bot1')

# Multiple Bots (comma-separated)
info = await connector.bot.get_info('bot1,bot2')

# All Bots
info = await connector.bot.get_info('ASF')

start(bot_names: str)

Start specified Bot(s).

result = await connector.bot.start('bot1')

stop(bot_names: str)

Stop specified Bot(s).

result = await connector.bot.stop('bot1')

pause(bot_names: str)

Pause card farming for specified Bot(s).

result = await connector.bot.pause('bot1')

resume(bot_names: str)

Resume card farming for specified Bot(s).

result = await connector.bot.resume('bot1')

redeem(bot_names: str, keys)

Redeem CD-Keys on specified Bot(s).

# Single key
result = await connector.bot.redeem('bot1', 'XXXXX-XXXXX-XXXXX')

# Multiple keys
keys = ['KEY1', 'KEY2', 'KEY3']
result = await connector.bot.redeem('bot1', keys)

add_license(bot_names: str, licenses)

Add free licenses.

result = await connector.bot.add_license('bot1', [12345, 67890])

get_inventory(bot_names: str, app_id: int = None, context_id: int = None)

Get inventory information.

# Get general inventory
inventory = await connector.bot.get_inventory('bot1')

# Get specific game inventory (Steam trading cards)
inventory = await connector.bot.get_inventory('bot1', app_id=753, context_id=6)

input(bot_names: str, input_type: str, input_value: str)

Provide input value for Bot (e.g., Steam Guard code).

result = await connector.bot.input('bot1', 'SteamGuard', 'ABCDE')

rename(bot_name: str, new_name: str)

Rename a Bot.

result = await connector.bot.rename('old_bot_name', 'new_bot_name')

delete_games_to_redeem_in_background(bot_names: str)

Delete background game redemption output files.

result = await connector.bot.delete_games_to_redeem_in_background('bot1')

NLogController

get_log_file()

Get ASF log file content.

log_content = await connector.nlog.get_log_file()
if log_content.get('Success'):
    print(log_content['Result'])

get_log_stream()

Get real-time log stream (requires WebSocket support).

# Note: This endpoint requires a WebSocket client
# Currently returns instructions on how to use WebSocket connection
result = await connector.nlog.get_log_stream()

TypeController

get_type(type_name: str)

Get type information for the specified type.

type_info = await connector.type.get_type('ArchiSteamFarm.Steam.Storage.BotConfig')

StructureController

get_structure(structure_name: str)

Get default structure for the specified type.

structure = await connector.structure.get_structure('ArchiSteamFarm.Storage.GlobalConfig')

CommandController (IPC API Legacy Feature)

Note: This Controller has been marked as legacy by ASF. It's recommended to use specific methods from ASFController and BotController.

execute(command: str)

Execute a command.

result = await connector.command.execute('status ASF')

Configuration Management

Configuration Validation

ASFConfig uses Pydantic for configuration validation:

from ASFConnector.config import ASFConfig
from pydantic import ValidationError

try:
    config = ASFConfig(
        asf_host='127.0.0.1',
        asf_port='1242',  # Automatic port range validation (1-65535)
        asf_path='Api'    # Automatically adds leading slash -> '/Api'
    )
    config.log_config()
except ValidationError as e:
    print(f"Configuration validation failed: {e}")

Configuration Parameters

Parameter Environment Variable Default Description
asf_host ASF_HOST 127.0.0.1 ASF IPC host address
asf_port ASF_PORT 1242 ASF IPC port (1-65535)
asf_password ASF_PASSWORD None ASF IPC password (optional)
asf_path ASF_PATH /Api ASF IPC API path

Performance Optimization

Connection Pool Reuse

Using the async with context manager significantly improves performance:

# Without connection pool (creates new connection for each request)
async with ASFConnector.from_config() as connector:
    await connector.asf.get_info()  # Slower

# With connection pool (reuses connections, recommended)
async with ASFConnector.from_config() as connector:
    for i in range(100):
        await connector.asf.get_info()  # Much faster!

Performance Comparison

Based on test results (10 requests):

Results for 10 requests:
  Legacy API (no pool):     0.109s (10.9ms per request)
  New Controller (no pool): 0.111s (11.1ms per request)
  New Controller (w/ pool): 0.004s (0.4ms per request)

Speedup with connection pool: 28.51x faster
Time saved per request: 10.7ms

Error Handling

All API calls return a dictionary containing a Success field:

response = await connector.asf.get_info()

if response.get('Success'):
    data = response.get('Result')
    print(f"Success: {data}")
else:
    error_msg = response.get('Message', 'Unknown error')
    print(f"Error: {error_msg}")

When IPC requests trigger HTTP/network exceptions, the response dictionary will also include:

  • ExceptionType: The corresponding custom exception class name (e.g., ASF_NotFound)
  • Exception: The specific exception instance with status_code and original payload
  • StatusCode: HTTP status code (if available)
  • ResponsePayload: JSON or plain text content returned by ASF (if available)

The library provides unified exception definitions, accessible through the top-level ASFConnector export or the ASFConnector.error module:

from ASFConnector import ASF_BadRequest, ASF_NotFound

response = await connector.type.get_type('ArchiSteamFarm.Storage.UnknownType')
if not response['Success']:
    exc = response['Exception']
    if isinstance(exc, ASF_NotFound):
        print("Type does not exist, original response:", response.get('ResponsePayload'))
    else:
        raise exc  # Raise or log as needed

All built-in exceptions inherit from ASFConnectorError. Common HTTP status code to exception mappings:

HTTP Status Code Exception Type
400 ASF_BadRequest
401 ASF_Unauthorized
403 ASF_Forbidden
404 ASF_NotFound
405 ASF_NotAllowed
406 ASF_NotAcceptable
411 ASF_LengthRequired
501 ASF_NotImplemented

More Information

License

This project follows the same license as dmcallejo/ASFBot.

Metadata

Release files for asfconnector 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asfconnector 0.0.3
File Size Uploaded Provenance
asfconnector-0.0.3.tar.gz 96.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for asfconnector 0.0.3
File Interpreter ABI Platform
asfconnector-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 131.6 kB

Release files / asfconnector-0.0.3.tar.gz

Download URL asfconnector-0.0.3.tar.gz
Size 96.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9b502db7fc18e85862c85f3079342820d25dd5b256e6f243dbb75da689e07fe9
BLAKE2b-256 checksum
How to use checksums
3fd4da201fe6853563899a067aff582695bd44d31035ee8026d894ef1af4bf4f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2025.

Transparency log

Release files / asfconnector-0.0.3-py3-none-any.whl

Download URL asfconnector-0.0.3-py3-none-any.whl
Size 34.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d44edd52f82b14983c3b9444d2130320be31808eebcf0409ce5950e90161dbe9
BLAKE2b-256 checksum
How to use checksums
e8fdc3549de095af2ee1de12de7650557d8b98e35820b283b862e68429614b2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2025.

Transparency log

Security for asfconnector 0.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for asfconnector-0.0.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page