As a practice of Google App Engine / Python, we will create a BOT service that automatically posts the results of the game called League of Legends on Twitter. Twitter authentication uses Tweepy that supports OAuth to make it a service that anyone can register. The game record is obtained from the official RIOT API. The source code is operated at GitBucket, and the finished product is operated at here.
GAE / P application settings are written in the language yaml. app.yaml is a file that describes the settings of the entire application such as AndroidManifest.xml in Android. It also describes URL routing settings like urls.py in Django. Since the version of the application that actually runs on the server can be easily switched, if you increase the version frequently when deploying, you will not have to panic in case of trouble.
app.yaml
application: example_app #Application name
version: 1
runtime: python27 #Python2.Use 7
api_version: 1
threadsafe: true
handlers: #Describe URL routing
- url: /hell
script: hell.app #hell.Call the py variable app
This time, we will implement the application in Python using webapp2.
hell.py
#! -*- coding: utf-8 -*-
import webapp2
class hellHandler(webapp2.RequestHandler): #Handler to which processing is passed
def get(self): #GET method processing
self.response.out.write('Hell World!')
def post(self): #Handling the POST method
self.response.out.write('Postes Hell World!')
app = webapp2.WSGIApplication([ ('/hell', hellHandler) ]) #handlers:Call the handler from the path / variable specified in
Go to `` `http://example_app.appspot.com/hell``` and you should see Hell World.
To use Tweepy on GAE, you need to prepare your own environment. First, download the entire tweepy folder from GitHub and place it in your project folder. Next, since Tweepy uses ssl, add the library to be used in app.yaml. Also, specify the callback address to force HTTPS communication to ensure security.
app.yaml
application: example_app
version: 1
runtime: python27
api_version: 1
threadsafe: true
libraries: #Specify the library to use
- name: ssl
version: latest
handlers:
- url: /
script: main.app
- url: /callback #Callback address
script: main.app
secure: always #Force HTTPS communication
Next, let's implement a test app that lets the user perform OAuth authentication and stores the access token key and access secret token key in the data store (GAE database). The data store has a different design from a typical RDBMS, but it has a Django-like O / R mapper, so it's not too hard to use the model somehow.
main.py
#! -*- coding: utf-8 -*-
from google.appengine.ext import db
import webapp2, tweepy
#Twitter Consumer Key
CONSUMER_KEY = '********************'
CONSUMER_SECRET = '**************************************'
class modelUser(db.Model): #Model definition for storing Twitter account information
twitter_name = db.StringProperty()
access_key = db.StringProperty()
access_secret = db.StringProperty()
date = db.DateTimeProperty(auto_now_add=True)
class mainHandler(webapp2.RequestHandler):
def get(self):
#Output authentication start button
self.response.out.write('<form method="POST" action="./"><button type="submit">Authentication</button></form>')
def post(self):
#Set the consumer key on Tweepy
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
try:
redirect_url = auth.get_authorization_url() #Get URL for OAuth authentication
self.redirect(redirect_url) #Redirect to URL for OAuth authentication
except Exception as e:
self.response.out.write('Ella')
class callbackHandler(webapp2.RequestHandler):
def get(self):
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
try:
#Let Tweepy authenticate various received parameters
auth.set_request_token(self.request.get('oauth_token'), self.request.get('oauth_verifier'))
auth.get_access_token(self.request.get('oauth_verifier'))
access_key = auth.access_token.key
access_secret = auth.access_token.secret
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth) #After that, you can get various information from this object.
modeluser = modelUser().get_or_insert(str(api.me().id)) #Set model key to Twitter internal ID
modeluser.twitter_name = api.me().screen_name #Twitter Id
modeluser.access_key = access_key #Access token key
modeluser.access_secret = access_secret #Access secret token key
modeluser.put() #Reflected in database
self.response.out.write('Completion of registration')
except Exception as e:
self.response.out.write('Ella')
app = webapp2.WSGIApplication([ ('/', mainHandler), ('/callback', callbackHandler) ])
The datastore has an attribute called a key, and it is convenient to set the key using `get_or_insert ('unique value')`
when creating an entry with a unique value. In addition, the key with a unique value is fetched with `key (). name ()`
, and if no key is specified, a random ID is automatically assigned and `` `key (). Get the ID with id () ```.
RIOT API
To use the RIOT API, first log in to the Developers Site (https://developer.riotgames.com/) with your LoL account. The API request limit is specified there as follows (as of 2014/02).
--10 requests / 10 seconds --500 requests / 10 minutes
This means that if your average request interval is less than 1.2 seconds, you run the risk of being subject to request limits. The shortest time for a LoL game is 20 minutes to surrender (although it may be faster), and theoretically 1000 users are the maximum to orbit the BOT without delay. That's enough.
Next, let's actually use / api / lol / {region} /v1.3/summoner/by-name/{summonerNames}
to get the summoner information. You can check the operation by entering the summoner name on the API page on the Developers Site. The data retrieved from the API is returned in JSON format. This time, we will use django's simplejson to parse JSON, so first specify django in the library.
app.yaml
application: example_app
version: 7
runtime: python27
api_version: 1
threadsafe: true
libraries:
- name: django
version: "1.4" #Specify the version you are familiar with
handlers:
- url: /registration
script: main.app
secure: always
Implement a web app in Python that returns a summoner ID when the user enters a summoner name.
main.py
#! -*- coding: utf-8 -*-
from google.appengine.api.urlfetch import fetch
from django.utils.simplejson import loads
import webapp2
from urllib import quote
from time import mktime
from cgi import escape
from datetime import datetime
RIOT_KEY = '***********************************'
def getId(resion, summoner_name): #Summoner ID acquisition function
#Get summoner information from API
result = fetch('https://prod.api.pvp.net/api/lol/'+resion+'/v1.3/summoner/by-name/'+quote(summoner_name)+'?api_key='+RIOT_KEY)
if result.status_code == 200:
#Pass to JSON parser and return ID and name
j = loads(result.content)[summoner_name.lower().replace(' ', '')]
return j['id'], j['name']
else:
return -1, None
class registrationHandler(webapp2.RequestHandler):
def get(self):
#Output acquisition start button
self.response.out.write('<form method="POST" action="./registration"><input type="radio" name="resion" value="1" checked="checked" />NA<input type="radio" name="resion" value="2" />EUW<input type="radio" name="resion" value="3" />EUNE<input type="text" name="summoner_name" /><button type="submit">Get</button></form>')
def post(self):
try:
#Get the entered name and region
summoner_name = escape(self.request.get('summoner_name'))
if escape(self.request.get('resion')) == '1':
resion = 'na'
elif escape(self.request.get('resion')) == '2':
resion = 'euw'
elif escape(self.request.get('resion')) == '3':
resion = 'eune'
#Call the summoner ID acquisition function
summoner_id, summoner_name = getId(resion, summoner_name)
#Output the result
if summoner_id > 0:
self.response.out.write('Summoner ID:'+summoner_id+'Summoner name:'+summoner_name)
else:
self.response.out.write('There is no summoner, but that is')
return
except Exception as e:
self.response.out.write('Ella')
app = webapp2.WSGIApplication([ ('/registration', registrationHandler) ])
It's going to be long, so I'll finish the first part here. In the second part, I would like to touch on how to actually turn the BOT using Queue, Backend, Cron, and Memchache. → Part 2 I wrote it!
Recommended Posts