Wiki.Action (mediawiki_client v0.6.0)
View SourceAdapter to the MediaWiki Action API
To create an API client call new/2 and specify a site to connect to.
Most functions return an api session which holds the latest results and can be reused to pipe chain requests together. As an example, when getting site statistics:
Request
Wiki.Action.new(:dewiki)
|> Wiki.Action.get!(
action: :query,
meta: :siteinfo,
siprop: :statistics
)Response
%Wiki.Action.Session{
...
result: %{
"batchcomplete" => true,
"query" => %{
"statistics" => %{
"activeusers" => 19393,
"admins" => 188,
"articles" => 2583636,
"edits" => 211249646,
"images" => 130213,
"jobs" => 0,
"pages" => 7164514,
"queued-massmessages" => 0,
"users" => 3716049
}
}
},
...
}Authentication
Log in with a bot password:
Request
authed_api = Wiki.Action.new(:enwiki)
|> Wiki.Action.authenticate!(
Application.get_env(:example_app, :bot_username),
Application.get_env(:example_app, :bot_password)
)Response
%Wiki.Action.Session{
...
result: %{
"login" => %{
"lguserid" => 2,
"lgusername" => "Admin",
"result" => "Success"
},
...
}Now the client can be used to get a token and make an edit:
Request
{:ok, api, token} = Wiki.Action.get_token(authed_api, :csrf)
Wiki.Action.post!(api,
action: :edit,
title: "Sandbox",
assert: :user,
token: token,
appendtext: "~~~~ was here."
)Response
%Wiki.Action.Session{
...
result: %{
"edit" => %{
"contentmodel" => "wikitext",
"new" => true,
"newrevid" => 38,
"newtimestamp" => "2025-11-06T13:36:43Z",
"oldrevid" => 0,
"pageid" => 20,
"result" => "Success",
"title" => "Sandbox",
"watched" => true
}
},
...
}Continuation
Any action that returns more items than the allowed batch size will provide
one or more -continue fields which can be transparently used to stream
results from multiple requests.
Request
Wiki.Action.new(:dewiki)
|> Wiki.Action.stream(
action: :query,
list: :recentchanges,
rclimit: 5
)
|> Stream.flat_map(fn response -> response["query"]["recentchanges"] end)
|> Stream.map(fn rc -> rc["timestamp"] <> " " <> rc["title"] end)
|> Stream.each(&IO.puts/1)
|> Stream.run()Response
2025-11-06T13:46:12Z Peter Schnupp
2025-11-06T13:46:03Z Kategorie:Mitglied der Hall of Fame des deutschen Sports
2025-11-06T13:46:02Z Portal:Radsport/Qualitätssicherung
2025-11-06T13:46:02Z Kategorie:Wikipedia:DHBW/2025-Controlling
2025-11-06T13:46:02Z Öffentlicher Personennahverkehr in Wien
2025-11-06T13:45:59Z Brouchaud
2025-11-06T13:45:43Z Steingutfabrik Paetsch
2025-11-06T13:45:38Z Kriegerdenkmal Feldmoching (1923)
2025-11-06T13:45:38Z Hotel Bellevue (Ruhla)
2025-11-06T13:45:35Z Emil und die Detektive
2025-11-06T13:45:33Z Parasesarma
...Wikibase
The Wikidata project provides structured data for other wiki projects, and can be accessed through the Action API.
Examples:
Search for entities called "alphabet",
Wiki.Action.new(:wikidatawiki)
|> Wiki.Action.get!(
action: :wbsearchentities,
search: "alphabet",
language: :en
)Search for entities with "Frank Zappa" anywhere in the description or contents,
Wiki.Action.new(:wikidatawiki)
|> Wiki.Action.get!(
action: :wbsearchentities,
search: "alphabet",
language: :en
)Retrieve all data about a specific entity with ID "Q42",
Wiki.Action.new(:wikidatawiki)
|> Wiki.Action.get!(
action: :wbgetentities,
ids: "Q42"
)Defaults
A few parameters are automatically added for convenience, but can be overridden if desired:
- The
:formatparameter defaults to:json. :formatversiondefaults to2.
Summary
Types
:debug- Turn on verbose logging by setting totrue:plug- In testing, replace network requests with a Plug-like mock:timeout- API call timeout, in seconds. Defaults to 60.0s:user_agent- Override the generic, built in user-agent header string.
Can be a SiteMatrix.Spec as returned by Wiki.SiteMatrix.get, dbname as an
atom like :enwiki, or raw api.php endpoint for the wiki you will connect
to. For example, "https://en.wikipedia.org/w/api.php"
Functions
Make requests to authenticate a client session. This should only be done using a bot username and password, which can be created for any normal user account.
Assertive variant of authenticate
Make an API GET request
Assertive variant of get.
Helper to make a token request
Create a new client session
Make an API POST request.
Assertive variant of post.
Make a GET request and follow continuations until exhausted or the stream is closed.
Upload a file from a local path
Upload a file with content passed directly, as binary or a stream
Types
@type client_options() :: [client_option()]
:debug- Turn on verbose logging by setting totrue:plug- In testing, replace network requests with a Plug-like mock:timeout- API call timeout, in seconds. Defaults to 60.0s:user_agent- Override the generic, built in user-agent header string.
@type site_action_handle() :: Wiki.SiteMatrix.Spec.t() | atom() | String.t()
Can be a SiteMatrix.Spec as returned by Wiki.SiteMatrix.get, dbname as an
atom like :enwiki, or raw api.php endpoint for the wiki you will connect
to. For example, "https://en.wikipedia.org/w/api.php"
Functions
@spec authenticate(Wiki.Action.Session.t(), String.t(), String.t()) :: Wiki.Action.Session.result()
Make requests to authenticate a client session. This should only be done using a bot username and password, which can be created for any normal user account.
Arguments
session- Base session pointing to a wiki.username- Bot username, may be different than the final logged-in username.password- Bot password. Protect this string, it allows others to take on-wiki actions on your behalf.
Return value
Authenticated session object.
@spec authenticate!(Wiki.Action.Session.t(), String.t(), String.t()) :: Wiki.Action.Session.t()
Assertive variant of authenticate
@spec get( Wiki.Action.Session.t(), keyword() ) :: Wiki.Action.Session.result()
Make an API GET request
Arguments
session-Wiki.Action.Sessionobject.params- Keyword list of query parameters as atoms or strings.
Return value
Session object with its .result populated.
@spec get!( Wiki.Action.Session.t(), keyword() ) :: Wiki.Action.Session.t()
Assertive variant of get.
@spec get_token(Wiki.Action.Session.t(), atom()) :: {:ok, Wiki.Action.Session.t(), token :: binary()} | {:error, any()}
Helper to make a token request
The Action API requires various tokens for login, edit actions, and so on. This function simplifies the request.
TODO: support multiple atoms
@spec new(site_action_handle(), client_options()) :: Wiki.Action.Session.t()
Create a new client session
Arguments
site- target wiki and its action endpointopts- configuration options which modify client behavior
Examples
Connect to German Wikipedia:
api = Wiki.Action.new(:dewiki)Connect to a local development wiki:
api = Wiki.Action.new("http://dev.wiki.local.wmftest.net:8080/w/api.php")
@spec post( Wiki.Action.Session.t(), keyword() ) :: Wiki.Action.Session.result()
Make an API POST request.
Arguments
session-Wiki.Action.Sessionobject. If credentials are required for this action, you should have created this object with theauthenticate/3function.params- Keyword list of query parameters as atoms or strings.
Return value
Session object with a populated :result attribute.
@spec post!( Wiki.Action.Session.t(), keyword() ) :: Wiki.Action.Session.t()
Assertive variant of post.
@spec stream( Wiki.Action.Session.t(), keyword() ) :: Enumerable.t()
Make a GET request and follow continuations until exhausted or the stream is closed.
Arguments
session-Wiki.Action.Sessionobject.params- Keyword list of query parameters as atoms or strings.
Return value
Enumerable Stream, where each returned chunk is a raw result map, possibly
containing multiple records. This corresponds to session.result from the other
entry points.
@spec upload(Wiki.Action.Session.t(), binary(), keyword()) :: Wiki.Action.Session.result()
Upload a file from a local path
Request
authed_api |> Wiki.Action.upload("/tmp/Triops_closeup.jpg")Response
{:ok, %Wiki.Action.Session{
...
result: %{
"upload" => %{
"filename" => "Triops_closeup.jpg",
"imageinfo" => %{
"bitdepth" => 8,
"canonicaltitle" => "File:Triops closeup.jpg",
"comment" => "",
"commonmetadata" => [
%{
"name" => "Copyright",
"value" => [%{"name" => 0, "value" => "Karsten Grabow"}]
},
%{
"name" => "JPEGFileComment",
"value" => [%{"name" => 0, "value" => "Copyright Karsten Grabow"}]
}
],
"descriptionurl" => "http://dev.wiki.local.wmftest.net:8080/wiki/File:Triops_closeup.jpg",
"extmetadata" => %{
"DateTime" => %{
"hidden" => "",
"source" => "mediawiki-metadata",
"value" => "2025-11-07T21:31:17Z"
},
"ObjectName" => %{
"source" => "mediawiki-metadata",
"value" => "Triops closeup"
}
},
"height" => 827,
"html" => "..."
"mediatype" => "BITMAP",
"metadata" => [
%{
"name" => "Copyright",
"value" => [%{"name" => 0, "value" => "Karsten Grabow"}]
},
%{
"name" => "JPEGFileComment",
"value" => [%{"name" => 0, "value" => "Copyright Karsten Grabow"}]
},
%{"name" => "MEDIAWIKI_EXIF_VERSION", "value" => 2}
],
"mime" => "image/jpeg",
"parsedcomment" => "",
"sha1" => "12ce3375983eb929fba91bf5267ad932929e9217",
"size" => 222944,
"timestamp" => "2025-11-07T21:31:17Z",
"url" => "http://dev.wiki.local.wmftest.net:8080/w/images/4/45/Triops_closeup.jpg",
"user" => "Admin",
"userid" => 2,
"width" => 1280
},
"result" => "Success"
}
},
}}Upload with additional parameters:
authed_api |> Wiki.Action.upload(
"/tmp/Test.jpg",
text: "This is a test file",
comment: "Upload initial draft from Elixir",
ignorewarnings: true
)
@spec upload_file_content( Wiki.Action.Session.t(), filename :: binary(), content :: binary() | Enumerable.t(), keyword() ) :: Wiki.Action.Session.result()
Upload a file with content passed directly, as binary or a stream