Skip to content

Commit

Permalink
Add support for HTTP authentication (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
gbenson authored Oct 31, 2024
1 parent f94a2b2 commit c55fc13
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
19 changes: 18 additions & 1 deletion mediawiki/configuraton.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""Configuration module"""
from dataclasses import asdict, dataclass, field
from datetime import datetime, timedelta
from typing import Dict, Optional, Union
from typing import Any, Callable, Dict, Optional, Tuple, Union

URL: str = "https://github.com/barrust/mediawiki"
VERSION: str = "0.7.4"

HTTPAuthenticator = Union[Tuple[str, str], Callable[[Any], Any]]


@dataclass
class Configuration:
Expand All @@ -24,6 +26,7 @@ class Configuration:
_password: Optional[str] = field(default=None, init=False, repr=False)
_refresh_interval: Optional[int] = field(default=None, init=False, repr=False)
_use_cache: bool = field(default=True, init=False, repr=False)
_http_auth: Optional[HTTPAuthenticator] = field(default=None, init=False, repr=False)

# not in repr
_reset_session: bool = field(default=True, init=False, repr=False)
Expand All @@ -45,6 +48,7 @@ def __init__(
password: Optional[str] = None,
refresh_interval: Optional[int] = None,
use_cache: bool = True,
http_auth: Optional[HTTPAuthenticator] = None,
):
if api_url:
self._api_url = api_url
Expand Down Expand Up @@ -85,6 +89,9 @@ def __init__(
if timeout:
self.timeout = timeout

if http_auth:
self.http_auth = http_auth

def __repr__(self):
"""repr"""
keys = [
Expand Down Expand Up @@ -268,3 +275,13 @@ def timeout(self) -> Optional[float]:
def timeout(self, timeout: Optional[float]):
"""Set request timeout in seconds (or fractions of a second)"""
self._timeout = None if timeout is None else float(timeout)

@property
def http_auth(self) -> Optional[HTTPAuthenticator]:
"""tuple|callable: HTTP authenticator to use to access the mediawiki site"""
return self._http_auth

@http_auth.setter
def http_auth(self, http_auth: Optional[HTTPAuthenticator]):
"""Set the HTTP authenticator, if needed, to use to access the mediawiki site"""
self._http_auth = http_auth
19 changes: 17 additions & 2 deletions mediawiki/mediawiki.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import requests
import requests.exceptions as rex

from mediawiki.configuraton import VERSION, Configuration
from mediawiki.configuraton import VERSION, Configuration, HTTPAuthenticator
from mediawiki.exceptions import (
HTTPTimeoutError,
MediaWikiAPIURLError,
Expand Down Expand Up @@ -45,7 +45,8 @@ class MediaWiki:
username (str): The username to use to log into the MediaWiki
password (str): The password to use to log into the MediaWiki
proxies (str): A dictionary of specific proxies to use in the Requests libary
verify_ssl (bool|str): Verify SSL Certificates to be passed directly into the Requests library"""
verify_ssl (bool|str): Verify SSL Certificates to be passed directly into the Requests library
http_auth (tuple|callable): HTTP authenticator to be passed directly into the Requests library"""

__slots__ = [
"_version",
Expand Down Expand Up @@ -74,6 +75,7 @@ def __init__(
password: Optional[str] = None,
proxies: Optional[Dict] = None,
verify_ssl: Union[bool, str] = True,
http_auth: Optional[HTTPAuthenticator] = None,
):
"""Init Function"""
self._version = VERSION
Expand All @@ -92,6 +94,7 @@ def __init__(
password=password,
refresh_interval=None,
use_cache=True,
http_auth=http_auth,
)

# requests library parameters
Expand Down Expand Up @@ -299,6 +302,17 @@ def refresh_interval(self, refresh_interval: int):
"""Set the new cache refresh interval"""
self._config.refresh_interval = refresh_interval

@property
def http_auth(self) -> Optional[HTTPAuthenticator]:
"""tuple|callable: HTTP authenticator to use to access the mediawiki site"""
return self._config.http_auth

@http_auth.setter
def http_auth(self, http_auth: Optional[HTTPAuthenticator]):
"""Set the HTTP authenticator, if needed, to use to access the mediawiki site"""
self._config.http_auth = http_auth
self._session.auth = http_auth

def login(self, username: str, password: str, strict: bool = True) -> bool:
"""Login as specified user
Expand Down Expand Up @@ -390,6 +404,7 @@ def _reset_session(self):

headers = {"User-Agent": self._config.user_agent}
self._session = requests.Session()
self._session.auth = self._config.http_auth
self._session.headers.update(headers)
if self._config.proxies is not None:
self._session.proxies.update(self._config.proxies)
Expand Down
32 changes: 32 additions & 0 deletions tests/mediawiki_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(
password=None,
proxies=None,
verify_ssl=True,
http_auth=None,
):
"""new init"""

Expand All @@ -63,6 +64,7 @@ def __init__(
password=password,
proxies=proxies,
verify_ssl=verify_ssl,
http_auth=http_auth,
)

def __repr__(self):
Expand Down Expand Up @@ -167,6 +169,7 @@ def test_repr_function(self):
site = MediaWikiOverloaded()
res = (
"Configuration(api_url=https://en.wikipedia.org/w/api.php, category_prefix=Category, "
"http_auth=None, "
"lang=en, password=None, proxies=None, rate_limit=False, rate_limit_min_wait=0:00:00.050000, "
"refresh_interval=None, timeout=15.0, use_cache=True, "
"user_agent=python-mediawiki/VERSION-0.7.4/(https://github.com/barrust/mediawiki)/BOT, username=None, verify_ssl=True)"
Expand Down Expand Up @@ -267,6 +270,35 @@ def test_set_timeout_bad(self):
"""test that we raise the ValueError"""
self.assertRaises(ValueError, lambda: MediaWikiOverloaded(timeout="foo"))

def test_default_http_auth(self):
"""test default HTTP authenticator"""
site = MediaWikiOverloaded()
self.assertIs(site.http_auth, None)
self.assertIs(site._session.auth, None)

def test_init_user_agent(self):
"""test initializing the HTTP authenticator"""
auth_func = lambda http_request: http_request
site = MediaWikiOverloaded(http_auth=auth_func)
self.assertIs(site.http_auth, auth_func)
self.assertIs(site._session.auth, auth_func)

def test_set_http_auth(self):
"""test setting HTTP authenticator"""
site = MediaWikiOverloaded()
auth_tuple = ("username", "password")
site.http_auth = auth_tuple
self.assertIs(site.http_auth, auth_tuple)
self.assertIs(site._session.auth, auth_tuple)

def test_set_http_auth_none(self):
"""test setting HTTP authenticator to None"""
auth_func = lambda http_request: http_request
site = MediaWikiOverloaded(http_auth=auth_func)
site.http_auth = None
self.assertIs(site.http_auth, None)
self.assertIs(site._session.auth, None)

def test_memoized(self):
"""test returning the memoized cache"""
site = MediaWikiOverloaded()
Expand Down

0 comments on commit c55fc13

Please sign in to comment.