Changelog¶
This page keeps a fairly detailed, human readable version of what has changed, and whats new for each version of the lib.
v0.3.4¶
Breaking Changes¶
Clan member events no longer have the clan argument. Clan can be accessed through player.clan.
New Things¶
Player.get_ordered_troops()
was added. From the doc-string,Get an ordered dict of a player’s troops against a predefined list of troops.
The most common use of this will be passing in one of the following: -
coc.ELIXIR_TROOP_ORDER
-coc.DARK_ELIXIR_TROOP_ORDER
-coc.SIEGE_MACHINE_ORDER
-coc.HOME_TROOP_ORDER
-coc.BUILDER_TROOPS_ORDER
Which will yield an ordered dict of the player’s troops, ordered as found in both barracks and labatory in-game.
Example:
# to get an ordered dict of a player's elixir troops. import coc player = client.get_player(...) elixir_troops = player.get_ordered_troops(coc.ELIXIR_TROOP_ORDER) for troop_name, troop in elixir_troops.items(): ...
Returns:
collections.OrderedDict
- An ordered dict of troops by name.Setting
cache=None
when logging in will remove any caching from the client.BasicPlayer.role
is now an enum, with str(x) giving the string as shown in-game.Super troops support was added.
SearchPlayer.town_hall_weapon
now returns the town hall weapon level for TH12+. This is 0 for lower THs.SearchClan.war_league
now gives the war league the clan has been placed in.
BugFixes¶
- Player updates weren’t firing correctly. This has been fixed.
WarPlayer.defenses
now returns the player’s defenses (rather than attacks…)- Maintenance errors are now ignored in iterators.
- Future rounds are now no longer included in
LeagueGroup.rounds
v0.3.3¶
Breaking Changes¶
SearchPlayer.versus_attacks_wins
has been renamed toSearchPlayer.versus_attack_wins
.- The
on_player_versus_attacks_change
event has been renamed toon_player_versus_attack_change
to match the above change. - There was a typo with the spelling of the
coc.Maintenance
exception. It has been renamed fromcoc.Maitenance
tococ.Maintenance
.
New Things¶
- Add a default Unranked league to
BasicPlayer.league
. - Added TH13 content.
BugFixes¶
- Fixed
client.get_members
raisingAttributeError
if no clan is found in the cache. client.get_warlog
was only returning league wars. This has been fixed.
v0.3.2¶
New Features.¶
- Rename
member_dict
–>members_dict
for consistency. - New helper function:
LeagueGroup.get_wars(round_number)()
which will return a LeagueWarIterator of all SCCWL wars in that round.
Bug Fixes¶
- BugFix for cache not updating properly on clans going into prep.
- Add list of possible friendly war prep times (in seconds). If prep time is not in that list, assume random war. This helps when the API reports weird prep times that aren’t exactly 23 hours for a random war.
v0.3.1¶
New Features.¶
- Clan Member Trophy Count Change, Clan Member Versus Trophy Count Change and Clan Member League Change were added as new events.
- Add ability to pass async and other iterables into methods that return iterators.
- Add the HogGlider to list of builder base troops.
- Added support for SearchClan.labels and SearchPlayer.labels. They will return a
Label
object. - Add a special parameter to Client to automatically “fix” or call utils.correct_tag on any tags passed in to calls.
- Client.get_clan_labels() and Client.get_player_labels() are now valid client calls.
BugFixes¶
- Getting clans and players for a location will now default to getting for the global leaderboard.
- LeagueWar will no longer throw an AttributeError when no clan is found.
- Never update the cache automatically when the EventsClient is used.
- Fixed War State Change not firing properly when a clan entered preparation or warEnded.
v0.3.0¶
Bug Fixes¶
- All iterators have been fixed in python 3.7
- Clan Member Join will now fire events correctly
- Properly parse HTML errors thrown by CloudFlare
- Accessing the
League.badge
attribute has been fixed - Clan events now sleep for the correct interval
WarMember.town_hall
has been fixed- The API used to fetch IP has been changed (##19) to https://api.ipify.org/
- Ensure the clan is in war before trying to find prep time (##21)
New Things¶
- Check out the Cache tab in sidebar for a how-to work with the new cache. It still works out of the box!
- You can now call utils with
coc.utils.X
- All events now have callbacks as an extra layer of security to stop them from failing.
- New Properties:
Clan.share_link
andPlayer.share_link
. - Add
utils.maybe_sort()
as an easy tool to sort clan war attacks. - All attributes that were prefaced with a
_
to dictate being iterables have been changed to be prefixed withiter
, ie._attacks
becomesiterattacks
. - Rename
SearchPlayer.level
toSearchPlayer.exp_level
- keep in line with API naming. - Default value can be passed to
BasicPlayer.league
; defaults to None - Default value for
SearchPlayer.builder_hall
is 0. - New Error: PrivateWarLog:
- Subclass of Forbidden and a special case for when a 403 is thrown from trying to access war info for a clan with a private war log.
- Redirect all Forbidden thrown errors in get_WARS methods to throw PrivateWarLog
- A valid operation is to do either:
try:
await coc.get_current_war(...)
except coc.Forbidden:
pass
# or:
try:
await coc.get_current_war(...)
except coc.PrivateWarLog:
pass
EventsClient.add_X_update
now accepts either a string or iterable.- New Method:
client.remove_events()
which works in the same way asclient.add_events()
- Speed up utils.get
- New Events:
- Player Clan Join - when a player joins a clan
- Player Clan Leave - when a player leaves a clan
- Player’s Clan Level Change - when a player’s clan’s level changes
- Player’s Clan Badge Change - when a player’s clan’s badges change.
- on_client_close which is dispatched upon closing the client
- Rename x_achievement_update –> x_achievement_change for consistency
Documentation¶
- Lots of the docs have had tidy-ups, with 2 new how-to’s dedicated to Cache and the Events Client.
v0.2.0¶
EventsClient¶
EventsClient
- Provides all functionality of
Client
, as well as an events-like system. - It will constantly request to the API every X seconds and detect indifferences between the cached and new results returned by API. It will then send out ‘events’, basically calling functions that you must register, to tell you that these things have happened
- Split into 3 categories: player, clan and war
Player
- All events regarding anything in the API that can change.
- E.g, name, troop levels (and unlocking), spells, heroes, donations, trophies etc.
Clans
- All events regarding anything in the API that can change.
- E.g. description, type (invite only etc.), ranks, donations etc. of members, levelups.
Wars
- All events regarding anything in the API that can change.
- E.g. new war attack, war state change
- You must register the funtions events will call with
EventsClient.add_events()
- You must ‘subscribe’ any clans, players or (clans in) wars you want to get with
EventsClient.add_clan_updates()
,EventsClient.add_player_update()
,EventsClient.add_war_update()
. - This can be a script that you run and will continue to run forever, calling your functions as events come through,
it doesn’t have to be integrated into a bot. To ease this use-case,
EventsClient.run_forever()
is handy.
Other Importants¶
- Cache has had another overhaul about how it works, is called and default operational use.
- From above,
default_cache
is a kwarg, and method ofClient
. It defaults to the inbuilt method, however you can pass your own function into this. - Logging in: the new recommended way of logging in is via
client = coc.login(email, pass, **kwargs)
withclient
being one of these kwargs: pass in eitherEventsClient
orClient
to use respective clients. This makes both Client class creation and HTTP logging in easy through one function. Any additional kwargs passed will become kwargs for the client you are using. CurrentWar
has been renamed, revamped and relooked at. A regular clan-war is now aClanWar
, withWarIterator
being renamed toClanWarIterator
.LeagueWarIterator
andCurrentWarIterator
now exist, Current wars being a mix of either clan or league wars.Client.get_clan_war()
now retrieves the currentClanWar
Client.get_current_war()
now attempts to retrieve the currentClanWar
, and if in thenotInWar
state, will attempt to search for a leauge war and return that, if found. This makes getting league wars and clan wars from the API much easier than before.ClanWar.type
andLeagueWar.type
now return a string of eithercwl, friendly, random
- which war type it is.Timestamp.time
has been renamed toTimestamp.raw_time
, and replaced withTimestamp.utc_timestamp
(now calledTimestamp.time
)- Add
ClanWar.status
returns a stringwinning, losing, tied, won, lost, tie
depending on stars + destruction.
BugFixes¶
- Lots of little ones with cache
- Performance upgrades with use of
__slots__
on more classes - Trying to iterate over used up iterators
- Only log requests throttled as debug
- Trying to pop a cache item failed
- Few little regex and other bugs in cache.
v0.1.3¶
BugFixes¶
- TypeError will no longer be raised if no tags were found
- Iterators will continue to search for next item if one fails
Important¶
New Properties/Attributes
WarMember.is_opponent
indicates if the member is a clanmate (false) or opponent (true)SearchPlayer.ordered_home_troops
,SearchPlayer.ordered_builder_troops
- returns ancollections.OrderedDict
of players troops, in the order found in game. Note: Siege Machines are included at the end of this.SearchPlayer.ordered_spells
- same, but for spellsSearchPlayer.ordered_heroes
- same, but for heroes.BaseWar.clan_tag
- all wars now have a permenant clan_tag attribute regardless of war state.cache.fully_populated
- helper bool to indicate if all possible items are cached, for eg. with locations and leagues - static information
New Methods:
client.get_league_named()
- get a league (ie. Bronze III etc.) by name.client.get_location_named()
- get a location (ie. Australia etc.) by name.cache.clear()
- reset the cache and clear all objects inside for that instance.cache.get_all_values()
- returns all values in the cache.cache.get_limit(limit)()
- get the first limit number of items in cache.
New Iterators:
PlayerIterator
,ClanIterator
,WarIterator
- returned when a function eg.client.get_players(tags)()
is called. These allow normal dot notion to be used inside async for, eg. async for clan in client.get_clans(tags): print(clan.name).Iterator.flatten()
will return a list of all objects inside the iterator. Note: operation may be slow.
Changed Attribute:
SearchPlayer.troops_dict
has been changed to bothSearchPlayer.home_troops_dict
andSearchPlayer.builder_troops_dict
, returning a dict of either home, or builder troops respectively.SearchPlayer.ordered_troops_dict
has been changed to bothSearchPlayer.ordered_home_troops_dict
andSearchPlayer.ordered_builder_troops_dict
, returning a dict of either home, or builder troops respectively.
Removed Dependency:
- lru-dict has been removed as a dependency due to a few windows problems while installing, and utilising
collections.OrderedDict
appears to be faster.
Documentation¶
- Many type-hints were added to functions to aid IDE integration
- Documentation was re-written to use the NumPy style.
- Discord Bot examples were updated
v0.1.2¶
BugFixes¶
- Fixed 2 problems which meant automatic token resets weren’t working. Please report any more bugs!
v0.1.1¶
BugFixes¶
- Stop nested asyncio loops from failing.
Important¶
New methods
Client.get_clans(tags)()
returns an AsyncIterator of clans.Client.get_current_wars(tags)()
returns an AsyncIterator of current warsClient.get_players(tags)()
returns an AsyncIterator of playersSearchClan.get_detailed_members()
returns an AsyncIterator ofSearchPlayer
for clans membersClient.set_cache(*cache_names, max_size, expiry)()
enables you to override the default cache settings on a per-cache basis. Expiry is in seconds.
Removed parameters
json=False
on all calls has been removed. UseDataClass._data
to get the dict as returned by the API if you so desire
Implemented ratelimits
throttle_limit
has been added as a parameter toClient
. This is the number of calls per token, per second, to be made
asyncio.Semaphore lock has been implemented
New cache structure and implementation.
- Max size and expiry (in seconds) can be set with
Client.set_cache()
- New instances of cache on a per-object (returned) basis, so different methods will implement different instances of the cache.
lru-dict
has been added as a requirement.- LRU is very fast and memory efficient, written in C.
- Max size and expiry (in seconds) can be set with
Enum for
CacheType
has been implemented. This is the preferred way to pass incache_names
toClient.set_cache()
as string names may change.- Can be called with
Client.set_cache(CacheType.search_clans, max_size=128, expiry=10)()
- Can be called with
New Exception:
InvalidCredentials
- This essentially replaces the (now redundant)
InvalidToken
exception, and is called when the email/pass pair passed is incorrect.
- This essentially replaces the (now redundant)
New util function:
coc.utils.clean_tag(tag, prefix='#')()
will return a ‘cleaned up’ version of the tag. It will:- Make all letters UPPERCASE
- Replace o (‘oh’) with 0 (zero)s
- Remove non-alphanumeric and whitespace
v0.1.0¶
BugFixes¶
- Fixed bug with loops breaking when reloading the client in a discord cog.
- A more specific error,
aiohttp.ContentTypeError
is raised when parsing non-json responses.
Important¶
Big thanks to Jab for some of these.
Big one! Client now only accepts an email/password pair rather than tokens. This pair is what you use to login to https://developer.clashofclans.com/#/login and will allow the client to automatically use, create, reset and find tokens, making it a much more streamlined process.
As such, the following parameters to client have been added:
key_count
: int: the number of tokens to rotate between when making API requests. This defaults to 1, and can be between 1 and 10key_names
: str: The name to use when creating tokens on the developer page. This defaults to Created with coc.py Client
Email and Password are now mandatory parameters and must be passed
update_tokens parameter has been removed. The client will automatically reset bad tokens.
In order to keep consistency with the official API docs, token has been renamed to key. This affects the following method/parameters:
on_token_reset(new_token)
–>on_key_reset(new_key)
HTTPClient.login()
–>HTTPClient.get_keys()
and otherwise consistent use of key during internals, docs, code and examples.
pytz and python-dateutil have both been removed as dependencies due to the ability to parse timestamps manually. This has been added to utils as a function:
from_timestamp(ts)
, returning a utc-datetime object.Dataclasses have received a makeover! Many new attributes are present, these are listed below. Most importantly, any property beginning with an underscore (_) use and return iterator objects. These are not lists, and relevant python documentation is here: https://docs.python.org/3/glossary.html#term-iterator.
These are up to 12x faster than lists, and as such for those who are concerned about speed, performance and memory should use these, while for the majority, calling the regular property should be fine (usually returning a list rather than iter).
SearchClan._members
WarClan._members
WarClan._attacks
WarClan._defenses
WarMember._attacks
WarMember._defenses
SearchPlayer._achievements
CurrentWar._attacks
CurrentWar._members
LeagueClan._members
LeagueGroup._clans
The following new attributes were added:
SearchClan.member_dict
WarClan.member_dict
WarClan.attacks
WarClan.defenses
WarMember.attacks
WarMember.defenses
SearchPlayer.achievements_dict
SearchPlayer.troops_dict
SearchPlayer.heroes_dict
SearchPlayer.spells_dict
Timestamp.time
The folowwing new methods were added:
- SearchClan.get_member(tag)
- CurrentWar.get_member(tag)
New utility functions:
- utils.get(iterable, **attrs)
- Searches the iterable until a value with the given attribute is found.
Unlike
filter()
, this will return when the first value is found.
- Searches the iterable until a value with the given attribute is found.
Unlike
- utils.find(function, iterable)
- Searches through the iterable until a value which satisfies the function is found.
- from_timestamp(ts)
- Parses an ISO8601 timestamp as returned by the COC API into a datetime object
Documentation:¶
- Many docstrings were reformatted or worded, with punctuation and other typo’s fixed
- All new properties, attributes and methods have been documented.
- Update some examples, including a clan_info function in discord bots (Thanks, Tuba).
v0.0.5¶
BugFixes¶
- Fixed how the lib detects an invalid IP error, as SC changed how the error message works
- Fixed bug with semi-complete URL when using the API dev site
email
andpassword
inClient
are nowNone
by default. This was throwing and error before.- str() for
Achievement
,Hero
,Troop
,Spell
now all return respective names
Important¶
- Added a new exception:
Forbidden
. This is thrown when a 403 is returned, but the error is not one of invalid token, instead when you aren’t allowed to get the resource eg. private war log. - A
RuntimeError
will be raised if you try to passupdate_stats
asTrue
but don’t set theemail
orpassword
- Added the
Client.on_token_reset()
which is called whenever the lib updates your token. By default this does nothing, however you can override it by either subclassing or using the decorator@Client.event()
above your newasync def on_token_reset
. This function can be a regular or coroutine.
Documentation¶
- Add examples. I will expand on these as I see fit. Feel free to let me know if you want more.
- Fix broken codeblock examples
- Update incorrect function name in the example in README.rst (
player_name
–>get_some_player
v0.0.4¶
BugFixes¶
- Fix some problems comparing naive and aware timestamps in
Timestamp
- Add a private
_data
attribute to all data classes. This is the json as the API returns it. It makesjson=True
parameters in requests easy to handle. - Only cache complete clan results - ie.
Client.search_clans
only returned aBasicClan
, so in order to add some cache consistency, cached clans now only containSearchClan
.
Important¶
- New Class -
LeagueWarLogEntry
is similar toWarLog
, however it has it’s own set of attributes to ensure it is easier to use and know which ones are present and not. - This new class is utilised in
Client.get_warlog
, which returns alist
of bothLeagueWarLogEntry
andWarLog
, depending on the war.
Documentation¶
- Utilise sphinx_rtd_theme for the RTD page
- Add this changelog
- Continue to fix typos and little errors as they are found.
v0.0.2¶
BugFixes¶
- Fix some attributes from inherited classes not being present
- Fix some
AttributeError
from being thrown due to incomplete data from API - When a clan is not in war,
WarClan
will not be present. Some errors were being thrown due to incomplete data being given from API - Allow for text-only responses from API (ie. not json)
Important Changes¶
- Actually specify that the package coc needs to be installed when installing with pip
- Fix incorrect spelling of both
Achievement
andInvalidArgument
- Update the examples in the README to work (search_players is not a thing)
v0.0.1¶
Initial Commit!