| This page is part of theMediaWiki Action API documentation. |
| MediaWiki Action API |
|---|
| Basics |
| Authentication |
| Accounts and Users |
| Page Operations |
|
| Search |
| Developer Utilities |
| Tutorials |
| v · d · e |
In this tutorial, you will get a demo of an article ideas generator app that suggests articles from various categories that don't yet exist on English Wikipedia.
This tutorial will teach you how to do this using:
A step-by-step process of building this application:
To set up the Python development environment for a Flask application, you will need to install Python, create a virtual environment, and install Flask and Requests.
Learn more about the differences between Python2 and Python3 here. To install Python3 on your local machine, follow step-by-step instructions in theseinstallation guides.
Here is how to set up the development environment for building the application:
$mkdirarticle-ideas-generator$cdarticle-ideas-generator/This will create a new directory and change into it$python3--version#Python 3.6.5This command checks your Python version$python3-mvenvvenvThis command will create a virtual environment named 'venv'$sourcevenv/bin/activateThis will activate the virtual environment$pipinstallFlaskrequestsThis command will install the Flask and Requests packages with all their dependencies |
Place the following code in$HOME/article-ideas-generator/articles.py
#!/usr/bin/python3""" articles.py1 MediaWiki Action API Code Samples Article ideas generator app: suggests articles from various categories that don't yet exist on English Wikipedia. The app uses action=parse module and prop=links module as a generator. MIT license"""fromflaskimportFlask,request,render_templateimportrequestsAPP=Flask(__name__)@APP.route('/')defindex():""" Displays the index page accessible at '/' """returnrender_template('articles.html')if__name__=='__main__':APP.run() |
Drop this one line of code<h1>Article ideas generator</h1> in a HTML file inside thetemplates folder:$article-ideas-generator/templates/articles.html
render_template method which renders the template namedarticles.html from thetemplates directory.Next run your Flask app with the commandpython articles.py and openhttp://127.0.0.1:5000/ to view your app in the browser.You should be able to see "Article ideas generator" in your browser window.
Let's do some app styling.To do so, add link tags to load an external and internal stylesheet.External stylesheet, in this case, is the URL of a CSS file for the fontAmatic.
Replace the existing code in$article-ideas-generator/templates/articles.html with the following:
<linkrel="stylesheet"href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700"><linkrel="stylesheet"href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans"><linkrel="stylesheet"href="/static/style.css"><h1>Article ideas generator</h1><p>Some ideas for topics to write articles on:</p>
Place the following code in$HOME/article-ideas-generator/static/style.css
h1{color:black;font-family:'Amatic SC',cursive;font-size:4.5em;font-weight:normal;}p{font-family:'Josefin Sans',sans-serif;font-size:1.4em;} |
$HOME/article-ideas-generator├── templates/│ └── articles.html├── static/│ └── style.css├── articles.py└── venv/
Let's write some code in aget_page_sections() function in$HOME/article-ideas-generator/articles.py to fetch page sections fromWikipedia:Requested articles.This function takes page name as an argument and makes aGET request to the Action API to parse sections of the page.API call consists of an endpointhttps://en.wikipedia.org/w/api.php and query string parameters.Some of the key parameters are:
action=parse - module to parse content on a pagepage=page - page title to parseprop=sections - tells which piece of information to retrieve, in this example it is sectionsdefget_page_sections(page):""" Get page sections """params={"action":"parse","page":page,"prop":"sections","format":"json"}res=SESSION.get(url=API_ENDPOINT,params=params)data=res.json()if'error'indata:returnparsed_sections=dataanddata['parse']anddata['parse']['sections']sections=[]forsectioninparsed_sections:ifsection['toclevel']==1:sections.append(section['line'])returnsections
Next, extend the Python Flask route/ in$HOME/article-ideas-generator/articles.py to call the function defined above and also pass the results returned by the function torender_template.
APP=Flask(__name__)SESSION=requests.Session()API_ENDPOINT='https://en.wikipedia.org/w/api.php'PAGE={}@APP.route('/')defindex():""" Displays the index page accessible at '/' """globalPAGEresults=[]PAGE={'name':'Wikipedia:Requested_articles','type':'category'}results=get_page_sections(PAGE['name'])returnrender_template("articles.html",results=results,pagetype=PAGE['type'])
Place the followingJinja template code in$HOME/article-ideas-generator/templates/articles.html.It dynamically renders an array of category buttons based on page sections obtained via the API above.
{%ifresults%}<p>Choose a{{pagetype}}</p><formmethod="POST">{%forpagenameinresults%}<buttonname="{{pagetype}}"class="{{pagetype}}"value="{{pagename}}">{{pagename}}</button>{%endfor%}{%else%}<p>Ooooops! We couldn't find any results.</p><buttononclick="location.href='/'">Start over</button></form>{%endif%}
Place the following code in$HOME/article-ideas-generator/static/style.css for button styling.
Based on a category or section selected by the user in the previous step, we want to fetch subsections fromWikipedia:Requested articles.Extend the Python Flask route/ in$HOME/article-ideas-generator/articles.py to handle POST requests.You can do so by adding bothGET andPOST in themethods argument list in the route decorator.You can then obtain category selection available in adictionary format from therequest object, which is passed toget_page_sections() function for further processing.
Let's write some code in aget_red_links() function in$HOME/article-ideas-generator/articles.py to fetch around 20 articles with missing links on a page.This function takes page name as an argument, makes aGET request to the Action API, and returns all links embedded on that page.From further extraction, you can obtain those links that are missing and don't yet exist on English Wikipedia.The API call consists of an endpointhttps://en.wikipedia.org/w/api.php and query string parameters.Some of the key parameters are:
action=query - module to query informationtitles=title - page title to collect linksgenerator=links - query module's submodulelinks used as agenerator module to get a set of links embedded on a pagegpllimit=20 - number of links to fetchdefget_red_links(title):""" Get missing links on a page """params={"action":"query","titles":title,"generator":"links","gpllimit":20,"format":"json"}res=SESSION.get(url=API_ENDPOINT,params=params)data=res.json()pages=dataanddata['query']anddata['query']['pages']links=[]forpageinpages.values():if'missing'inpage:links.append(page['title'])returnlinks
Next, extend theif block for thePOST method in the/ route in$HOME/article-ideas-generator/articles.py to call theget_red_links() function if the page from which the request is issued is of typesubcategory.
ifrequest.method=='POST':if'category'inrequest.form:PAGE['name']=PAGE['name']+'/'+request.form.to_dict()['category']PAGE['type']='subcategory'results=get_page_sections(PAGE['name'])elif'subcategory'inrequest.form:PAGE['name']=PAGE['name']+'#'+request.form.to_dict()['subcategory']PAGE['type']='links'results=get_red_links(PAGE['name'])
Place the followingJinja template code in$HOME/article-ideas-generator/templates/articles.html.It dynamically renders a list of links using data obtained via the API above.
View the complete Python, CSS, and HTML code.
| $HOME/article-ideas-generator/articles.py |
|---|
#!/usr/bin/python3""" articles.py MediaWiki Action API Code Samples Article ideas generator app: suggests articles from various categories that don't yet exist on English Wikipedia. The app uses action=parse module and prop=links module as a generator. MIT license"""fromflaskimportFlask,request,render_templateimportrequestsAPP=Flask(__name__)SESSION=requests.Session()API_ENDPOINT='https://en.wikipedia.org/w/api.php'PAGE={}@APP.route('/',methods=['GET','POST'])defindex():""" Displays the index page accessible at '/' """globalPAGEresults=[]ifrequest.method=='POST':if'category'inrequest.form:PAGE['name']=PAGE['name']+'/'+ \request.form.to_dict()['category']PAGE['type']='subcategory'results=get_page_sections(PAGE['name'])elif'subcategory'inrequest.form:PAGE['name']=PAGE['name']+'#'+ \request.form.to_dict()['subcategory']PAGE['type']='links'results=get_red_links(PAGE['name'])else:PAGE={'name':'Wikipedia:Requested_articles','type':'category'}results=get_page_sections(PAGE['name'])returnrender_template("articles.html",results=results,pagetype=PAGE['type'])defget_page_sections(page):""" Get page sections """params={"action":"parse","page":page,"prop":"sections","format":"json"}res=SESSION.get(url=API_ENDPOINT,params=params)data=res.json()if'error'indata:returnparsed_sections=dataanddata['parse']anddata['parse']['sections']sections=[]forsectioninparsed_sections:ifsection['toclevel']==1:sections.append(section['line'])returnsectionsdefget_red_links(title):""" Get missing links on a page """params={"action":"query","titles":title,"generator":"links","gpllimit":20,"format":"json"}res=SESSION.get(url=API_ENDPOINT,params=params)data=res.json()pages=dataanddata['query']anddata['query']['pages']links=[]forpageinpages.values():if'missing'inpage:links.append(page['title'])returnlinksif__name__=='__main__':APP.run() |
| $HOME/article-ideas-generator/static/style.css |
|---|
h1{color:black;font-family:'Amatic SC',cursive;font-size:4.5em;font-weight:normal;}div{left:10%;position:absolute;right:10%;text-align:center;top:5%;}p{font-family:'Josefin Sans',sans-serif;font-size:1.4em;}button{background-color:#06b6c9;border:none;border-radius:5px;color:white;font-size:1.2em;margin:5px;padding:20px;}.subcategory{background-color:#EE6352;}a{color:red;font-size:1.2em;line-height:1.4em;} |
| $HOME/article-ideas-generator/templates/articles.html |
|---|
<title>Article ideas generator</title><linkrel="stylesheet"href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700"><linkrel="stylesheet"href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans"><linkrel="stylesheet"href="/static/style.css"><div><h1>Article ideas generator</h1>{%if'links'inpagetype%}<p>Some ideas for topics to write articles on:</p>{%forlinkinresults%}<ahref="//en.wikipedia.org/w/index.php?title={{link}}&action=edit&redlink=1">{{link}}</a><br>{%endfor%}<buttononclick="location.href='/'">Take me to the homepage</button>{%else%}{%ifresults%}<p>Choose a{{pagetype}}</p><formmethod="POST">{%forpagenameinresults%}<buttonname="{{pagetype}}"class="{{pagetype}}"value="{{pagename}}">{{pagename}}</button>{%endfor%}{%else%}<p>Ooooops! We couldn't find any results.</p><buttononclick="location.href='/'">Start over</button></form>{%endif%}{%endif%}</div> |