Skip to content

Instantly share code, notes, and snippets.

@antonpaquin
Created February 13, 2023 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonpaquin/94ff400be72374334956b1af2e3c151f to your computer and use it in GitHub Desktop.
Save antonpaquin/94ff400be72374334956b1af2e3c151f to your computer and use it in GitHub Desktop.
import argparse
import json
import requests
api_key = '********-****-****-****-************'
stake_id = 'PU6qkjczILwnKHfMV2Yy'
def fetch(endpoint, params=None):
r = requests.get(
url=f'https://manifold.markets/api{endpoint}',
params=params,
headers={
'Authorization': f'Key {api_key}'
}
)
r.raise_for_status()
return json.loads(r.content)
def get_market_id(url):
slug = url.split('/')[-1]
resp = fetch(f'/v0/slug/{slug}')
return resp['id']
def get_comments(market_id):
resp = fetch('/v0/comments', {'contractId': market_id})
return resp
def get_comment_text(c):
if 'type' not in c:
return get_comment_text(c['content'])
elif c['type'] in {'doc', 'paragraph'}:
return '\n'.join([get_comment_text(x) for x in c.get('content', [])])
elif c['type'] == 'text':
return c['text']
elif c['type'] == 'hardBreak':
return '\n'
elif c['type'] == 'mention':
return '@' + c['attrs']['id']
else:
return str(c)
def extract_vote(txt):
key = '!vote'
pos = txt.lower().find(key)
if pos == -1:
raise ValueError()
pos += 1 + len(key)
end = pos
while end < len(txt) and txt[end] not in {' ', '\n'}:
end += 1
return txt[pos:end]
def get_votes(policy_id):
policy_comments = sorted(get_comments(policy_id), key=lambda x: x['createdTime'])
votes = {}
for comment in policy_comments:
user = comment['userId']
txt = get_comment_text(comment)
if '!vote' in txt.lower():
vote = extract_vote(txt)
if vote.lower() == 'null':
if user in votes:
votes.pop(user)
else:
votes[user] = vote
return votes
def get_weight(user_id):
resp = fetch(f'/v0/bets', {'contractId': stake_id, 'userId': user_id})
shares = []
for bet in resp:
mul = 1
if bet['outcome'] == 'NO':
mul = -1
if 'fills' in bet:
for fill in bet['fills']:
shares.append(mul * fill['shares'])
else:
shares.append(mul * bet['shares'])
shares.sort(key=abs)
return int(sum(shares))
def get_weights(user_ids):
res = {}
for user_id in user_ids:
w = get_weight(user_id)
if w > 0:
res[user_id] = w
return res
def get_username(user_id):
return fetch(f'/v0/user/by-id/{user_id}')['username']
def agg_weights(votes, weights):
vote_weights = {}
for user_id, vote in votes.items():
if user_id in weights:
if vote not in vote_weights:
vote_weights[vote] = 0
vote_weights[vote] += weights[user_id]
return vote_weights
def rand_dist(vote_weights):
x0 = 0
res = []
for vote, weight in vote_weights.items():
res.append((vote, f'{x0+1}-{x0+weight}'))
x0 += weight
return res
def fmt_resp(votes, weights, names, vote_weights, vote_rand_dist):
res = []
for user_id, vote in votes.items():
if user_id in weights:
name = names[user_id]
weight = weights[user_id]
res.append(f'@{name} voted {vote} (weight {weight})')
res.append('')
res.append('Totals: ')
for vote, weight in vote_weights.items():
res.append(f'{vote}: {weight}')
res.append('')
rand_max = sum(vote_weights.values())
res.append(f'To be chosen from a random draw 1-{rand_max}')
for vote, rand_range in vote_rand_dist:
res.append(f'{rand_range} = {vote}')
return '\n'.join(res)
def main(url):
policy_id = get_market_id(url)
votes = get_votes(policy_id)
user_ids = list(votes.keys())
weights = get_weights(user_ids)
names = {user_id: get_username(user_id) for user_id in user_ids}
vote_weights = agg_weights(votes, weights)
vote_rand_dist = rand_dist(vote_weights)
print(fmt_resp(votes, weights, names, vote_weights, vote_rand_dist))
def cli_args():
parser = argparse.ArgumentParser()
parser.add_argument('url')
return parser.parse_args()
if __name__ == '__main__':
_args = cli_args()
main(_args.url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment