Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ nosetests.xml
#PyPi
setup.cfg
.pypirc

# macOS
.DS_Store

# Test artifacts
pytest.xml
72 changes: 72 additions & 0 deletions examples/authentication_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Example of using Personal Access Token authentication with MediaWikiAPI.

Wikimedia API supports Personal Access Tokens for authentication.
See: https://api.wikimedia.org/wiki/Authentication

This example shows how to configure MediaWikiAPI with:
1. Personal Access Token authentication
2. Custom HTTP headers
"""

from mediawikiapi import MediaWikiAPI
from mediawikiapi.config import Config

# Example 1: Using Personal Access Token
# Get your token from: https://api.wikimedia.org/
access_token = "your_personal_access_token_here"

config_with_token = Config(access_token=access_token)
api_with_auth = MediaWikiAPI(config=config_with_token)

# Now all requests will include: Authorization: Bearer <token>
# page = api_with_auth.page("Python (programming language)")
# print(page.summary)


# Example 2: Using custom headers
custom_headers = {
"X-Custom-Header": "my-value",
"Accept-Language": "en-US",
}

config_with_headers = Config(custom_headers=custom_headers)
api_with_headers = MediaWikiAPI(config=config_with_headers)


# Example 3: Combining access token with custom headers
config_combined = Config(
access_token=access_token,
custom_headers={
"X-Application-Name": "MyWikipediaBot",
"X-Application-Version": "1.0.0",
},
)
api_combined = MediaWikiAPI(config=config_combined)


# Example 4: Override default User-Agent
config_custom_ua = Config(
custom_headers={"User-Agent": "MyCustomBot/1.0 (contact@example.com)"}
)
api_custom_ua = MediaWikiAPI(config=config_custom_ua)


# Example 5: Using with Wikimedia API (not Wikipedia)
# For authenticated requests to Wikimedia API endpoints
config_wikimedia = Config(
mediawiki_url="https://api.wikimedia.org/core/v1/wikipedia/en/",
access_token=access_token,
)
# Note: Wikimedia API has different endpoints and response formats
# This is just an example of how to configure authentication


if __name__ == "__main__":
print("Authentication examples loaded successfully!")
print("\nConfiguration with access token:")
print(f" Headers: {config_with_token.get_headers()}")
print("\nConfiguration with custom headers:")
print(f" Headers: {config_with_headers.get_headers()}")
print("\nCombined configuration:")
print(f" Headers: {config_combined.get_headers()}")
42 changes: 40 additions & 2 deletions mediawikiapi/config.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from datetime import timedelta
from typing import Union, Optional
from typing import Union, Optional, Dict
from .language import Language


class Config(object):
"""
Contains global configuration
Contains global configuration for MediaWiki API requests.
"""

DEFAULT_TIMEOUT = 3.0
Expand All @@ -22,7 +22,23 @@ def __init__(
timeout: Optional[float] = None,
rate_limit: Optional[Union[int, timedelta]] = None,
mediawiki_url: Optional[str] = None,
access_token: Optional[str] = None,
custom_headers: Optional[Dict[str, str]] = None,
):
"""
Initialize MediaWiki API configuration.

Args:
language: Language code for Wikipedia (e.g., 'en', 'fr'). Defaults to 'en'.
user_agent: Custom User-Agent string for requests. Defaults to library identifier.
timeout: Request timeout in seconds. Defaults to 3.0.
rate_limit: Minimum time between requests (int as milliseconds or timedelta).
mediawiki_url: Custom MediaWiki API URL. Defaults to Wikipedia URL pattern.
access_token: Personal Access Token for Wikimedia API authentication.
See https://api.wikimedia.org/wiki/Authentication
custom_headers: Additional HTTP headers to include in all requests.
Can override default headers including User-Agent.
"""
if language is not None:
self.__lang = Language(language)
else:
Expand All @@ -33,6 +49,8 @@ def __init__(
self.timeout: float = timeout or self.DEFAULT_TIMEOUT
self.user_agent: str = user_agent or self.DEFAULT_USER_AGENT
self.mediawiki_url: str = mediawiki_url or self.API_URL
self.access_token: Optional[str] = access_token
self.custom_headers: Dict[str, str] = custom_headers or {}

@classmethod
def donate_url(cls) -> str:
Expand Down Expand Up @@ -95,3 +113,23 @@ def rate_limit(self, rate_limit: Optional[Union[int, timedelta]] = None) -> None
self.__rate_limit = rate_limit
else:
self.__rate_limit = timedelta(milliseconds=rate_limit)

def get_headers(self) -> Dict[str, str]:
"""
Get HTTP headers for API requests including authentication.

Returns:
Dictionary of HTTP headers including User-Agent, Authorization (if access_token is set),
and any custom headers.
"""
headers = {"User-Agent": self.user_agent}

# Add Personal Access Token authentication if provided
# https://api.wikimedia.org/wiki/Authentication
if self.access_token:
headers["Authorization"] = f"Bearer {self.access_token}"

# Merge custom headers (custom headers can override defaults)
headers.update(self.custom_headers)

return headers
2 changes: 1 addition & 1 deletion mediawikiapi/requestsession.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def request(
if "action" not in params:
params["action"] = "query"

headers = {"User-Agent": config.user_agent}
headers = config.get_headers()

if (
self.__rate_limit_last_call
Expand Down
28 changes: 24 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ flake8 = "^7.1.2"
pytest = "^8.3.5"
pytest-cov = "^6.0.0"
pytest-vcr = "^1.0.2"
responses = "^0.25.0"
typing-extensions = "^4.12.2"
types-beautifulsoup4 = "^4.12.0.20250204"
types-requests = "^2.32.0.20250306"
Expand Down
Loading