Repository: TheAlgorithms/Python

Issue:
web_programming/fetch_github_info.py err
<pre>message: Bad credentials. The API can&apos;t be accessed using username/password authentication. Please create a personal access token to access this endpoint: http://github.com/settings/tokens
documentation_url: https://docs.github.com/articles/creating-a-personal-access-token-for-the-command-line
</pre>


Discussion:

Resolving patch:
diff --git a/web_programming/fetch_github_info.py b/web_programming/fetch_github_info.py
--- a/web_programming/fetch_github_info.py
+++ b/web_programming/fetch_github_info.py
@@ -1,26 +1,50 @@
 #!/usr/bin/env python3
-
 """
 Created by sarathkaul on 14/11/19
+Updated by lawric1 on 24/11/20
 
-Basic authentication using an API password is deprecated and will soon no longer work.
-Visit https://developer.github.com/changes/2020-02-14-deprecating-password-auth
-for more information around suggested workarounds and removal dates.
-"""
+Authentication will be made via access token.
+To generate your personal access token visit https://github.com/settings/tokens.
+
+NOTE:
+Never hardcode any credential information in the code. Always use an environment
+file to store the private information and use the `os` module to get the information
+during runtime.
 
+Create a ".env" file in the root directory and write these two lines in that file
+with your token::
+
+#!/usr/bin/env bash
+export USER_TOKEN=""
+"""
+import os
+from typing import Any, Dict
 
 import requests
 
-_GITHUB_API = "https://api.github.com/user"
+BASE_URL = "https://api.github.com"
 
+# https://docs.github.com/en/free-pro-team@latest/rest/reference/users#get-the-authenticated-user
+AUTHENTICATED_USER_ENDPOINT = BASE_URL + "/user"
 
-def fetch_github_info(auth_user: str, auth_pass: str) -> dict:
+# https://github.com/settings/tokens
+USER_TOKEN = os.environ.get("USER_TOKEN", "")
+
+
+def fetch_github_info(auth_token: str) -> Dict[Any, Any]:
     """
     Fetch GitHub info of a user using the requests module
     """
-    return requests.get(_GITHUB_API, auth=(auth_user, auth_pass)).json()
-
-
-if __name__ == "__main__":
-    for key, value in fetch_github_info("<USER NAME>", "<PASSWORD>").items():
-        print(f"{key}: {value}")
+    headers = {
+        "Authorization": f"token {auth_token}",
+        "Accept": "application/vnd.github.v3+json",
+    }
+    return requests.get(AUTHENTICATED_USER_ENDPOINT, headers=headers).json()
+
+
+if __name__ == "__main__":  # pragma: no cover
+    if USER_TOKEN:
+        for key, value in fetch_github_info(USER_TOKEN).items():
+            print(f"{key}: {value}")
+    else:
+        raise ValueError("'USER_TOKEN' field cannot be empty.")


Test patch:
diff --git a/web_programming/test_fetch_github_info.py b/web_programming/test_fetch_github_info.py
new file mode 100644
--- /dev/null
+++ b/web_programming/test_fetch_github_info.py
@@ -0,0 +1,27 @@
+import json
+
+import requests
+
+from .fetch_github_info import AUTHENTICATED_USER_ENDPOINT, fetch_github_info
+
+
+def test_fetch_github_info(monkeypatch):
+    class FakeResponse:
+        def __init__(self, content) -> None:
+            assert isinstance(content, (bytes, str))
+            self.content = content
+
+        def json(self):
+            return json.loads(self.content)
+
+    def mock_response(*args, **kwargs):
+        assert args[0] == AUTHENTICATED_USER_ENDPOINT
+        assert "Authorization" in kwargs["headers"]
+        assert kwargs["headers"]["Authorization"].startswith("token ")
+        assert "Accept" in kwargs["headers"]
+        return FakeResponse(b'{"login":"test","id":1}')
+
+    monkeypatch.setattr(requests, "get", mock_response)
+    result = fetch_github_info("token")
+    assert result["login"] == "test"
+    assert result["id"] == 1