A python wrapper for the swgoh-comlink tool, plus an in-package local stat calculator (StatCalc).
Supports both synchronous and asynchronous usage via SwgohComlink and SwgohComlinkAsync.
Requires Python 3.11 or higher.
v3 is in alpha and distributed via GitHub Releases. The PyPI
package swgoh_comlink is still v2.x; passing --pre to pip will
NOT pick up v3 alphas (they are not published to PyPI).
The alpha is hosted on the maintainer fork MarTrepodi/comlink-python (the upstream repo stays on v2.x until reintegration). Install the v3.0.0a1 wheel directly:
pip install https://github.com/MarTrepodi/comlink-python/releases/download/v3.0.0a1/swgoh_comlink-3.0.0a1-py3-none-any.whlOr install from a git ref:
pip install git+https://github.com/MarTrepodi/comlink-python.git@v3.0.0a1Strongly recommended: install the alpha in a dedicated virtual
environment with a rollback path to the public v2.x release — see
docs/v3/install-alpha.md.
What this gives you:
- Typed client at
from swgoh_comlink.typed import SwgohComlink - Async parity (typed + dict) with
SwgohComlinkAsync GameDataCache— disk-persisted/data+/localization- Bimorphic
StatCalc.calc_player_stats(player_struct)(nomsgspec.to_builtins(...)boilerplate required) healthcheck(),raw_request(), retries viaprofile="bot"
See docs/v3/migration.md for v2 → v3
patterns and examples/typed/ for ready-to-run
examples of the typed surface.
What it does NOT promise: API stability across alphas. Breaking
changes between aN and a(N+1) are allowed. See
ADR-0008
for the policy. Report bugs against the v3 label.
Install from PyPi package repository using the following shell command.
uv pip install swgoh_comlinkThe PyPI release tracks v2.x. For the v3 alpha see "Alpha (v3) install" above.
Basic default usage:
from swgoh_comlink import SwgohComlink
comlink = SwgohComlink()
player_data = comlink.get_player(allycode=245866537)
player_name = player_data['name']
guild_id = player_data['guildId']
guild = comlink.get_guild(guild_id=guild_id)
guild_name = guild['profile']['name']With a custom comlink URL:
from swgoh_comlink import SwgohComlink
comlink = SwgohComlink(url='http://localhost:3500')
player_data = comlink.get_player(allycode=245866537)With an external swgoh-stats service:
from swgoh_comlink import SwgohComlink
comlink = SwgohComlink(url='http://localhost:3500', stats_url='http://localhost:3550')
player_data = comlink.get_player(allycode=245866537)
player_roster = player_data['rosterUnit']
roster_with_stats = comlink.get_unit_stats(player_roster)With HMAC authentication:
from swgoh_comlink import SwgohComlink
comlink = SwgohComlink(
url='http://localhost:3000',
access_key='public_key',
secret_key='this_string_should_be_secret'
)
player_data = comlink.get_player(allycode=245866537)As a context manager (auto-closes connections):
from swgoh_comlink import SwgohComlink
with SwgohComlink() as comlink:
player_data = comlink.get_player(allycode=245866537)The SwgohComlinkAsync class provides the same API with async/await support. All public methods have identical signatures to the sync client.
from swgoh_comlink import SwgohComlinkAsync
async with SwgohComlinkAsync() as comlink:
player_data = await comlink.get_player(allycode=245866537)
player_name = player_data['name']
guild_id = player_data['guildId']
guild = await comlink.get_guild(guild_id=guild_id)
guild_name = guild['profile']['name']Without a context manager, call aclose() when done:
comlink = SwgohComlinkAsync()
try:
player_data = await comlink.get_player(allycode=245866537)
finally:
await comlink.aclose()Both clients accept the same constructor parameters and support connection pooling via persistent httpx clients.
StatCalc and StatCalcAsync calculate unit stats and Galactic Power locally without requiring an external swgoh-stats service. StatCalc fetches game data synchronously on initialization; StatCalcAsync provides an async factory method (await StatCalcAsync.create()) for non-blocking initialization. Both accept pre-loaded data for offline use.
Instead of fetching a static gameData.json from GitHub, you can build game data
dynamically from a running Comlink service using GameDataBuilder / GameDataBuilderAsync:
from swgoh_comlink import SwgohComlink, StatCalc, GameDataBuilder
comlink = SwgohComlink()
game_data = GameDataBuilder(comlink).build()
calc = StatCalc(game_data=game_data)Async:
from swgoh_comlink import SwgohComlinkAsync, StatCalcAsync, GameDataBuilderAsync
async with SwgohComlinkAsync() as comlink:
game_data = await GameDataBuilderAsync(comlink).build()
calc = StatCalcAsync(game_data=game_data)The builder fetches only the required game data collections in a single API call
and transforms them into the format StatCalc expects.
from swgoh_comlink import SwgohComlink, StatCalc
comlink = SwgohComlink()
calc = StatCalc() # fetches latest game data from GitHub on init
# Calculate stats for a full player roster
player = comlink.get_player(allycode=245866537)
calc.calc_roster_stats(player['rosterUnit'])
# Or calculate stats for a single character
unit = {
"defId": "BOSSK",
"rarity": 7,
"level": 85,
"gear": 13,
"equipped": [],
"skills": [],
}
calc.calc_char_stats(unit)
print(unit["stats"]) # final stats, mods, and GP added in-place
print(unit["gp"]) # galactic powercalc = StatCalc(game_data=my_game_data_dict)StatCalcAsync provides an async factory method for fetching game data without blocking the event loop. All calculation methods are inherited from StatCalc and remain synchronous (they are pure computation).
from swgoh_comlink import SwgohComlinkAsync, StatCalcAsync
async with SwgohComlinkAsync() as comlink:
calc = await StatCalcAsync.create() # fetches game data from GitHub async
player = await comlink.get_player(allycode=245866537)
calc.calc_roster_stats(player['rosterUnit'])With pre-loaded game data (no async fetch needed):
calc = StatCalcAsync(game_data=my_game_data_dict)| Method | Description |
|---|---|
calc_char_stats(unit) |
Calculate stats and GP for a single character (modifies in-place) |
calc_ship_stats(unit, crew) |
Calculate stats and GP for a ship with its crew |
calc_roster_stats(units) |
Calculate stats for all units in a roster (list or dict) |
calc_player_stats(players) |
Calculate stats for one or more full player payloads |
calc_char_gp(char) |
Calculate GP for a character |
calc_ship_gp(ship, crew) |
Calculate GP for a ship |
set_game_data(game_data) |
Replace the game data used by the calculator |
Constructor parameters for SwgohComlink and SwgohComlinkAsync:
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
str |
http://localhost:3000 |
URL where swgoh-comlink is running |
stats_url |
str |
http://localhost:3223 |
URL where swgoh-stats service is running |
access_key |
str |
None |
HMAC public key. Also reads from ACCESS_KEY env var |
secret_key |
str |
None |
HMAC private key. Also reads from SECRET_KEY env var |
host |
str |
None |
Server hostname (overrides url and stats_url) |
port |
int |
3000 |
Comlink TCP port (used with host) |
stats_port |
int |
3223 |
Stats service TCP port (used with host) |
verify_ssl |
bool |
True |
Enable TLS certificate verification |
Methods available on both SwgohComlink and SwgohComlinkAsync (async methods use await):
| Method | Description |
|---|---|
get_player(allycode, player_id, enums) |
Get player data by allycode or player ID |
get_player_arena(allycode, player_id, player_details_only, enums) |
Get player arena profile |
get_guild(guild_id, include_recent_guild_activity_info, enums) |
Get guild data by guild ID |
get_guilds_by_name(name, start_index, count, enums) |
Search guilds by name |
get_guilds_by_criteria(search_criteria, start_index, count, enums) |
Search guilds by criteria |
get_game_data(version, include_pve_units, request_segment, enums) |
Get game data collections |
get_game_metadata(client_specs, enums) |
Get current game and localization versions |
get_localization(localization_id, locale, unzip, enums) |
Get localization bundles |
get_enums() |
Get game data enums |
get_events(enums) |
Get current game events |
get_leaderboard(leaderboard_type, league, division, ...) |
Get GAC leaderboard data |
get_guild_leaderboard(leaderboard_id, count, enums) |
Get guild leaderboard data |
get_unit_stats(request_payload, flags, language) |
Calculate unit stats via swgoh-stats |
get_latest_game_data_version() |
Get latest game data and language versions |
get_name_spaces(only_compatible, enums) |
Get available namespaces |
get_segmented_content(content_name_space, accept_language, enums) |
Retrieve segmented content |
The examples/ directory contains runnable scripts for common tasks using both the sync and async clients.
Synchronous (examples/Sync/)
| Script | Description |
|---|---|
get_player.py |
Get a player's full profile including roster |
get_guild.py |
Look up guild info from a player's ally code |
get_events.py |
Retrieve current game events with timestamps |
get_game_data.py |
Retrieve game data collections |
get_gac_leaderboard.py |
Get GAC leaderboard data |
get_gac_brackets.py |
Scan GAC brackets and search for a player |
calc_stats_local.py |
Calculate character stats locally with StatCalc |
search_for_guilds.py |
Search for guilds by name or criteria |
Asynchronous (examples/Async/)
| Script | Description |
|---|---|
get_player.py |
Get a player's full profile using await |
concurrent_requests.py |
Fetch multiple players in parallel with asyncio.gather() |
streaming_guild_roster.py |
Fetch all guild members concurrently with asyncio.TaskGroup |
streaming_guild_roster_advanced.py |
Production-quality guild roster fetch with CLI args and retry logic |
calc_stats_local.py |
Calculate character stats locally with StatCalcAsync |
See the full examples listing for all available scripts and usage details.
Logging is handled by the python logging module. The library follows Python best practice by attaching only a NullHandler — no output is produced unless your application configures logging.
For details on enabling and customizing log output, see docs/logging.md.
This release replaces requests with httpx and changes how logging is configured. If you are upgrading from a previous version, see the Migration Guide for a walkthrough of required changes:
- Replace
requestswithhttpxin your dependencies - Update
except requests.RequestExceptiontoexcept httpx.RequestError(or catchSwgohComlinkException) - Update any
get_logger(log_level=...)calls — configure logging via the standardloggingmodule instead - Use a context manager (
with SwgohComlink() ...) or callclose()to release connections
Integration tests are opt-in and require a running comlink service:
# Run integration tests (requires comlink on localhost:3000)
RUN_INTEGRATION_TESTS=1 uv run pytest tests/integration/ -v
# Run with HMAC tests (requires comlink-hmac on localhost:3001)
HMAC_ACCESS_KEY=your_key HMAC_SECRET_KEY=your_secret \
RUN_INTEGRATION_TESTS=1 uv run pytest tests/integration/ -vHMAC tests are automatically skipped when HMAC_ACCESS_KEY and HMAC_SECRET_KEY environment variables are not set.
See the online wiki for more information.
Issues for the v3 alpha can be reported at MarTrepodi/comlink-python (use the v3 label). Issues for the stable v2.x PyPI release belong upstream at swgoh-utils/comlink-python.
Join the discord server