Migration Guide¶
This guide covers the changes needed when upgrading from swgoh_comlink v1.x (the requests-based release)
to the new version that introduces async support, StatCalc, and httpx.
1. Update dependencies¶
The HTTP library changed from requests to httpx.
# Remove the old dependency
pip uninstall requests
# Install the new version
pip install --upgrade swgoh_comlink
If your project pins dependencies, update your requirements.txt or pyproject.toml:
httpx is installed automatically as a dependency of swgoh_comlink, so in most cases
you only need to upgrade the package itself.
2. Update exception handling¶
The exception raised on HTTP errors changed from requests.RequestException to
httpx.RequestError. The library still wraps transport errors in its own
SwgohComlinkException, so if you catch that you are already covered.
from swgoh_comlink import SwgohComlink
- import requests
+ import httpx
comlink = SwgohComlink()
try:
player = comlink.get_player(allycode=245866537)
- except requests.RequestException as e:
+ except httpx.RequestError as e:
print(f"Network error: {e}")
Recommended: Catch SwgohComlinkException instead of transport-level errors — this
insulates your code from future HTTP library changes:
from swgoh_comlink import SwgohComlink
from swgoh_comlink.exceptions import (
SwgohComlinkException,
SwgohComlinkValueError,
SwgohComlinkTypeError,
)
comlink = SwgohComlink()
try:
player = comlink.get_player(allycode=245866537)
except SwgohComlinkValueError as e:
print(f"Invalid argument value: {e}")
except SwgohComlinkTypeError as e:
print(f"Invalid argument type: {e}")
except SwgohComlinkException as e:
print(f"Comlink error: {e}")
The exception hierarchy is:
SwgohComlinkException— base for all library errorsSwgohComlinkValueError(also inheritsValueError) — invalid argument valuesSwgohComlinkTypeError(also inheritsTypeError) — invalid argument types
3. Update logging configuration¶
The get_logger() helper no longer accepts a log_level parameter and no longer
attaches handlers or sets log levels automatically. The library now follows Python best
practice by attaching only a NullHandler to the package root logger.
Before:
from swgoh_comlink.globals import get_logger
logger = get_logger(__name__, log_level="DEBUG") # auto-configured handler + level
After:
Or target only the swgoh_comlink namespace:
import logging
comlink_logger = logging.getLogger("swgoh_comlink")
comlink_logger.setLevel(logging.DEBUG)
comlink_logger.addHandler(logging.StreamHandler())
See Logging for more examples including the built-in LoggingFormatter
and rotating file handlers.
4. Close the client when done¶
The new version uses persistent httpx connection pools for better performance.
This means the client should be closed when you are finished with it.
Context manager (recommended):
with SwgohComlink() as comlink:
player = comlink.get_player(allycode=245866537)
# connections are closed automatically
Manual close:
comlink = SwgohComlink()
try:
player = comlink.get_player(allycode=245866537)
finally:
comlink.close()
Existing code that does not call close() will still work — connections are cleaned up
on garbage collection — but explicitly closing is preferred to avoid resource warnings.
5. Helpers module refactoring¶
The monolithic helpers.py file has been refactored into a helpers/ subpackage.
All existing import paths continue to work — a backward-compatible re-export shim
ensures no breaking changes.
What moved¶
| Before | After (internal location) |
|---|---|
helpers.py (single file) |
helpers/ subpackage with focused modules |
Constants.STAT_ENUMS |
helpers/_stat_data.STAT_ENUMS (re-exported) |
Constants.STATS |
helpers/_stat_data.STATS (re-exported) |
StatCalc.STATS_NAME_MAP |
Now imports from helpers/_stat_data.STATS |
Constants.get() changes¶
Constants.get() still works for all legacy PascalCase names (e.g., "UnitDefinitions")
as well as the new UPPER_SNAKE_CASE DataItems names (e.g., "UNITS"):
from swgoh_comlink.helpers import Constants
# All three forms still work:
Constants.get("UnitDefinitions") # -> '137438953472' (legacy name)
Constants.get("UNITS") # -> '137438953472' (DataItems name)
Constants.get("Segment1") # -> '2097151' (class attribute)
Recommendation: Prefer using DataItems enum values directly for type safety, request
only the collections you need, and combine members with | — see
GameDataItems server alignment below:
from swgoh_comlink.helpers import DataItems
items = DataItems.SKILL | DataItems.EQUIPMENT
data = comlink.get_game_data(items=items)
Migration checker CLI¶
A CLI tool is included to scan your codebase for patterns that may need updating:
# Scan a project directory
python -m swgoh_comlink.migrate /path/to/your/project
# Or use the console script
swgoh-migrate /path/to/your/project
# Filter by severity and exclude directories
swgoh-migrate . --severity=WARNING --exclude .venv dist
The tool reports deprecated imports, removed APIs, and suggests replacements.
6. Subclass and internal API changes¶
These only matter if you subclass SwgohComlink or call private methods directly.
Constructor inheritance¶
SwgohComlink and SwgohComlinkAsync now inherit from SwgohComlinkBase. The
constructor parameters are unchanged, but the subclass signature uses **kwargs:
# Both still work:
comlink = SwgohComlink(url="http://myhost:3000")
comlink = SwgohComlink(host="myhost", port=3000)
_request() signature¶
def _request(
self,
method: str = "POST",
- url_base: str | None = None,
endpoint: str | None = None,
payload: dict | list | None = None,
+ stats: bool = False,
+ timeout: float | None = None,
) -> dict | list:
url_basewas removed — the method now selects betweenself.url_baseandself.stats_url_basebased on thestatsflag.timeoutallows per-request timeout overrides.
_post() signature¶
Same changes as _request() — url_base replaced by stats and timeout.
7. Removed sentinels¶
All sentinel objects (OPTIONAL, NotSet, REQUIRED, MISSING, GIVEN,
MutualExclusiveRequired) have been removed from swgoh_comlink.helpers.
Remove any sentinel imports from your code.
- from swgoh_comlink.helpers import (
- REQUIRED,
- MISSING,
- GIVEN,
- OPTIONAL,
- NotSet,
- MutualExclusiveRequired,
- )
Functions that previously used sentinel defaults now use standard Python
patterns: required parameters have no default, and optional parameters
default to None.
8. GAC bracket helpers¶
get_gac_brackets() and async_get_gac_brackets() have two changes:
-
The
limitparameter changed from a sentinel default tointwith default0(where0means "no limit"): -
Bracket boundary discovery now uses exponential probing with binary search, reducing HTTP requests from O(n) to O(log n). The async variant also fetches brackets in parallel batches via
asyncio.gather. No code changes are needed on your side — the return format is identical.
9. GameDataItems server alignment¶
DataItems and Constants were re-synced against the live GameDataItemsEnum that
get_enums() now exposes. Two practical impacts:
Segment2 and Segment4 aggregate values changed. If you hardcoded the integers
in your own code (rather than referencing the constants by name), update them:
| Constant | Old value | New value |
|---|---|---|
DataItems.SEGMENT2 / Constants.Segment2 |
68717379584 |
1125968624222208 |
DataItems.SEGMENT4 / Constants.Segment4 |
281200098803712 |
3377424842620928 |
SEGMENT1 (2097151) and SEGMENT3 (206158430208) are unchanged.
Code that references the constant by name (DataItems.SEGMENT2, Constants.Segment2,
Constants.get("Segment2")) picks up the new values automatically.
get_game_data(items=...) accepts any in-range bitmask. Comlink accepts any
items value from 1 to 252 − 1, or -1 (DataItems.ALL) for everything,
so single collections (e.g. DataItems.UNITS), custom combinations and the
SEGMENT1–SEGMENT4 aggregates all work. Out-of-range values are rejected with an
HTTP 400. Earlier versions of this guide advised against single-collection values;
the failures behind that advice were most likely caused by a since-fixed Comlink bug
in how CDN URLs were built, so upgrade Comlink if you still see them.
Combine members with | rather than +. Aliased members (e.g. CONQUEST_DEFINITION
and ARTIFACT_DEFINITION, which are both the CONQUEST bit) set a different bit when
added together.
New members added (from the live GameDataItemsEnum): ABILITY_DECISION_TREE,
ERA_DEFINITION, UBS_UPDATE. New legacy-name aliases: AbilityDecisionTrees,
EraDefinitions, UBSUpdate, EpisodeDefinitions (plural), AccountLinking.
Summary of changes¶
| Area | Before (v1.x) | After |
|---|---|---|
| HTTP library | requests |
httpx |
| Transport exception | requests.RequestException |
httpx.RequestError |
| Exception hierarchy | SwgohComlinkException, SwgohComlinkValueError |
Added SwgohComlinkTypeError |
get_logger(log_level=) |
Accepted log_level, auto-configured handlers |
No log_level param, no auto-configuration |
| Default log output | Console output at INFO level | Silent (NullHandler only) |
| Client lifecycle | No close needed | Use with or call close() |
| Async support | Not available | SwgohComlinkAsync |
| Local stat calc | Not available | StatCalc (sync) / StatCalcAsync (async) |
_request(url_base=) |
url_base parameter |
stats bool + timeout |
helpers.py |
Single 1,970-line file | helpers/ subpackage (all imports preserved) |
| All sentinels | Exported from helpers | Removed — use None or required positional args |
get_gac_brackets(limit=) |
Sentinel default | int default 0 (0 = no limit) |
| GAC bracket scanning | Linear O(n) | Exponential probe + binary search O(log n) |
| Migration checker | Not available | swgoh-migrate CLI / python -m swgoh_comlink.migrate |
DataItems.SEGMENT2 value |
68717379584 |
1125968624222208 (server-aligned) |
DataItems.SEGMENT4 value |
281200098803712 |
3377424842620928 (server-aligned) |
get_game_data(items=) values |
Any bitmask | Any bitmask from 1 to 252 − 1, or -1; out of range → HTTP 400 |