mathsman5133 / coc.py Goto Github PK
View Code? Open in Web Editor NEWPython API Wrapper for Clash of Clans.
Home Page: https://cocpy.readthedocs.io/en/latest/
License: MIT License
Python API Wrapper for Clash of Clans.
Home Page: https://cocpy.readthedocs.io/en/latest/
License: MIT License
While installing the coc.py with py -3 -m pip install -U coc.py
i got following issue:
ERROR: Complete output from command 'C:\Users\******\AppData\Local\Programs\Python\Python37-32\python.exe' -u -c 'import setuptools, tokenize;__file__='"'"'C:\\Users\\*******\\AppData\\Local\\Temp\\pip-install-6yl2cf14\\lru-dict\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\********\AppData\Local\Temp\pip-record-8gehi4fb\install-record.txt' --single-version-externally-managed --compile: ERROR: running install running build running build_ext building 'lru' extension error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": https://visualstudio.microsoft.com/downloads/
but Microsoft Visual C++ 14.0 is installed
Please check iterators.py I think WarIterator has an error (says get_player, but should probably be something different)
Currently it won't allow async iterators, which is a bit of a pain because many database and other connections provide data inside these.
Ideal solution: be able to pass an async iterator straight into method parameter
For example, if you try to get a clan with a tag that doesn't exist, it raises coc.NotFound
. The documentation should reflect that.
I'm getting this everytime on linux (debian 9)
aiohttp.client_exceptions.ClientOSError: [Errno 104] Connection reset by peer
Unclosed client session
File "/root/LootPvp/env/lib/python3.7/site-packages/aiohttp/client.py", line 497, in _request
await resp.start(conn)
File "/root/LootPvp/env/lib/python3.7/site-packages/aiohttp/client_reqrep.py", line 844, in start
message, payload = await self._protocol.read() # type: ignore # noqa
File "/root/LootPvp/env/lib/python3.7/site-packages/aiohttp/streams.py", line 588, in read
await self._waiter
File "/usr/local/lib/python3.7/asyncio/futures.py", line 260, in __await__
yield self # This tells Task to wait for completion.
File "/usr/local/lib/python3.7/asyncio/tasks.py", line 292, in __wakeup
future.result()
File "/usr/local/lib/python3.7/asyncio/futures.py", line 178, in result
raise self._exception
aiohttp.client_exceptions.ClientOSError: [Errno 104] Connection reset by peer
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fd9cd8b9470>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7fd9cd77ae88>, 2247353.651511028)]']
connector: <aiohttp.connector.TCPConnector object at 0x7fd9cd8b94a8>
Hi, I tried to login the client with the following code:
import sys
sys.path.append("./coc.py")
import coc
import logging
logging.basicConfig(level=logging.DEBUG)
client = coc.login('[email protected]', 'pass.')
print(client)
And the login never succeeds, log is shown here:
DEBUG:asyncio:Using selector: KqueueSelector
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 936, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore # noqa
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 820, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 846, in _create_connection_transport
yield from waiter
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/sslproto.py", line 505, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "main.py", line 9, in <module>
client = coc.login('email', 'pass')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/coc/login.py", line 54, in login
instance.loop.run_until_complete(instance.login(email, password))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
return future.result()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/coc/client.py", line 167, in login
await self.http.get_keys()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/coc/http.py", line 149, in get_keys
response_dict, session = await self.login_to_site(self.email, self.password)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/coc/http.py", line 378, in login_to_site
"https://developer.clashofclans.com/api/login", json=login_data, headers=headers,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/client.py", line 1012, in __aenter__
self._resp = await self._coro
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/client.py", line 483, in _request
timeout=real_timeout
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 523, in connect
proto = await self._create_connection(req, traces, timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 859, in _create_connection
req, traces, timeout)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 1004, in _create_direct_connection
raise last_exc
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 986, in _create_direct_connection
req=req, client_error=client_error)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/aiohttp/connector.py", line 941, in _wrap_create_connection
raise ClientConnectorSSLError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host developer.clashofclans.com:443 ssl:default [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)]
ERROR:asyncio:Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fc13122f240>
Any idea what the reason is? Thanks so much!
War log entries made before a certain point in February 2015 have a teamSize
of null
in the API. When coc.py tries to calculate max_stars for each clan in the log entry, this null teamSize
causes the calculation to fail and throw a TypeError.
You can test this by calling Client.get_warlog() with the clan #Y0URUJ9G
.
This should be called automatically to cleanup the loops and close the HTTP client, rather than the user having to manually .close()
.
This also needs a check to make sure it is not incompatible or causes strange errors with other libraries, especially discord.py which has it's own sigterm callbacks.
Still on the old version. It is missing 3 super troops in the coc.enums.SUPER_TROOP_ORDER which causes the ordered_home_troops() to break. Fix is just to add the three troops to the list. Proof of Concept below:
new_troops = ["Super Archer","Inferno Dragon","Super Valkyrie","Super Witch"]
coc.enums.SUPER_TROOP_ORDER.extend(new_troops)
coc.enums.HOME_TROOP_ORDER = coc.enums.ELIXIR_TROOP_ORDER + coc.enums.SUPER_TROOP_ORDER + coc.enums.DARK_ELIXIR_TROOP_ORDER + coc.enums.SIEGE_MACHINE_ORDER
key_order = {k: v for v, k in enumerate(coc.enums.HOME_TROOP_ORDER)}
OrderedDict(sorted(player.home_troops_dict.items(), key=lambda i: key_order.get(i[0])))
When I try to import from coc import wars
then I get the following error:
$ pyhon3
>>> from coc import wars
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/python3.7/site-packages/coc/wars.py", line 30, in <module>
from .iterators import LeagueWarIterator
File "/path/to/python3.7/site-packages/coc/iterators.py", line 31, in <module>
from .utils import item
ModuleNotFoundError: No module named 'coc.utils'
$ pip3 show coc.py
Name: coc.py
Version: 0.3.4
Summary: A python wrapper for the Clash of Clans API
Home-page: https://github.com/mathsman5133/coc.py
Author: mathsman5133
Author-email: None
License: MIT
Location: /path/to/python3.7/site-packages
Requires: aiohttp
Required-by:
Can someone help me with that?
This has been a little dead lately, but is a nice simple API wrapper for Mike's API.
This should take a tag (clan, player, war etc) and apply the following modifications to it:
I'm anticipating this to be a large use-case, so a short, simple guide with a few neat examples would be nice.
According to the latest changes on the API the attack duration for WarAttack has now the attribute duration
, so the average attack duration is also an accessible property of the clan. Would be nice to add it to the WarClan
object.
If I have time to code it, I will open a pull request.
Thanks for your work
Have a nice day
The current examples are quite simply, shocking. They sometimes work and often don't. We need a new set of examples, listing some of the common use cases, that have been tested to work, are clean, well set-out and easy to understand.
get_max_level_for_townhall()
Examples:
Max level for Yeti in Th14 is 3
but the max level is actually 4
Max level for Hog Rider in th14 is 10
but the max level is actually 11
I'm happy to adapt, change, simplify, make better the current guide, but a few more (new) examples will be nice, too: https://cocpy.readthedocs.io/en/latest/events.html
When I find other things, I'll come back and edit this.
client.py - line 555 - should just be ClanWar.is_cwl
players.py - line 47 - no Attributes listed in docstring
players.py - line 11, 113, 115, 155, 157, 159, 161, 163, 165, 167 - you used int instead of :class:int
clans.py - line 118 - class WarLeague is not clickable. Should it be coc.WarLeague?
clans.py - line 218 - extra colon that Sphinx doesn't like
wars.py - line 193, 228, 383 - extra colon that Sphinx doesn't like
wars.py - line 345 - something funny going on here with Sphinx
war_members.py - line 118 - you used int instead of :class:int
Recommendation for migration documentation:
When you place an example, include the attributes in the function definition
@coc.PlayerEvents.trophies() # an event that is run for every player, when their `.trophies` attribute changes.
async def foo(old_trophies, new_trophies): ...
@client.event
@coc.WarEvents.state() # an event that is run when a war `.state` has changed
async def foo(old_state, new_state): ...```
While I know you talk about callback arguments, I think it will be easier for users to see these in the examples. (In this case, I'm looking specifically at the examples in the Decorators section.
I don't if I don't know how to catch it, but it does not work with except coc.errors.PrivateWarLog:
File "/root/LootPvp/env/lib/python3.7/site-packages/pyrogram/client/ext/dispatcher.py", line 183, in update_worker
await handler.callback(self.client, *args)
File "/root/CoC/plugin/clan.py", line 100, in boh
leagueGroup = await client.get_league_group("#GPVP29UQ")
File "/root/LootPvp/env/lib/python3.7/site-packages/coc/client.py", line 768, in get_league_group
r = await self.http.get_clan_war_league_group(clan_tag)
File "/root/LootPvp/env/lib/python3.7/site-packages/coc/http.py", line 211, in request
raise NotFound(r, data)
coc.errors.NotFound: Not Found (status code: 404)
Some attributes such as clan_rank
and previous_clan_rank
are only present in a ClanMember object/endpoint which should be doubled in the Player object if the user uses clan.get_detailed_members
to get the data.
possible code
def get_best_opponent_attack(self, defender_tag: str) -> typing.Optional["WarAttack"]:
"""Return the best opponent :class:`WarAttack` for the tag provided.
If no attacks are found, this will return ``None``.
Returns
--------
Optional[:class:`WarAttack`]: The best opponent attack for the tag provided.
"""
defender = self.get_member(defender_tag)
if not defender:
return None
return defender.best_opponent_attack
Currently, I'm looping through all members to get to the one I want, then doing member.best_opponent_attack
. It would be nice to leverage the dict to provide a tag and go directly to that member.
Is it possible to search a clan for the clan name as it's on the API but looking through the documentation I can't find it, if it isn't possible, is there anyway to get the auth key currently being used, something like coc.token
so you can create custom requests easily?
'NoneType' object has no attribute 'time'
Traceback (most recent call last):
File "/root/LootPvp/env/lib/python3.7/site-packages/pyrogram/client/ext/dispatcher.py", line 183, in update_worker
await handler.callback(self.client, *args)
File "/root/CoC/plugin/clan.py", line 52, in clan
tipo = trad[clanWar.type]
File "/root/LootPvp/env/lib/python3.7/site-packages/coc/wars.py", line 157, in type
if (self.start_time.time - self.preparation_start_time.time).seconds == 82800: # 23hr prep
AttributeError: 'NoneType' object has no attribute 'time'
@
Hi there!
I've installed the library. But I've got a problem with this code:
import coc
coc.login(email, password, key_names, key_count)
The issue is:
Exception ignored in: <function ClientSession.del at 0x02845810>
Traceback (most recent call last):
File "D:\py371\lib\site-packages\aiohttp-4.0.0a1-py3.7-win32.egg\aiohttp\clien
t.py", line 269, in del
File "D:\py371\lib\site-packages\aiohttp-4.0.0a1-py3.7-win32.egg\aiohttp\clien
t.py", line 894, in closed
AttributeError: _connector
Traceback (most recent call last):
File "", line 1, in
File "D:\py371\lib\site-packages\coc\login.py", line 54, in login
instance.loop.run_until_complete(instance.login(email, password))
File "D:\py371\lib\asyncio\base_events.py", line 573, in run_until_complete
return future.result()
File "D:\py371\lib\site-packages\coc\client.py", line 191, in login
cache_max_size=self.cache_max_size,
File "D:\py371\lib\site-packages\coc\http.py", line 206, in init
loop=self.loop, connector=connector, timeout=aiohttp.ClientTimeout(total=tim
eout)
TypeError: init() got an unexpected keyword argument 'loop'
I think the problem with aiohttp, I'd deleted 4.0.0a1v and installed stable 3.7.2v, but the error is still raising. What version of aiohttp should I use?
Edited: my OS is windows
I am trying to use coc.py in a flask v2 application. Upon doing client.login(...)
I get the following error:
DEBUG:coc.http:https://developer.clashofclans.com/api/apikey/list has received {'error': 'general', 'description': 'Temporary application error, request failed.'}
But I see another worker that worked. My guess is that API is rejecting because workers at the same time are trying to access the API in a short amount of time.
How do I get around this? Is there a better way to initialize client in flask?
Is it possible to set keys manually? client.keys
seems to be private.
When maintenance hits, we often waste a huge amount of resources continuing to query the API thousands of times a minute when we know that they're all going to return a maintenance error. The library should be able to detect when a maintenance error is first hit, block any current or future requests from being processed, fire an on_maintenance
event and then start a loop which queries the API once every 30 seconds and once it gets through, it should fire an event on_maintenance_complete
and once again allow the regular request traffic to flow.
I imported the module just the way OP asked me to. But while running one of the example scripts, I get this error. Can someone please assist me?
I wanted to make use of your API wrapper, but instead of the flat functions and decorator setup you have in your examples, I wanted to have mine setup as a class inheriting from EventsClient.
However it doesn't seem very happy, and from within the coc.py library I'm getting lots of
TypeError: reset_event_cache() missing 1 required positional argument: 'cache_name'
and other 'missing 1 required positional argument' type errors.
Here's a simple version of my code that demonstrates the issue
`
import asyncio
from coc import EventsClient
class ClashConnection(EventsClient):
def __init__(self, username, password, clan_tag):
super().__init__()
self.username = username
self._password = password
self.clan_tag = clan_tag
self.function_mappings = {
'on_clan_update': self.clan_updated,
}
async def start(self):
await self.login(self.username, self._password)
self.add_clan_update(self.clan_tag, retry_interval=30) # <-- this bit is the first place it falls over
self.add_events(function_dicts=self.function_mappings)
self.start_updates()
@staticmethod
async def clan_updated():
print('clan was updated')
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('username')
parser.add_argument('password')
parser.add_argument('clan_tag')
args = parser.parse_args()
cc = ClashConnection(args.username, args.password, args.clan_tag)
loop = asyncio.get_event_loop()
loop.run_until_complete(cc.start())
`
Is this something that you don't support, or am I just missing something obvious?
Type hints make working with a package in an IDE such as PyCharm a lot more intuitive and, well, just easier.
This is a good first issue and a PR should prevent circular imports, and ensure that all type hints match what is actually returned, and update the documentation or flag it if it is wrong ๐
I am using the example on this page, which mostly works other than the errors it spits out at the end. See below:
...
League War Season - No opponent info available
League War Season - No opponent info available
League War Season - No opponent info available
League War Season - No opponent info available
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001C73B34A1F0>
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001C73B34A1F0>
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001C73B34A1F0>
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 116, in __del__
self.close()
File "C:\Program Files\Python38\lib\asyncio\proactor_events.py", line 108, in close
self._loop.call_soon(self._call_connection_lost, None)
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 719, in call_soon
self._check_closed()
File "C:\Program Files\Python38\lib\asyncio\base_events.py", line 508, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
The only part of the script that has been modified is the username, password, and clan search string. What does that error mean and why is it happening? I've tried other examples as well and had similar issues.
Honestly, this python library seems to be overly complex. I don't understand why there are so many asynchronous functions either. I appreciate that it exists, but it's difficult to use.
Error:- I tried giving army link without troops and spell one by one it errored out , if i give both it works normally
Steps to reproduce error
code:
@bot.command()
async def parse_army(ctx,army_link:str):
troops, spells = coc_client.parse_army_link(army_link)
print(troops,spells)
parsed_link_output = ''
if troops or spells: #checking if troops or spells is present in link
for troop, quantity in troops:
parsed_link_output += "The user wants {} {}s. They each have {} DPS.\n".format(quantity, troop.name, troop.dps)
for spell, quantity in spells:
parsed_link_output += "The user wants {} {}s.\n".format(quantity, spell.name)
else:
parsed_link_output += "Invalid Link!"
await ctx.send(parsed_link_output)
link used :
- without spell -> https://link.clashofclans.com/en?action=CopyArmy&army=s5x2
- without troops -> https://link.clashofclans.com/en?action=CopyArmy&army=u10x0-2x3
Output:
[] []
[] []
Trying to register a account but page said check your mail and their is no mail regarding clash of clans in any folder. tried with different mail also.
The list ACHIEVEMENT_ORDER = [] contains "Keep your village safe" twice
Line 1822 in client.py has this line:
if player.previous_clan_rank != cached_player.previous_clan_rank:
According to the docs the attribute is called player.clan_previous_rank
The rewrite brings the ability to pass your own cls
into most calls. We should have tests to make sure doing this actually works!
Examples are king! They're super helpful and should be mostly short, easy code snippets to write.
They should be under the "Examples" section of the doc-string.
When asking for member.best_opponent_attack
, if there were no attacks on the specified base, you get a TypeError because the function on line 90 of war_members.py (get_attack) expects two arguments (attacker_tag, defender_tag) but only gets one. In this case, the function should either return None
indicating that there were no attacks on that base.
Test case (probably only good for 2 more hours since a new war will start):
Clan: #CVCJR89
Player: SMELLY COW (#GGJV88GG)
File "C:\Users\Patrick\AppData\Local\Programs\Python\Python36\lib\site-packages\coc\war_members.py", line 90, in best_opponent_attack
return self.war.get_attack((self._best_opponent_attacker, self.tag))
2020-07-14 16:38:21.331 | ERROR | __main__:on_command_error:125 - TypeError: get_attack() missing 1 required positional argument: 'defender_tag'
It will be nice to have template for issues and pr, so people can submit pr and issue in correct manner
print(f"{member.name} townhall{member.town_hall} has joined {clan.name}")
AttributeError: 'ClanMember' object has no attribute 'town_hall'
i am using member_join event and it takes clan
and ClanMember
as param and i wnt to show town_hall also when member join how can i access that, as clanMember dont have this attribute
As title explains, Super Dragon is_super_troop returns False rather than returning True.
It is also included in home_troops, which I am assuming is due to the prior fact.
As edge-cases and weird bugs come up in the library, I'd like to be more diligent in making sure that tests are properly written to ensure these don't crop up again in the future!
A good starting point would be to trawl back through the #coc-py-help channel in the API server to find common issues or weird edge-cases.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.