API:Generador de ideas de artículos
| API de acciones de MediaWiki |
|---|
| Uso básico |
| Autentificación |
| Cuentas y usuarios |
| Operaciones en páginas |
|
| Búsqueda |
| Herramientas de desarrollador |
| Tutoriales |
| v · d · e |
Visión general
En este tutorial, encontrarás una demo de una aplicación generadora de ideas para artículos que sugiere artículos de varias categorías que todavía no existan en la Wikipedia en inglés.
Este tutorial te enseñará cómo realizar esto por medio de:
- Entorno de trabajo de Python y Flask
- MediaWiki Action API's Parse and Links module
Proceso paso a paso para construir esta aplicación:
Paso 1: Configurar el entorno de desarrollo de Python y Flask
Para configurar el entorno de desarrollo de Python para una aplicación de Flask, necesitarás instalar Python, crear un entorno virtual e instalar Flask.
Aprende más sobre las diferencias entre Python2 y Python3 aquí. Para instalar Python3 en tu máquina local, sigue las instrucciones paso a paso en estas guías de instalación.
Aquí se muestra cómo configurar el entorno de desarrollo para construir la aplicación:
$ mkdirarticle-ideas-generator $ cdarticle-ideas-generator/ Esto creará un nuevo directorio y se ubicará en él. $ python3--version#Python 3.6.5 Este comando revisa tu versión de Python $ python3-mvenvvenv Este comando creará un entorno virtual llamado 'venv' $ sourcevenv/bin/activate Esto activará el entorno virtual $ pipinstallFlaskrequests Este comando instalará el paquete de Flask con todas sus dependencias
Paso 2: Crear una aplicación de Flask simple
Mostrar una página estática simple
Coloca el siguiente código en $HOME/article-ideas-generator/articles.py
#!/usr/bin/python3 """ articles.py1 Muestras de código de la API de acciones de MediaWiki Aplicación generadora de ideas para artículos: sugiere artículos de varias categorías que todavía no existan en la Wikipedia en inglés. La aplicación utiliza el módulo action=parse y el módulo prop=links como un generador. Licencia del MIT """ fromflaskimport Flask, request, render_template importrequests APP = Flask(__name__) @APP.route('/') defindex(): """ Muestra la página del índice accesible en '/' """ return render_template('articles.html') if __name__ == '__main__': APP.run()
Drop this one line of code <h1>Article ideas generator</h1> in a HTML file inside the templates folder:
$article-ideas-generator/templates/articles.html
render_template method which renders the template named articles.html from the templates directory.Next run your Flask app with the command python articles.py and open http://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.
Style your app
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 font Amatic.
Replace the existing code in $article-ideas-generator/templates/articles.html with the following:
<link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700"> <link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans"> <link rel="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; } |
Application layout
$HOME/article-ideas-generator ├── templates/ │ └── articles.html ├── static/ │ └── style.css ├── articles.py └── venv/
Step 3: Fetch page sections from Wikipedia:Requested articles
Let's write some code in a get_page_sections() function in $HOME/article-ideas-generator/articles.py to fetch page sections from Wikipedia:Requested articles.
This function takes page name as an argument and makes a GET request to the Action API to parse sections of the page.
API call consists of an endpoint https://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 sections
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' in data: return parsed_sections = data and data['parse'] and data['parse']['sections'] sections = [] for section in parsed_sections: if section['toclevel'] == 1: sections.append(section['line']) return sections
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 to render_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 '/' """ global PAGE results = [] PAGE = {'name': 'Wikipedia:Requested_articles', 'type': 'category'} results = get_page_sections(PAGE['name']) return render_template( "articles.html", results=results, pagetype=PAGE['type'])
Place the following Jinja 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.
{% if results %} <p>Choose a {{ pagetype }}</p> <form method="POST"> {% for pagename in results %} <button name="{{ pagetype }}" class="{{ pagetype }}" value="{{ pagename }}">{{ pagename }}</button> {% endfor %} {% else %} <p>Ooooops! We couldn't find any results.</p> <button onclick="location.href='/'">Start over</button> </form> {% endif %}
Place the following code in $HOME/article-ideas-generator/static/style.css for button styling.
Step 4: Get more sections based on user selection
Based on a category or section selected by the user in the previous step, we want to fetch subsections from Wikipedia:Requested articles.
Extend the Python Flask route / in $HOME/article-ideas-generator/articles.py to handle POST requests.
You can do so by adding both GET and POST in the methods argument list in the route decorator.
You can then obtain category selection available in a dictionary format from the request object, which is passed to get_page_sections() function for further processing.
Step 5: Collect and display articles with missing links
Let's write some code in a get_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 a GET 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 endpoint https://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 submodulelinksused as a generator module to get a set of links embedded on a pagegpllimit=20- number of links to fetch
defget_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 = data and data['query'] and data['query']['pages'] links = [] for page in pages.values(): if 'missing' in page: links.append(page['title']) return links
Next, extend the if block for the POST method in the / route in $HOME/article-ideas-generator/articles.py to call the get_red_links() function if the page from which the request is issued is of type subcategory.
if request.method == 'POST': if 'category' in request.form: PAGE['name'] = PAGE['name'] + '/' + request.form.to_dict()['category'] PAGE['type'] = 'subcategory' results = get_page_sections(PAGE['name']) elif 'subcategory' in request.form: PAGE['name'] = PAGE['name'] + '#' + request.form.to_dict()['subcategory'] PAGE['type'] = 'links' results = get_red_links(PAGE['name'])
Place the following Jinja template code in $HOME/article-ideas-generator/templates/articles.html.
It dynamically renders a list of links using data obtained via the API above.
{% if 'links' in pagetype %} <p>Some ideas for topics to write articles on:</p> {% for link in results %} <a href="//en.wikipedia.org/w/index.php?title={{ link }}&action=edit&redlink=1">{{ link }}</a><br> {% endfor %} <button onclick="location.href='/'">Take me to the homepage</button> {% endif %}
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 """ fromflaskimport Flask, request, render_template importrequests APP = 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 '/' """ global PAGE results = [] if request.method == 'POST': if 'category' in request.form: PAGE['name'] = PAGE['name'] + '/' + \ request.form.to_dict()['category'] PAGE['type'] = 'subcategory' results = get_page_sections(PAGE['name']) elif 'subcategory' in request.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']) return render_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' in data: return parsed_sections = data and data['parse'] and data['parse']['sections'] sections = [] for section in parsed_sections: if section['toclevel'] == 1: sections.append(section['line']) return sections defget_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 = data and data['query'] and data['query']['pages'] links = [] for page in pages.values(): if 'missing' in page: links.append(page['title']) return links if __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> <link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Amatic+SC:700"> <link rel="stylesheet" href="//tools-static.wmflabs.org/fontcdn/css?family=Josefin+Sans"> <link rel="stylesheet" href="/static/style.css"> <div> <h1>Article ideas generator</h1> {% if 'links' in pagetype %} <p>Some ideas for topics to write articles on:</p> {% for link in results %} <a href="//en.wikipedia.org/w/index.php?title={{ link }}&action=edit&redlink=1">{{ link }} </a> <br> {% endfor %} <button onclick="location.href='/'">Take me to the homepage</button> {% else %} {% if results %} <p>Choose a {{ pagetype }}</p> <form method="POST"> {% for pagename in results %} <button name="{{ pagetype }}" class="{{ pagetype }}" value="{{ pagename }}">{{ pagename }}</button> {% endfor %} {% else %} <p>Ooooops! We couldn't find any results.</p> <button onclick="location.href='/'">Start over</button> </form> {% endif %} {% endif %} </div> |
Next steps
- Contribute a demo app that you have developed using the MediaWiki API to this code samples repository.