# Using Wikibooks/Scripting and the MediaWiki API

While this section is most useful for administrators, any user can make
use of the MediaWiki API, and hence this section should benefit any
Wikibookian.

### The MediaWiki API

MediaWiki offers a powerful API tool that can allow you to perform
virtually any task that you can do on-wiki using API calls. Consider the
following example:

https://en.wikipedia.org/w/api.php?action=query&prop=revisions&titles=Pet_door&rvslots=\*&rvprop=content&formatversion=2

Try it on your web browser. You\'ll get a page that looks like this:

> MediaWiki API result
>
> This is the HTML representation of the JSON format. HTML is good for
> debugging, but is unsuitable for application use.
>
> Specify the `<var>`{=html}format`</var>`{=html} parameter to change
> the output format. To see the non-HTML representation of the JSON
> format, set format=json.
>
> See the complete documentation, or the API help for more information.

and a bunch of JSON text, which contains the content of the title \"Pet
door\".

How does this help? Well, if you want to get the details of 100
articles, you do not have to manually visit all of them! Just use a
simple bash script that would do this work for you.

### Scripting

Now, how does this apply to a Wikibooks administrator? Suppose you\'re
working on a large deletion request. If there are
500 of the pages, manually deleting each page is likely to take hours
and cause frustration to you! Instead, use a Python 3 script! The
MediaWiki API page on MediaWiki.org
contains a list of all such API calls, and contains helpful example code
from which the code in this page was derived from.

First, the script. Here it is. The annotations explain what\'s going on.

``` python
import requests # import the necessary modules

S = requests.Session()

URL = "https://en.wikibooks.org/w/api.php" # the API location for Wikibooks

file_object = open("pages_to_delete.txt", "r", encoding="utf-8") # open the file in utf-8 encoding (otherwise files with accents and non-Latin characters may not work)
f1 = file_object.readlines()

# Step 1: Retrieve a login token
PARAMS_1 = {
    "action": "query",
    "meta": "tokens",
    "type": "login",
    "format": "json"
}

R = S.get(url=URL, params=PARAMS_1)
DATA = R.json()

LOGIN_TOKEN = DATA['query']['tokens']['logintoken']

# Step 2: Send a post request to login.
# Obtain credentials for BOT_USERNAME & BOT_PASSWORDS via Special:BotPasswords
# (https://www.mediawiki.org/wiki/Special:BotPasswords)
# You will need to make sure that the bot username has the necessary rights to perform the requested task
PARAMS_2 = {
    "action": "login",
    "lgname": "BOT_USERNAME",
    "lgpassword": "BOT_PASSWORD",
    "lgtoken": LOGIN_TOKEN,
    "format": "json"
}

R = S.post(URL, data=PARAMS_2)

# Step 3: While logged in, get an CSRF token
PARAMS_3 = {
    "action": "query",
    "meta": "tokens",
    "format": "json"
}

R = S.get(url=URL, params=PARAMS_3)
DATA = R.json()

CSRF_TOKEN = DATA["query"]["tokens"]["csrftoken"]

# Step 4: Send a post request to delete each page
for x in f1:
    # depends on what you're doing - you may need to tweak the script a bit
    if ("Pinyin" not in x):
        continue
    # remove possible trailing spaces
    if (x.isalnum() == False):
        xx = x.rstrip(x[-1])
    else:
        xx = x
    print(xx)
    # tell Wikibooks to delete!
    PARAMS_4 = {
    'action':"delete",
    'title':xx,
    'token':CSRF_TOKEN,
    'format':"json"
    }
    R = S.post(URL, data=PARAMS_4)
    DATA = R.json()
    print(DATA)

print("done")
```

So how do you use it? Put this in a Python file, put all the pages to
delete in `pages_to_delete.txt`, and run it. Watch the output - if there
are errors, MediaWiki will let you know. Common issues include

-   cannot find the requests module - install it using `pip`
-   not adapting the script. For instance, if you\'re performing
    undeletions, you may want to put the new pages in a different
    location from the old ones. Make sure that they work as expected!
    You may want to perform a test run first.

If you\'re stuck at any point, just ask at WB:RR.

Now, this can be easily adapted. Suppose instead of deleting, you want
to undelete these pages. Then all that is needed is replace `PARAMS_4`
to

``` python
 PARAMS_4 = {
 "action": "undelete",
 "format": "json",
 "token": CSRF_TOKEN,
 "title": xx,
 "reason": "per [[WB:RFU]]"
  }
```

Even non-admins can benefit from the use of the script. Suppose you\'re
trying to mass-move pages. In that case, `PARAMS_4` can be changed to

``` python
PARAMS_4 = {
    "action": "move",
    "format": "json",
    "from": "Current title",
    "to": "Page with new title",
    "reason": "Typo",
    "movetalk": "1", # move the corresponding talk page
    "noredirect": "1", # suppress redirects when moving (only available to reviewers and higher)
    "token": CSRF_TOKEN
}
```

While unlikely, it is possible to run into ratelimit issues when running
scripts such as these. In that case, if you\'re not yet a reviewer, the
best choice would be to become one.

